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