micro-zk-proofs
Version:
Create & verify zero-knowledge SNARK proofs in parallel, using noble cryptography
49 lines • 1.66 kB
JavaScript
/**
* MiMC: Efficient Encryption and Cryptographic
* Hashing with Minimal Multiplicative Complexity.
* https://eprint.iacr.org/2016/492.pdf
* https://crypto.ethereum.org/bounties/mimc-hash-challenge
* @module
*/
import { bn254 } from '@noble/curves/bn254';
import { keccak_256 } from '@noble/hashes/sha3';
const Fr = bn254.fields.Fr;
const SEED = 'mimcsponge';
const NROUNDS = 220;
export function getIV(seed = SEED) {
return Fr.create(Fr.fromBytes(keccak_256(`${seed}_iv`)));
}
export function getConstants(seed = SEED, nRounds = NROUNDS) {
const cts = [BigInt(0)];
let c = keccak_256(seed);
for (let i = 0; i < nRounds - 2; i++)
cts.push(Fr.create(Fr.fromBytes((c = keccak_256(c)))));
cts.push(BigInt(0));
return cts;
}
const CONSTANTS = getConstants(SEED, NROUNDS);
export function hash(L, R, k) {
for (let i = 0; i < NROUNDS; i++) {
const t = i == 0 ? Fr.addN(L, k) : Fr.addN(Fr.addN(L, k), CONSTANTS[i]);
const tmp = Fr.addN(R, Fr.pow(t, BigInt(5)));
if (i < NROUNDS - 1) {
R = L;
L = tmp;
}
else
R = tmp;
}
return { xL: Fr.create(L), xR: Fr.create(R) };
}
export function multiHash(lst, key = Fr.ZERO, numOutputs = 1) {
let R = Fr.ZERO;
let C = Fr.ZERO;
for (let i = 0; i < lst.length; i++)
({ xL: R, xR: C } = hash(Fr.addN(R, BigInt(lst[i])), C, key));
const out = [R];
for (let i = 1; i < numOutputs; i++, out.push(R))
({ xL: R, xR: C } = hash(R, C, key));
const res = out.map((x) => Fr.create(x));
return numOutputs === 1 ? res[0] : res;
}
//# sourceMappingURL=mimcsponge.js.map