UNPKG

micro-zk-proofs

Version:

Create & verify zero-knowledge SNARK proofs in parallel, using noble cryptography

49 lines 1.66 kB
/** * 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