circomlib/src/mimc7.js
src/mimc7.jsRaw
1const Scalar = require("ffjavascript").Scalar;
2const ZqField = require("ffjavascript").ZqField;
3
4const Web3Utils = require("web3-utils");
5const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
6exports.F = F;
7
8const SEED = "mimc";
9const NROUNDS = 91;
10
11exports.getIV = (seed) => {
12 if (typeof seed === "undefined") seed = SEED;
13 const c = Web3Utils.keccak256(seed+"_iv");
14 const cn = Scalar.FromString(Web3Utils.toBN(c).toString());
15 const iv = cn.mod(F.p);
16 return iv;
17};
18
19exports.getConstants = (seed, nRounds) => {
20 if (typeof seed === "undefined") seed = SEED;
21 if (typeof nRounds === "undefined") nRounds = NROUNDS;
22 const cts = new Array(nRounds);
23 let c = Web3Utils.keccak256(SEED);
24 for (let i=1; i<nRounds; i++) {
25 c = Web3Utils.keccak256(c);
26
27 const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.p.toString()));
28 const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
29 cts[i] = Scalar.fromString(Web3Utils.toBN(c2).toString());
30 }
31 cts[0] = F.e(0);
32 return cts;
33};
34
35const cts = exports.getConstants(SEED, 91);
36
37exports.hash = (_x_in, _k) =>{
38 const x_in = F.e(_x_in);
39 const k = F.e(_k);
40 let r;
41 for (let i=0; i<NROUNDS; i++) {
42 const c = cts[i];
43 const t = (i==0) ? F.add(x_in, k) : F.add(F.add(r, k), c);
44 r = F.pow(t, 7);
45 }
46 return F.add(r, k);
47};
48
49exports.multiHash = (arr, key) => {
50 let r;
51 if (typeof(key) === "undefined") {
52 r = F.zero;
53 } else {
54 r = key;
55 }
56 for (let i=0; i<arr.length; i++) {
57 r = F.add(
58 F.add(
59 r,
60 arr[i]
61 ),
62 exports.hash(F.e(arr[i]), r)
63 );
64 }
65 return r;
66};