permute<F extends PastaFieldElement<F>> static method
void
permute<
F extends PastaFieldElement<F>>( - List<F> state,
- 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]);
}
}