@solarity/zkit 0.2.6 → 0.3.0-rc.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.
Files changed (79) hide show
  1. package/dist/core/CircuitZKit.d.ts +22 -21
  2. package/dist/core/CircuitZKit.d.ts.map +1 -1
  3. package/dist/core/CircuitZKit.js +28 -43
  4. package/dist/core/CircuitZKit.js.map +1 -1
  5. package/dist/core/protocols/AbstractImplementer.d.ts +15 -0
  6. package/dist/core/protocols/AbstractImplementer.d.ts.map +1 -0
  7. package/dist/core/protocols/AbstractImplementer.js +36 -0
  8. package/dist/core/protocols/AbstractImplementer.js.map +1 -0
  9. package/dist/core/protocols/Groth16Implementer.d.ts +10 -0
  10. package/dist/core/protocols/Groth16Implementer.d.ts.map +1 -0
  11. package/dist/core/protocols/Groth16Implementer.js +50 -0
  12. package/dist/core/protocols/Groth16Implementer.js.map +1 -0
  13. package/dist/core/protocols/PlonkImplementer.d.ts +10 -0
  14. package/dist/core/protocols/PlonkImplementer.d.ts.map +1 -0
  15. package/dist/core/protocols/PlonkImplementer.js +51 -0
  16. package/dist/core/protocols/PlonkImplementer.js.map +1 -0
  17. package/dist/core/protocols/index.d.ts +4 -0
  18. package/dist/core/protocols/index.d.ts.map +1 -0
  19. package/dist/core/protocols/index.js +10 -0
  20. package/dist/core/protocols/index.js.map +1 -0
  21. package/dist/core/templates/verifier_groth16.vy.ejs +3 -3
  22. package/dist/core/templates/verifier_plonk.sol.ejs +779 -0
  23. package/dist/core/templates/verifier_plonk.vy.ejs +650 -0
  24. package/dist/index.d.ts +4 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +6 -1
  27. package/dist/index.js.map +1 -1
  28. package/dist/types/circuit-zkit.d.ts +0 -34
  29. package/dist/types/circuit-zkit.d.ts.map +1 -1
  30. package/dist/types/proof-utils.d.ts +7 -0
  31. package/dist/types/proof-utils.d.ts.map +1 -0
  32. package/dist/types/proof-utils.js +3 -0
  33. package/dist/types/proof-utils.js.map +1 -0
  34. package/dist/types/protocols/groth16.d.ts +28 -0
  35. package/dist/types/protocols/groth16.d.ts.map +1 -0
  36. package/dist/types/protocols/groth16.js +3 -0
  37. package/dist/types/protocols/groth16.js.map +1 -0
  38. package/dist/types/protocols/index.d.ts +31 -0
  39. package/dist/types/protocols/index.d.ts.map +1 -0
  40. package/dist/types/protocols/index.js +19 -0
  41. package/dist/types/protocols/index.js.map +1 -0
  42. package/dist/types/protocols/plonk.d.ts +26 -0
  43. package/dist/types/protocols/plonk.d.ts.map +1 -0
  44. package/dist/types/{types.js → protocols/plonk.js} +1 -1
  45. package/dist/types/protocols/plonk.js.map +1 -0
  46. package/package.json +1 -1
  47. package/src/core/CircuitZKit.ts +40 -63
  48. package/src/core/protocols/AbstractImplementer.ts +67 -0
  49. package/src/core/protocols/Groth16Implementer.ts +29 -0
  50. package/src/core/protocols/PlonkImplementer.ts +32 -0
  51. package/src/core/protocols/index.ts +3 -0
  52. package/src/core/templates/verifier_groth16.vy.ejs +3 -3
  53. package/src/core/templates/verifier_plonk.sol.ejs +779 -0
  54. package/src/core/templates/verifier_plonk.vy.ejs +650 -0
  55. package/src/index.ts +5 -1
  56. package/src/types/circuit-zkit.ts +0 -31
  57. package/src/types/proof-utils.ts +9 -0
  58. package/src/types/protocols/groth16.ts +21 -0
  59. package/src/types/protocols/index.ts +49 -0
  60. package/src/types/protocols/plonk.ts +28 -0
  61. package/dist/config/config.d.ts +0 -27
  62. package/dist/config/config.d.ts.map +0 -1
  63. package/dist/config/config.js +0 -19
  64. package/dist/config/config.js.map +0 -1
  65. package/dist/core/CircomZKit.d.ts +0 -39
  66. package/dist/core/CircomZKit.d.ts.map +0 -1
  67. package/dist/core/CircomZKit.js +0 -94
  68. package/dist/core/CircomZKit.js.map +0 -1
  69. package/dist/core/ManagerZKit.d.ts +0 -97
  70. package/dist/core/ManagerZKit.d.ts.map +0 -1
  71. package/dist/core/ManagerZKit.js +0 -222
  72. package/dist/core/ManagerZKit.js.map +0 -1
  73. package/dist/types/types.d.ts +0 -46
  74. package/dist/types/types.d.ts.map +0 -1
  75. package/dist/types/types.js.map +0 -1
  76. package/dist/utils/utils.d.ts +0 -18
  77. package/dist/utils/utils.d.ts.map +0 -1
  78. package/dist/utils/utils.js +0 -58
  79. package/dist/utils/utils.js.map +0 -1
