Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecc.test.cpp
Go to the documentation of this file.
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3
4#include <cstdint>
5
29
30namespace bb::avm2::constraining {
31namespace {
32
33using ::testing::Return;
34using ::testing::StrictMock;
35
36using tracegen::EccTraceBuilder;
37using tracegen::TestTraceContainer;
38using tracegen::ToRadixTraceBuilder;
39
41using C = Column;
42using ecc = bb::avm2::ecc<FF>;
43using scalar_mul = bb::avm2::scalar_mul<FF>;
44using mem_aware_ecc = bb::avm2::ecc_mem<FF>;
45using EccSimulator = simulation::Ecc;
46using ToRadixSimulator = simulation::ToRadix;
47
48using simulation::EccAddEvent;
49using simulation::EccAddMemoryEvent;
50using simulation::EventEmitter;
51using simulation::MemoryStore;
52using simulation::MockExecutionIdManager;
53using simulation::MockGreaterThan;
54using simulation::MockMemory;
55using simulation::NoopEventEmitter;
56using simulation::PureGreaterThan;
57using simulation::PureToRadix;
58using simulation::ScalarMulEvent;
59using simulation::ToRadixEvent;
60using simulation::ToRadixMemoryEvent;
61
62// Known good points for P and Q
63FF p_x("0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
64FF p_y("0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
65EmbeddedCurvePoint p(p_x, p_y, false);
66
67FF q_x("0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7");
68FF q_y("0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3");
69EmbeddedCurvePoint q(q_x, q_y, false);
70
71TEST(EccAddConstrainingTest, EccEmptyRow)
72{
73 check_relation<ecc>(testing::empty_trace());
74}
75
76TEST(EccAddConstrainingTest, EccAdd)
77{
78 // R = P + Q;
79 FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6");
80 FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
81 EmbeddedCurvePoint r(r_x, r_y, false);
82
83 auto trace = TestTraceContainer({ {
84 { C::ecc_add_op, 1 },
85 { C::ecc_double_op, 0 },
86
87 { C::ecc_inv_2_p_y, FF::zero() },
88 { C::ecc_inv_x_diff, (q.x() - p.x()).invert() },
89 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
90
91 { C::ecc_lambda, (q.y() - p.y()) / (q.x() - p.x()) },
92
93 // Point P
94 { C::ecc_p_is_inf, static_cast<int>(p.is_infinity()) },
95 { C::ecc_p_x, p.x() },
96 { C::ecc_p_y, p.y() },
97
98 // Point Q
99 { C::ecc_q_is_inf, static_cast<int>(q.is_infinity()) },
100 { C::ecc_q_x, q.x() },
101 { C::ecc_q_y, q.y() },
102
103 // Resulting Point
104 { C::ecc_r_is_inf, static_cast<int>(r.is_infinity()) },
105 { C::ecc_r_x, r.x() },
106 { C::ecc_r_y, r.y() },
107
108 { C::ecc_result_infinity, 0 },
109
110 { C::ecc_sel, 1 },
111 { C::ecc_use_computed_result, 1 },
112 { C::ecc_x_match, 0 },
113 { C::ecc_y_match, 0 },
114
115 } });
116
117 check_relation<ecc>(trace);
118}
119
120TEST(EccAddConstrainingTest, EccDouble)
121{
122 // R = P + P;
123 FF r_x("0x088b996194bb5e6e8e5e49733bb671c3e660cf77254f743f366cc8e33534ee3b");
124 FF r_y("0x2807ffa01c0f522d0be1e1acfb6914ac8eabf1acf420c0629d37beee992e9a0e");
125 EmbeddedCurvePoint r(r_x, r_y, false);
126
127 auto trace = TestTraceContainer({ {
128 { C::ecc_add_op, 0 },
129 { C::ecc_double_op, 1 },
130
131 { C::ecc_inv_2_p_y, (p.y() * 2).invert() },
132 { C::ecc_inv_x_diff, FF::zero() },
133 { C::ecc_inv_y_diff, FF::zero() },
134
135 { C::ecc_lambda, (p.x() * p.x() * 3) / (p.y() * 2) },
136
137 // Point P
138 { C::ecc_p_is_inf, static_cast<int>(p.is_infinity()) },
139 { C::ecc_p_x, p.x() },
140 { C::ecc_p_y, p.y() },
141
142 // Point Q set to point p since this is doubling
143 { C::ecc_q_is_inf, static_cast<int>(p.is_infinity()) },
144 { C::ecc_q_x, p.x() },
145 { C::ecc_q_y, p.y() },
146
147 // Resulting Point
148 { C::ecc_r_is_inf, static_cast<int>(r.is_infinity()) },
149 { C::ecc_r_x, r.x() },
150 { C::ecc_r_y, r.y() },
151
152 { C::ecc_result_infinity, 0 },
153
154 { C::ecc_sel, 1 },
155 { C::ecc_use_computed_result, 1 },
156 { C::ecc_x_match, 1 },
157 { C::ecc_y_match, 1 },
158
159 } });
160
161 check_relation<ecc>(trace);
162}
163
164TEST(EccAddConstrainingTest, EccAddResultingInInfinity)
165{
166 // R = P + (-P) = O; , where O is the point at infinity
167 EmbeddedCurvePoint q(p.x(), -p.y(), false);
168 EmbeddedCurvePoint r(0, 0, true);
169
170 auto trace = TestTraceContainer({ {
171 { C::ecc_add_op, 0 },
172 { C::ecc_double_op, 0 },
173
174 { C::ecc_inv_2_p_y, FF::zero() },
175 { C::ecc_inv_x_diff, FF::zero() },
176 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
177
178 { C::ecc_lambda, 0 },
179
180 // Point P
181 { C::ecc_p_is_inf, static_cast<int>(p.is_infinity()) },
182 { C::ecc_p_x, p.x() },
183 { C::ecc_p_y, p.y() },
184
185 // Point Q
186 { C::ecc_q_is_inf, static_cast<int>(q.is_infinity()) },
187 { C::ecc_q_x, q.x() },
188 { C::ecc_q_y, q.y() },
189
190 // Resulting Point
191 { C::ecc_r_is_inf, static_cast<int>(r.is_infinity()) },
192 { C::ecc_r_x, r.x() },
193 { C::ecc_r_y, r.y() },
194
195 { C::ecc_result_infinity, 1 },
196
197 { C::ecc_sel, 1 },
198 { C::ecc_x_match, 1 },
199 { C::ecc_y_match, 0 },
200 } });
201
202 check_relation<ecc>(trace);
203}
204
205TEST(EccAddConstrainingTest, EccAddingToInfinity)
206{
207 EmbeddedCurvePoint p(0, 0, true);
208
209 // R = O + Q = Q; , where O is the point at infinity
210
211 EmbeddedCurvePoint r(q.x(), q.y(), false);
212
213 auto trace = TestTraceContainer({ {
214 { C::ecc_add_op, 1 },
215 { C::ecc_double_op, 0 },
216
217 { C::ecc_inv_2_p_y, FF::zero() },
218 { C::ecc_inv_x_diff, (q.x() - p.x()).invert() },
219 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
220
221 { C::ecc_lambda, (q.y() - p.y()) / (q.x() - p.x()) },
222
223 // Point P
224 { C::ecc_p_is_inf, static_cast<int>(p.is_infinity()) },
225 { C::ecc_p_x, p.x() },
226 { C::ecc_p_y, p.y() },
227
228 // Point Q
229 { C::ecc_q_is_inf, static_cast<int>(q.is_infinity()) },
230 { C::ecc_q_x, q.x() },
231 { C::ecc_q_y, q.y() },
232
233 // Resulting Point
234 { C::ecc_r_is_inf, static_cast<int>(r.is_infinity()) },
235 { C::ecc_r_x, r.x() },
236 { C::ecc_r_y, r.y() },
237
238 { C::ecc_result_infinity, 0 },
239
240 { C::ecc_sel, 1 },
241 { C::ecc_x_match, 0 },
242 { C::ecc_y_match, 0 },
243 } });
244
245 check_relation<ecc>(trace);
246}
247
248TEST(EccAddConstrainingTest, EccAddingInfinity)
249{
250 EmbeddedCurvePoint q(0, 0, true);
251
252 // R = P + O = P; , where O is the point at infinity
253 EmbeddedCurvePoint r(p.x(), p.y(), false);
254
255 auto trace = TestTraceContainer({ {
256 { C::ecc_add_op, 1 },
257 { C::ecc_double_op, 0 },
258
259 { C::ecc_inv_2_p_y, (p.y() * 2).invert() },
260 { C::ecc_inv_x_diff, (q.x() - p.x()).invert() },
261 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
262
263 { C::ecc_lambda, (q.y() - p.y()) / (q.x() - p.x()) },
264
265 // Point P
266 { C::ecc_p_is_inf, static_cast<int>(p.is_infinity()) },
267 { C::ecc_p_x, p.x() },
268 { C::ecc_p_y, p.y() },
269
270 // Point Q
271 { C::ecc_q_is_inf, static_cast<int>(q.is_infinity()) },
272 { C::ecc_q_x, q.x() },
273 { C::ecc_q_y, q.y() },
274
275 // Resulting Point
276 { C::ecc_r_is_inf, static_cast<int>(r.is_infinity()) },
277 { C::ecc_r_x, r.x() },
278 { C::ecc_r_y, r.y() },
279
280 { C::ecc_result_infinity, 0 },
281
282 { C::ecc_sel, 1 },
283 { C::ecc_x_match, 0 },
284 { C::ecc_y_match, 0 },
285
286 } });
287
288 check_relation<ecc>(trace);
289}
290
291TEST(EccAddConstrainingTest, EccDoublingInf)
292{
293 EmbeddedCurvePoint p(0, 0, true);
294
295 // r = O + O = O; , where O is the point at infinity
296 EmbeddedCurvePoint r(0, 0, true);
297
298 auto trace = TestTraceContainer({ {
299 { C::ecc_add_op, 0 },
300 { C::ecc_double_op, 1 },
301
302 { C::ecc_inv_2_p_y, FF::zero() },
303 { C::ecc_inv_x_diff, FF::zero() },
304 { C::ecc_inv_y_diff, FF::zero() },
305
306 { C::ecc_lambda, FF::zero() },
307
308 // Point P
309 { C::ecc_p_is_inf, static_cast<int>(p.is_infinity()) },
310 { C::ecc_p_x, p.x() },
311 { C::ecc_p_y, p.y() },
312
313 // Point Q
314 { C::ecc_q_is_inf, static_cast<int>(p.is_infinity()) },
315 { C::ecc_q_x, p.x() },
316 { C::ecc_q_y, p.y() },
317
318 // Resulting Point
319 { C::ecc_r_is_inf, static_cast<int>(r.is_infinity()) },
320 { C::ecc_r_x, r.x() },
321 { C::ecc_r_y, r.y() },
322
323 { C::ecc_result_infinity, 1 },
324
325 { C::ecc_sel, 1 },
326 { C::ecc_x_match, 1 },
327 { C::ecc_y_match, 1 },
328
329 } });
330
331 check_relation<ecc>(trace);
332}
333
334TEST(EccAddConstrainingTest, EccTwoOps)
335{
336 EmbeddedCurvePoint r1 = p + q;
337 EmbeddedCurvePoint r2 = r1 + r1;
338
339 auto trace = TestTraceContainer({ {
340 { C::ecc_add_op, 1 },
341 { C::ecc_double_op, 0 },
342
343 { C::ecc_inv_2_p_y, FF::zero() },
344 { C::ecc_inv_x_diff, (q.x() - p.x()).invert() },
345 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
346
347 { C::ecc_lambda, (q.y() - p.y()) / (q.x() - p.x()) },
348
349 // Point P
350 { C::ecc_p_is_inf, static_cast<int>(p.is_infinity()) },
351 { C::ecc_p_x, p.x() },
352 { C::ecc_p_y, p.y() },
353
354 // Point Q
355 { C::ecc_q_is_inf, static_cast<int>(q.is_infinity()) },
356 { C::ecc_q_x, q.x() },
357 { C::ecc_q_y, q.y() },
358
359 // Resulting Point
360 { C::ecc_r_is_inf, static_cast<int>(r1.is_infinity()) },
361 { C::ecc_r_x, r1.x() },
362 { C::ecc_r_y, r1.y() },
363
364 { C::ecc_result_infinity, 0 },
365
366 { C::ecc_sel, 1 },
367 { C::ecc_use_computed_result, 1 },
368 { C::ecc_x_match, 0 },
369 { C::ecc_y_match, 0 },
370
371 },
372 {
373 { C::ecc_add_op, 0 },
374 { C::ecc_double_op, 1 },
375
376 { C::ecc_inv_2_p_y, (r1.y() * 2).invert() },
377 { C::ecc_inv_x_diff, FF::zero() },
378 { C::ecc_inv_y_diff, FF::zero() },
379
380 { C::ecc_lambda, (r1.x() * r1.x() * 3) / (r1.y() * 2) },
381
382 // Point P
383 { C::ecc_p_is_inf, static_cast<int>(r1.is_infinity()) },
384 { C::ecc_p_x, r1.x() },
385 { C::ecc_p_y, r1.y() },
386
387 // Point Q set to point p since this is doubling
388 { C::ecc_q_is_inf, static_cast<int>(r1.is_infinity()) },
389 { C::ecc_q_x, r1.x() },
390 { C::ecc_q_y, r1.y() },
391
392 // Resulting Point
393 { C::ecc_r_is_inf, static_cast<int>(r2.is_infinity()) },
394 { C::ecc_r_x, r2.x() },
395 { C::ecc_r_y, r2.y() },
396
397 { C::ecc_result_infinity, 0 },
398
399 { C::ecc_sel, 1 },
400 { C::ecc_use_computed_result, 1 },
401 { C::ecc_x_match, 1 },
402 { C::ecc_y_match, 1 },
403
404 } });
405
406 check_relation<ecc>(trace);
407}
408
409TEST(EccAddConstrainingTest, EccNegativeBadAdd)
410{
411 // R != P + Q;
412
413 FF r_x("0x20f096ae3de9aea007e0b94a0274b2443d6682d1901f6909f284ec967bc169be");
414 FF r_y("0x27948713833bb314e828f2b6f45f408da6564a3ac03b9e430a9c6634bb849ef2");
415 EmbeddedCurvePoint r(r_x, r_y, false);
416
417 auto trace = TestTraceContainer({ {
418 { C::ecc_add_op, 1 },
419 { C::ecc_double_op, 0 },
420
421 { C::ecc_inv_2_p_y, FF::zero() },
422 { C::ecc_inv_x_diff, (q.x() - p.x()).invert() },
423 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
424
425 { C::ecc_lambda, (q.y() - p.y()) / (q.x() - p.x()) },
426
427 // Point P
428 { C::ecc_p_is_inf, static_cast<int>(p.is_infinity()) },
429 { C::ecc_p_x, p.x() },
430 { C::ecc_p_y, p.y() },
431
432 // Point Q
433 { C::ecc_q_is_inf, static_cast<int>(q.is_infinity()) },
434 { C::ecc_q_x, q.x() },
435 { C::ecc_q_y, q.y() },
436
437 // Resulting Point
438 { C::ecc_r_is_inf, static_cast<int>(r.is_infinity()) },
439 { C::ecc_r_x, r.x() },
440 { C::ecc_r_y, r.y() },
441
442 { C::ecc_result_infinity, 0 },
443
444 { C::ecc_sel, 1 },
445 { C::ecc_x_match, 0 },
446 { C::ecc_y_match, 0 },
447
448 } });
449
450 EXPECT_THROW_WITH_MESSAGE(check_relation<ecc>(trace, ecc::SR_OUTPUT_X_COORD), "OUTPUT_X_COORD");
451}
452
453TEST(EccAddConstrainingTest, EccNegativeBadDouble)
454{
455 // R != P + P;
456
457 FF r_x("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6");
458 FF r_y("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
459 EmbeddedCurvePoint r(r_x, r_y, false);
460
461 auto trace = TestTraceContainer({ {
462 { C::ecc_add_op, 0 },
463 { C::ecc_double_op, 1 },
464
465 { C::ecc_inv_2_p_y, (p.y() * 2).invert() },
466 { C::ecc_inv_x_diff, FF::zero() },
467 { C::ecc_inv_y_diff, FF::zero() },
468
469 { C::ecc_lambda, (p.x() * p.x() * 3) / (p.y() * 2) },
470
471 // Point P
472 { C::ecc_p_is_inf, static_cast<int>(p.is_infinity()) },
473 { C::ecc_p_x, p.x() },
474 { C::ecc_p_y, p.y() },
475
476 // Point Q set to point p since this is doubling
477 { C::ecc_q_is_inf, static_cast<int>(p.is_infinity()) },
478 { C::ecc_q_x, p.x() },
479 { C::ecc_q_y, p.y() },
480
481 // Resulting Point
482 { C::ecc_r_is_inf, static_cast<int>(r.is_infinity()) },
483 { C::ecc_r_x, r.x() },
484 { C::ecc_r_y, r.y() },
485
486 { C::ecc_result_infinity, 0 },
487
488 { C::ecc_sel, 1 },
489 { C::ecc_x_match, 1 },
490 { C::ecc_y_match, 1 },
491
492 } });
493
494 EXPECT_THROW_WITH_MESSAGE(check_relation<ecc>(trace, ecc::SR_OUTPUT_X_COORD), "OUTPUT_X_COORD");
495}
496
497TEST(ScalarMulConstrainingTest, ScalarMulEmptyRow)
498{
499 check_relation<scalar_mul>(testing::empty_trace());
500}
501
502TEST(ScalarMulConstrainingTest, MulByOne)
503{
504 EccTraceBuilder builder;
505
506 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
507 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
508 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
509
510 StrictMock<MockExecutionIdManager> execution_id_manager;
511 StrictMock<MockGreaterThan> gt;
512 PureToRadix to_radix_simulator = PureToRadix();
513 EccSimulator ecc_simulator(execution_id_manager,
514 gt,
515 to_radix_simulator,
516 ecc_add_event_emitter,
517 scalar_mul_event_emitter,
518 ecc_add_memory_event_emitter);
519
520 FF scalar = FF(1);
521 ecc_simulator.scalar_mul(p, scalar);
522
523 TestTraceContainer trace({
524 { { C::precomputed_first_row, 1 } },
525 });
526
527 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
528 EXPECT_EQ(trace.get_num_rows(), /*start_row=*/1 + 254);
529 check_relation<scalar_mul>(trace);
530}
531
532TEST(ScalarMulConstrainingTest, BasicMul)
533{
534 EccTraceBuilder builder;
535
536 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
537 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
538 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
539
540 StrictMock<MockExecutionIdManager> execution_id_manager;
541 StrictMock<MockGreaterThan> gt;
542 PureToRadix to_radix_simulator = PureToRadix();
543 EccSimulator ecc_simulator(execution_id_manager,
544 gt,
545 to_radix_simulator,
546 ecc_add_event_emitter,
547 scalar_mul_event_emitter,
548 ecc_add_memory_event_emitter);
549
550 FF scalar = FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
551 ecc_simulator.scalar_mul(p, scalar);
552
553 TestTraceContainer trace({
554 { { C::precomputed_first_row, 1 } },
555 });
556
557 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
558 EXPECT_EQ(trace.get_num_rows(), /*start_row=*/1 + 254);
559 check_relation<scalar_mul>(trace);
560}
561
562TEST(ScalarMulConstrainingTest, MultipleInvocations)
563{
564 EccTraceBuilder builder;
565
566 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
567 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
568 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
569
570 StrictMock<MockExecutionIdManager> execution_id_manager;
571 StrictMock<MockGreaterThan> gt;
572 PureToRadix to_radix_simulator = PureToRadix();
573 EccSimulator ecc_simulator(execution_id_manager,
574 gt,
575 to_radix_simulator,
576 ecc_add_event_emitter,
577 scalar_mul_event_emitter,
578 ecc_add_memory_event_emitter);
579
580 ecc_simulator.scalar_mul(p, FF("0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"));
581 ecc_simulator.scalar_mul(q, FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"));
582
583 TestTraceContainer trace({
584 { { C::precomputed_first_row, 1 } },
585 });
586
587 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
588 EXPECT_EQ(trace.get_num_rows(), /*start_row=*/1 + (254) * 2);
589 check_relation<scalar_mul>(trace);
590}
591
592TEST(ScalarMulConstrainingTest, MulInteractions)
593{
594 EccTraceBuilder builder;
595
596 EventEmitter<EccAddEvent> ecc_add_event_emitter;
597 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
598 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
599 EventEmitter<ToRadixEvent> to_radix_event_emitter;
600 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
601
602 StrictMock<MockExecutionIdManager> execution_id_manager;
603 StrictMock<MockGreaterThan> gt;
604 ToRadixSimulator to_radix_simulator(execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
605 EccSimulator ecc_simulator(execution_id_manager,
606 gt,
607 to_radix_simulator,
608 ecc_add_event_emitter,
609 scalar_mul_event_emitter,
610 ecc_add_memory_event_emitter);
611
612 FF scalar = FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
613 ecc_simulator.scalar_mul(p, scalar);
614
615 TestTraceContainer trace({
616 { { C::precomputed_first_row, 1 } },
617 });
618
619 ToRadixTraceBuilder to_radix_builder;
620 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
621 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
622 to_radix_builder.process(to_radix_event_emitter.dump_events(), trace);
623
624 check_interaction<EccTraceBuilder,
628}
629
630TEST(ScalarMulConstrainingTest, MulAddInteractionsInfinity)
631{
632 EccTraceBuilder builder;
633
634 EventEmitter<EccAddEvent> ecc_add_event_emitter;
635 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
636 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
637
638 StrictMock<MockExecutionIdManager> execution_id_manager;
639 StrictMock<MockGreaterThan> gt;
640 PureToRadix to_radix_simulator = PureToRadix();
641 EccSimulator ecc_simulator(execution_id_manager,
642 gt,
643 to_radix_simulator,
644 ecc_add_event_emitter,
645 scalar_mul_event_emitter,
646 ecc_add_memory_event_emitter);
647
648 EmbeddedCurvePoint result = ecc_simulator.scalar_mul(EmbeddedCurvePoint::infinity(), FF(10));
649 ASSERT_TRUE(result.is_infinity());
650
651 TestTraceContainer trace({
652 { { C::precomputed_first_row, 1 } },
653 });
654
655 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
656 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
657
658 check_interaction<EccTraceBuilder, lookup_scalar_mul_double_settings, lookup_scalar_mul_add_settings>(trace);
659
660 check_relation<scalar_mul>(trace);
661 check_relation<ecc>(trace);
662}
663
664TEST(ScalarMulConstrainingTest, NegativeMulAddInteractions)
665{
666 EccTraceBuilder builder;
667
668 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
669 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
670 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
671
672 StrictMock<MockExecutionIdManager> execution_id_manager;
673 StrictMock<MockGreaterThan> gt;
674 PureToRadix to_radix_simulator = PureToRadix();
675 EccSimulator ecc_simulator(execution_id_manager,
676 gt,
677 to_radix_simulator,
678 ecc_add_event_emitter,
679 scalar_mul_event_emitter,
680 ecc_add_memory_event_emitter);
681
682 FF scalar = FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
683 ecc_simulator.scalar_mul(p, scalar);
684
685 TestTraceContainer trace({
686 { { C::precomputed_first_row, 1 } },
687 });
688
689 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
690
691 EXPECT_THROW_WITH_MESSAGE((check_interaction<EccTraceBuilder, lookup_scalar_mul_double_settings>(trace)),
692 "Failed.*SCALAR_MUL_DOUBLE. Could not find tuple in destination.");
693 EXPECT_THROW_WITH_MESSAGE((check_interaction<EccTraceBuilder, lookup_scalar_mul_add_settings>(trace)),
694 "Failed.*SCALAR_MUL_ADD. Could not find tuple in destination.");
695}
696
697TEST(ScalarMulConstrainingTest, NegativeMulRadixInteractions)
698{
699 EccTraceBuilder builder;
700
701 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
702 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
703 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
704
705 StrictMock<MockExecutionIdManager> execution_id_manager;
706 StrictMock<MockGreaterThan> gt;
707 PureToRadix to_radix_simulator = PureToRadix();
708 EccSimulator ecc_simulator(execution_id_manager,
709 gt,
710 to_radix_simulator,
711 ecc_add_event_emitter,
712 scalar_mul_event_emitter,
713 ecc_add_memory_event_emitter);
714
715 FF scalar = FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
716 ecc_simulator.scalar_mul(p, scalar);
717
718 TestTraceContainer trace({
719 { { C::precomputed_first_row, 1 } },
720 });
721
722 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
723
724 EXPECT_THROW_WITH_MESSAGE((check_interaction<EccTraceBuilder, lookup_scalar_mul_to_radix_settings>(trace)),
725 "Failed.*SCALAR_MUL_TO_RADIX. Could not find tuple in destination.");
726
727 check_relation<scalar_mul>(trace);
728}
729
730TEST(ScalarMulConstrainingTest, NegativeDisableSel)
731{
732 EccTraceBuilder builder;
733
734 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
735 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
736 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
737
738 StrictMock<MockExecutionIdManager> execution_id_manager;
739 StrictMock<MockGreaterThan> gt;
740 PureToRadix to_radix_simulator = PureToRadix();
741 EccSimulator ecc_simulator(execution_id_manager,
742 gt,
743 to_radix_simulator,
744 ecc_add_event_emitter,
745 scalar_mul_event_emitter,
746 ecc_add_memory_event_emitter);
747
748 FF scalar = FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
749 ecc_simulator.scalar_mul(p, scalar);
750
751 TestTraceContainer trace({
752 { { C::precomputed_first_row, 1 } },
753 });
754
755 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
756 // Disable the selector in one of the rows between start and end
757 trace.set(Column::scalar_mul_sel, 5, 0);
759 "SELECTOR_CONSISTENCY");
760}
761
762TEST(ScalarMulConstrainingTest, NegativeEnableStartFirstRow)
763{
764 EccTraceBuilder builder;
765
766 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
767 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
768 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
769
770 StrictMock<MockExecutionIdManager> execution_id_manager;
771 StrictMock<MockGreaterThan> gt;
772 PureToRadix to_radix_simulator = PureToRadix();
773 EccSimulator ecc_simulator(execution_id_manager,
774 gt,
775 to_radix_simulator,
776 ecc_add_event_emitter,
777 scalar_mul_event_emitter,
778 ecc_add_memory_event_emitter);
779
780 FF scalar = FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
781 ecc_simulator.scalar_mul(p, scalar);
782
783 TestTraceContainer trace({
784 { { C::precomputed_first_row, 1 } },
785 });
786
787 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
788 // Enable the start in the first row
789 trace.set(Column::scalar_mul_start, 0, 1);
790 EXPECT_THROW_WITH_MESSAGE(check_relation<scalar_mul>(trace, scalar_mul::SR_SELECTOR_ON_START), "SELECTOR_ON_START");
791}
792
793TEST(ScalarMulConstrainingTest, NegativeMutateScalarOnEnd)
794{
795 EccTraceBuilder builder;
796
797 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
798 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
799 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
800
801 StrictMock<MockExecutionIdManager> execution_id_manager;
802 StrictMock<MockGreaterThan> gt;
803 PureToRadix to_radix_simulator = PureToRadix();
804 EccSimulator ecc_simulator(execution_id_manager,
805 gt,
806 to_radix_simulator,
807 ecc_add_event_emitter,
808 scalar_mul_event_emitter,
809 ecc_add_memory_event_emitter);
810
811 FF scalar = FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
812 ecc_simulator.scalar_mul(p, scalar);
813
814 TestTraceContainer trace({
815 { { C::precomputed_first_row, 1 } },
816 });
817
818 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
819 // Mutate the scalar on the end row
820 trace.set(Column::scalar_mul_scalar, 254, 27);
822 "INPUT_CONSISTENCY_SCALAR");
823}
824
825TEST(ScalarMulConstrainingTest, NegativeMutatePointXOnEnd)
826{
827 EccTraceBuilder builder;
828
829 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
830 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
831 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
832
833 StrictMock<MockExecutionIdManager> execution_id_manager;
834 StrictMock<MockGreaterThan> gt;
835 PureToRadix to_radix_simulator = PureToRadix();
836 EccSimulator ecc_simulator(execution_id_manager,
837 gt,
838 to_radix_simulator,
839 ecc_add_event_emitter,
840 scalar_mul_event_emitter,
841 ecc_add_memory_event_emitter);
842
843 FF scalar = FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
844 ecc_simulator.scalar_mul(p, scalar);
845
846 TestTraceContainer trace({
847 { { C::precomputed_first_row, 1 } },
848 });
849
850 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
851 // Mutate the point on the end row
852 trace.set(Column::scalar_mul_point_x, 254, q.x());
853
855 "INPUT_CONSISTENCY_X");
856}
857
858TEST(ScalarMulConstrainingTest, NegativeMutatePointYOnEnd)
859{
860 EccTraceBuilder builder;
861
862 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
863 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
864 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
865
866 StrictMock<MockExecutionIdManager> execution_id_manager;
867 StrictMock<MockGreaterThan> gt;
868 PureToRadix to_radix_simulator = PureToRadix();
869 EccSimulator ecc_simulator(execution_id_manager,
870 gt,
871 to_radix_simulator,
872 ecc_add_event_emitter,
873 scalar_mul_event_emitter,
874 ecc_add_memory_event_emitter);
875
876 FF scalar = FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
877 ecc_simulator.scalar_mul(p, scalar);
878
879 TestTraceContainer trace({
880 { { C::precomputed_first_row, 1 } },
881 });
882
883 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
884 // Mutate the point on the end row
885 trace.set(Column::scalar_mul_point_y, 254, q.y());
886
888 "INPUT_CONSISTENCY_Y");
889}
890
891TEST(ScalarMulConstrainingTest, NegativeMutatePointInfOnEnd)
892{
893 EccTraceBuilder builder;
894
895 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
896 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
897 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
898
899 StrictMock<MockExecutionIdManager> execution_id_manager;
900 StrictMock<MockGreaterThan> gt;
901 PureToRadix to_radix_simulator = PureToRadix();
902 EccSimulator ecc_simulator(execution_id_manager,
903 gt,
904 to_radix_simulator,
905 ecc_add_event_emitter,
906 scalar_mul_event_emitter,
907 ecc_add_memory_event_emitter);
908
909 FF scalar = FF("0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
910 ecc_simulator.scalar_mul(p, scalar);
911
912 TestTraceContainer trace({
913 { { C::precomputed_first_row, 1 } },
914 });
915
916 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
917 // Mutate the point on the end row
918 trace.set(Column::scalar_mul_point_inf, 254, 1);
919
921 "INPUT_CONSISTENCY_INF");
922}
923
925// Memory Aware Ecc Add
927
928TEST(EccAddMemoryConstrainingTest, EccAddMemoryEmptyRow)
929{
930 check_relation<mem_aware_ecc>(testing::empty_trace());
931}
932
933TEST(EccAddMemoryConstrainingTest, EccAddMemory)
934{
935 TestTraceContainer trace;
936 EccTraceBuilder builder;
938
939 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
940 EventEmitter<EccAddEvent> ecc_add_event_emitter;
941 NoopEventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
942 NoopEventEmitter<ToRadixEvent> to_radix_event_emitter;
943
944 StrictMock<MockExecutionIdManager> execution_id_manager;
945 EXPECT_CALL(execution_id_manager, get_execution_id)
946 .WillRepeatedly(Return(0)); // Use a fixed execution IDfor the test
947 PureGreaterThan gt;
948 PureToRadix to_radix_simulator = PureToRadix();
949 EccSimulator ecc_simulator(execution_id_manager,
950 gt,
951 to_radix_simulator,
952 ecc_add_event_emitter,
953 scalar_mul_event_emitter,
954 ecc_add_memory_event_emitter);
955
956 MemoryAddress dst_address = 5;
957 ecc_simulator.add(memory, p, q, dst_address);
958 builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(), trace);
959 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
960
961 check_relation<mem_aware_ecc>(trace);
962}
963
964TEST(EccAddMemoryConstrainingTest, EccAddMemoryInteractions)
965{
966
967 EccTraceBuilder builder;
969
970 StrictMock<MockExecutionIdManager> execution_id_manager;
971 EXPECT_CALL(execution_id_manager, get_execution_id)
972 .WillRepeatedly(Return(0)); // Use a fixed execution IDfor the test
973 PureGreaterThan gt;
974 PureToRadix to_radix_simulator = PureToRadix();
975
976 EventEmitter<EccAddEvent> ecc_add_event_emitter;
977 NoopEventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
978 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
979 NoopEventEmitter<ToRadixEvent> to_radix_event_emitter;
980 EccSimulator ecc_simulator(execution_id_manager,
981 gt,
982 to_radix_simulator,
983 ecc_add_event_emitter,
984 scalar_mul_event_emitter,
985 ecc_add_memory_event_emitter);
986
987 EmbeddedCurvePoint result = p + q;
988
989 uint32_t dst_address = 0x1000;
990 // Set the execution and gt traces
991 TestTraceContainer trace = TestTraceContainer({
992 // Row 0
993 {
994 // Execution
995 { C::execution_sel, 1 },
996 { C::execution_sel_exec_dispatch_ecc_add, 1 },
997 { C::execution_rop_6_, dst_address },
998 { C::execution_register_0_, p.x() },
999 { C::execution_register_1_, p.y() },
1000 { C::execution_register_2_, p.is_infinity() ? 1 : 0 },
1001 { C::execution_register_3_, q.x() },
1002 { C::execution_register_4_, q.y() },
1003 { C::execution_register_5_, q.is_infinity() ? 1 : 0 },
1004 // GT - dst out of range check
1005 { C::gt_sel, 1 },
1006 { C::gt_input_a, dst_address + 2 }, // highest write address is dst_address + 2
1007 { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS },
1008 { C::gt_res, 0 },
1009 // Memory Writes
1010 { C::memory_address, dst_address },
1011 { C::memory_value, result.x() },
1012 { C::memory_sel, 1 },
1013 { C::memory_rw, 1 }, // write
1014 { C::memory_tag, static_cast<uint8_t>(MemoryTag::FF) },
1015 },
1016 {
1017 // Memory Writes
1018 { C::memory_address, dst_address + 1 },
1019 { C::memory_value, result.y() },
1020 { C::memory_sel, 1 },
1021 { C::memory_rw, 1 }, // write
1022 { C::memory_tag, static_cast<uint8_t>(MemoryTag::FF) },
1023 },
1024 {
1025 // Memory Writes
1026 { C::memory_address, dst_address + 2 },
1027 { C::memory_value, result.is_infinity() },
1028 { C::memory_sel, 1 },
1029 { C::memory_rw, 1 }, // write
1030 { C::memory_tag, static_cast<uint8_t>(MemoryTag::U1) },
1031 },
1032 });
1033
1034 ecc_simulator.add(memory, p, q, dst_address);
1035
1036 builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(), trace);
1037 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
1038
1039 check_all_interactions<EccTraceBuilder>(trace);
1040 check_relation<mem_aware_ecc>(trace);
1041}
1042
1043TEST(EccAddMemoryConstrainingTest, EccAddMemoryInvalidDstRange)
1044{
1045
1046 EccTraceBuilder builder;
1048
1049 NoopEventEmitter<ToRadixEvent> to_radix_event_emitter;
1050 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
1051 EventEmitter<EccAddEvent> ecc_add_event_emitter;
1052 NoopEventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
1053
1054 StrictMock<MockExecutionIdManager> execution_id_manager;
1055 EXPECT_CALL(execution_id_manager, get_execution_id)
1056 .WillRepeatedly(Return(0)); // Use a fixed execution IDfor the test
1057 PureGreaterThan gt;
1058 PureToRadix to_radix_simulator = PureToRadix();
1059
1060 EccSimulator ecc_simulator(execution_id_manager,
1061 gt,
1062 to_radix_simulator,
1063 ecc_add_event_emitter,
1064 scalar_mul_event_emitter,
1065 ecc_add_memory_event_emitter);
1066
1067 uint32_t dst_address = AVM_HIGHEST_MEM_ADDRESS - 1; // Invalid address, will result in out of range error
1068 // Set the execution and gt traces
1069 TestTraceContainer trace = TestTraceContainer({
1070 // Row 0
1071 {
1072 // Execution
1073 { C::execution_sel, 1 },
1074 { C::execution_sel_exec_dispatch_ecc_add, 1 },
1075 { C::execution_rop_6_, dst_address },
1076 { C::execution_register_0_, p.x() },
1077 { C::execution_register_1_, p.y() },
1078 { C::execution_register_2_, p.is_infinity() ? 1 : 0 },
1079 { C::execution_register_3_, q.x() },
1080 { C::execution_register_4_, q.y() },
1081 { C::execution_register_5_, q.is_infinity() ? 1 : 0 },
1082 { C::execution_sel_opcode_error, 1 },
1083 // GT - dst out of range check
1084 { C::gt_sel, 1 },
1085 { C::gt_input_a, static_cast<uint64_t>(dst_address) + 2 },
1086 { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS },
1087 { C::gt_res, 1 },
1088 },
1089 });
1090
1091 EXPECT_THROW_WITH_MESSAGE(ecc_simulator.add(memory, p, q, dst_address), "EccException.* dst address out of range");
1092
1093 builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(), trace);
1094 EXPECT_EQ(ecc_add_event_emitter.get_events().size(), 0); // Expect 0 add events since error in ecc_mem
1095
1096 check_all_interactions<EccTraceBuilder>(trace);
1097 check_relation<mem_aware_ecc>(trace);
1098}
1099
1100TEST(EccAddMemoryConstrainingTest, EccAddMemoryPointError)
1101{
1102
1103 EccTraceBuilder builder;
1105 EventEmitter<EccAddEvent> ecc_add_event_emitter;
1106 NoopEventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
1107 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
1108
1109 StrictMock<MockExecutionIdManager> execution_id_manager;
1110 EXPECT_CALL(execution_id_manager, get_execution_id)
1111 .WillRepeatedly(Return(0)); // Use a fixed execution IDfor the test
1112 PureGreaterThan gt;
1113 PureToRadix to_radix_simulator = PureToRadix();
1114
1115 EccSimulator ecc_simulator(execution_id_manager,
1116 gt,
1117 to_radix_simulator,
1118 ecc_add_event_emitter,
1119 scalar_mul_event_emitter,
1120 ecc_add_memory_event_emitter);
1121
1122 // Point P is not on the curve
1123 FF p_x("0x0000000000063d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
1124 FF p_y("0x00000000000c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
1125 EmbeddedCurvePoint p(p_x, p_y, false);
1126
1127 uint32_t dst_address = 0x1000;
1128
1129 EXPECT_CALL(execution_id_manager, get_execution_id()).WillOnce(::testing::Return(0));
1130 // Set the execution and gt traces
1131 TestTraceContainer trace = TestTraceContainer({
1132 // Row 0
1133 {
1134 // Execution
1135 { C::execution_sel, 1 },
1136 { C::execution_sel_exec_dispatch_ecc_add, 1 },
1137 { C::execution_rop_6_, dst_address },
1138 { C::execution_register_0_, p.x() },
1139 { C::execution_register_1_, p.y() },
1140 { C::execution_register_2_, p.is_infinity() ? 1 : 0 },
1141 { C::execution_register_3_, q.x() },
1142 { C::execution_register_4_, q.y() },
1143 { C::execution_register_5_, q.is_infinity() ? 1 : 0 },
1144 { C::execution_sel_opcode_error, 1 }, // Indicate an error in the operation
1145 // GT - dst out of range check
1146 { C::gt_sel, 1 },
1147 { C::gt_input_a, dst_address + 2 }, // highest write address is dst_address + 2
1148 { C::gt_input_b, AVM_HIGHEST_MEM_ADDRESS },
1149 { C::gt_res, 0 },
1150 },
1151 });
1152
1153 EXPECT_THROW(ecc_simulator.add(memory, p, q, dst_address), simulation::EccException);
1154
1155 builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(), trace);
1156 // Expect no events to be emitted since the operation failed
1157 EXPECT_EQ(ecc_add_event_emitter.get_events().size(), 0);
1158
1159 check_all_interactions<EccTraceBuilder>(trace);
1160 check_relation<mem_aware_ecc>(trace);
1161}
1162
1163} // namespace
1164} // namespace bb::avm2::constraining
#define AVM_HIGHEST_MEM_ADDRESS
static constexpr size_t SR_OUTPUT_X_COORD
Definition ecc.hpp:42
static constexpr size_t SR_INPUT_CONSISTENCY_X
static constexpr size_t SR_INPUT_CONSISTENCY_INF
static constexpr size_t SR_SELECTOR_CONSISTENCY
static constexpr size_t SR_SELECTOR_ON_START
static constexpr size_t SR_INPUT_CONSISTENCY_Y
static constexpr size_t SR_INPUT_CONSISTENCY_SCALAR
void process(const simulation::EventEmitterInterface< simulation::AluEvent >::Container &events, TraceContainer &trace)
void set(Column col, uint32_t row, const FF &value)
AluTraceBuilder builder
Definition alu.test.cpp:123
ExecutionIdManager execution_id_manager
GreaterThan gt
TestTraceContainer trace
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
Definition macros.hpp:7
void check_interaction(tracegen::TestTraceContainer &trace)
TEST(TxExecutionConstrainingTest, WriteTreeValue)
Definition tx.test.cpp:402
TestTraceContainer empty_trace()
Definition fixtures.cpp:153
lookup_settings< lookup_scalar_mul_double_settings_ > lookup_scalar_mul_double_settings
StandardAffinePoint< AvmFlavorSettings::EmbeddedCurve::AffineElement > EmbeddedCurvePoint
Definition field.hpp:12
lookup_settings< lookup_scalar_mul_to_radix_settings_ > lookup_scalar_mul_to_radix_settings
lookup_settings< lookup_scalar_mul_add_settings_ > lookup_scalar_mul_add_settings
uint32_t MemoryAddress
AvmFlavorSettings::FF FF
Definition field.hpp:10
typename Flavor::FF FF
MemoryStore memory