Skip to content

Commit

Permalink
make hash to group return canonical result directly
Browse files Browse the repository at this point in the history
  • Loading branch information
mitschabaude committed Apr 9, 2024
1 parent ab55588 commit be034f2
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 14 deletions.
19 changes: 7 additions & 12 deletions crypto/poseidon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,13 @@ function makeHashToGroup(hash: (i: bigint[]) => bigint) {
let digest = hash(input);
let g = fieldToGroup(digest);
if (g === undefined) return undefined;
// we split the y coordinate into two elements, x0 = -sqrt(y^2) and x1 = sqrt(y^2)
// then put the even root into x0, and the odd one into x1 so APIs equal even tho the underlying algorithms to calculate the sqrt differ
// we do the same in-snark - so both APIs are deterministic
let isEven = g.y % 2n === 0n;
let gy_neg = Fp.negate(g.y);
return {
x: g.x,
y: {
x0: isEven ? g.y : gy_neg,
x1: isEven ? gy_neg : g.y,
},
};

// the y coordinate is calculated using a square root, so it has two possible values
// to make the output deterministic, we negate y if it is odd
// we do the same in-snark, so both APIs match
let isOdd = (g.y & 1n) === 1n;
let y = isOdd ? Fp.negate(g.y) : g.y;
return { x: g.x, y };
};
}

Expand Down
5 changes: 3 additions & 2 deletions crypto/poseidon.unit-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { test, Random } from '../../lib/testing/property.js';
import { Test } from '../../snarky.js';
import { FieldConst } from '../../lib/provable/core/fieldvar.js';
import { MlArray } from '../../lib/ml/base.js';
import { Fp } from './finite-field.js';

function checkTestVectors(
testVectors: { input: string[]; output: string }[],
Expand Down Expand Up @@ -34,11 +35,11 @@ test(Random.array(Random.field, Random.nat(20)), (xs) => {
);

expect(g1).toBeDefined();

expect(g1.x).toEqual(FieldConst.toBigint(g2x));

let g2y_ = FieldConst.toBigint(g2y);
expect(g1.y.x0 === g2y_ || g1.y.x1 === g2y_).toEqual(true);
expect(g1.y === g2y_ || Fp.negate(g1.y) === g2y_).toEqual(true);
expect(Fp.isEven(g1.y)).toEqual(true);
});

console.log('poseidon hashToGroup implementations match! 🎉');
Expand Down

0 comments on commit be034f2

Please sign in to comment.