@@ -0,0 +1,779 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ /* AUTOGENERATED FILE BY HARDHAT-ZKIT. DO NOT EDIT. */
4
+
5
+ pragma solidity >=0.7.0 <0.9.0;
6
+
7
+ contract <%=verifier_id%> {
8
+ // Omega
9
+ uint256 constant W1 = <%=w%>;
10
+ // Scalar field size
11
+ uint256 constant SCALAR_SIZE = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
12
+ // Base field size
13
+ uint256 constant BASE_SIZE = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
14
+
15
+ // [1]_1
16
+ uint256 constant G1_X = 1;
17
+ uint256 constant G1_Y = 2;
18
+ // [1]_2
19
+ uint256 constant G2_X1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
20
+ uint256 constant G2_X2 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
21
+ uint256 constant G2_Y1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
22
+ uint256 constant G2_Y2 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
23
+
24
+ // Verification Key data
25
+ uint32 constant N = <%=2**power%>;
26
+
27
+ uint256 constant QM_X = <%=Qm[0]%>;
28
+ uint256 constant QM_Y = <%=Qm[0] == "0" ? "0" : Qm[1]%>;
29
+ uint256 constant QL_X = <%=Ql[0]%>;
30
+ uint256 constant QL_Y = <%=Ql[0] == "0" ? "0" : Ql[1]%>;
31
+ uint256 constant QR_X = <%=Qr[0]%>;
32
+ uint256 constant QR_Y = <%=Qr[0] == "0" ? "0" : Qr[1]%>;
33
+ uint256 constant QO_X = <%=Qo[0]%>;
34
+ uint256 constant QO_Y = <%=Qo[0] == "0" ? "0" : Qo[1]%>;
35
+ uint256 constant QC_X = <%=Qc[0]%>;
36
+ uint256 constant QC_Y = <%=Qc[0] == "0" ? "0" : Qc[1]%>;
37
+ uint256 constant S1_X = <%=S1[0]%>;
38
+ uint256 constant S1_Y = <%=S1[0] == "0" ? "0" : S1[1]%>;
39
+ uint256 constant S2_X = <%=S2[0]%>;
40
+ uint256 constant S2_Y = <%=S2[0] == "0" ? "0" : S2[1]%>;
41
+ uint256 constant S3_X = <%=S3[0]%>;
42
+ uint256 constant S3_Y = <%=S3[0] == "0" ? "0" : S3[1]%>;
43
+ uint256 constant K1 = <%=k1%>;
44
+ uint256 constant K2 = <%=k2%>;
45
+ uint256 constant X2_X1 = <%=X_2[0][0]%>;
46
+ uint256 constant X2_X2 = <%=X_2[0][1]%>;
47
+ uint256 constant X2_Y1 = <%=X_2[1][0]%>;
48
+ uint256 constant X2_Y2 = <%=X_2[1][1]%>;
49
+
50
+ // Proof values offsets
51
+ // Byte offset of every parameter of the proof array
52
+ // Polynomial commitments
53
+ uint256 constant P_A = 0;
54
+ uint256 constant P_B = 64;
55
+ uint256 constant P_C = 128;
56
+ uint256 constant P_Z = 192;
57
+ uint256 constant P_T1 = 256;
58
+ uint256 constant P_T2 = 320;
59
+ uint256 constant P_T3 = 384;
60
+ uint256 constant P_WX_I = 448;
61
+ uint256 constant P_WX_IW = 512;
62
+ // Opening evaluations
63
+ uint256 constant P_EVAL_A = 576;
64
+ uint256 constant P_EVAL_B = 608;
65
+ uint256 constant P_EVAL_C = 640;
66
+ uint256 constant P_EVAL_S1 = 672;
67
+ uint256 constant P_EVAL_S2 = 704;
68
+ uint256 constant P_EVAL_ZW = 736;
69
+
70
+ // Memory data
71
+ // Challenges
72
+ uint256 constant P_ALPHA = 0;
73
+ uint256 constant P_BETA = 32;
74
+ uint256 constant P_GAMMA = 64;
75
+ uint256 constant P_XI = 96;
76
+ uint256 constant P_XIN = 128;
77
+ uint256 constant P_BETA_XI = 160;
78
+ uint256 constant P_V1 = 192;
79
+ uint256 constant P_V2 = 224;
80
+ uint256 constant P_V3 = 256;
81
+ uint256 constant P_V4 = 288;
82
+ uint256 constant P_V5 = 320;
83
+ uint256 constant P_U = 352;
84
+
85
+ uint256 constant P_PI = 384;
86
+ uint256 constant P_EVAL_R0 = 416;
87
+ uint256 constant P_D = 448;
88
+ uint256 constant P_F = 512;
89
+ uint256 constant P_E = 576;
90
+ uint256 constant P_TMP = 640;
91
+ uint256 constant P_ALPHA2 = 704;
92
+ uint256 constant P_ZH = 736;
93
+ uint256 constant P_ZH_INV = 768;
94
+
95
+ uint256 constant P_EVAL_L1 = 800;
96
+ <% let pLastMem = 800+32*nPublic %>
97
+ uint256 constant P_TOTAL_SIZE = <%=pLastMem%>;
98
+
99
+ function verifyProof(
100
+ uint256[24] memory proofArr_,
101
+ uint256[<%=nPublic%>] memory publicSignals_
102
+ ) public view returns (bool verified_) {
103
+ assembly {
104
+ function inverse(a_, q_) -> inv {
105
+ let t := 0
106
+ let newt := 1
107
+ let r := q_
108
+ let newr := a_
109
+ let quotient := 0
110
+ let aux := 0
111
+
112
+ for { } newr { } {
113
+ quotient := sdiv(r, newr)
114
+ aux := sub(t, mul(quotient, newt))
115
+ t := newt
116
+ newt:= aux
117
+
118
+ aux := sub(r,mul(quotient, newr))
119
+ r := newr
120
+ newr := aux
121
+ }
122
+
123
+ if gt(r, 1) { revert(0,0) }
124
+ if slt(t, 0) { t:= add(t, q_) }
125
+
126
+ inv := t
127
+ }
128
+
129
+ function inverseArray(pVals_, n_) {
130
+ let pAux := mload(64) // Point to the next free position
131
+ let pIn := pVals_
132
+ let lastPIn := add(pVals_, mul(n_, 32)) // Read n elements
133
+ let acc := mload(pIn) // Read the first element
134
+ pIn := add(pIn, 32) // Point to the second element
135
+ let inv := 0
136
+
137
+ for { } lt(pIn, lastPIn) {
138
+ pAux := add(pAux, 32)
139
+ pIn := add(pIn, 32)
140
+ }
141
+ {
142
+ mstore(pAux, acc)
143
+ acc := mulmod(acc, mload(pIn), SCALAR_SIZE)
144
+ }
145
+
146
+ acc := inverse(acc, SCALAR_SIZE)
147
+
148
+ // At this point pAux point to the next free position, we subtract 1 to point to the last used
149
+ pAux := sub(pAux, 32)
150
+ // pIn points to the n+1 element, we subtract to point to n
151
+ pIn := sub(pIn, 32)
152
+ lastPIn := pVals_ // We don't process the first element
153
+
154
+ for { } gt(pIn, lastPIn) {
155
+ pAux := sub(pAux, 32)
156
+ pIn := sub(pIn, 32)
157
+ }
158
+ {
159
+ inv := mulmod(acc, mload(pAux), SCALAR_SIZE)
160
+ acc := mulmod(acc, mload(pIn), SCALAR_SIZE)
161
+ mstore(pIn, inv)
162
+ }
163
+ // pIn points to first element, we just set it
164
+ mstore(pIn, acc)
165
+ }
166
+
167
+ function checkField(signal_) -> res_ {
168
+ res_ := lt(signal_, SCALAR_SIZE)
169
+ }
170
+
171
+ function checkInput(proof_) -> res_ {
172
+ res_ := checkField(mload(add(proof_, P_EVAL_A)))
173
+ res_ := and(res_, checkField(mload(add(proof_, P_EVAL_B))))
174
+ res_ := and(res_, checkField(mload(add(proof_, P_EVAL_C))))
175
+ res_ := and(res_, checkField(mload(add(proof_, P_EVAL_S1))))
176
+ res_ := and(res_, checkField(mload(add(proof_, P_EVAL_S2))))
177
+ res_ := and(res_, checkField(mload(add(proof_, P_EVAL_ZW))))
178
+ }
179
+
180
+ function calculateChallenges(pMem_, proof_, pubSignals_) {
181
+ let beta := 0
182
+ let aux := 0
183
+ let mIn := mload(64) // Pointer to the next free memory position
184
+
185
+ // Compute challenge.beta & challenge.gamma
186
+ mstore(mIn, QM_X)
187
+ mstore(add(mIn, 32), QM_Y)
188
+ mstore(add(mIn, 64), QL_X)
189
+ mstore(add(mIn, 96), QL_Y)
190
+ mstore(add(mIn, 128), QR_X)
191
+ mstore(add(mIn, 160), QR_Y)
192
+ mstore(add(mIn, 192), QO_X)
193
+ mstore(add(mIn, 224), QO_Y)
194
+ mstore(add(mIn, 256), QC_X)
195
+ mstore(add(mIn, 288), QC_Y)
196
+ mstore(add(mIn, 320), S1_X)
197
+ mstore(add(mIn, 352), S1_Y)
198
+ mstore(add(mIn, 384), S2_X)
199
+ mstore(add(mIn, 416), S2_Y)
200
+ mstore(add(mIn, 448), S3_X)
201
+ mstore(add(mIn, 480), S3_Y)
202
+
203
+ <% for (let i = 0; i < nPublic; i++) {%>mstore(add(mIn, <%=512 + i * 32%>), mload(add(pubSignals_, <%=i * 32%>)))
204
+ <% } %>
205
+ mstore(add(mIn, <%=512 + nPublic * 32%>), mload(add(proof_, P_A)))
206
+ mstore(add(mIn, <%=512 + nPublic * 32 + 32%>), mload(add(proof_, add(P_A, 32))))
207
+ mstore(add(mIn, <%=512 + nPublic * 32 + 64%>), mload(add(proof_, P_B)))
208
+ mstore(add(mIn, <%=512 + nPublic * 32 + 96%>), mload(add(proof_, add(P_B, 32))))
209
+ mstore(add(mIn, <%=512 + nPublic * 32 + 128%>), mload(add(proof_, P_C)))
210
+ mstore(add(mIn, <%=512 + nPublic * 32 + 160%>), mload(add(proof_, add(P_C, 32))))
211
+
212
+ beta := mod(keccak256(mIn, <%=704 + 32 * nPublic%>), SCALAR_SIZE)
213
+ mstore(add(pMem_, P_BETA), beta)
214
+
215
+ // challenges.gamma
216
+ mstore(
217
+ add(pMem_, P_GAMMA),
218
+ mod(keccak256(add(pMem_, P_BETA), 32), SCALAR_SIZE)
219
+ )
220
+
221
+ // challenges.alpha
222
+ mstore(mIn, mload(add(pMem_, P_BETA)))
223
+ mstore(add(mIn, 32), mload(add(pMem_, P_GAMMA)))
224
+ mstore(add(mIn, 64), mload(add(proof_, P_Z)))
225
+ mstore(add(mIn, 96), mload(add(proof_, add(P_Z, 32))))
226
+
227
+ aux := mod(keccak256(mIn, 128), SCALAR_SIZE)
228
+ mstore(add(pMem_, P_ALPHA), aux)
229
+ mstore(add(pMem_, P_ALPHA2), mulmod(aux, aux, SCALAR_SIZE))
230
+
231
+ // challenges.xi
232
+ mstore(mIn, aux)
233
+ mstore(add(mIn, 32), mload(add(proof_, P_T1)))
234
+ mstore(add(mIn, 64), mload(add(proof_, add(P_T1, 32))))
235
+ mstore(add(mIn, 96), mload(add(proof_, P_T2)))
236
+ mstore(add(mIn, 128), mload(add(proof_, add(P_T2, 32))))
237
+ mstore(add(mIn, 160), mload(add(proof_, P_T3)))
238
+ mstore(add(mIn, 192), mload(add(proof_, add(P_T3, 32))))
239
+
240
+ aux := mod(keccak256(mIn, 224), SCALAR_SIZE)
241
+ mstore(add(pMem_, P_XI), aux)
242
+
243
+ // challenges.v
244
+ mstore(mIn, aux)
245
+ mstore(add(mIn, 32), mload(add(proof_, P_EVAL_A)))
246
+ mstore(add(mIn, 64), mload(add(proof_, P_EVAL_B)))
247
+ mstore(add(mIn, 96), mload(add(proof_, P_EVAL_C)))
248
+ mstore(add(mIn, 128), mload(add(proof_, P_EVAL_S1)))
249
+ mstore(add(mIn, 160), mload(add(proof_, P_EVAL_S2)))
250
+ mstore(add(mIn, 192), mload(add(proof_, P_EVAL_ZW)))
251
+
252
+ let v1 := mod(keccak256(mIn, 224), SCALAR_SIZE)
253
+ mstore(add(pMem_, P_V1), v1)
254
+
255
+ // challenges.beta * challenges.xi
256
+ mstore(add(pMem_, P_BETA_XI), mulmod(beta, aux, SCALAR_SIZE))
257
+
258
+ // challenges.xi^n
259
+ <% for (let i = 0; i < power; i++) {%>aux := mulmod(aux, aux, SCALAR_SIZE)
260
+ <% } %>
261
+ mstore(add(pMem_, P_XIN), aux)
262
+
263
+ // Zh
264
+ aux := addmod(aux, sub(SCALAR_SIZE, 1), SCALAR_SIZE)
265
+ mstore(add(pMem_, P_ZH), aux)
266
+ mstore(add(pMem_, P_ZH_INV), aux) // We will invert later together with lagrange pols
267
+
268
+ // challenges.v^2, challenges.v^3, challenges.v^4, challenges.v^5
269
+ aux := mulmod(v1, v1, SCALAR_SIZE)
270
+ mstore(add(pMem_, P_V2), aux)
271
+ aux := mulmod(aux, v1, SCALAR_SIZE)
272
+ mstore(add(pMem_, P_V3), aux)
273
+ aux := mulmod(aux, v1, SCALAR_SIZE)
274
+ mstore(add(pMem_, P_V4), aux)
275
+ aux := mulmod(aux, v1, SCALAR_SIZE)
276
+ mstore(add(pMem_, P_V5), aux)
277
+
278
+ // challenges.u
279
+ mstore(mIn, mload(add(proof_, P_WX_I)))
280
+ mstore(add(mIn, 32), mload(add(proof_, add(P_WX_I, 32))))
281
+ mstore(add(mIn, 64), mload(add(proof_, P_WX_IW)))
282
+ mstore(add(mIn, 96), mload(add(proof_, add(P_WX_IW, 32))))
283
+
284
+ mstore(add(pMem_, P_U), mod(keccak256(mIn, 128), SCALAR_SIZE))
285
+ }
286
+
287
+ function calculateLagrange(pMem_) {
288
+ let w := 1
289
+
290
+ for { let i := 0 } lt(i, <%=nPublic%>) { i := add(i, 1) } {
291
+ mstore(
292
+ add(pMem_, add(P_EVAL_L1, mul(i, 32))),
293
+ mulmod(
294
+ N,
295
+ mod(
296
+ add(sub(mload(add(pMem_, P_XI)), w), SCALAR_SIZE),
297
+ SCALAR_SIZE
298
+ ),
299
+ SCALAR_SIZE
300
+ )
301
+ )
302
+
303
+ w := mulmod(w, W1, SCALAR_SIZE)
304
+ }
305
+
306
+ inverseArray(add(pMem_, P_ZH_INV), <%=nPublic + 1%>)
307
+
308
+ let zh := mload(add(pMem_, P_ZH))
309
+ w := 1
310
+
311
+ for { let i := 0 } lt(i, <%=nPublic%>) { i := add(i, 1) } {
312
+ mstore(
313
+ add(pMem_, add(P_EVAL_L1, mul(i, 32))),
314
+ mulmod(
315
+ w,
316
+ mulmod(
317
+ mload(add(pMem_, add(P_EVAL_L1, mul(i, 32)))),
318
+ zh,
319
+ SCALAR_SIZE
320
+ ),
321
+ SCALAR_SIZE
322
+ )
323
+ )
324
+
325
+ w := mulmod(w, W1, SCALAR_SIZE)
326
+ }
327
+ }
328
+
329
+ function calculatePI(pMem_, pPub_) {
330
+ let pi := 0
331
+
332
+ for { let i := 0 } lt(i, <%=nPublic%>) { i := add(i, 1) } {
333
+ pi := addmod(
334
+ sub(
335
+ SCALAR_SIZE,
336
+ mulmod(
337
+ mload(add(pMem_, add(P_EVAL_L1, mul(i, 32)))),
338
+ mload(add(pPub_, mul(i, 32))),
339
+ SCALAR_SIZE
340
+ )
341
+ ),
342
+ pi,
343
+ SCALAR_SIZE
344
+ )
345
+ }
346
+
347
+ mstore(add(pMem_, P_PI), pi)
348
+ }
349
+
350
+ function calculateR0(pMem_, proof_) {
351
+ let e1 := mload(add(pMem_, P_PI))
352
+
353
+ let e2 := mulmod(
354
+ mload(add(pMem_, P_EVAL_L1)),
355
+ mload(add(pMem_, P_ALPHA2)),
356
+ SCALAR_SIZE
357
+ )
358
+
359
+ let e3a := addmod(
360
+ mload(add(proof_, P_EVAL_A)),
361
+ mulmod(
362
+ mload(add(pMem_, P_BETA)),
363
+ mload(add(proof_, P_EVAL_S1)),
364
+ SCALAR_SIZE
365
+ ),
366
+ SCALAR_SIZE
367
+ )
368
+ e3a := addmod(e3a, mload(add(pMem_, P_GAMMA)), SCALAR_SIZE)
369
+
370
+ let e3b := addmod(
371
+ mload(add(proof_, P_EVAL_B)),
372
+ mulmod(
373
+ mload(add(pMem_, P_BETA)),
374
+ mload(add(proof_, P_EVAL_S2)),
375
+ SCALAR_SIZE
376
+ ),
377
+ SCALAR_SIZE
378
+ )
379
+ e3b := addmod(e3b, mload(add(pMem_, P_GAMMA)), SCALAR_SIZE)
380
+
381
+ let e3c := addmod(
382
+ mload(add(proof_, P_EVAL_C)),
383
+ mload(add(pMem_, P_GAMMA)),
384
+ SCALAR_SIZE
385
+ )
386
+
387
+ let e3 := mulmod(mulmod(e3a, e3b, SCALAR_SIZE), e3c, SCALAR_SIZE)
388
+ e3 := mulmod(e3, mload(add(proof_, P_EVAL_ZW)), SCALAR_SIZE)
389
+ e3 := mulmod(e3, mload(add(pMem_, P_ALPHA)), SCALAR_SIZE)
390
+
391
+ let r0 := addmod(
392
+ e1,
393
+ mod(sub(SCALAR_SIZE, e2), SCALAR_SIZE),
394
+ SCALAR_SIZE
395
+ )
396
+ r0 := addmod(r0, mod(sub(SCALAR_SIZE, e3), SCALAR_SIZE), SCALAR_SIZE)
397
+
398
+ mstore(add(pMem_, P_EVAL_R0), r0)
399
+ }
400
+
401
+ function g1_set(pR_, pP_) {
402
+ mstore(pR_, mload(pP_))
403
+ mstore(add(pR_, 32), mload(add(pP_,32)))
404
+ }
405
+
406
+ function g1_setC(pR_, x_, y_) {
407
+ mstore(pR_, x_)
408
+ mstore(add(pR_, 32), y_)
409
+ }
410
+
411
+ function g1_acc(pR_, pP_) -> res_ {
412
+ let mIn := mload(64)
413
+ mstore(mIn, mload(pR_))
414
+ mstore(add(mIn,32), mload(add(pR_, 32)))
415
+ mstore(add(mIn,64), mload(pP_))
416
+ mstore(add(mIn,96), mload(add(pP_, 32)))
417
+
418
+ res_ := staticcall(sub(gas(), 2000), 6, mIn, 128, pR_, 64)
419
+ }
420
+
421
+ function g1_mulAccC(pR_, x_, y_, s_) -> res_ {
422
+ let mIn := mload(64)
423
+ mstore(mIn, x_)
424
+ mstore(add(mIn,32), y_)
425
+ mstore(add(mIn,64), s_)
426
+
427
+ res_ := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
428
+
429
+ if iszero(res_) {
430
+ leave
431
+ }
432
+
433
+ mstore(add(mIn,64), mload(pR_))
434
+ mstore(add(mIn,96), mload(add(pR_, 32)))
435
+
436
+ res_ := staticcall(sub(gas(), 2000), 6, mIn, 128, pR_, 64)
437
+ }
438
+
439
+ function g1_mulSetC(pR_, x_, y_, s_) -> res_ {
440
+ let mIn := mload(64)
441
+ mstore(mIn, x_)
442
+ mstore(add(mIn,32), y_)
443
+ mstore(add(mIn,64), s_)
444
+
445
+ res_ := staticcall(sub(gas(), 2000), 7, mIn, 96, pR_, 64)
446
+ }
447
+
448
+ function g1_mulSet(pR_, pP_, s_) -> res_ {
449
+ res_ := g1_mulSetC(pR_, mload(pP_), mload(add(pP_, 32)), s_)
450
+ }
451
+
452
+ function calculateD(pMem_, proof_) -> isOk_ {
453
+ let _pD := add(pMem_, P_D)
454
+ let gamma := mload(add(pMem_, P_GAMMA))
455
+ let mIn := mload(64)
456
+ mstore(64, add(mIn, 256)) // d1, d2, d3 & d4 (4 * 64 bytes)
457
+
458
+ g1_setC(_pD, QC_X, QC_Y)
459
+
460
+ if iszero(
461
+ g1_mulAccC(
462
+ _pD, QM_X, QM_Y,
463
+ mulmod(
464
+ mload(add(proof_, P_EVAL_A)),
465
+ mload(add(proof_, P_EVAL_B)),
466
+ SCALAR_SIZE
467
+ )
468
+ )
469
+ ) {
470
+ leave
471
+ }
472
+ if iszero(g1_mulAccC(_pD, QL_X, QL_Y, mload(add(proof_, P_EVAL_A)))) {
473
+ leave
474
+ }
475
+ if iszero(g1_mulAccC(_pD, QR_X, QR_Y, mload(add(proof_, P_EVAL_B)))) {
476
+ leave
477
+ }
478
+ if iszero(g1_mulAccC(_pD, QO_X, QO_Y, mload(add(proof_, P_EVAL_C)))) {
479
+ leave
480
+ }
481
+
482
+ let betaxi := mload(add(pMem_, P_BETA_XI))
483
+ let val1 := addmod(
484
+ addmod(mload(add(proof_, P_EVAL_A)), betaxi, SCALAR_SIZE),
485
+ gamma,
486
+ SCALAR_SIZE
487
+ )
488
+
489
+ let val2 := addmod(
490
+ addmod(
491
+ mload(add(proof_, P_EVAL_B)),
492
+ mulmod(betaxi, K1, SCALAR_SIZE),
493
+ SCALAR_SIZE
494
+ ),
495
+ gamma,
496
+ SCALAR_SIZE
497
+ )
498
+
499
+ let val3 := addmod(
500
+ addmod(
501
+ mload(add(proof_, P_EVAL_C)),
502
+ mulmod(betaxi, K2, SCALAR_SIZE),
503
+ SCALAR_SIZE
504
+ ),
505
+ gamma,
506
+ SCALAR_SIZE
507
+ )
508
+
509
+ let d2a := mulmod(
510
+ mulmod(mulmod(val1, val2, SCALAR_SIZE), val3, SCALAR_SIZE),
511
+ mload(add(pMem_, P_ALPHA)),
512
+ SCALAR_SIZE
513
+ )
514
+
515
+ let d2b := mulmod(
516
+ mload(add(pMem_, P_EVAL_L1)),
517
+ mload(add(pMem_, P_ALPHA2)),
518
+ SCALAR_SIZE
519
+ )
520
+
521
+ // We'll use mIn to save d2
522
+ g1_set(add(mIn, 192), add(proof_, P_Z))
523
+
524
+ if iszero(
525
+ g1_mulSet(
526
+ mIn,
527
+ add(mIn, 192),
528
+ addmod(
529
+ addmod(d2a, d2b, SCALAR_SIZE),
530
+ mload(add(pMem_, P_U)),
531
+ SCALAR_SIZE
532
+ )
533
+ )
534
+ ) {
535
+ leave
536
+ }
537
+
538
+ val1 := addmod(
539
+ addmod(
540
+ mload(add(proof_, P_EVAL_A)),
541
+ mulmod(
542
+ mload(add(pMem_, P_BETA)),
543
+ mload(add(proof_, P_EVAL_S1)),
544
+ SCALAR_SIZE
545
+ ),
546
+ SCALAR_SIZE
547
+ ),
548
+ gamma,
549
+ SCALAR_SIZE
550
+ )
551
+
552
+ val2 := addmod(
553
+ addmod(
554
+ mload(add(proof_, P_EVAL_B)),
555
+ mulmod(
556
+ mload(add(pMem_, P_BETA)),
557
+ mload(add(proof_, P_EVAL_S2)),
558
+ SCALAR_SIZE
559
+ ),
560
+ SCALAR_SIZE
561
+ ),
562
+ gamma,
563
+ SCALAR_SIZE
564
+ )
565
+
566
+ val3 := mulmod(
567
+ mulmod(mload(add(pMem_, P_ALPHA)), mload(add(pMem_, P_BETA)), SCALAR_SIZE),
568
+ mload(add(proof_, P_EVAL_ZW)),
569
+ SCALAR_SIZE
570
+ )
571
+
572
+ // We'll use mIn + 64 to save d3
573
+ if iszero(
574
+ g1_mulSetC(
575
+ add(mIn, 64), S3_X, S3_Y,
576
+ mulmod(mulmod(val1, val2, SCALAR_SIZE), val3, SCALAR_SIZE)
577
+ )
578
+ ) {
579
+ leave
580
+ }
581
+
582
+ // We'll use mIn + 128 to save d4
583
+ g1_set(add(mIn, 128), add(proof_, P_T1))
584
+
585
+ if iszero(
586
+ g1_mulAccC(
587
+ add(mIn, 128),
588
+ mload(add(proof_, P_T2)),
589
+ mload(add(proof_, add(P_T2, 32))),
590
+ mload(add(pMem_, P_XIN))
591
+ )
592
+ ) {
593
+ leave
594
+ }
595
+
596
+ let xin2 := mulmod(
597
+ mload(add(pMem_, P_XIN)),
598
+ mload(add(pMem_, P_XIN)),
599
+ SCALAR_SIZE
600
+ )
601
+
602
+ if iszero(
603
+ g1_mulAccC(
604
+ add(mIn, 128),
605
+ mload(add(proof_, P_T3)),
606
+ mload(add(proof_, add(P_T3, 32))),
607
+ xin2
608
+ )
609
+ ) {
610
+ leave
611
+ }
612
+
613
+ if iszero(
614
+ g1_mulSetC(
615
+ add(mIn, 128),
616
+ mload(add(mIn, 128)),
617
+ mload(add(mIn, 160)),
618
+ mload(add(pMem_, P_ZH))
619
+ )
620
+ ) {
621
+ leave
622
+ }
623
+
624
+ mstore(add(add(mIn, 64), 32), mod(sub(BASE_SIZE, mload(add(add(mIn, 64), 32))), BASE_SIZE))
625
+ mstore(add(mIn, 160), mod(sub(BASE_SIZE, mload(add(mIn, 160))), BASE_SIZE))
626
+
627
+ if iszero(g1_acc(_pD, mIn)) { leave }
628
+ if iszero(g1_acc(_pD, add(mIn, 64))) { leave }
629
+ if iszero(g1_acc(_pD, add(mIn, 128))) { leave }
630
+
631
+ isOk_ := 1
632
+ }
633
+
634
+ function calculateF(pMem_, proof_) -> isOk_ {
635
+ let p := add(pMem_, P_F)
636
+
637
+ g1_set(p, add(pMem_, P_D))
638
+
639
+ if iszero(
640
+ g1_mulAccC(
641
+ p,
642
+ mload(add(proof_, P_A)),
643
+ mload(add(proof_, add(P_A, 32))),
644
+ mload(add(pMem_, P_V1))
645
+ )
646
+ ) {
647
+ leave
648
+ }
649
+
650
+ if iszero(
651
+ g1_mulAccC(
652
+ p,
653
+ mload(add(proof_, P_B)),
654
+ mload(add(proof_, add(P_B, 32))),
655
+ mload(add(pMem_, P_V2))
656
+ )
657
+ ) {
658
+ leave
659
+ }
660
+
661
+ if iszero(
662
+ g1_mulAccC(
663
+ p,
664
+ mload(add(proof_, P_C)),
665
+ mload(add(proof_, add(P_C, 32))),
666
+ mload(add(pMem_, P_V3))
667
+ )
668
+ ) {
669
+ leave
670
+ }
671
+
672
+ if iszero(g1_mulAccC(p, S1_X, S1_Y, mload(add(pMem_, P_V4)))) {
673
+ leave
674
+ }
675
+ if iszero(g1_mulAccC(p, S2_X, S2_Y, mload(add(pMem_, P_V5)))) {
676
+ leave
677
+ }
678
+
679
+ isOk_ := 1
680
+ }
681
+
682
+ function calculateE(pMem_, proof_) -> isOk_ {
683
+ let s := mod(sub(SCALAR_SIZE, mload(add(pMem_, P_EVAL_R0))), SCALAR_SIZE)
684
+
685
+ s := addmod(s, mulmod(mload(add(proof_, P_EVAL_A)), mload(add(pMem_, P_V1)), SCALAR_SIZE), SCALAR_SIZE)
686
+ s := addmod(s, mulmod(mload(add(proof_, P_EVAL_B)), mload(add(pMem_, P_V2)), SCALAR_SIZE), SCALAR_SIZE)
687
+ s := addmod(s, mulmod(mload(add(proof_, P_EVAL_C)), mload(add(pMem_, P_V3)), SCALAR_SIZE), SCALAR_SIZE)
688
+ s := addmod(s, mulmod(mload(add(proof_, P_EVAL_S1)), mload(add(pMem_, P_V4)), SCALAR_SIZE), SCALAR_SIZE)
689
+ s := addmod(s, mulmod(mload(add(proof_, P_EVAL_S2)), mload(add(pMem_, P_V5)), SCALAR_SIZE), SCALAR_SIZE)
690
+ s := addmod(s, mulmod(mload(add(proof_, P_EVAL_ZW)), mload(add(pMem_, P_U)), SCALAR_SIZE), SCALAR_SIZE)
691
+
692
+ isOk_ := g1_mulSetC(add(pMem_, P_E), G1_X, G1_Y, s)
693
+ }
694
+
695
+ function checkPairing(pMem_, proof_) -> isOk_ {
696
+ let mIn := mload(64)
697
+ mstore(64, add(mIn, 576)) // [0..383] = pairing data, [384..447] = P_WX_I, [448..512] = P_WX_IW
698
+
699
+ let _pWxi := add(mIn, 384)
700
+ let _pWxiw := add(mIn, 448)
701
+ let _aux := add(mIn, 512)
702
+
703
+ g1_set(_pWxi, add(proof_, P_WX_I))
704
+ g1_set(_pWxiw, add(proof_, P_WX_IW))
705
+
706
+ // A1
707
+ if iszero(g1_mulSet(mIn, _pWxiw, mload(add(pMem_, P_U)))) {
708
+ leave
709
+ }
710
+ if iszero(g1_acc(mIn, _pWxi)) {
711
+ leave
712
+ }
713
+ mstore(add(mIn, 32), mod(sub(BASE_SIZE, mload(add(mIn, 32))), BASE_SIZE))
714
+
715
+ // [X]_2
716
+ mstore(add(mIn,64), X2_X2)
717
+ mstore(add(mIn,96), X2_X1)
718
+ mstore(add(mIn,128), X2_Y2)
719
+ mstore(add(mIn,160), X2_Y1)
720
+
721
+ // B1
722
+ if iszero(g1_mulSet(add(mIn, 192), _pWxi, mload(add(pMem_, P_XI)))) {
723
+ leave
724
+ }
725
+
726
+ let s := mulmod(mload(add(pMem_, P_U)), mload(add(pMem_, P_XI)), SCALAR_SIZE)
727
+ s := mulmod(s, W1, SCALAR_SIZE)
728
+
729
+ if iszero(g1_mulSet(_aux, _pWxiw, s)) {
730
+ leave
731
+ }
732
+ if iszero(g1_acc(add(mIn, 192), _aux)) {
733
+ leave
734
+ }
735
+ if iszero(g1_acc(add(mIn, 192), add(pMem_, P_F))) {
736
+ leave
737
+ }
738
+
739
+ mstore(add(pMem_, add(P_E, 32)), mod(sub(BASE_SIZE, mload(add(pMem_, add(P_E, 32)))), BASE_SIZE))
740
+
741
+ if iszero(g1_acc(add(mIn, 192), add(pMem_, P_E))) {
742
+ leave
743
+ }
744
+
745
+ // [1]_2
746
+ mstore(add(mIn,256), G2_X2)
747
+ mstore(add(mIn,288), G2_X1)
748
+ mstore(add(mIn,320), G2_Y2)
749
+ mstore(add(mIn,352), G2_Y1)
750
+
751
+ if iszero(staticcall(sub(gas(), 2000), 8, mIn, 384, mIn, 0x20)) {
752
+ leave
753
+ }
754
+
755
+ isOk_ := and(1, mload(mIn))
756
+ }
757
+
758
+ let pointer_ := mload(64) // free pointer
759
+ mstore(64, add(pointer_, P_TOTAL_SIZE))
760
+
761
+ verified_ := checkInput(proofArr_)
762
+
763
+ /// @dev check pairings
764
+ if not(iszero(verified_)) {
765
+ calculateChallenges(pointer_, proofArr_, publicSignals_)
766
+ calculateLagrange(pointer_)
767
+ calculatePI(pointer_, publicSignals_)
768
+ calculateR0(pointer_, proofArr_)
769
+
770
+ verified_ := and(verified_, calculateD(pointer_, proofArr_))
771
+ verified_ := and(verified_, calculateF(pointer_, proofArr_))
772
+ verified_ := and(verified_, calculateE(pointer_, proofArr_))
773
+ verified_ := and(verified_, checkPairing(pointer_, proofArr_))
774
+ }
775
+
776
+ mstore(64, sub(pointer_, P_TOTAL_SIZE))
777
+ }
778
+ }
779
+ }