@solarity/zkit 0.2.5 → 0.3.0-rc.0

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