barretenberg
Loading...
Searching...
No Matches
src
barretenberg
dsl
acir_proofs
contract.hpp
1
#pragma once
2
#include <iostream>
3
4
// Source code for the Ultraplonk Solidity verifier.
5
// It's expected that the AcirComposer will inject a library which will load the verification key into memory.
6
7
const
std::string CONTRACT_SOURCE = R
"(
12
abstract contract BaseUltraVerifier {
13
// VERIFICATION KEY MEMORY LOCATIONS
14
uint256 internal constant N_LOC = 0x380;
15
uint256 internal constant NUM_INPUTS_LOC = 0x3a0;
16
uint256 internal constant OMEGA_LOC = 0x3c0;
17
uint256 internal constant DOMAIN_INVERSE_LOC = 0x3e0;
18
uint256 internal constant Q1_X_LOC = 0x400;
19
uint256 internal constant Q1_Y_LOC = 0x420;
20
uint256 internal constant Q2_X_LOC = 0x440;
21
uint256 internal constant Q2_Y_LOC = 0x460;
22
uint256 internal constant Q3_X_LOC = 0x480;
23
uint256 internal constant Q3_Y_LOC = 0x4a0;
24
uint256 internal constant Q4_X_LOC = 0x4c0;
25
uint256 internal constant Q4_Y_LOC = 0x4e0;
26
uint256 internal constant QM_X_LOC = 0x500;
27
uint256 internal constant QM_Y_LOC = 0x520;
28
uint256 internal constant QC_X_LOC = 0x540;
29
uint256 internal constant QC_Y_LOC = 0x560;
30
uint256 internal constant QARITH_X_LOC = 0x580;
31
uint256 internal constant QARITH_Y_LOC = 0x5a0;
32
uint256 internal constant QSORT_X_LOC = 0x5c0;
33
uint256 internal constant QSORT_Y_LOC = 0x5e0;
34
uint256 internal constant QELLIPTIC_X_LOC = 0x600;
35
uint256 internal constant QELLIPTIC_Y_LOC = 0x620;
36
uint256 internal constant QAUX_X_LOC = 0x640;
37
uint256 internal constant QAUX_Y_LOC = 0x660;
38
uint256 internal constant SIGMA1_X_LOC = 0x680;
39
uint256 internal constant SIGMA1_Y_LOC = 0x6a0;
40
uint256 internal constant SIGMA2_X_LOC = 0x6c0;
41
uint256 internal constant SIGMA2_Y_LOC = 0x6e0;
42
uint256 internal constant SIGMA3_X_LOC = 0x700;
43
uint256 internal constant SIGMA3_Y_LOC = 0x720;
44
uint256 internal constant SIGMA4_X_LOC = 0x740;
45
uint256 internal constant SIGMA4_Y_LOC = 0x760;
46
uint256 internal constant TABLE1_X_LOC = 0x780;
47
uint256 internal constant TABLE1_Y_LOC = 0x7a0;
48
uint256 internal constant TABLE2_X_LOC = 0x7c0;
49
uint256 internal constant TABLE2_Y_LOC = 0x7e0;
50
uint256 internal constant TABLE3_X_LOC = 0x800;
51
uint256 internal constant TABLE3_Y_LOC = 0x820;
52
uint256 internal constant TABLE4_X_LOC = 0x840;
53
uint256 internal constant TABLE4_Y_LOC = 0x860;
54
uint256 internal constant TABLE_TYPE_X_LOC = 0x880;
55
uint256 internal constant TABLE_TYPE_Y_LOC = 0x8a0;
56
uint256 internal constant ID1_X_LOC = 0x8c0;
57
uint256 internal constant ID1_Y_LOC = 0x8e0;
58
uint256 internal constant ID2_X_LOC = 0x900;
59
uint256 internal constant ID2_Y_LOC = 0x920;
60
uint256 internal constant ID3_X_LOC = 0x940;
61
uint256 internal constant ID3_Y_LOC = 0x960;
62
uint256 internal constant ID4_X_LOC = 0x980;
63
uint256 internal constant ID4_Y_LOC = 0x9a0;
64
uint256 internal constant CONTAINS_RECURSIVE_PROOF_LOC = 0x9c0;
65
uint256 internal constant RECURSIVE_PROOF_PUBLIC_INPUT_INDICES_LOC = 0x9e0;
66
uint256 internal constant G2X_X0_LOC = 0xa00;
67
uint256 internal constant G2X_X1_LOC = 0xa20;
68
uint256 internal constant G2X_Y0_LOC = 0xa40;
69
uint256 internal constant G2X_Y1_LOC = 0xa60;
70
71
// ### PROOF DATA MEMORY LOCATIONS
72
uint256 internal constant W1_X_LOC = 0x1200;
73
uint256 internal constant W1_Y_LOC = 0x1220;
74
uint256 internal constant W2_X_LOC = 0x1240;
75
uint256 internal constant W2_Y_LOC = 0x1260;
76
uint256 internal constant W3_X_LOC = 0x1280;
77
uint256 internal constant W3_Y_LOC = 0x12a0;
78
uint256 internal constant W4_X_LOC = 0x12c0;
79
uint256 internal constant W4_Y_LOC = 0x12e0;
80
uint256 internal constant S_X_LOC = 0x1300;
81
uint256 internal constant S_Y_LOC = 0x1320;
82
uint256 internal constant Z_X_LOC = 0x1340;
83
uint256 internal constant Z_Y_LOC = 0x1360;
84
uint256 internal constant Z_LOOKUP_X_LOC = 0x1380;
85
uint256 internal constant Z_LOOKUP_Y_LOC = 0x13a0;
86
uint256 internal constant T1_X_LOC = 0x13c0;
87
uint256 internal constant T1_Y_LOC = 0x13e0;
88
uint256 internal constant T2_X_LOC = 0x1400;
89
uint256 internal constant T2_Y_LOC = 0x1420;
90
uint256 internal constant T3_X_LOC = 0x1440;
91
uint256 internal constant T3_Y_LOC = 0x1460;
92
uint256 internal constant T4_X_LOC = 0x1480;
93
uint256 internal constant T4_Y_LOC = 0x14a0;
94
95
uint256 internal constant W1_EVAL_LOC = 0x1600;
96
uint256 internal constant W2_EVAL_LOC = 0x1620;
97
uint256 internal constant W3_EVAL_LOC = 0x1640;
98
uint256 internal constant W4_EVAL_LOC = 0x1660;
99
uint256 internal constant S_EVAL_LOC = 0x1680;
100
uint256 internal constant Z_EVAL_LOC = 0x16a0;
101
uint256 internal constant Z_LOOKUP_EVAL_LOC = 0x16c0;
102
uint256 internal constant Q1_EVAL_LOC = 0x16e0;
103
uint256 internal constant Q2_EVAL_LOC = 0x1700;
104
uint256 internal constant Q3_EVAL_LOC = 0x1720;
105
uint256 internal constant Q4_EVAL_LOC = 0x1740;
106
uint256 internal constant QM_EVAL_LOC = 0x1760;
107
uint256 internal constant QC_EVAL_LOC = 0x1780;
108
uint256 internal constant QARITH_EVAL_LOC = 0x17a0;
109
uint256 internal constant QSORT_EVAL_LOC = 0x17c0;
110
uint256 internal constant QELLIPTIC_EVAL_LOC = 0x17e0;
111
uint256 internal constant QAUX_EVAL_LOC = 0x1800;
112
uint256 internal constant TABLE1_EVAL_LOC = 0x1840;
113
uint256 internal constant TABLE2_EVAL_LOC = 0x1860;
114
uint256 internal constant TABLE3_EVAL_LOC = 0x1880;
115
uint256 internal constant TABLE4_EVAL_LOC = 0x18a0;
116
uint256 internal constant TABLE_TYPE_EVAL_LOC = 0x18c0;
117
uint256 internal constant ID1_EVAL_LOC = 0x18e0;
118
uint256 internal constant ID2_EVAL_LOC = 0x1900;
119
uint256 internal constant ID3_EVAL_LOC = 0x1920;
120
uint256 internal constant ID4_EVAL_LOC = 0x1940;
121
uint256 internal constant SIGMA1_EVAL_LOC = 0x1960;
122
uint256 internal constant SIGMA2_EVAL_LOC = 0x1980;
123
uint256 internal constant SIGMA3_EVAL_LOC = 0x19a0;
124
uint256 internal constant SIGMA4_EVAL_LOC = 0x19c0;
125
uint256 internal constant W1_OMEGA_EVAL_LOC = 0x19e0;
126
uint256 internal constant W2_OMEGA_EVAL_LOC = 0x2000;
127
uint256 internal constant W3_OMEGA_EVAL_LOC = 0x2020;
128
uint256 internal constant W4_OMEGA_EVAL_LOC = 0x2040;
129
uint256 internal constant S_OMEGA_EVAL_LOC = 0x2060;
130
uint256 internal constant Z_OMEGA_EVAL_LOC = 0x2080;
131
uint256 internal constant Z_LOOKUP_OMEGA_EVAL_LOC = 0x20a0;
132
uint256 internal constant TABLE1_OMEGA_EVAL_LOC = 0x20c0;
133
uint256 internal constant TABLE2_OMEGA_EVAL_LOC = 0x20e0;
134
uint256 internal constant TABLE3_OMEGA_EVAL_LOC = 0x2100;
135
uint256 internal constant TABLE4_OMEGA_EVAL_LOC = 0x2120;
136
137
uint256 internal constant PI_Z_X_LOC = 0x2300;
138
uint256 internal constant PI_Z_Y_LOC = 0x2320;
139
uint256 internal constant PI_Z_OMEGA_X_LOC = 0x2340;
140
uint256 internal constant PI_Z_OMEGA_Y_LOC = 0x2360;
141
142
// Used for elliptic widget. These are alias names for wire + shifted wire evaluations
143
uint256 internal constant X1_EVAL_LOC = W2_EVAL_LOC;
144
uint256 internal constant X2_EVAL_LOC = W1_OMEGA_EVAL_LOC;
145
uint256 internal constant X3_EVAL_LOC = W2_OMEGA_EVAL_LOC;
146
uint256 internal constant Y1_EVAL_LOC = W3_EVAL_LOC;
147
uint256 internal constant Y2_EVAL_LOC = W4_OMEGA_EVAL_LOC;
148
uint256 internal constant Y3_EVAL_LOC = W3_OMEGA_EVAL_LOC;
149
uint256 internal constant QBETA_LOC = Q3_EVAL_LOC;
150
uint256 internal constant QBETA_SQR_LOC = Q4_EVAL_LOC;
151
uint256 internal constant QSIGN_LOC = Q1_EVAL_LOC;
152
153
// ### CHALLENGES MEMORY OFFSETS
154
155
uint256 internal constant C_BETA_LOC = 0x2600;
156
uint256 internal constant C_GAMMA_LOC = 0x2620;
157
uint256 internal constant C_ALPHA_LOC = 0x2640;
158
uint256 internal constant C_ETA_LOC = 0x2660;
159
uint256 internal constant C_ETA_SQR_LOC = 0x2680;
160
uint256 internal constant C_ETA_CUBE_LOC = 0x26a0;
161
162
uint256 internal constant C_ZETA_LOC = 0x26c0;
163
uint256 internal constant C_CURRENT_LOC = 0x26e0;
164
uint256 internal constant C_V0_LOC = 0x2700;
165
uint256 internal constant C_V1_LOC = 0x2720;
166
uint256 internal constant C_V2_LOC = 0x2740;
167
uint256 internal constant C_V3_LOC = 0x2760;
168
uint256 internal constant C_V4_LOC = 0x2780;
169
uint256 internal constant C_V5_LOC = 0x27a0;
170
uint256 internal constant C_V6_LOC = 0x27c0;
171
uint256 internal constant C_V7_LOC = 0x27e0;
172
uint256 internal constant C_V8_LOC = 0x2800;
173
uint256 internal constant C_V9_LOC = 0x2820;
174
uint256 internal constant C_V10_LOC = 0x2840;
175
uint256 internal constant C_V11_LOC = 0x2860;
176
uint256 internal constant C_V12_LOC = 0x2880;
177
uint256 internal constant C_V13_LOC = 0x28a0;
178
uint256 internal constant C_V14_LOC = 0x28c0;
179
uint256 internal constant C_V15_LOC = 0x28e0;
180
uint256 internal constant C_V16_LOC = 0x2900;
181
uint256 internal constant C_V17_LOC = 0x2920;
182
uint256 internal constant C_V18_LOC = 0x2940;
183
uint256 internal constant C_V19_LOC = 0x2960;
184
uint256 internal constant C_V20_LOC = 0x2980;
185
uint256 internal constant C_V21_LOC = 0x29a0;
186
uint256 internal constant C_V22_LOC = 0x29c0;
187
uint256 internal constant C_V23_LOC = 0x29e0;
188
uint256 internal constant C_V24_LOC = 0x2a00;
189
uint256 internal constant C_V25_LOC = 0x2a20;
190
uint256 internal constant C_V26_LOC = 0x2a40;
191
uint256 internal constant C_V27_LOC = 0x2a60;
192
uint256 internal constant C_V28_LOC = 0x2a80;
193
uint256 internal constant C_V29_LOC = 0x2aa0;
194
uint256 internal constant C_V30_LOC = 0x2ac0;
195
196
uint256 internal constant C_U_LOC = 0x2b00;
197
198
// ### LOCAL VARIABLES MEMORY OFFSETS
199
uint256 internal constant DELTA_NUMERATOR_LOC = 0x3000;
200
uint256 internal constant DELTA_DENOMINATOR_LOC = 0x3020;
201
uint256 internal constant ZETA_POW_N_LOC = 0x3040;
202
uint256 internal constant PUBLIC_INPUT_DELTA_LOC = 0x3060;
203
uint256 internal constant ZERO_POLY_LOC = 0x3080;
204
uint256 internal constant L_START_LOC = 0x30a0;
205
uint256 internal constant L_END_LOC = 0x30c0;
206
uint256 internal constant R_ZERO_EVAL_LOC = 0x30e0;
207
208
uint256 internal constant PLOOKUP_DELTA_NUMERATOR_LOC = 0x3100;
209
uint256 internal constant PLOOKUP_DELTA_DENOMINATOR_LOC = 0x3120;
210
uint256 internal constant PLOOKUP_DELTA_LOC = 0x3140;
211
212
uint256 internal constant ACCUMULATOR_X_LOC = 0x3160;
213
uint256 internal constant ACCUMULATOR_Y_LOC = 0x3180;
214
uint256 internal constant ACCUMULATOR2_X_LOC = 0x31a0;
215
uint256 internal constant ACCUMULATOR2_Y_LOC = 0x31c0;
216
uint256 internal constant PAIRING_LHS_X_LOC = 0x31e0;
217
uint256 internal constant PAIRING_LHS_Y_LOC = 0x3200;
218
uint256 internal constant PAIRING_RHS_X_LOC = 0x3220;
219
uint256 internal constant PAIRING_RHS_Y_LOC = 0x3240;
220
221
// ### SUCCESS FLAG MEMORY LOCATIONS
222
uint256 internal constant GRAND_PRODUCT_SUCCESS_FLAG = 0x3300;
223
uint256 internal constant ARITHMETIC_TERM_SUCCESS_FLAG = 0x3020;
224
uint256 internal constant BATCH_OPENING_SUCCESS_FLAG = 0x3340;
225
uint256 internal constant OPENING_COMMITMENT_SUCCESS_FLAG = 0x3360;
226
uint256 internal constant PAIRING_PREAMBLE_SUCCESS_FLAG = 0x3380;
227
uint256 internal constant PAIRING_SUCCESS_FLAG = 0x33a0;
228
uint256 internal constant RESULT_FLAG = 0x33c0;
229
230
// misc stuff
231
uint256 internal constant OMEGA_INVERSE_LOC = 0x3400;
232
uint256 internal constant C_ALPHA_SQR_LOC = 0x3420;
233
uint256 internal constant C_ALPHA_CUBE_LOC = 0x3440;
234
uint256 internal constant C_ALPHA_QUAD_LOC = 0x3460;
235
uint256 internal constant C_ALPHA_BASE_LOC = 0x3480;
236
237
// ### RECURSION VARIABLE MEMORY LOCATIONS
238
uint256 internal constant RECURSIVE_P1_X_LOC = 0x3500;
239
uint256 internal constant RECURSIVE_P1_Y_LOC = 0x3520;
240
uint256 internal constant RECURSIVE_P2_X_LOC = 0x3540;
241
uint256 internal constant RECURSIVE_P2_Y_LOC = 0x3560;
242
243
uint256 internal constant PUBLIC_INPUTS_HASH_LOCATION = 0x3580;
244
245
// sub-identity storage
246
uint256 internal constant PERMUTATION_IDENTITY = 0x3600;
247
uint256 internal constant PLOOKUP_IDENTITY = 0x3620;
248
uint256 internal constant ARITHMETIC_IDENTITY = 0x3640;
249
uint256 internal constant SORT_IDENTITY = 0x3660;
250
uint256 internal constant ELLIPTIC_IDENTITY = 0x3680;
251
uint256 internal constant AUX_IDENTITY = 0x36a0;
252
uint256 internal constant AUX_NON_NATIVE_FIELD_EVALUATION = 0x36c0;
253
uint256 internal constant AUX_LIMB_ACCUMULATOR_EVALUATION = 0x36e0;
254
uint256 internal constant AUX_RAM_CONSISTENCY_EVALUATION = 0x3700;
255
uint256 internal constant AUX_ROM_CONSISTENCY_EVALUATION = 0x3720;
256
uint256 internal constant AUX_MEMORY_EVALUATION = 0x3740;
257
258
uint256 internal constant QUOTIENT_EVAL_LOC = 0x3760;
259
uint256 internal constant ZERO_POLY_INVERSE_LOC = 0x3780;
260
261
// when hashing public inputs we use memory at NU_CHALLENGE_INPUT_LOC_A, as the hash input size is unknown at compile time
262
uint256 internal constant NU_CHALLENGE_INPUT_LOC_A = 0x37a0;
263
uint256 internal constant NU_CHALLENGE_INPUT_LOC_B = 0x37c0;
264
uint256 internal constant NU_CHALLENGE_INPUT_LOC_C = 0x37e0;
265
266
bytes4 internal constant PUBLIC_INPUT_INVALID_BN128_G1_POINT_SELECTOR = 0xeba9f4a6;
267
bytes4 internal constant PUBLIC_INPUT_GE_P_SELECTOR = 0x374a972f;
268
bytes4 internal constant MOD_EXP_FAILURE_SELECTOR = 0xf894a7bc;
269
bytes4 internal constant EC_SCALAR_MUL_FAILURE_SELECTOR = 0xf755f369;
270
bytes4 internal constant PROOF_FAILURE_SELECTOR = 0x0711fcec;
271
272
uint256 internal constant ETA_INPUT_LENGTH = 0xc0; // W1, W2, W3 = 6 * 0x20 bytes
273
274
// We need to hash 41 field elements when generating the NU challenge
275
// w1, w2, w3, w4, s, z, z_lookup, q1, q2, q3, q4, qm, qc, qarith (14)
276
// qsort, qelliptic, qaux, sigma1, sigma2, sigma, sigma4, (7)
277
// table1, table2, table3, table4, tabletype, id1, id2, id3, id4, (9)
278
// w1_omega, w2_omega, w3_omega, w4_omega, s_omega, z_omega, z_lookup_omega, (7)
279
// table1_omega, table2_omega, table3_omega, table4_omega (4)
280
uint256 internal constant NU_INPUT_LENGTH = 0x520; // 0x520 = 41 * 0x20
281
282
// There are ELEVEN G1 group elements added into the transcript in the `beta` round, that we need to skip over
283
// W1, W2, W3, W4, S, Z, Z_LOOKUP, T1, T2, T3, T4
284
uint256 internal constant NU_CALLDATA_SKIP_LENGTH = 0x2c0; // 11 * 0x40 = 0x2c0
285
286
uint256 internal constant NEGATIVE_INVERSE_OF_2_MODULO_P =
287
0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000000;
288
uint256 internal constant LIMB_SIZE = 0x100000000000000000; // 2<<68
289
uint256 internal constant SUBLIMB_SHIFT = 0x4000; // 2<<14
290
291
// y^2 = x^3 + ax + b
292
// for Grumpkin, a = 0 and b = -17. We use b in a custom gate relation that evaluates elliptic curve arithmetic
293
uint256 internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = 17;
294
error PUBLIC_INPUT_COUNT_INVALID(uint256 expected, uint256 actual);
295
error PUBLIC_INPUT_INVALID_BN128_G1_POINT();
296
error PUBLIC_INPUT_GE_P();
297
error MOD_EXP_FAILURE();
298
error EC_SCALAR_MUL_FAILURE();
299
error PROOF_FAILURE();
300
301
function getVerificationKeyHash() public pure virtual returns (bytes32);
302
303
function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure virtual;
304
311
function verify(bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool) {
312
loadVerificationKey(N_LOC, OMEGA_INVERSE_LOC);
313
314
uint256 requiredPublicInputCount;
315
assembly {
316
requiredPublicInputCount := mload(NUM_INPUTS_LOC)
317
}
318
if (requiredPublicInputCount != _publicInputs.length) {
319
revert PUBLIC_INPUT_COUNT_INVALID(requiredPublicInputCount, _publicInputs.length);
320
}
321
322
assembly {
323
let q := 21888242871839275222246405745257275088696311157297823662689037894645226208583 // EC group order
324
let p := 21888242871839275222246405745257275088548364400416034343698204186575808495617 // Prime field order
325
329
{
330
let data_ptr := add(calldataload(0x04), 0x24)
331
332
mstore(W1_Y_LOC, mod(calldataload(data_ptr), q))
333
mstore(W1_X_LOC, mod(calldataload(add(data_ptr, 0x20)), q))
334
335
mstore(W2_Y_LOC, mod(calldataload(add(data_ptr, 0x40)), q))
336
mstore(W2_X_LOC, mod(calldataload(add(data_ptr, 0x60)), q))
337
338
mstore(W3_Y_LOC, mod(calldataload(add(data_ptr, 0x80)), q))
339
mstore(W3_X_LOC, mod(calldataload(add(data_ptr, 0xa0)), q))
340
341
mstore(W4_Y_LOC, mod(calldataload(add(data_ptr, 0xc0)), q))
342
mstore(W4_X_LOC, mod(calldataload(add(data_ptr, 0xe0)), q))
343
344
mstore(S_Y_LOC, mod(calldataload(add(data_ptr, 0x100)), q))
345
mstore(S_X_LOC, mod(calldataload(add(data_ptr, 0x120)), q))
346
mstore(Z_Y_LOC, mod(calldataload(add(data_ptr, 0x140)), q))
347
mstore(Z_X_LOC, mod(calldataload(add(data_ptr, 0x160)), q))
348
mstore(Z_LOOKUP_Y_LOC, mod(calldataload(add(data_ptr, 0x180)), q))
349
mstore(Z_LOOKUP_X_LOC, mod(calldataload(add(data_ptr, 0x1a0)), q))
350
mstore(T1_Y_LOC, mod(calldataload(add(data_ptr, 0x1c0)), q))
351
mstore(T1_X_LOC, mod(calldataload(add(data_ptr, 0x1e0)), q))
352
353
mstore(T2_Y_LOC, mod(calldataload(add(data_ptr, 0x200)), q))
354
mstore(T2_X_LOC, mod(calldataload(add(data_ptr, 0x220)), q))
355
356
mstore(T3_Y_LOC, mod(calldataload(add(data_ptr, 0x240)), q))
357
mstore(T3_X_LOC, mod(calldataload(add(data_ptr, 0x260)), q))
358
359
mstore(T4_Y_LOC, mod(calldataload(add(data_ptr, 0x280)), q))
360
mstore(T4_X_LOC, mod(calldataload(add(data_ptr, 0x2a0)), q))
361
362
mstore(W1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x2c0)), p))
363
mstore(W2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x2e0)), p))
364
mstore(W3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x300)), p))
365
mstore(W4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x320)), p))
366
mstore(S_EVAL_LOC, mod(calldataload(add(data_ptr, 0x340)), p))
367
mstore(Z_EVAL_LOC, mod(calldataload(add(data_ptr, 0x360)), p))
368
mstore(Z_LOOKUP_EVAL_LOC, mod(calldataload(add(data_ptr, 0x380)), p))
369
mstore(Q1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x3a0)), p))
370
mstore(Q2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x3c0)), p))
371
mstore(Q3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x3e0)), p))
372
mstore(Q4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x400)), p))
373
mstore(QM_EVAL_LOC, mod(calldataload(add(data_ptr, 0x420)), p))
374
mstore(QC_EVAL_LOC, mod(calldataload(add(data_ptr, 0x440)), p))
375
mstore(QARITH_EVAL_LOC, mod(calldataload(add(data_ptr, 0x460)), p))
376
mstore(QSORT_EVAL_LOC, mod(calldataload(add(data_ptr, 0x480)), p))
377
mstore(QELLIPTIC_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4a0)), p))
378
mstore(QAUX_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4c0)), p))
379
380
mstore(SIGMA1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x4e0)), p))
381
mstore(SIGMA2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x500)), p))
382
383
mstore(SIGMA3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x520)), p))
384
mstore(SIGMA4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x540)), p))
385
386
mstore(TABLE1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x560)), p))
387
mstore(TABLE2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x580)), p))
388
mstore(TABLE3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5a0)), p))
389
mstore(TABLE4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5c0)), p))
390
mstore(TABLE_TYPE_EVAL_LOC, mod(calldataload(add(data_ptr, 0x5e0)), p))
391
392
mstore(ID1_EVAL_LOC, mod(calldataload(add(data_ptr, 0x600)), p))
393
mstore(ID2_EVAL_LOC, mod(calldataload(add(data_ptr, 0x620)), p))
394
mstore(ID3_EVAL_LOC, mod(calldataload(add(data_ptr, 0x640)), p))
395
mstore(ID4_EVAL_LOC, mod(calldataload(add(data_ptr, 0x660)), p))
396
397
mstore(W1_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x680)), p))
398
mstore(W2_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6a0)), p))
399
mstore(W3_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6c0)), p))
400
mstore(W4_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x6e0)), p))
401
mstore(S_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x700)), p))
402
403
mstore(Z_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x720)), p))
404
405
mstore(Z_LOOKUP_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x740)), p))
406
mstore(TABLE1_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x760)), p))
407
mstore(TABLE2_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x780)), p))
408
mstore(TABLE3_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x7a0)), p))
409
mstore(TABLE4_OMEGA_EVAL_LOC, mod(calldataload(add(data_ptr, 0x7c0)), p))
410
411
mstore(PI_Z_Y_LOC, mod(calldataload(add(data_ptr, 0x7e0)), q))
412
mstore(PI_Z_X_LOC, mod(calldataload(add(data_ptr, 0x800)), q))
413
414
mstore(PI_Z_OMEGA_Y_LOC, mod(calldataload(add(data_ptr, 0x820)), q))
415
mstore(PI_Z_OMEGA_X_LOC, mod(calldataload(add(data_ptr, 0x840)), q))
416
}
417
421
{
422
if mload(CONTAINS_RECURSIVE_PROOF_LOC) {
423
let public_inputs_ptr := add(calldataload(0x24), 0x24)
424
let index_counter := add(shl(5, mload(RECURSIVE_PROOF_PUBLIC_INPUT_INDICES_LOC)), public_inputs_ptr)
425
426
let x0 := calldataload(index_counter)
427
x0 := add(x0, shl(68, calldataload(add(index_counter, 0x20))))
428
x0 := add(x0, shl(136, calldataload(add(index_counter, 0x40))))
429
x0 := add(x0, shl(204, calldataload(add(index_counter, 0x60))))
430
let y0 := calldataload(add(index_counter, 0x80))
431
y0 := add(y0, shl(68, calldataload(add(index_counter, 0xa0))))
432
y0 := add(y0, shl(136, calldataload(add(index_counter, 0xc0))))
433
y0 := add(y0, shl(204, calldataload(add(index_counter, 0xe0))))
434
let x1 := calldataload(add(index_counter, 0x100))
435
x1 := add(x1, shl(68, calldataload(add(index_counter, 0x120))))
436
x1 := add(x1, shl(136, calldataload(add(index_counter, 0x140))))
437
x1 := add(x1, shl(204, calldataload(add(index_counter, 0x160))))
438
let y1 := calldataload(add(index_counter, 0x180))
439
y1 := add(y1, shl(68, calldataload(add(index_counter, 0x1a0))))
440
y1 := add(y1, shl(136, calldataload(add(index_counter, 0x1c0))))
441
y1 := add(y1, shl(204, calldataload(add(index_counter, 0x1e0))))
442
mstore(RECURSIVE_P1_X_LOC, x0)
443
mstore(RECURSIVE_P1_Y_LOC, y0)
444
mstore(RECURSIVE_P2_X_LOC, x1)
445
mstore(RECURSIVE_P2_Y_LOC, y1)
446
447
// validate these are valid bn128 G1 points
448
if iszero(and(and(lt(x0, q), lt(x1, q)), and(lt(y0, q), lt(y1, q)))) {
449
mstore(0x00, PUBLIC_INPUT_INVALID_BN128_G1_POINT_SELECTOR)
450
revert(0x00, 0x04)
451
}
452
}
453
}
454
455
{
459
mstore(0x00, shl(224, mload(N_LOC)))
460
mstore(0x04, shl(224, mload(NUM_INPUTS_LOC)))
461
let challenge := keccak256(0x00, 0x08)
462
466
mstore(PUBLIC_INPUTS_HASH_LOCATION, challenge)
467
// The public input location is stored at 0x24, we then add 0x24 to skip selector and the length of public inputs
468
let public_inputs_start := add(calldataload(0x24), 0x24)
469
// copy the public inputs over
470
let public_input_size := mul(mload(NUM_INPUTS_LOC), 0x20)
471
calldatacopy(add(PUBLIC_INPUTS_HASH_LOCATION, 0x20), public_inputs_start, public_input_size)
472
473
// copy W1, W2, W3 into challenge. Each point is 0x40 bytes, so load 0xc0 = 3 * 0x40 bytes (ETA input length)
474
let w_start := add(calldataload(0x04), 0x24)
475
calldatacopy(add(add(PUBLIC_INPUTS_HASH_LOCATION, 0x20), public_input_size), w_start, ETA_INPUT_LENGTH)
476
477
// Challenge is the old challenge + public inputs + W1, W2, W3 (0x20 + public_input_size + 0xc0)
478
let challenge_bytes_size := add(0x20, add(public_input_size, ETA_INPUT_LENGTH))
479
480
challenge := keccak256(PUBLIC_INPUTS_HASH_LOCATION, challenge_bytes_size)
481
{
482
let eta := mod(challenge, p)
483
mstore(C_ETA_LOC, eta)
484
mstore(C_ETA_SQR_LOC, mulmod(eta, eta, p))
485
mstore(C_ETA_CUBE_LOC, mulmod(mload(C_ETA_SQR_LOC), eta, p))
486
}
487
491
mstore(0x00, challenge)
492
mstore(0x20, mload(W4_Y_LOC))
493
mstore(0x40, mload(W4_X_LOC))
494
mstore(0x60, mload(S_Y_LOC))
495
mstore(0x80, mload(S_X_LOC))
496
challenge := keccak256(0x00, 0xa0)
497
mstore(C_BETA_LOC, mod(challenge, p))
498
502
mstore(0x00, challenge)
503
mstore8(0x20, 0x01)
504
challenge := keccak256(0x00, 0x21)
505
mstore(C_GAMMA_LOC, mod(challenge, p))
506
510
mstore(0x00, challenge)
511
mstore(0x20, mload(Z_Y_LOC))
512
mstore(0x40, mload(Z_X_LOC))
513
mstore(0x60, mload(Z_LOOKUP_Y_LOC))
514
mstore(0x80, mload(Z_LOOKUP_X_LOC))
515
challenge := keccak256(0x00, 0xa0)
516
mstore(C_ALPHA_LOC, mod(challenge, p))
517
521
let alpha := mload(C_ALPHA_LOC)
522
mstore(C_ALPHA_SQR_LOC, mulmod(alpha, alpha, p))
523
mstore(C_ALPHA_CUBE_LOC, mulmod(mload(C_ALPHA_SQR_LOC), alpha, p))
524
mstore(C_ALPHA_QUAD_LOC, mulmod(mload(C_ALPHA_CUBE_LOC), alpha, p))
525
mstore(C_ALPHA_BASE_LOC, alpha)
526
530
mstore(0x00, challenge)
531
mstore(0x20, mload(T1_Y_LOC))
532
mstore(0x40, mload(T1_X_LOC))
533
mstore(0x60, mload(T2_Y_LOC))
534
mstore(0x80, mload(T2_X_LOC))
535
mstore(0xa0, mload(T3_Y_LOC))
536
mstore(0xc0, mload(T3_X_LOC))
537
mstore(0xe0, mload(T4_Y_LOC))
538
mstore(0x100, mload(T4_X_LOC))
539
540
challenge := keccak256(0x00, 0x120)
541
542
mstore(C_ZETA_LOC, mod(challenge, p))
543
mstore(C_CURRENT_LOC, challenge)
544
}
545
554
{
555
let beta := mload(C_BETA_LOC) // β
556
let gamma := mload(C_GAMMA_LOC) // γ
557
let work_root := mload(OMEGA_LOC) // ω
558
let numerator_value := 1
559
let denominator_value := 1
560
561
let p_clone := p // move p to the front of the stack
562
let valid_inputs := true
563
564
// Load the starting point of the public inputs (jump over the selector and the length of public inputs [0x24])
565
let public_inputs_ptr := add(calldataload(0x24), 0x24)
566
567
// endpoint_ptr = public_inputs_ptr + num_inputs * 0x20. // every public input is 0x20 bytes
568
let endpoint_ptr := add(public_inputs_ptr, mul(mload(NUM_INPUTS_LOC), 0x20))
569
570
// root_1 = β * 0x05
571
let root_1 := mulmod(beta, 0x05, p_clone) // k1.β
572
// root_2 = β * 0x0c
573
let root_2 := mulmod(beta, 0x0c, p_clone)
574
// @note 0x05 + 0x07 == 0x0c == external coset generator
575
576
for {} lt(public_inputs_ptr, endpoint_ptr) { public_inputs_ptr := add(public_inputs_ptr, 0x20) } {
587
let input := calldataload(public_inputs_ptr)
588
valid_inputs := and(valid_inputs, lt(input, p_clone))
589
let temp := addmod(input, gamma, p_clone)
590
591
numerator_value := mulmod(numerator_value, add(root_1, temp), p_clone)
592
denominator_value := mulmod(denominator_value, add(root_2, temp), p_clone)
593
594
root_1 := mulmod(root_1, work_root, p_clone)
595
root_2 := mulmod(root_2, work_root, p_clone)
596
}
597
598
// Revert if not all public inputs are field elements (i.e. < p)
599
if iszero(valid_inputs) {
600
mstore(0x00, PUBLIC_INPUT_GE_P_SELECTOR)
601
revert(0x00, 0x04)
602
}
603
604
mstore(DELTA_NUMERATOR_LOC, numerator_value)
605
mstore(DELTA_DENOMINATOR_LOC, denominator_value)
606
}
607
612
{
613
let delta_base := mulmod(mload(C_GAMMA_LOC), addmod(mload(C_BETA_LOC), 1, p), p)
614
let delta_numerator := delta_base
615
{
616
let exponent := mload(N_LOC)
617
let count := 1
618
for {} lt(count, exponent) { count := add(count, count) } {
619
delta_numerator := mulmod(delta_numerator, delta_numerator, p)
620
}
621
}
622
mstore(PLOOKUP_DELTA_NUMERATOR_LOC, delta_numerator)
623
624
let delta_denominator := mulmod(delta_base, delta_base, p)
625
delta_denominator := mulmod(delta_denominator, delta_denominator, p)
626
mstore(PLOOKUP_DELTA_DENOMINATOR_LOC, delta_denominator)
627
}
631
{
653
let zeta := mload(C_ZETA_LOC)
654
655
// compute zeta^n, where n is a power of 2
656
let vanishing_numerator := zeta
657
{
658
// pow_small
659
let exponent := mload(N_LOC)
660
let count := 1
661
for {} lt(count, exponent) { count := add(count, count) } {
662
vanishing_numerator := mulmod(vanishing_numerator, vanishing_numerator, p)
663
}
664
}
665
mstore(ZETA_POW_N_LOC, vanishing_numerator)
666
vanishing_numerator := addmod(vanishing_numerator, sub(p, 1), p)
667
668
let accumulating_root := mload(OMEGA_INVERSE_LOC)
669
let work_root := sub(p, accumulating_root)
670
let domain_inverse := mload(DOMAIN_INVERSE_LOC)
671
672
let vanishing_denominator := addmod(zeta, work_root, p)
673
work_root := mulmod(work_root, accumulating_root, p)
674
vanishing_denominator := mulmod(vanishing_denominator, addmod(zeta, work_root, p), p)
675
work_root := mulmod(work_root, accumulating_root, p)
676
vanishing_denominator := mulmod(vanishing_denominator, addmod(zeta, work_root, p), p)
677
vanishing_denominator :=
678
mulmod(vanishing_denominator, addmod(zeta, mulmod(work_root, accumulating_root, p), p), p)
679
680
work_root := mload(OMEGA_LOC)
681
682
let lagrange_numerator := mulmod(vanishing_numerator, domain_inverse, p)
683
let l_start_denominator := addmod(zeta, sub(p, 1), p)
684
685
accumulating_root := mulmod(work_root, work_root, p)
686
687
let l_end_denominator :=
688
addmod(
689
mulmod(mulmod(mulmod(accumulating_root, accumulating_root, p), work_root, p), zeta, p), sub(p, 1), p
690
)
691
695
let accumulator := mload(DELTA_DENOMINATOR_LOC)
696
let t0 := accumulator
697
accumulator := mulmod(accumulator, vanishing_denominator, p)
698
let t1 := accumulator
699
accumulator := mulmod(accumulator, vanishing_numerator, p)
700
let t2 := accumulator
701
accumulator := mulmod(accumulator, l_start_denominator, p)
702
let t3 := accumulator
703
accumulator := mulmod(accumulator, mload(PLOOKUP_DELTA_DENOMINATOR_LOC), p)
704
let t4 := accumulator
705
{
706
mstore(0, 0x20)
707
mstore(0x20, 0x20)
708
mstore(0x40, 0x20)
709
mstore(0x60, mulmod(accumulator, l_end_denominator, p))
710
mstore(0x80, sub(p, 2))
711
mstore(0xa0, p)
712
if iszero(staticcall(gas(), 0x05, 0x00, 0xc0, 0x00, 0x20)) {
713
mstore(0x0, MOD_EXP_FAILURE_SELECTOR)
714
revert(0x00, 0x04)
715
}
716
accumulator := mload(0x00)
717
}
718
719
t4 := mulmod(accumulator, t4, p)
720
accumulator := mulmod(accumulator, l_end_denominator, p)
721
722
t3 := mulmod(accumulator, t3, p)
723
accumulator := mulmod(accumulator, mload(PLOOKUP_DELTA_DENOMINATOR_LOC), p)
724
725
t2 := mulmod(accumulator, t2, p)
726
accumulator := mulmod(accumulator, l_start_denominator, p)
727
728
t1 := mulmod(accumulator, t1, p)
729
accumulator := mulmod(accumulator, vanishing_numerator, p)
730
731
t0 := mulmod(accumulator, t0, p)
732
accumulator := mulmod(accumulator, vanishing_denominator, p)
733
734
accumulator := mulmod(mulmod(accumulator, accumulator, p), mload(DELTA_DENOMINATOR_LOC), p)
735
736
mstore(PUBLIC_INPUT_DELTA_LOC, mulmod(mload(DELTA_NUMERATOR_LOC), accumulator, p))
737
mstore(ZERO_POLY_LOC, mulmod(vanishing_numerator, t0, p))
738
mstore(ZERO_POLY_INVERSE_LOC, mulmod(vanishing_denominator, t1, p))
739
mstore(L_START_LOC, mulmod(lagrange_numerator, t2, p))
740
mstore(PLOOKUP_DELTA_LOC, mulmod(mload(PLOOKUP_DELTA_NUMERATOR_LOC), t3, p))
741
mstore(L_END_LOC, mulmod(lagrange_numerator, t4, p))
742
}
743
759
{
760
let alpha := mload(C_ALPHA_LOC)
761
let beta := mload(C_BETA_LOC)
762
let gamma := mload(C_GAMMA_LOC)
763
772
let t1 :=
773
mulmod(
774
add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(ID1_EVAL_LOC), p)),
775
add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(ID2_EVAL_LOC), p)),
776
p
777
)
778
let t2 :=
779
mulmod(
780
add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(ID3_EVAL_LOC), p)),
781
add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(ID4_EVAL_LOC), p)),
782
p
783
)
784
let result := mulmod(mload(C_ALPHA_BASE_LOC), mulmod(mload(Z_EVAL_LOC), mulmod(t1, t2, p), p), p)
785
t1 :=
786
mulmod(
787
add(add(mload(W1_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA1_EVAL_LOC), p)),
788
add(add(mload(W2_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA2_EVAL_LOC), p)),
789
p
790
)
791
t2 :=
792
mulmod(
793
add(add(mload(W3_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA3_EVAL_LOC), p)),
794
add(add(mload(W4_EVAL_LOC), gamma), mulmod(beta, mload(SIGMA4_EVAL_LOC), p)),
795
p
796
)
797
result :=
798
addmod(
799
result,
800
sub(p, mulmod(mload(C_ALPHA_BASE_LOC), mulmod(mload(Z_OMEGA_EVAL_LOC), mulmod(t1, t2, p), p), p)),
801
p
802
)
803
811
mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p))
812
result :=
813
addmod(
814
result,
815
mulmod(
816
mload(C_ALPHA_BASE_LOC),
817
mulmod(
818
mload(L_END_LOC),
819
addmod(mload(Z_OMEGA_EVAL_LOC), sub(p, mload(PUBLIC_INPUT_DELTA_LOC)), p),
820
p
821
),
822
p
823
),
824
p
825
)
826
mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p))
827
mstore(
828
PERMUTATION_IDENTITY,
829
addmod(
830
result,
831
mulmod(
832
mload(C_ALPHA_BASE_LOC),
833
mulmod(mload(L_START_LOC), addmod(mload(Z_EVAL_LOC), sub(p, 1), p), p),
834
p
835
),
836
p
837
)
838
)
839
mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p))
840
}
841
845
{
855
let f := mulmod(mload(C_ETA_LOC), mload(Q3_EVAL_LOC), p)
856
f :=
857
addmod(f, addmod(mload(W3_EVAL_LOC), mulmod(mload(QC_EVAL_LOC), mload(W3_OMEGA_EVAL_LOC), p), p), p)
858
f := mulmod(f, mload(C_ETA_LOC), p)
859
f :=
860
addmod(f, addmod(mload(W2_EVAL_LOC), mulmod(mload(QM_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), p), p)
861
f := mulmod(f, mload(C_ETA_LOC), p)
862
f :=
863
addmod(f, addmod(mload(W1_EVAL_LOC), mulmod(mload(Q2_EVAL_LOC), mload(W1_OMEGA_EVAL_LOC), p), p), p)
864
865
// t(z) = table4(z).η³ + table3(z).η² + table2(z).η + table1(z)
866
let t :=
867
addmod(
868
addmod(
869
addmod(
870
mulmod(mload(TABLE4_EVAL_LOC), mload(C_ETA_CUBE_LOC), p),
871
mulmod(mload(TABLE3_EVAL_LOC), mload(C_ETA_SQR_LOC), p),
872
p
873
),
874
mulmod(mload(TABLE2_EVAL_LOC), mload(C_ETA_LOC), p),
875
p
876
),
877
mload(TABLE1_EVAL_LOC),
878
p
879
)
880
881
// t(zw) = table4(zw).η³ + table3(zw).η² + table2(zw).η + table1(zw)
882
let t_omega :=
883
addmod(
884
addmod(
885
addmod(
886
mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_ETA_CUBE_LOC), p),
887
mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_ETA_SQR_LOC), p),
888
p
889
),
890
mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_ETA_LOC), p),
891
p
892
),
893
mload(TABLE1_OMEGA_EVAL_LOC),
894
p
895
)
896
909
let gamma_beta_constant := mulmod(mload(C_GAMMA_LOC), addmod(mload(C_BETA_LOC), 1, p), p)
910
let numerator := addmod(mulmod(f, mload(TABLE_TYPE_EVAL_LOC), p), mload(C_GAMMA_LOC), p)
911
let temp0 := addmod(addmod(t, mulmod(t_omega, mload(C_BETA_LOC), p), p), gamma_beta_constant, p)
912
numerator := mulmod(numerator, temp0, p)
913
numerator := mulmod(numerator, addmod(mload(C_BETA_LOC), 1, p), p)
914
temp0 := mulmod(mload(C_ALPHA_LOC), mload(L_START_LOC), p)
915
numerator := addmod(numerator, temp0, p)
916
numerator := mulmod(numerator, mload(Z_LOOKUP_EVAL_LOC), p)
917
numerator := addmod(numerator, sub(p, temp0), p)
918
930
let denominator :=
931
addmod(
932
addmod(mload(S_EVAL_LOC), mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_BETA_LOC), p), p),
933
gamma_beta_constant,
934
p
935
)
936
let temp1 := mulmod(mload(C_ALPHA_SQR_LOC), mload(L_END_LOC), p)
937
denominator := addmod(denominator, sub(p, temp1), p)
938
denominator := mulmod(denominator, mload(Z_LOOKUP_OMEGA_EVAL_LOC), p)
939
denominator := addmod(denominator, mulmod(temp1, mload(PLOOKUP_DELTA_LOC), p), p)
940
941
mstore(PLOOKUP_IDENTITY, mulmod(addmod(numerator, sub(p, denominator), p), mload(C_ALPHA_BASE_LOC), p))
942
943
// update alpha
944
mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p))
945
}
946
950
{
987
let w1q1 := mulmod(mload(W1_EVAL_LOC), mload(Q1_EVAL_LOC), p)
988
let w2q2 := mulmod(mload(W2_EVAL_LOC), mload(Q2_EVAL_LOC), p)
989
let w3q3 := mulmod(mload(W3_EVAL_LOC), mload(Q3_EVAL_LOC), p)
990
let w4q3 := mulmod(mload(W4_EVAL_LOC), mload(Q4_EVAL_LOC), p)
991
992
// @todo - Add a explicit test that hits QARITH == 3
993
// w1w2qm := (w_1 . w_2 . q_m . (QARITH_EVAL_LOC - 3)) / 2
994
let w1w2qm :=
995
mulmod(
996
mulmod(
997
mulmod(mulmod(mload(W1_EVAL_LOC), mload(W2_EVAL_LOC), p), mload(QM_EVAL_LOC), p),
998
addmod(mload(QARITH_EVAL_LOC), sub(p, 3), p),
999
p
1000
),
1001
NEGATIVE_INVERSE_OF_2_MODULO_P,
1002
p
1003
)
1004
1005
// (w_1 . w_2 . q_m . (q_arith - 3)) / -2) + (w_1 . q_1) + (w_2 . q_2) + (w_3 . q_3) + (w_4 . q_4) + q_c
1006
let identity :=
1007
addmod(
1008
mload(QC_EVAL_LOC), addmod(w4q3, addmod(w3q3, addmod(w2q2, addmod(w1q1, w1w2qm, p), p), p), p), p
1009
)
1010
1011
// if q_arith == 3 we evaluate an additional mini addition gate (on top of the regular one), where:
1012
// w_1 + w_4 - w_1_omega + q_m = 0
1013
// we use this gate to save an addition gate when adding or subtracting non-native field elements
1014
// α * (q_arith - 2) * (w_1 + w_4 - w_1_omega + q_m)
1015
let extra_small_addition_gate_identity :=
1016
mulmod(
1017
mload(C_ALPHA_LOC),
1018
mulmod(
1019
addmod(mload(QARITH_EVAL_LOC), sub(p, 2), p),
1020
addmod(
1021
mload(QM_EVAL_LOC),
1022
addmod(
1023
sub(p, mload(W1_OMEGA_EVAL_LOC)), addmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p), p
1024
),
1025
p
1026
),
1027
p
1028
),
1029
p
1030
)
1031
1032
// if q_arith == 2 OR q_arith == 3 we add the 4th wire of the NEXT gate into the arithmetic identity
1033
// N.B. if q_arith > 2, this wire value will be scaled by (q_arith - 1) relative to the other gate wires!
1034
// alpha_base * q_arith * (identity + (q_arith - 1) * (w_4_omega + extra_small_addition_gate_identity))
1035
mstore(
1036
ARITHMETIC_IDENTITY,
1037
mulmod(
1038
mload(C_ALPHA_BASE_LOC),
1039
mulmod(
1040
mload(QARITH_EVAL_LOC),
1041
addmod(
1042
identity,
1043
mulmod(
1044
addmod(mload(QARITH_EVAL_LOC), sub(p, 1), p),
1045
addmod(mload(W4_OMEGA_EVAL_LOC), extra_small_addition_gate_identity, p),
1046
p
1047
),
1048
p
1049
),
1050
p
1051
),
1052
p
1053
)
1054
)
1055
1056
// update alpha
1057
mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_SQR_LOC), p))
1058
}
1059
1063
{
1082
let minus_two := sub(p, 2)
1083
let minus_three := sub(p, 3)
1084
let d1 := addmod(mload(W2_EVAL_LOC), sub(p, mload(W1_EVAL_LOC)), p)
1085
let d2 := addmod(mload(W3_EVAL_LOC), sub(p, mload(W2_EVAL_LOC)), p)
1086
let d3 := addmod(mload(W4_EVAL_LOC), sub(p, mload(W3_EVAL_LOC)), p)
1087
let d4 := addmod(mload(W1_OMEGA_EVAL_LOC), sub(p, mload(W4_EVAL_LOC)), p)
1088
1089
let range_accumulator :=
1090
mulmod(
1091
mulmod(
1092
mulmod(addmod(mulmod(d1, d1, p), sub(p, d1), p), addmod(d1, minus_two, p), p),
1093
addmod(d1, minus_three, p),
1094
p
1095
),
1096
mload(C_ALPHA_BASE_LOC),
1097
p
1098
)
1099
range_accumulator :=
1100
addmod(
1101
range_accumulator,
1102
mulmod(
1103
mulmod(
1104
mulmod(addmod(mulmod(d2, d2, p), sub(p, d2), p), addmod(d2, minus_two, p), p),
1105
addmod(d2, minus_three, p),
1106
p
1107
),
1108
mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p),
1109
p
1110
),
1111
p
1112
)
1113
range_accumulator :=
1114
addmod(
1115
range_accumulator,
1116
mulmod(
1117
mulmod(
1118
mulmod(addmod(mulmod(d3, d3, p), sub(p, d3), p), addmod(d3, minus_two, p), p),
1119
addmod(d3, minus_three, p),
1120
p
1121
),
1122
mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_SQR_LOC), p),
1123
p
1124
),
1125
p
1126
)
1127
range_accumulator :=
1128
addmod(
1129
range_accumulator,
1130
mulmod(
1131
mulmod(
1132
mulmod(addmod(mulmod(d4, d4, p), sub(p, d4), p), addmod(d4, minus_two, p), p),
1133
addmod(d4, minus_three, p),
1134
p
1135
),
1136
mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p),
1137
p
1138
),
1139
p
1140
)
1141
range_accumulator := mulmod(range_accumulator, mload(QSORT_EVAL_LOC), p)
1142
1143
mstore(SORT_IDENTITY, range_accumulator)
1144
1145
// update alpha
1146
mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_QUAD_LOC), p))
1147
}
1148
1152
{
1166
// q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0
1167
let x_diff := addmod(mload(X2_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p)
1168
let y2_sqr := mulmod(mload(Y2_EVAL_LOC), mload(Y2_EVAL_LOC), p)
1169
let y1_sqr := mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p)
1170
let y1y2 := mulmod(mulmod(mload(Y1_EVAL_LOC), mload(Y2_EVAL_LOC), p), mload(QSIGN_LOC), p)
1171
1172
let x_add_identity :=
1173
addmod(
1174
mulmod(
1175
addmod(mload(X3_EVAL_LOC), addmod(mload(X2_EVAL_LOC), mload(X1_EVAL_LOC), p), p),
1176
mulmod(x_diff, x_diff, p),
1177
p
1178
),
1179
addmod(
1180
sub(
1181
p,
1182
addmod(y2_sqr, y1_sqr, p)
1183
),
1184
addmod(y1y2, y1y2, p),
1185
p
1186
),
1187
p
1188
)
1189
x_add_identity :=
1190
mulmod(
1191
mulmod(
1192
x_add_identity,
1193
addmod(
1194
1,
1195
sub(p, mload(QM_EVAL_LOC)),
1196
p
1197
),
1198
p
1199
),
1200
mload(C_ALPHA_BASE_LOC),
1201
p
1202
)
1203
1204
// q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0
1205
let y1_plus_y3 := addmod(
1206
mload(Y1_EVAL_LOC),
1207
mload(Y3_EVAL_LOC),
1208
p
1209
)
1210
let y_diff := addmod(mulmod(mload(Y2_EVAL_LOC), mload(QSIGN_LOC), p), sub(p, mload(Y1_EVAL_LOC)), p)
1211
let y_add_identity :=
1212
addmod(
1213
mulmod(y1_plus_y3, x_diff, p),
1214
mulmod(addmod(mload(X3_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p), y_diff, p),
1215
p
1216
)
1217
y_add_identity :=
1218
mulmod(
1219
mulmod(y_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p),
1220
mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p),
1221
p
1222
)
1223
1224
// ELLIPTIC_IDENTITY = (x_identity + y_identity) * Q_ELLIPTIC_EVAL
1225
mstore(
1226
ELLIPTIC_IDENTITY, mulmod(addmod(x_add_identity, y_add_identity, p), mload(QELLIPTIC_EVAL_LOC), p)
1227
)
1228
}
1229
{
1243
// (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0
1244
let x1_sqr := mulmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p)
1245
let y1_sqr := mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p)
1246
let x_pow_4 := mulmod(addmod(y1_sqr, GRUMPKIN_CURVE_B_PARAMETER_NEGATED, p), mload(X1_EVAL_LOC), p)
1247
let y1_sqr_mul_4 := mulmod(y1_sqr, 4, p)
1248
let x1_pow_4_mul_9 := mulmod(x_pow_4, 9, p)
1249
let x1_sqr_mul_3 := mulmod(x1_sqr, 3, p)
1250
let x_double_identity :=
1251
addmod(
1252
mulmod(
1253
addmod(mload(X3_EVAL_LOC), addmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p), p),
1254
y1_sqr_mul_4,
1255
p
1256
),
1257
sub(p, x1_pow_4_mul_9),
1258
p
1259
)
1260
// (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0
1261
let y_double_identity :=
1262
addmod(
1263
mulmod(x1_sqr_mul_3, addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p),
1264
sub(
1265
p,
1266
mulmod(
1267
addmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p),
1268
addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p),
1269
p
1270
)
1271
),
1272
p
1273
)
1274
x_double_identity := mulmod(x_double_identity, mload(C_ALPHA_BASE_LOC), p)
1275
y_double_identity :=
1276
mulmod(y_double_identity, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), p)
1277
x_double_identity := mulmod(x_double_identity, mload(QM_EVAL_LOC), p)
1278
y_double_identity := mulmod(y_double_identity, mload(QM_EVAL_LOC), p)
1279
// ELLIPTIC_IDENTITY += (x_double_identity + y_double_identity) * Q_DOUBLE_EVAL
1280
mstore(
1281
ELLIPTIC_IDENTITY,
1282
addmod(
1283
mload(ELLIPTIC_IDENTITY),
1284
mulmod(addmod(x_double_identity, y_double_identity, p), mload(QELLIPTIC_EVAL_LOC), p),
1285
p
1286
)
1287
)
1288
1289
// update alpha
1290
mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_QUAD_LOC), p))
1291
}
1292
1296
{
1297
{
1318
let limb_subproduct :=
1319
addmod(
1320
mulmod(mload(W1_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p),
1321
mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_EVAL_LOC), p),
1322
p
1323
)
1324
1325
let non_native_field_gate_2 :=
1326
addmod(
1327
addmod(
1328
mulmod(mload(W1_EVAL_LOC), mload(W4_EVAL_LOC), p),
1329
mulmod(mload(W2_EVAL_LOC), mload(W3_EVAL_LOC), p),
1330
p
1331
),
1332
sub(p, mload(W3_OMEGA_EVAL_LOC)),
1333
p
1334
)
1335
non_native_field_gate_2 := mulmod(non_native_field_gate_2, LIMB_SIZE, p)
1336
non_native_field_gate_2 := addmod(non_native_field_gate_2, sub(p, mload(W4_OMEGA_EVAL_LOC)), p)
1337
non_native_field_gate_2 := addmod(non_native_field_gate_2, limb_subproduct, p)
1338
non_native_field_gate_2 := mulmod(non_native_field_gate_2, mload(Q4_EVAL_LOC), p)
1339
limb_subproduct := mulmod(limb_subproduct, LIMB_SIZE, p)
1340
limb_subproduct :=
1341
addmod(limb_subproduct, mulmod(mload(W1_OMEGA_EVAL_LOC), mload(W2_OMEGA_EVAL_LOC), p), p)
1342
let non_native_field_gate_1 :=
1343
mulmod(
1344
addmod(limb_subproduct, sub(p, addmod(mload(W3_EVAL_LOC), mload(W4_EVAL_LOC), p)), p),
1345
mload(Q3_EVAL_LOC),
1346
p
1347
)
1348
let non_native_field_gate_3 :=
1349
mulmod(
1350
addmod(
1351
addmod(limb_subproduct, mload(W4_EVAL_LOC), p),
1352
sub(p, addmod(mload(W3_OMEGA_EVAL_LOC), mload(W4_OMEGA_EVAL_LOC), p)),
1353
p
1354
),
1355
mload(QM_EVAL_LOC),
1356
p
1357
)
1358
let non_native_field_identity :=
1359
mulmod(
1360
addmod(addmod(non_native_field_gate_1, non_native_field_gate_2, p), non_native_field_gate_3, p),
1361
mload(Q2_EVAL_LOC),
1362
p
1363
)
1364
1365
mstore(AUX_NON_NATIVE_FIELD_EVALUATION, non_native_field_identity)
1366
}
1367
1368
{
1382
let limb_accumulator_1 := mulmod(mload(W2_OMEGA_EVAL_LOC), SUBLIMB_SHIFT, p)
1383
limb_accumulator_1 := addmod(limb_accumulator_1, mload(W1_OMEGA_EVAL_LOC), p)
1384
limb_accumulator_1 := mulmod(limb_accumulator_1, SUBLIMB_SHIFT, p)
1385
limb_accumulator_1 := addmod(limb_accumulator_1, mload(W3_EVAL_LOC), p)
1386
limb_accumulator_1 := mulmod(limb_accumulator_1, SUBLIMB_SHIFT, p)
1387
limb_accumulator_1 := addmod(limb_accumulator_1, mload(W2_EVAL_LOC), p)
1388
limb_accumulator_1 := mulmod(limb_accumulator_1, SUBLIMB_SHIFT, p)
1389
limb_accumulator_1 := addmod(limb_accumulator_1, mload(W1_EVAL_LOC), p)
1390
limb_accumulator_1 := addmod(limb_accumulator_1, sub(p, mload(W4_EVAL_LOC)), p)
1391
limb_accumulator_1 := mulmod(limb_accumulator_1, mload(Q4_EVAL_LOC), p)
1392
1406
let limb_accumulator_2 := mulmod(mload(W3_OMEGA_EVAL_LOC), SUBLIMB_SHIFT, p)
1407
limb_accumulator_2 := addmod(limb_accumulator_2, mload(W2_OMEGA_EVAL_LOC), p)
1408
limb_accumulator_2 := mulmod(limb_accumulator_2, SUBLIMB_SHIFT, p)
1409
limb_accumulator_2 := addmod(limb_accumulator_2, mload(W1_OMEGA_EVAL_LOC), p)
1410
limb_accumulator_2 := mulmod(limb_accumulator_2, SUBLIMB_SHIFT, p)
1411
limb_accumulator_2 := addmod(limb_accumulator_2, mload(W4_EVAL_LOC), p)
1412
limb_accumulator_2 := mulmod(limb_accumulator_2, SUBLIMB_SHIFT, p)
1413
limb_accumulator_2 := addmod(limb_accumulator_2, mload(W3_EVAL_LOC), p)
1414
limb_accumulator_2 := addmod(limb_accumulator_2, sub(p, mload(W4_OMEGA_EVAL_LOC)), p)
1415
limb_accumulator_2 := mulmod(limb_accumulator_2, mload(QM_EVAL_LOC), p)
1416
1417
mstore(
1418
AUX_LIMB_ACCUMULATOR_EVALUATION,
1419
mulmod(addmod(limb_accumulator_1, limb_accumulator_2, p), mload(Q3_EVAL_LOC), p)
1420
)
1421
}
1422
1423
{
1438
let memory_record_check := mulmod(mload(W3_EVAL_LOC), mload(C_ETA_LOC), p)
1439
memory_record_check := addmod(memory_record_check, mload(W2_EVAL_LOC), p)
1440
memory_record_check := mulmod(memory_record_check, mload(C_ETA_LOC), p)
1441
memory_record_check := addmod(memory_record_check, mload(W1_EVAL_LOC), p)
1442
memory_record_check := mulmod(memory_record_check, mload(C_ETA_LOC), p)
1443
memory_record_check := addmod(memory_record_check, mload(QC_EVAL_LOC), p)
1444
1445
let partial_record_check := memory_record_check
1446
memory_record_check := addmod(memory_record_check, sub(p, mload(W4_EVAL_LOC)), p)
1447
1448
mstore(AUX_MEMORY_EVALUATION, memory_record_check)
1449
1450
// index_delta = w_1_omega - w_1
1451
let index_delta := addmod(mload(W1_OMEGA_EVAL_LOC), sub(p, mload(W1_EVAL_LOC)), p)
1452
// record_delta = w_4_omega - w_4
1453
let record_delta := addmod(mload(W4_OMEGA_EVAL_LOC), sub(p, mload(W4_EVAL_LOC)), p)
1454
// index_is_monotonically_increasing = index_delta * (index_delta - 1)
1455
let index_is_monotonically_increasing := mulmod(index_delta, addmod(index_delta, sub(p, 1), p), p)
1456
1457
// adjacent_values_match_if_adjacent_indices_match = record_delta * (1 - index_delta)
1458
let adjacent_values_match_if_adjacent_indices_match :=
1459
mulmod(record_delta, addmod(1, sub(p, index_delta), p), p)
1460
1461
// AUX_ROM_CONSISTENCY_EVALUATION = ((adjacent_values_match_if_adjacent_indices_match * alpha) + index_is_monotonically_increasing) * alpha + partial_record_check
1462
mstore(
1463
AUX_ROM_CONSISTENCY_EVALUATION,
1464
addmod(
1465
mulmod(
1466
addmod(
1467
mulmod(adjacent_values_match_if_adjacent_indices_match, mload(C_ALPHA_LOC), p),
1468
index_is_monotonically_increasing,
1469
p
1470
),
1471
mload(C_ALPHA_LOC),
1472
p
1473
),
1474
memory_record_check,
1475
p
1476
)
1477
)
1478
1479
{
1489
let next_gate_access_type := mulmod(mload(W3_OMEGA_EVAL_LOC), mload(C_ETA_LOC), p)
1490
next_gate_access_type := addmod(next_gate_access_type, mload(W2_OMEGA_EVAL_LOC), p)
1491
next_gate_access_type := mulmod(next_gate_access_type, mload(C_ETA_LOC), p)
1492
next_gate_access_type := addmod(next_gate_access_type, mload(W1_OMEGA_EVAL_LOC), p)
1493
next_gate_access_type := mulmod(next_gate_access_type, mload(C_ETA_LOC), p)
1494
next_gate_access_type := addmod(mload(W4_OMEGA_EVAL_LOC), sub(p, next_gate_access_type), p)
1495
1496
// value_delta = w_3_omega - w_3
1497
let value_delta := addmod(mload(W3_OMEGA_EVAL_LOC), sub(p, mload(W3_EVAL_LOC)), p)
1498
// adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation = (1 - index_delta) * value_delta * (1 - next_gate_access_type);
1499
1500
let adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation :=
1501
mulmod(
1502
addmod(1, sub(p, index_delta), p),
1503
mulmod(value_delta, addmod(1, sub(p, next_gate_access_type), p), p),
1504
p
1505
)
1506
1507
// AUX_RAM_CONSISTENCY_EVALUATION
1508
1522
let access_type := addmod(mload(W4_EVAL_LOC), sub(p, partial_record_check), p)
1523
let access_check := mulmod(access_type, addmod(access_type, sub(p, 1), p), p)
1524
let next_gate_access_type_is_boolean :=
1525
mulmod(next_gate_access_type, addmod(next_gate_access_type, sub(p, 1), p), p)
1526
let RAM_cci :=
1527
mulmod(
1528
adjacent_values_match_if_adjacent_indices_match_and_next_access_is_a_read_operation,
1529
mload(C_ALPHA_LOC),
1530
p
1531
)
1532
RAM_cci := addmod(RAM_cci, index_is_monotonically_increasing, p)
1533
RAM_cci := mulmod(RAM_cci, mload(C_ALPHA_LOC), p)
1534
RAM_cci := addmod(RAM_cci, next_gate_access_type_is_boolean, p)
1535
RAM_cci := mulmod(RAM_cci, mload(C_ALPHA_LOC), p)
1536
RAM_cci := addmod(RAM_cci, access_check, p)
1537
1538
mstore(AUX_RAM_CONSISTENCY_EVALUATION, RAM_cci)
1539
}
1540
1541
{
1542
// timestamp_delta = w_2_omega - w_2
1543
let timestamp_delta := addmod(mload(W2_OMEGA_EVAL_LOC), sub(p, mload(W2_EVAL_LOC)), p)
1544
1545
// RAM_timestamp_check_identity = (1 - index_delta) * timestamp_delta - w_3
1546
let RAM_timestamp_check_identity :=
1547
addmod(
1548
mulmod(timestamp_delta, addmod(1, sub(p, index_delta), p), p), sub(p, mload(W3_EVAL_LOC)), p
1549
)
1550
1562
let memory_identity := mulmod(mload(AUX_ROM_CONSISTENCY_EVALUATION), mload(Q2_EVAL_LOC), p)
1563
memory_identity :=
1564
addmod(memory_identity, mulmod(RAM_timestamp_check_identity, mload(Q4_EVAL_LOC), p), p)
1565
memory_identity :=
1566
addmod(memory_identity, mulmod(mload(AUX_MEMORY_EVALUATION), mload(QM_EVAL_LOC), p), p)
1567
memory_identity := mulmod(memory_identity, mload(Q1_EVAL_LOC), p)
1568
memory_identity :=
1569
addmod(
1570
memory_identity, mulmod(mload(AUX_RAM_CONSISTENCY_EVALUATION), mload(QARITH_EVAL_LOC), p), p
1571
)
1572
1573
let auxiliary_identity := addmod(memory_identity, mload(AUX_NON_NATIVE_FIELD_EVALUATION), p)
1574
auxiliary_identity := addmod(auxiliary_identity, mload(AUX_LIMB_ACCUMULATOR_EVALUATION), p)
1575
auxiliary_identity := mulmod(auxiliary_identity, mload(QAUX_EVAL_LOC), p)
1576
auxiliary_identity := mulmod(auxiliary_identity, mload(C_ALPHA_BASE_LOC), p)
1577
1578
mstore(AUX_IDENTITY, auxiliary_identity)
1579
1580
// update alpha
1581
mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_CUBE_LOC), p))
1582
}
1583
}
1584
}
1585
1586
{
1596
mstore(
1597
QUOTIENT_EVAL_LOC,
1598
mulmod(
1599
addmod(
1600
addmod(
1601
addmod(
1602
addmod(
1603
addmod(mload(PERMUTATION_IDENTITY), mload(PLOOKUP_IDENTITY), p),
1604
mload(ARITHMETIC_IDENTITY),
1605
p
1606
),
1607
mload(SORT_IDENTITY),
1608
p
1609
),
1610
mload(ELLIPTIC_IDENTITY),
1611
p
1612
),
1613
mload(AUX_IDENTITY),
1614
p
1615
),
1616
mload(ZERO_POLY_INVERSE_LOC),
1617
p
1618
)
1619
)
1620
}
1621
1625
{
1626
let current_challenge := mload(C_CURRENT_LOC)
1627
// get a calldata pointer that points to the start of the data we want to copy
1628
let calldata_ptr := add(calldataload(0x04), 0x24)
1629
1630
calldata_ptr := add(calldata_ptr, NU_CALLDATA_SKIP_LENGTH)
1631
1632
mstore(NU_CHALLENGE_INPUT_LOC_A, current_challenge)
1633
mstore(NU_CHALLENGE_INPUT_LOC_B, mload(QUOTIENT_EVAL_LOC))
1634
calldatacopy(NU_CHALLENGE_INPUT_LOC_C, calldata_ptr, NU_INPUT_LENGTH)
1635
1636
// hash length = (0x20 + num field elements), we include the previous challenge in the hash
1637
let challenge := keccak256(NU_CHALLENGE_INPUT_LOC_A, add(NU_INPUT_LENGTH, 0x40))
1638
1639
mstore(C_V0_LOC, mod(challenge, p))
1640
// We need THIRTY-ONE independent nu challenges!
1641
mstore(0x00, challenge)
1642
mstore8(0x20, 0x01)
1643
mstore(C_V1_LOC, mod(keccak256(0x00, 0x21), p))
1644
mstore8(0x20, 0x02)
1645
mstore(C_V2_LOC, mod(keccak256(0x00, 0x21), p))
1646
mstore8(0x20, 0x03)
1647
mstore(C_V3_LOC, mod(keccak256(0x00, 0x21), p))
1648
mstore8(0x20, 0x04)
1649
mstore(C_V4_LOC, mod(keccak256(0x00, 0x21), p))
1650
mstore8(0x20, 0x05)
1651
mstore(C_V5_LOC, mod(keccak256(0x00, 0x21), p))
1652
mstore8(0x20, 0x06)
1653
mstore(C_V6_LOC, mod(keccak256(0x00, 0x21), p))
1654
mstore8(0x20, 0x07)
1655
mstore(C_V7_LOC, mod(keccak256(0x00, 0x21), p))
1656
mstore8(0x20, 0x08)
1657
mstore(C_V8_LOC, mod(keccak256(0x00, 0x21), p))
1658
mstore8(0x20, 0x09)
1659
mstore(C_V9_LOC, mod(keccak256(0x00, 0x21), p))
1660
mstore8(0x20, 0x0a)
1661
mstore(C_V10_LOC, mod(keccak256(0x00, 0x21), p))
1662
mstore8(0x20, 0x0b)
1663
mstore(C_V11_LOC, mod(keccak256(0x00, 0x21), p))
1664
mstore8(0x20, 0x0c)
1665
mstore(C_V12_LOC, mod(keccak256(0x00, 0x21), p))
1666
mstore8(0x20, 0x0d)
1667
mstore(C_V13_LOC, mod(keccak256(0x00, 0x21), p))
1668
mstore8(0x20, 0x0e)
1669
mstore(C_V14_LOC, mod(keccak256(0x00, 0x21), p))
1670
mstore8(0x20, 0x0f)
1671
mstore(C_V15_LOC, mod(keccak256(0x00, 0x21), p))
1672
mstore8(0x20, 0x10)
1673
mstore(C_V16_LOC, mod(keccak256(0x00, 0x21), p))
1674
mstore8(0x20, 0x11)
1675
mstore(C_V17_LOC, mod(keccak256(0x00, 0x21), p))
1676
mstore8(0x20, 0x12)
1677
mstore(C_V18_LOC, mod(keccak256(0x00, 0x21), p))
1678
mstore8(0x20, 0x13)
1679
mstore(C_V19_LOC, mod(keccak256(0x00, 0x21), p))
1680
mstore8(0x20, 0x14)
1681
mstore(C_V20_LOC, mod(keccak256(0x00, 0x21), p))
1682
mstore8(0x20, 0x15)
1683
mstore(C_V21_LOC, mod(keccak256(0x00, 0x21), p))
1684
mstore8(0x20, 0x16)
1685
mstore(C_V22_LOC, mod(keccak256(0x00, 0x21), p))
1686
mstore8(0x20, 0x17)
1687
mstore(C_V23_LOC, mod(keccak256(0x00, 0x21), p))
1688
mstore8(0x20, 0x18)
1689
mstore(C_V24_LOC, mod(keccak256(0x00, 0x21), p))
1690
mstore8(0x20, 0x19)
1691
mstore(C_V25_LOC, mod(keccak256(0x00, 0x21), p))
1692
mstore8(0x20, 0x1a)
1693
mstore(C_V26_LOC, mod(keccak256(0x00, 0x21), p))
1694
mstore8(0x20, 0x1b)
1695
mstore(C_V27_LOC, mod(keccak256(0x00, 0x21), p))
1696
mstore8(0x20, 0x1c)
1697
mstore(C_V28_LOC, mod(keccak256(0x00, 0x21), p))
1698
mstore8(0x20, 0x1d)
1699
mstore(C_V29_LOC, mod(keccak256(0x00, 0x21), p))
1700
1701
// @follow-up - Why are both v29 and v30 using appending 0x1d to the prior challenge and hashing, should it not change?
1702
mstore8(0x20, 0x1d)
1703
challenge := keccak256(0x00, 0x21)
1704
mstore(C_V30_LOC, mod(challenge, p))
1705
1706
// separator
1707
mstore(0x00, challenge)
1708
mstore(0x20, mload(PI_Z_Y_LOC))
1709
mstore(0x40, mload(PI_Z_X_LOC))
1710
mstore(0x60, mload(PI_Z_OMEGA_Y_LOC))
1711
mstore(0x80, mload(PI_Z_OMEGA_X_LOC))
1712
1713
mstore(C_U_LOC, mod(keccak256(0x00, 0xa0), p))
1714
}
1715
1716
let success := 0
1717
// VALIDATE T1
1718
{
1719
let x := mload(T1_X_LOC)
1720
let y := mload(T1_Y_LOC)
1721
let xx := mulmod(x, x, q)
1722
// validate on curve
1723
success := eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))
1724
mstore(ACCUMULATOR_X_LOC, x)
1725
mstore(add(ACCUMULATOR_X_LOC, 0x20), y)
1726
}
1727
// VALIDATE T2
1728
{
1729
let x := mload(T2_X_LOC) // 0x1400
1730
let y := mload(T2_Y_LOC) // 0x1420
1731
let xx := mulmod(x, x, q)
1732
// validate on curve
1733
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1734
mstore(0x00, x)
1735
mstore(0x20, y)
1736
}
1737
mstore(0x40, mload(ZETA_POW_N_LOC))
1738
// accumulator_2 = [T2].zeta^n
1739
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1740
// accumulator = [T1] + accumulator_2
1741
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1742
1743
// VALIDATE T3
1744
{
1745
let x := mload(T3_X_LOC)
1746
let y := mload(T3_Y_LOC)
1747
let xx := mulmod(x, x, q)
1748
// validate on curve
1749
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1750
mstore(0x00, x)
1751
mstore(0x20, y)
1752
}
1753
mstore(0x40, mulmod(mload(ZETA_POW_N_LOC), mload(ZETA_POW_N_LOC), p))
1754
// accumulator_2 = [T3].zeta^{2n}
1755
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1756
// accumulator = accumulator + accumulator_2
1757
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1758
1759
// VALIDATE T4
1760
{
1761
let x := mload(T4_X_LOC)
1762
let y := mload(T4_Y_LOC)
1763
let xx := mulmod(x, x, q)
1764
// validate on curve
1765
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1766
mstore(0x00, x)
1767
mstore(0x20, y)
1768
}
1769
mstore(0x40, mulmod(mulmod(mload(ZETA_POW_N_LOC), mload(ZETA_POW_N_LOC), p), mload(ZETA_POW_N_LOC), p))
1770
// accumulator_2 = [T4].zeta^{3n}
1771
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1772
// accumulator = accumulator + accumulator_2
1773
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1774
1775
// VALIDATE W1
1776
{
1777
let x := mload(W1_X_LOC)
1778
let y := mload(W1_Y_LOC)
1779
let xx := mulmod(x, x, q)
1780
// validate on curve
1781
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1782
mstore(0x00, x)
1783
mstore(0x20, y)
1784
}
1785
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V0_LOC), p))
1786
// accumulator_2 = v0.(u + 1).[W1]
1787
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1788
// accumulator = accumulator + accumulator_2
1789
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1790
1791
// VALIDATE W2
1792
{
1793
let x := mload(W2_X_LOC)
1794
let y := mload(W2_Y_LOC)
1795
let xx := mulmod(x, x, q)
1796
// validate on curve
1797
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1798
mstore(0x00, x)
1799
mstore(0x20, y)
1800
}
1801
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V1_LOC), p))
1802
// accumulator_2 = v1.(u + 1).[W2]
1803
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1804
// accumulator = accumulator + accumulator_2
1805
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1806
1807
// VALIDATE W3
1808
{
1809
let x := mload(W3_X_LOC)
1810
let y := mload(W3_Y_LOC)
1811
let xx := mulmod(x, x, q)
1812
// validate on curve
1813
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1814
mstore(0x00, x)
1815
mstore(0x20, y)
1816
}
1817
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V2_LOC), p))
1818
// accumulator_2 = v2.(u + 1).[W3]
1819
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1820
// accumulator = accumulator + accumulator_2
1821
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1822
1823
// VALIDATE W4
1824
{
1825
let x := mload(W4_X_LOC)
1826
let y := mload(W4_Y_LOC)
1827
let xx := mulmod(x, x, q)
1828
// validate on curve
1829
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1830
mstore(0x00, x)
1831
mstore(0x20, y)
1832
}
1833
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V3_LOC), p))
1834
// accumulator_2 = v3.(u + 1).[W4]
1835
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1836
// accumulator = accumulator + accumulator_2
1837
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1838
1839
// VALIDATE S
1840
{
1841
let x := mload(S_X_LOC)
1842
let y := mload(S_Y_LOC)
1843
let xx := mulmod(x, x, q)
1844
// validate on curve
1845
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1846
mstore(0x00, x)
1847
mstore(0x20, y)
1848
}
1849
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V4_LOC), p))
1850
// accumulator_2 = v4.(u + 1).[S]
1851
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1852
// accumulator = accumulator + accumulator_2
1853
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1854
1855
// VALIDATE Z
1856
{
1857
let x := mload(Z_X_LOC)
1858
let y := mload(Z_Y_LOC)
1859
let xx := mulmod(x, x, q)
1860
// validate on curve
1861
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1862
mstore(0x00, x)
1863
mstore(0x20, y)
1864
}
1865
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V5_LOC), p))
1866
// accumulator_2 = v5.(u + 1).[Z]
1867
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1868
// accumulator = accumulator + accumulator_2
1869
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1870
1871
// VALIDATE Z_LOOKUP
1872
{
1873
let x := mload(Z_LOOKUP_X_LOC)
1874
let y := mload(Z_LOOKUP_Y_LOC)
1875
let xx := mulmod(x, x, q)
1876
// validate on curve
1877
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1878
mstore(0x00, x)
1879
mstore(0x20, y)
1880
}
1881
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V6_LOC), p))
1882
// accumulator_2 = v6.(u + 1).[Z_LOOKUP]
1883
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1884
// accumulator = accumulator + accumulator_2
1885
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1886
1887
// VALIDATE Q1
1888
{
1889
let x := mload(Q1_X_LOC)
1890
let y := mload(Q1_Y_LOC)
1891
let xx := mulmod(x, x, q)
1892
// validate on curve
1893
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1894
mstore(0x00, x)
1895
mstore(0x20, y)
1896
}
1897
mstore(0x40, mload(C_V7_LOC))
1898
// accumulator_2 = v7.[Q1]
1899
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1900
// accumulator = accumulator + accumulator_2
1901
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1902
1903
// VALIDATE Q2
1904
{
1905
let x := mload(Q2_X_LOC)
1906
let y := mload(Q2_Y_LOC)
1907
let xx := mulmod(x, x, q)
1908
// validate on curve
1909
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1910
mstore(0x00, x)
1911
mstore(0x20, y)
1912
}
1913
mstore(0x40, mload(C_V8_LOC))
1914
// accumulator_2 = v8.[Q2]
1915
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1916
// accumulator = accumulator + accumulator_2
1917
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1918
1919
// VALIDATE Q3
1920
{
1921
let x := mload(Q3_X_LOC)
1922
let y := mload(Q3_Y_LOC)
1923
let xx := mulmod(x, x, q)
1924
// validate on curve
1925
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1926
mstore(0x00, x)
1927
mstore(0x20, y)
1928
}
1929
mstore(0x40, mload(C_V9_LOC))
1930
// accumulator_2 = v9.[Q3]
1931
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1932
// accumulator = accumulator + accumulator_2
1933
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1934
1935
// VALIDATE Q4
1936
{
1937
let x := mload(Q4_X_LOC)
1938
let y := mload(Q4_Y_LOC)
1939
let xx := mulmod(x, x, q)
1940
// validate on curve
1941
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1942
mstore(0x00, x)
1943
mstore(0x20, y)
1944
}
1945
mstore(0x40, mload(C_V10_LOC))
1946
// accumulator_2 = v10.[Q4]
1947
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1948
// accumulator = accumulator + accumulator_2
1949
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1950
1951
// VALIDATE QM
1952
{
1953
let x := mload(QM_X_LOC)
1954
let y := mload(QM_Y_LOC)
1955
let xx := mulmod(x, x, q)
1956
// validate on curve
1957
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1958
mstore(0x00, x)
1959
mstore(0x20, y)
1960
}
1961
mstore(0x40, mload(C_V11_LOC))
1962
// accumulator_2 = v11.[Q;]
1963
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1964
// accumulator = accumulator + accumulator_2
1965
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1966
1967
// VALIDATE QC
1968
{
1969
let x := mload(QC_X_LOC)
1970
let y := mload(QC_Y_LOC)
1971
let xx := mulmod(x, x, q)
1972
// validate on curve
1973
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1974
mstore(0x00, x)
1975
mstore(0x20, y)
1976
}
1977
mstore(0x40, mload(C_V12_LOC))
1978
// accumulator_2 = v12.[QC]
1979
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1980
// accumulator = accumulator + accumulator_2
1981
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1982
1983
// VALIDATE QARITH
1984
{
1985
let x := mload(QARITH_X_LOC)
1986
let y := mload(QARITH_Y_LOC)
1987
let xx := mulmod(x, x, q)
1988
// validate on curve
1989
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
1990
mstore(0x00, x)
1991
mstore(0x20, y)
1992
}
1993
mstore(0x40, mload(C_V13_LOC))
1994
// accumulator_2 = v13.[QARITH]
1995
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
1996
// accumulator = accumulator + accumulator_2
1997
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
1998
1999
// VALIDATE QSORT
2000
{
2001
let x := mload(QSORT_X_LOC)
2002
let y := mload(QSORT_Y_LOC)
2003
let xx := mulmod(x, x, q)
2004
// validate on curve
2005
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2006
mstore(0x00, x)
2007
mstore(0x20, y)
2008
}
2009
mstore(0x40, mload(C_V14_LOC))
2010
// accumulator_2 = v14.[QSORT]
2011
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2012
// accumulator = accumulator + accumulator_2
2013
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2014
2015
// VALIDATE QELLIPTIC
2016
{
2017
let x := mload(QELLIPTIC_X_LOC)
2018
let y := mload(QELLIPTIC_Y_LOC)
2019
let xx := mulmod(x, x, q)
2020
// validate on curve
2021
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2022
mstore(0x00, x)
2023
mstore(0x20, y)
2024
}
2025
mstore(0x40, mload(C_V15_LOC))
2026
// accumulator_2 = v15.[QELLIPTIC]
2027
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2028
// accumulator = accumulator + accumulator_2
2029
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2030
2031
// VALIDATE QAUX
2032
{
2033
let x := mload(QAUX_X_LOC)
2034
let y := mload(QAUX_Y_LOC)
2035
let xx := mulmod(x, x, q)
2036
// validate on curve
2037
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2038
mstore(0x00, x)
2039
mstore(0x20, y)
2040
}
2041
mstore(0x40, mload(C_V16_LOC))
2042
// accumulator_2 = v15.[Q_AUX]
2043
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2044
// accumulator = accumulator + accumulator_2
2045
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2046
2047
// VALIDATE SIGMA1
2048
{
2049
let x := mload(SIGMA1_X_LOC)
2050
let y := mload(SIGMA1_Y_LOC)
2051
let xx := mulmod(x, x, q)
2052
// validate on curve
2053
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2054
mstore(0x00, x)
2055
mstore(0x20, y)
2056
}
2057
mstore(0x40, mload(C_V17_LOC))
2058
// accumulator_2 = v17.[sigma1]
2059
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2060
// accumulator = accumulator + accumulator_2
2061
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2062
2063
// VALIDATE SIGMA2
2064
{
2065
let x := mload(SIGMA2_X_LOC)
2066
let y := mload(SIGMA2_Y_LOC)
2067
let xx := mulmod(x, x, q)
2068
// validate on curve
2069
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2070
mstore(0x00, x)
2071
mstore(0x20, y)
2072
}
2073
mstore(0x40, mload(C_V18_LOC))
2074
// accumulator_2 = v18.[sigma2]
2075
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2076
// accumulator = accumulator + accumulator_2
2077
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2078
2079
// VALIDATE SIGMA3
2080
{
2081
let x := mload(SIGMA3_X_LOC)
2082
let y := mload(SIGMA3_Y_LOC)
2083
let xx := mulmod(x, x, q)
2084
// validate on curve
2085
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2086
mstore(0x00, x)
2087
mstore(0x20, y)
2088
}
2089
mstore(0x40, mload(C_V19_LOC))
2090
// accumulator_2 = v19.[sigma3]
2091
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2092
// accumulator = accumulator + accumulator_2
2093
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2094
2095
// VALIDATE SIGMA4
2096
{
2097
let x := mload(SIGMA4_X_LOC)
2098
let y := mload(SIGMA4_Y_LOC)
2099
let xx := mulmod(x, x, q)
2100
// validate on curve
2101
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2102
mstore(0x00, x)
2103
mstore(0x20, y)
2104
}
2105
mstore(0x40, mload(C_V20_LOC))
2106
// accumulator_2 = v20.[sigma4]
2107
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2108
// accumulator = accumulator + accumulator_2
2109
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2110
2111
// VALIDATE TABLE1
2112
{
2113
let x := mload(TABLE1_X_LOC)
2114
let y := mload(TABLE1_Y_LOC)
2115
let xx := mulmod(x, x, q)
2116
// validate on curve
2117
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2118
mstore(0x00, x)
2119
mstore(0x20, y)
2120
}
2121
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V21_LOC), p))
2122
// accumulator_2 = u.[table1]
2123
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2124
// accumulator = accumulator + accumulator_2
2125
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2126
2127
// VALIDATE TABLE2
2128
{
2129
let x := mload(TABLE2_X_LOC)
2130
let y := mload(TABLE2_Y_LOC)
2131
let xx := mulmod(x, x, q)
2132
// validate on curve
2133
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2134
mstore(0x00, x)
2135
mstore(0x20, y)
2136
}
2137
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V22_LOC), p))
2138
// accumulator_2 = u.[table2]
2139
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2140
// accumulator = accumulator + accumulator_2
2141
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2142
2143
// VALIDATE TABLE3
2144
{
2145
let x := mload(TABLE3_X_LOC)
2146
let y := mload(TABLE3_Y_LOC)
2147
let xx := mulmod(x, x, q)
2148
// validate on curve
2149
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2150
mstore(0x00, x)
2151
mstore(0x20, y)
2152
}
2153
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V23_LOC), p))
2154
// accumulator_2 = u.[table3]
2155
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2156
// accumulator = accumulator + accumulator_2
2157
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2158
2159
// VALIDATE TABLE4
2160
{
2161
let x := mload(TABLE4_X_LOC)
2162
let y := mload(TABLE4_Y_LOC)
2163
let xx := mulmod(x, x, q)
2164
// validate on curve
2165
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2166
mstore(0x00, x)
2167
mstore(0x20, y)
2168
}
2169
mstore(0x40, mulmod(addmod(mload(C_U_LOC), 0x1, p), mload(C_V24_LOC), p))
2170
// accumulator_2 = u.[table4]
2171
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2172
// accumulator = accumulator + accumulator_2
2173
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2174
2175
// VALIDATE TABLE_TYPE
2176
{
2177
let x := mload(TABLE_TYPE_X_LOC)
2178
let y := mload(TABLE_TYPE_Y_LOC)
2179
let xx := mulmod(x, x, q)
2180
// validate on curve
2181
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2182
mstore(0x00, x)
2183
mstore(0x20, y)
2184
}
2185
mstore(0x40, mload(C_V25_LOC))
2186
// accumulator_2 = v25.[TableType]
2187
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2188
// accumulator = accumulator + accumulator_2
2189
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2190
2191
// VALIDATE ID1
2192
{
2193
let x := mload(ID1_X_LOC)
2194
let y := mload(ID1_Y_LOC)
2195
let xx := mulmod(x, x, q)
2196
// validate on curve
2197
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2198
mstore(0x00, x)
2199
mstore(0x20, y)
2200
}
2201
mstore(0x40, mload(C_V26_LOC))
2202
// accumulator_2 = v26.[ID1]
2203
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2204
// accumulator = accumulator + accumulator_2
2205
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2206
2207
// VALIDATE ID2
2208
{
2209
let x := mload(ID2_X_LOC)
2210
let y := mload(ID2_Y_LOC)
2211
let xx := mulmod(x, x, q)
2212
// validate on curve
2213
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2214
mstore(0x00, x)
2215
mstore(0x20, y)
2216
}
2217
mstore(0x40, mload(C_V27_LOC))
2218
// accumulator_2 = v27.[ID2]
2219
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2220
// accumulator = accumulator + accumulator_2
2221
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2222
2223
// VALIDATE ID3
2224
{
2225
let x := mload(ID3_X_LOC)
2226
let y := mload(ID3_Y_LOC)
2227
let xx := mulmod(x, x, q)
2228
// validate on curve
2229
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2230
mstore(0x00, x)
2231
mstore(0x20, y)
2232
}
2233
mstore(0x40, mload(C_V28_LOC))
2234
// accumulator_2 = v28.[ID3]
2235
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2236
// accumulator = accumulator + accumulator_2
2237
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2238
2239
// VALIDATE ID4
2240
{
2241
let x := mload(ID4_X_LOC)
2242
let y := mload(ID4_Y_LOC)
2243
let xx := mulmod(x, x, q)
2244
// validate on curve
2245
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2246
mstore(0x00, x)
2247
mstore(0x20, y)
2248
}
2249
mstore(0x40, mload(C_V29_LOC))
2250
// accumulator_2 = v29.[ID4]
2251
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2252
// accumulator = accumulator + accumulator_2
2253
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2254
2258
{
2268
let batch_evaluation :=
2269
mulmod(
2270
mload(C_V0_LOC),
2271
addmod(mulmod(mload(W1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W1_EVAL_LOC), p),
2272
p
2273
)
2274
batch_evaluation :=
2275
addmod(
2276
batch_evaluation,
2277
mulmod(
2278
mload(C_V1_LOC),
2279
addmod(mulmod(mload(W2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W2_EVAL_LOC), p),
2280
p
2281
),
2282
p
2283
)
2284
batch_evaluation :=
2285
addmod(
2286
batch_evaluation,
2287
mulmod(
2288
mload(C_V2_LOC),
2289
addmod(mulmod(mload(W3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W3_EVAL_LOC), p),
2290
p
2291
),
2292
p
2293
)
2294
batch_evaluation :=
2295
addmod(
2296
batch_evaluation,
2297
mulmod(
2298
mload(C_V3_LOC),
2299
addmod(mulmod(mload(W4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(W4_EVAL_LOC), p),
2300
p
2301
),
2302
p
2303
)
2304
batch_evaluation :=
2305
addmod(
2306
batch_evaluation,
2307
mulmod(
2308
mload(C_V4_LOC),
2309
addmod(mulmod(mload(S_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(S_EVAL_LOC), p),
2310
p
2311
),
2312
p
2313
)
2314
batch_evaluation :=
2315
addmod(
2316
batch_evaluation,
2317
mulmod(
2318
mload(C_V5_LOC),
2319
addmod(mulmod(mload(Z_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_EVAL_LOC), p),
2320
p
2321
),
2322
p
2323
)
2324
batch_evaluation :=
2325
addmod(
2326
batch_evaluation,
2327
mulmod(
2328
mload(C_V6_LOC),
2329
addmod(mulmod(mload(Z_LOOKUP_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(Z_LOOKUP_EVAL_LOC), p),
2330
p
2331
),
2332
p
2333
)
2334
2351
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V7_LOC), mload(Q1_EVAL_LOC), p), p)
2352
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V8_LOC), mload(Q2_EVAL_LOC), p), p)
2353
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V9_LOC), mload(Q3_EVAL_LOC), p), p)
2354
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V10_LOC), mload(Q4_EVAL_LOC), p), p)
2355
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V11_LOC), mload(QM_EVAL_LOC), p), p)
2356
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V12_LOC), mload(QC_EVAL_LOC), p), p)
2357
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V13_LOC), mload(QARITH_EVAL_LOC), p), p)
2358
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V14_LOC), mload(QSORT_EVAL_LOC), p), p)
2359
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V15_LOC), mload(QELLIPTIC_EVAL_LOC), p), p)
2360
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V16_LOC), mload(QAUX_EVAL_LOC), p), p)
2361
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V17_LOC), mload(SIGMA1_EVAL_LOC), p), p)
2362
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V18_LOC), mload(SIGMA2_EVAL_LOC), p), p)
2363
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V19_LOC), mload(SIGMA3_EVAL_LOC), p), p)
2364
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V20_LOC), mload(SIGMA4_EVAL_LOC), p), p)
2365
2378
batch_evaluation :=
2379
addmod(
2380
batch_evaluation,
2381
mulmod(
2382
mload(C_V21_LOC),
2383
addmod(mulmod(mload(TABLE1_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE1_EVAL_LOC), p),
2384
p
2385
),
2386
p
2387
)
2388
batch_evaluation :=
2389
addmod(
2390
batch_evaluation,
2391
mulmod(
2392
mload(C_V22_LOC),
2393
addmod(mulmod(mload(TABLE2_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE2_EVAL_LOC), p),
2394
p
2395
),
2396
p
2397
)
2398
batch_evaluation :=
2399
addmod(
2400
batch_evaluation,
2401
mulmod(
2402
mload(C_V23_LOC),
2403
addmod(mulmod(mload(TABLE3_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE3_EVAL_LOC), p),
2404
p
2405
),
2406
p
2407
)
2408
batch_evaluation :=
2409
addmod(
2410
batch_evaluation,
2411
mulmod(
2412
mload(C_V24_LOC),
2413
addmod(mulmod(mload(TABLE4_OMEGA_EVAL_LOC), mload(C_U_LOC), p), mload(TABLE4_EVAL_LOC), p),
2414
p
2415
),
2416
p
2417
)
2418
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V25_LOC), mload(TABLE_TYPE_EVAL_LOC), p), p)
2419
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V26_LOC), mload(ID1_EVAL_LOC), p), p)
2420
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V27_LOC), mload(ID2_EVAL_LOC), p), p)
2421
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V28_LOC), mload(ID3_EVAL_LOC), p), p)
2422
batch_evaluation := addmod(batch_evaluation, mulmod(mload(C_V29_LOC), mload(ID4_EVAL_LOC), p), p)
2423
batch_evaluation := addmod(batch_evaluation, mload(QUOTIENT_EVAL_LOC), p)
2424
2425
mstore(0x00, 0x01) // [1].x
2426
mstore(0x20, 0x02) // [1].y
2427
mstore(0x40, sub(p, batch_evaluation))
2428
// accumulator_2 = -[1].(batch_evaluation)
2429
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2430
// accumulator = accumulator + accumulator_2
2431
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2432
2433
mstore(OPENING_COMMITMENT_SUCCESS_FLAG, success)
2434
}
2435
2439
{
2440
let u := mload(C_U_LOC)
2441
let zeta := mload(C_ZETA_LOC)
2442
// VALIDATE PI_Z
2443
{
2444
let x := mload(PI_Z_X_LOC)
2445
let y := mload(PI_Z_Y_LOC)
2446
let xx := mulmod(x, x, q)
2447
// validate on curve
2448
success := eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q))
2449
mstore(0x00, x)
2450
mstore(0x20, y)
2451
}
2452
// compute zeta.[PI_Z] and add into accumulator
2453
mstore(0x40, zeta)
2454
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2455
// accumulator = accumulator + accumulator_2
2456
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, ACCUMULATOR_X_LOC, 0x40))
2457
2458
// VALIDATE PI_Z_OMEGA
2459
{
2460
let x := mload(PI_Z_OMEGA_X_LOC)
2461
let y := mload(PI_Z_OMEGA_Y_LOC)
2462
let xx := mulmod(x, x, q)
2463
// validate on curve
2464
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2465
mstore(0x00, x)
2466
mstore(0x20, y)
2467
}
2468
mstore(0x40, mulmod(mulmod(u, zeta, p), mload(OMEGA_LOC), p))
2469
// accumulator_2 = u.zeta.omega.[PI_Z_OMEGA]
2470
success := and(success, staticcall(gas(), 7, 0x00, 0x60, ACCUMULATOR2_X_LOC, 0x40))
2471
// PAIRING_RHS = accumulator + accumulator_2
2472
success := and(success, staticcall(gas(), 6, ACCUMULATOR_X_LOC, 0x80, PAIRING_RHS_X_LOC, 0x40))
2473
2474
mstore(0x00, mload(PI_Z_X_LOC))
2475
mstore(0x20, mload(PI_Z_Y_LOC))
2476
mstore(0x40, mload(PI_Z_OMEGA_X_LOC))
2477
mstore(0x60, mload(PI_Z_OMEGA_Y_LOC))
2478
mstore(0x80, u)
2479
success := and(success, staticcall(gas(), 7, 0x40, 0x60, 0x40, 0x40))
2480
// PAIRING_LHS = [PI_Z] + [PI_Z_OMEGA] * u
2481
success := and(success, staticcall(gas(), 6, 0x00, 0x80, PAIRING_LHS_X_LOC, 0x40))
2482
// negate lhs y-coordinate
2483
mstore(PAIRING_LHS_Y_LOC, sub(q, mload(PAIRING_LHS_Y_LOC)))
2484
2485
if mload(CONTAINS_RECURSIVE_PROOF_LOC) {
2486
// VALIDATE RECURSIVE P1
2487
{
2488
let x := mload(RECURSIVE_P1_X_LOC)
2489
let y := mload(RECURSIVE_P1_Y_LOC)
2490
let xx := mulmod(x, x, q)
2491
// validate on curve
2492
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2493
mstore(0x00, x)
2494
mstore(0x20, y)
2495
}
2496
2497
// compute u.u.[recursive_p1] and write into 0x60
2498
mstore(0x40, mulmod(u, u, p))
2499
success := and(success, staticcall(gas(), 7, 0x00, 0x60, 0x60, 0x40))
2500
// VALIDATE RECURSIVE P2
2501
{
2502
let x := mload(RECURSIVE_P2_X_LOC)
2503
let y := mload(RECURSIVE_P2_Y_LOC)
2504
let xx := mulmod(x, x, q)
2505
// validate on curve
2506
success := and(success, eq(mulmod(y, y, q), addmod(mulmod(x, xx, q), 3, q)))
2507
mstore(0x00, x)
2508
mstore(0x20, y)
2509
}
2510
// compute u.u.[recursive_p2] and write into 0x00
2511
// 0x40 still contains u*u
2512
success := and(success, staticcall(gas(), 7, 0x00, 0x60, 0x00, 0x40))
2513
2514
// compute u.u.[recursiveP1] + rhs and write into rhs
2515
mstore(0xa0, mload(PAIRING_RHS_X_LOC))
2516
mstore(0xc0, mload(PAIRING_RHS_Y_LOC))
2517
success := and(success, staticcall(gas(), 6, 0x60, 0x80, PAIRING_RHS_X_LOC, 0x40))
2518
2519
// compute u.u.[recursiveP2] + lhs and write into lhs
2520
mstore(0x40, mload(PAIRING_LHS_X_LOC))
2521
mstore(0x60, mload(PAIRING_LHS_Y_LOC))
2522
success := and(success, staticcall(gas(), 6, 0x00, 0x80, PAIRING_LHS_X_LOC, 0x40))
2523
}
2524
2525
if iszero(success) {
2526
mstore(0x0, EC_SCALAR_MUL_FAILURE_SELECTOR)
2527
revert(0x00, 0x04)
2528
}
2529
mstore(PAIRING_PREAMBLE_SUCCESS_FLAG, success)
2530
}
2531
2535
{
2536
// rhs paired with [1]_2
2537
// lhs paired with [x]_2
2538
2539
mstore(0x00, mload(PAIRING_RHS_X_LOC))
2540
mstore(0x20, mload(PAIRING_RHS_Y_LOC))
2541
mstore(0x40, 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2) // this is [1]_2
2542
mstore(0x60, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)
2543
mstore(0x80, 0x090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b)
2544
mstore(0xa0, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)
2545
2546
mstore(0xc0, mload(PAIRING_LHS_X_LOC))
2547
mstore(0xe0, mload(PAIRING_LHS_Y_LOC))
2548
mstore(0x100, mload(G2X_X0_LOC))
2549
mstore(0x120, mload(G2X_X1_LOC))
2550
mstore(0x140, mload(G2X_Y0_LOC))
2551
mstore(0x160, mload(G2X_Y1_LOC))
2552
2553
success := staticcall(gas(), 8, 0x00, 0x180, 0x00, 0x20)
2554
mstore(PAIRING_SUCCESS_FLAG, success)
2555
mstore(RESULT_FLAG, mload(0x00))
2556
}
2557
if iszero(
2558
and(
2559
and(and(mload(PAIRING_SUCCESS_FLAG), mload(RESULT_FLAG)), mload(PAIRING_PREAMBLE_SUCCESS_FLAG)),
2560
mload(OPENING_COMMITMENT_SUCCESS_FLAG)
2561
)
2562
) {
2563
mstore(0x0, PROOF_FAILURE_SELECTOR)
2564
revert(0x00, 0x04)
2565
}
2566
{
2567
mstore(0x00, 0x01)
2568
return(0x00, 0x20) // Proof succeeded!
2569
}
2570
}
2571
}
2572
}
2573
2574
contract UltraVerifier is BaseUltraVerifier {
2575
function getVerificationKeyHash() public pure override(BaseUltraVerifier) returns (bytes32) {
2576
return UltraVerificationKey.verificationKeyHash();
2577
}
2578
2579
function loadVerificationKey(uint256 vk, uint256 _omegaInverseLoc) internal pure virtual override(BaseUltraVerifier) {
2580
UltraVerificationKey.loadVerificationKey(vk, _omegaInverseLoc);
2581
}
2582
}
2583
)";
Generated by
1.9.6