permute<F extends PastaFieldElement<F>> static method

void permute<F extends PastaFieldElement<F>>(
  1. List<F> state,
  2. PoseidonSpec<F> spec
)

Implementation

static void permute<F extends PastaFieldElement<F>>(
  List<F> state,
  PoseidonSpec<F> spec,
) {
  final constants = spec.constants;
  final mds = constants.mds;
  final roundConstants = constants.constants;
  final int t = state.length;
  final int rF = spec.fullRounds() ~/ 2;
  final int rP = spec.partialRounds();
  final F zero = spec.zero();
  // Matrix multiplication
  void applyMds(List<F> s) {
    final newState = List<F>.filled(t, zero);
    for (int i = 0; i < t; i++) {
      for (int j = 0; j < t; j++) {
        newState[i] = newState[i] + (mds[i][j] * s[j]);
      }
    }
    for (int i = 0; i < t; i++) {
      s[i] = newState[i];
    }
  }

  // Full round: apply S-box to all state words
  void fullRound(List<F> s, List<F> rcs) {
    for (int i = 0; i < t; i++) {
      s[i] = spec.sbox(s[i] + rcs[i]);
    }
    applyMds(s);
  }

  // Partial round: S-box only on first state word
  void partialRound(List<F> s, List<F> rcs) {
    for (int i = 0; i < t; i++) {
      s[i] = s[i] + rcs[i];
    }
    s[0] = spec.sbox(s[0]);
    applyMds(s);
  }

  // Sequence of rounds: rF full rounds, rP partial rounds, rF full rounds
  final rounds = <void Function(List<F>, List<F>)>[];
  rounds.addAll(List.filled(rF, fullRound));
  rounds.addAll(List.filled(rP, partialRound));
  rounds.addAll(List.filled(rF, fullRound));

  // Apply rounds in order with corresponding round constants
  for (int i = 0; i < rounds.length; i++) {
    rounds[i](state, roundConstants[i]);
  }
}