forked from vmtree/sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mimcSponge.js
62 lines (54 loc) · 1.69 KB
/
mimcSponge.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// source: https://github.com/iden3/circomlib/blob/v0.5.5/src/mimcsponge.js
const { BigNumber } = require('@ethersproject/bignumber');
const { hexZeroPad } = require('@ethersproject/bytes');
const { keccak256 } = require('@ethersproject/keccak256');
const { F } = require('./utils');
const SEED = "mimcsponge";
const NROUNDS = 220;
function getConstants(seed, nRounds) {
if (typeof seed === "undefined") seed = SEED;
if (typeof nRounds === "undefined") nRounds = NROUNDS;
const cts = new Array(nRounds);
let c = keccak256(Buffer.from(seed));
for (let i=1; i<nRounds; i++) {
c = keccak256(c);
const n1 = BigNumber.from(c).mod(BigNumber.from(F.p.toString()));
const c2 = hexZeroPad(n1.toHexString(), 64);
cts[i] = F.e(BigNumber.from(c2).toString());
}
cts[0] = F.e(0);
cts[cts.length - 1] = F.e(0);
return cts;
};
const cts = getConstants(SEED, NROUNDS);
function mimcHash(_xL_in, _xR_in, _k) {
let xL = F.e(_xL_in);
let xR = F.e(_xR_in);
const k = F.e(_k);
for (let i=0; i<NROUNDS; i++) {
const c = cts[i];
const t = (i==0) ? F.add(xL, k) : F.add(F.add(xL, k), c);
const xR_tmp = F.e(xR);
if (i < (NROUNDS - 1)) {
xR = xL;
xL = F.add(xR_tmp, F.pow(t, 5));
} else {
xR = F.add(xR_tmp, F.pow(t, 5));
}
}
return {
xL: F.normalize(xL),
xR: F.normalize(xR),
};
};
module.exports = function mimcSponge(arr) {
let R = F.zero;
let C = F.zero;
for (let i=0; i<arr.length; i++) {
R = F.add(R, F.e(arr[i]));
const S = mimcHash(R, C, F.zero);
R = S.xL;
C = S.xR;
}
return F.normalize(R);
};