poseidon: refactor params

This commit is contained in:
Paul Miller 2023-08-21 16:16:40 +00:00
parent d285fcce06
commit e7ac5e85d3
No known key found for this signature in database
GPG Key ID: 697079DA6878B89B

View File

@ -80,18 +80,17 @@ export function splitConstants(rc: bigint[], t: number) {
} }
export function poseidon(opts: PoseidonOpts) { export function poseidon(opts: PoseidonOpts) {
const { t, Fp, rounds, sboxFn, reversePartialPowIdx } = validateOpts(opts); const _opts = validateOpts(opts);
const halfRoundsFull = Math.floor(opts.roundsFull / 2); const { Fp, mds, roundConstants, rounds, roundsPartial, sboxFn, t } = _opts;
const partialIdx = reversePartialPowIdx ? t - 1 : 0; const halfRoundsFull = _opts.roundsFull / 2;
const partialIdx = _opts.reversePartialPowIdx ? t - 1 : 0;
const poseidonRound = (values: bigint[], isFull: boolean, idx: number) => { const poseidonRound = (values: bigint[], isFull: boolean, idx: number) => {
values = values.map((i, j) => Fp.add(i, opts.roundConstants[idx][j])); values = values.map((i, j) => Fp.add(i, roundConstants[idx][j]));
if (isFull) values = values.map((i) => sboxFn(i)); if (isFull) values = values.map((i) => sboxFn(i));
else values[partialIdx] = sboxFn(values[partialIdx]); else values[partialIdx] = sboxFn(values[partialIdx]);
// Matrix multiplication // Matrix multiplication
values = opts.mds.map((i) => values = mds.map((i) => i.reduce((acc, i, j) => Fp.add(acc, Fp.mulN(i, values[j])), Fp.ZERO));
i.reduce((acc, i, j) => Fp.add(acc, Fp.mulN(i, values[j])), Fp.ZERO)
);
return values; return values;
}; };
const poseidonHash = function poseidonHash(values: bigint[]) { const poseidonHash = function poseidonHash(values: bigint[]) {
@ -105,7 +104,7 @@ export function poseidon(opts: PoseidonOpts) {
// Apply r_f/2 full rounds. // Apply r_f/2 full rounds.
for (let i = 0; i < halfRoundsFull; i++) values = poseidonRound(values, true, round++); for (let i = 0; i < halfRoundsFull; i++) values = poseidonRound(values, true, round++);
// Apply r_p partial rounds. // Apply r_p partial rounds.
for (let i = 0; i < opts.roundsPartial; i++) values = poseidonRound(values, false, round++); for (let i = 0; i < roundsPartial; i++) values = poseidonRound(values, false, round++);
// Apply r_f/2 full rounds. // Apply r_f/2 full rounds.
for (let i = 0; i < halfRoundsFull; i++) values = poseidonRound(values, true, round++); for (let i = 0; i < halfRoundsFull; i++) values = poseidonRound(values, true, round++);
@ -114,6 +113,6 @@ export function poseidon(opts: PoseidonOpts) {
return values; return values;
}; };
// For verification in tests // For verification in tests
poseidonHash.roundConstants = opts.roundConstants; poseidonHash.roundConstants = roundConstants;
return poseidonHash; return poseidonHash;
} }