arnaucube
arnaucube/circomlibPublic Self-hosted repository
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};