circomlibjs-hinkal-fork 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +21 -0
- package/.vscode/launch.json +40 -0
- package/README.md +18 -0
- package/badmsges.md +0 -0
- package/build/main.cjs +27397 -0
- package/hardhat.config.js +6 -0
- package/main.js +25 -0
- package/package.json +40 -0
- package/rollup.cjs.config.js +16 -0
- package/src/babyjub.js +139 -0
- package/src/eddsa.js +286 -0
- package/src/evmasm.js +209 -0
- package/src/mimc7.js +78 -0
- package/src/mimc7_gencontract.js +113 -0
- package/src/mimc7_print_iv.js +18 -0
- package/src/mimc7_printconstants.js +26 -0
- package/src/mimc7_printcontract.js +14 -0
- package/src/mimcsponge.js +100 -0
- package/src/mimcsponge_gencontract.js +125 -0
- package/src/mimcsponge_printconstants.js +25 -0
- package/src/mimcsponge_printcontract.js +14 -0
- package/src/pedersen_hash.js +132 -0
- package/src/pedersen_printbases.js +36 -0
- package/src/poseidon_constants.js +207 -0
- package/src/poseidon_constants.json +206 -0
- package/src/poseidon_constants_opt.js +24806 -0
- package/src/poseidon_constants_opt.json +24806 -0
- package/src/poseidon_gencontract.js +209 -0
- package/src/poseidon_opt.js +119 -0
- package/src/poseidon_printcontract.js +14 -0
- package/src/poseidon_printmatrix.js +22 -0
- package/src/poseidon_reference.js +83 -0
- package/src/poseidon_wasm.js +440 -0
- package/src/smt.js +309 -0
- package/src/smt_hashes_mimc.js +16 -0
- package/src/smt_hashes_poseidon.js +17 -0
- package/src/smt_memdb.js +57 -0
- package/src/testblake.js +18 -0
- package/tools/poseidon_optimize_constants.js +301 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import {Scalar, ZqField, utils} from "ffjavascript";
|
|
4
|
+
const { unstringifyBigInts } = utils;
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// Version to write in hexadecimal
|
|
8
|
+
function stringifyBigInts(o) {
|
|
9
|
+
if ((typeof(o) == "bigint") || o.eq !== undefined) {
|
|
10
|
+
return "0x"+o.toString(16);
|
|
11
|
+
} else if (o instanceof Uint8Array) {
|
|
12
|
+
return Scalar.fromRprLE(o, 0);
|
|
13
|
+
} else if (Array.isArray(o)) {
|
|
14
|
+
return o.map(stringifyBigInts);
|
|
15
|
+
} else if (typeof o == "object") {
|
|
16
|
+
const res = {};
|
|
17
|
+
const keys = Object.keys(o);
|
|
18
|
+
keys.forEach( (k) => {
|
|
19
|
+
res[k] = stringifyBigInts(o[k]);
|
|
20
|
+
});
|
|
21
|
+
return res;
|
|
22
|
+
} else {
|
|
23
|
+
return o;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const { C, M } = unstringifyBigInts(JSON.parse(fs.readFileSync(path.join("src", "poseidon_constants.json"), "utf8")));
|
|
28
|
+
|
|
29
|
+
const N_ROUNDS_F = 8;
|
|
30
|
+
const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68];
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
function matrix_inverse(Fr, A) {
|
|
34
|
+
const m = A.length;
|
|
35
|
+
const B=[];
|
|
36
|
+
for (let i=0; i<m; i++) {
|
|
37
|
+
if (A[i].length != m) throw new Error("Matrix is not square");
|
|
38
|
+
B[i] = [];
|
|
39
|
+
for (let j=0; j<m; j++) B[i][j] = A[i][j];
|
|
40
|
+
for (let j=0; j<m; j++) B[i][m+j] = i==j ? Fr.one : Fr.zero;
|
|
41
|
+
}
|
|
42
|
+
const n=2*m;
|
|
43
|
+
let h=0; // curRow
|
|
44
|
+
let k=0; // curColumn
|
|
45
|
+
|
|
46
|
+
// Triangularize
|
|
47
|
+
while ((h<m)&&(k<n)) {
|
|
48
|
+
// Find the pivot
|
|
49
|
+
let i_max;
|
|
50
|
+
for (i_max=h; (i_max<m)&&(Fr.isZero(B[i_max][k])); i_max++);
|
|
51
|
+
if (i_max==m) throw new Error("Matrix is not inveritible");
|
|
52
|
+
|
|
53
|
+
[B[h], B[i_max]] = [B[i_max], B[h]];
|
|
54
|
+
|
|
55
|
+
const inv_pivot = Fr.inv(B[h][k]);
|
|
56
|
+
|
|
57
|
+
for (let i=h+1; i<m; i++) {
|
|
58
|
+
const f = Fr.mul(B[i][k], inv_pivot);
|
|
59
|
+
B[i][k] = Fr.zero;
|
|
60
|
+
for (let j=k+1; j<n; j++) B[i][j] = Fr.sub(B[i][j], Fr.mul(B[h][j], f));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
B[h][k] = Fr.one;
|
|
64
|
+
for (let j=k+1; j<n; j++) B[h][j] = Fr.mul(B[h][j], inv_pivot);
|
|
65
|
+
h++;
|
|
66
|
+
k++;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (let i=m-2; i>=0; i--) {
|
|
70
|
+
for (let i2=i+1; i2<m; i2++) {
|
|
71
|
+
const f = B[i][i2];
|
|
72
|
+
for (let k=m; k<n; k++) B[i][k] = Fr.sub(B[i][k], Fr.mul(f,B[i2][k]));
|
|
73
|
+
B[i][i2] = Fr.zero;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
for (let i=0; i<m; i++) {
|
|
78
|
+
B[i] = B[i].slice(-m);
|
|
79
|
+
}
|
|
80
|
+
return B;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function matrix_print(Fr, A) {
|
|
84
|
+
for (let i=0; i<A.length; i++) {
|
|
85
|
+
let S = "";
|
|
86
|
+
for (let j=0;j<A[i].length; j++) {
|
|
87
|
+
if (j>0) S = S + ", ";
|
|
88
|
+
S = S + Fr.toString(A[i][j]);
|
|
89
|
+
}
|
|
90
|
+
console.log(S);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function vec_print(Fr, v) {
|
|
95
|
+
for (let i=0; i<v.length; i++) {
|
|
96
|
+
console.log(Fr.toString(v[i]));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function vec_mul_matrix(Fr, v, A) {
|
|
101
|
+
checkSquare(A);
|
|
102
|
+
if (v.length != A.length) throw new Error("Invalid vec mul sizes");
|
|
103
|
+
const res = [];
|
|
104
|
+
for (let j=0; j<v.length; j++) {
|
|
105
|
+
res[j] = Fr.zero;
|
|
106
|
+
for (let i=0; i<A.length; i++) {
|
|
107
|
+
res[j] = Fr.add(res[j], Fr.mul(v[i], A[i][j]));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return res;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function matrix_mul_vec(Fr, A, v) {
|
|
114
|
+
checkSquare(A);
|
|
115
|
+
if (v.length != A.length) throw new Error("Invalid vec mul sizes");
|
|
116
|
+
const res = [];
|
|
117
|
+
for (let i=0; i<v.length; i++) {
|
|
118
|
+
res[i] = Fr.zero;
|
|
119
|
+
for (let j=0; j<A.length; j++) {
|
|
120
|
+
res[i] = Fr.add(res[i], Fr.mul(A[i][j], v[j]));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return res;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function matrix_mul(Fr, A, B) {
|
|
127
|
+
checkSquare(A);
|
|
128
|
+
if (A.length != B.length) throw new Error("multiplication different sizes");
|
|
129
|
+
const res = [];
|
|
130
|
+
for (let i=0; i<A.length; i++) {
|
|
131
|
+
res[i] = [];
|
|
132
|
+
for (let j=0; j<A.length; j++) {
|
|
133
|
+
res[i][j] = Fr.zero;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
for (let i=0; i<A.length; i++) {
|
|
137
|
+
for (let j=0; j<A.length; j++) {
|
|
138
|
+
for (let k=0; k<A.length; k++) {
|
|
139
|
+
res[i][j] = Fr.add( res[i][j], Fr.mul(A[i][k], B[k][j]) );
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return res;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function matrix_traspose(A) {
|
|
148
|
+
checkSquare(A);
|
|
149
|
+
const res = [];
|
|
150
|
+
for (let i=0; i<A.length; i++) {
|
|
151
|
+
res[i] = [];
|
|
152
|
+
for (let j=0; j<A.length; j++) {
|
|
153
|
+
res[i][j] = A[j][i];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return res;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function checkSquare(A) {
|
|
160
|
+
const n= A.length;
|
|
161
|
+
for (let i=0; i<A.length; i++) {
|
|
162
|
+
if (A[i].length != n) throw new Error("Matrix is not square");
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
function convertConstants(Fr, t, C, M) {
|
|
169
|
+
let res = [];
|
|
170
|
+
const nRoundsF = N_ROUNDS_F;
|
|
171
|
+
const nRoundsP = N_ROUNDS_P[t - 2];
|
|
172
|
+
|
|
173
|
+
const Minv = matrix_inverse(Fr, M);
|
|
174
|
+
|
|
175
|
+
for (let k=0; k<t; k++) res.push(C[k]);
|
|
176
|
+
|
|
177
|
+
for (let r=0; r<nRoundsF/2-1; r++) {
|
|
178
|
+
const cr = C.slice((r+1)*t, (r+1)*t+t);
|
|
179
|
+
const crt = vec_mul_matrix(Fr, cr, Minv);
|
|
180
|
+
for (let k=0; k<t; k++) res.push(crt[k]);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const partialConst = [];
|
|
184
|
+
let acc = [];
|
|
185
|
+
for (let k=0; k<t; k++) acc[k] = C[(nRoundsF/2+ nRoundsP -1 +1)*t+k];
|
|
186
|
+
|
|
187
|
+
for (let r=nRoundsF/2+nRoundsP-1; r>=nRoundsF/2; r--) {
|
|
188
|
+
const accp = vec_mul_matrix(Fr, acc, Minv);
|
|
189
|
+
partialConst.push(accp[0]);
|
|
190
|
+
accp[0] = Fr.zero;
|
|
191
|
+
for (let k=0; k<t; k++) acc[k] = Fr.add(accp[k], C[(r-1+1)*t+k]);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const accp = vec_mul_matrix(Fr, acc, Minv);
|
|
195
|
+
for (let k=0; k<t; k++) res.push(accp[k]);
|
|
196
|
+
|
|
197
|
+
for (let i=0; i<partialConst.length; i++) res.push(partialConst[partialConst.length-1-i]);
|
|
198
|
+
|
|
199
|
+
for (let r=nRoundsF/2 + nRoundsP; r< nRoundsF+nRoundsP-1; r++) {
|
|
200
|
+
const cr = C.slice((r+1)*t, (r+1)*t+t);
|
|
201
|
+
const crt = vec_mul_matrix(Fr, cr, Minv);
|
|
202
|
+
for (let k=0; k<t; k++) res.push(crt[k]);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return res;
|
|
206
|
+
}
|
|
207
|
+
/*
|
|
208
|
+
m_{0,0} m_{0,1} m_{0,2} ........... m_{0,t-1}
|
|
209
|
+
w_0 1 0 ........... 0
|
|
210
|
+
w_1 0 1 ........... 0
|
|
211
|
+
. . . . .
|
|
212
|
+
. . . . .
|
|
213
|
+
w_{t-2} 0 0 ........... 1
|
|
214
|
+
*/
|
|
215
|
+
// Returns sparse matrix with format: [m_{0,0}, m_0, ..... m_{t-2}, m_{0,1}, ... m_{0, t-1}]
|
|
216
|
+
|
|
217
|
+
function sparseFactorize(Fr, m) {
|
|
218
|
+
|
|
219
|
+
const m_hat = [];
|
|
220
|
+
const mp = [];
|
|
221
|
+
const w = [];
|
|
222
|
+
for (let i=0; i<m.length; i++) {
|
|
223
|
+
mp[i] = [];
|
|
224
|
+
if (i<m.length-1) m_hat[i] = [];
|
|
225
|
+
for (let j=0; j<m.length; j++) {
|
|
226
|
+
if ((i>0) &&(j>0)) {
|
|
227
|
+
m_hat[i-1][j-1] = m[i][j];
|
|
228
|
+
mp[i][j] = m[i][j];
|
|
229
|
+
} else {
|
|
230
|
+
mp[i][j] = ((i==0)&&(j==0)) ? Fr.one : Fr.zero;
|
|
231
|
+
}
|
|
232
|
+
if ((i>0)&&(j==0)) w[i-1] = m[i][j];
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
const m_hat_inv = matrix_inverse(Fr, m_hat);
|
|
236
|
+
const wp = matrix_mul_vec(Fr, m_hat_inv, w);
|
|
237
|
+
|
|
238
|
+
const S = [];
|
|
239
|
+
|
|
240
|
+
S.push(m[0][0]);
|
|
241
|
+
for (let k=0; k<wp.length; k++) S.push(wp[k]);
|
|
242
|
+
for (let k=1; k<m.length; k++) S.push(m[0][k]);
|
|
243
|
+
|
|
244
|
+
return [mp, S];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function calculatePS(Fr, t, M) {
|
|
248
|
+
const nRoundsP = N_ROUNDS_P[t - 2];
|
|
249
|
+
const sparse = [];
|
|
250
|
+
let m=M;
|
|
251
|
+
|
|
252
|
+
for (let i=0; i<nRoundsP; i++) {
|
|
253
|
+
const [mp, mpp] = sparseFactorize(Fr, m);
|
|
254
|
+
sparse.push(mpp);
|
|
255
|
+
m = matrix_mul(Fr, M, mp);
|
|
256
|
+
}
|
|
257
|
+
const P = m;
|
|
258
|
+
const S = [];
|
|
259
|
+
|
|
260
|
+
for (let i=0; i<sparse.length; i++) {
|
|
261
|
+
for (let k=0; k<sparse[sparse.length-1-i].length; k++) {
|
|
262
|
+
S.push(sparse[sparse.length-1-i][k]);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return [P, S];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
async function run() {
|
|
271
|
+
// Prime bn128
|
|
272
|
+
const Fr = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
|
273
|
+
|
|
274
|
+
let opt = {
|
|
275
|
+
C: [],
|
|
276
|
+
M: [],
|
|
277
|
+
P: [],
|
|
278
|
+
S: []
|
|
279
|
+
};
|
|
280
|
+
for (let i=1; i<=16; i++) {
|
|
281
|
+
const oM = matrix_traspose(M[i-1]);
|
|
282
|
+
const oC = convertConstants(Fr, i+1, C[i-1], oM);
|
|
283
|
+
const [oP, oS] = calculatePS(Fr, i+1, oM);
|
|
284
|
+
opt.C.push(oC);
|
|
285
|
+
opt.M.push(oM);
|
|
286
|
+
opt.P.push(oP);
|
|
287
|
+
opt.S.push(oS);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
opt = stringifyBigInts(opt);
|
|
291
|
+
|
|
292
|
+
fs.writeFileSync(path.join( "src", "poseidon_constants_opt.js"), "export default " + JSON.stringify(opt, null, 1), "utf8");
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
run().then(()=> {
|
|
296
|
+
process.exit(0);
|
|
297
|
+
}, (err) => {
|
|
298
|
+
// console.log(err);
|
|
299
|
+
console.log(err.stack);
|
|
300
|
+
process.exit(1);
|
|
301
|
+
});
|