1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
34using ::testing::Return;
35using ::testing::StrictMock;
37using tracegen::EccTraceBuilder;
38using tracegen::TestTraceContainer;
39using tracegen::ToRadixTraceBuilder;
46using EccSimulator = simulation::Ecc;
47using ToRadixSimulator = simulation::ToRadix;
49using simulation::EccAddEvent;
50using simulation::EccAddMemoryEvent;
51using simulation::EventEmitter;
52using simulation::MemoryStore;
53using simulation::MockExecutionIdManager;
54using simulation::MockGreaterThan;
55using simulation::MockMemory;
56using simulation::NoopEventEmitter;
57using simulation::PureGreaterThan;
58using simulation::PureToRadix;
59using simulation::ScalarMulEvent;
60using simulation::ToRadixEvent;
61using simulation::ToRadixMemoryEvent;
64FF p_x(
"0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
65FF p_y(
"0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
68FF q_x(
"0x009242167ec31949c00cbe441cd36757607406e87844fa2c8c4364a4403e66d7");
69FF q_y(
"0x0fe3016d64cfa8045609f375284b6b739b5fa282e4cbb75cc7f1687ecc7420e3");
72TEST(EccAddConstrainingTest, EccEmptyRow)
77TEST(EccAddConstrainingTest, EccAdd)
80 FF r_x(
"0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6");
81 FF r_y(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
84 auto trace = TestTraceContainer({ {
86 { C::ecc_double_op, 0 },
89 { C::ecc_inv_x_diff, (q.x() - p.x()).invert() },
90 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
92 { C::ecc_lambda, (q.y() - p.y()) / (q.x() - p.x()) },
95 { C::ecc_p_is_inf,
static_cast<int>(p.is_infinity()) },
96 { C::ecc_p_x, p.x() },
97 { C::ecc_p_y, p.y() },
100 { C::ecc_q_is_inf,
static_cast<int>(q.is_infinity()) },
101 { C::ecc_q_x, q.x() },
102 { C::ecc_q_y, q.y() },
105 { C::ecc_r_is_inf,
static_cast<int>(r.is_infinity()) },
106 { C::ecc_r_x, r.x() },
107 { C::ecc_r_y, r.y() },
109 { C::ecc_result_infinity, 0 },
112 { C::ecc_use_computed_result, 1 },
113 { C::ecc_x_match, 0 },
114 { C::ecc_y_match, 0 },
118 check_relation<ecc>(trace);
121TEST(EccAddConstrainingTest, EccDouble)
124 FF r_x(
"0x088b996194bb5e6e8e5e49733bb671c3e660cf77254f743f366cc8e33534ee3b");
125 FF r_y(
"0x2807ffa01c0f522d0be1e1acfb6914ac8eabf1acf420c0629d37beee992e9a0e");
128 auto trace = TestTraceContainer({ {
129 { C::ecc_add_op, 0 },
130 { C::ecc_double_op, 1 },
132 { C::ecc_inv_2_p_y, (p.y() * 2).invert() },
136 { C::ecc_lambda, (p.x() * p.x() * 3) / (p.y() * 2) },
139 { C::ecc_p_is_inf,
static_cast<int>(p.is_infinity()) },
140 { C::ecc_p_x, p.x() },
141 { C::ecc_p_y, p.y() },
144 { C::ecc_q_is_inf,
static_cast<int>(p.is_infinity()) },
145 { C::ecc_q_x, p.x() },
146 { C::ecc_q_y, p.y() },
149 { C::ecc_r_is_inf,
static_cast<int>(r.is_infinity()) },
150 { C::ecc_r_x, r.x() },
151 { C::ecc_r_y, r.y() },
153 { C::ecc_result_infinity, 0 },
156 { C::ecc_use_computed_result, 1 },
157 { C::ecc_x_match, 1 },
158 { C::ecc_y_match, 1 },
162 check_relation<ecc>(trace);
171TEST(EccAddConstrainingTest, EccAddSameYDifferentX)
174 FF local_p_x(
"0x04c95d1b26d63d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
175 FF local_p_y(
"0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
180 FF local_q_x(
"0x14dd39aa19e1c8b29e0c530a28106a7d64d2213486baba3c86dce51bdddf75bb");
181 FF local_q_y(
"0x035b6dd9e63c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
185 ASSERT_NE(local_p.x(), local_q.x());
186 ASSERT_EQ(local_p.y(), local_q.y());
189 FF local_r_x(
"0x16bdb7ada0799a3088b9dd3faade12c3f79dbfe9cb1234783a1a7add546398dc");
190 FF local_r_y(
"0x2d08e098faf58cb97223d13f2a1b87dd6614173f3cefe87ca6a74e3034c244a1");
194 EventEmitter<EccAddEvent> ecc_add_event_emitter;
195 NoopEventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
196 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
200 PureToRadix to_radix_simulator;
204 ecc_add_event_emitter,
205 scalar_mul_event_emitter,
206 ecc_add_memory_event_emitter);
210 ASSERT_EQ(result, local_r) <<
"Simulation produced wrong result";
213 TestTraceContainer
trace;
215 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
218 check_relation<ecc>(trace);
221TEST(EccAddConstrainingTest, EccAddResultingInInfinity)
227 auto trace = TestTraceContainer({ {
228 { C::ecc_add_op, 0 },
229 { C::ecc_double_op, 0 },
233 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
235 { C::ecc_lambda, 0 },
238 { C::ecc_p_is_inf,
static_cast<int>(p.is_infinity()) },
239 { C::ecc_p_x, p.x() },
240 { C::ecc_p_y, p.y() },
243 { C::ecc_q_is_inf,
static_cast<int>(q.is_infinity()) },
244 { C::ecc_q_x, q.x() },
245 { C::ecc_q_y, q.y() },
248 { C::ecc_r_is_inf,
static_cast<int>(r.is_infinity()) },
249 { C::ecc_r_x, r.x() },
250 { C::ecc_r_y, r.y() },
252 { C::ecc_result_infinity, 1 },
255 { C::ecc_x_match, 1 },
256 { C::ecc_y_match, 0 },
259 check_relation<ecc>(trace);
262TEST(EccAddConstrainingTest, EccAddingToInfinity)
270 auto trace = TestTraceContainer({ {
271 { C::ecc_add_op, 1 },
272 { C::ecc_double_op, 0 },
275 { C::ecc_inv_x_diff, (q.x() - p.x()).invert() },
276 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
278 { C::ecc_lambda, (q.y() - p.y()) / (q.x() - p.x()) },
281 { C::ecc_p_is_inf,
static_cast<int>(p.is_infinity()) },
282 { C::ecc_p_x, p.x() },
283 { C::ecc_p_y, p.y() },
286 { C::ecc_q_is_inf,
static_cast<int>(q.is_infinity()) },
287 { C::ecc_q_x, q.x() },
288 { C::ecc_q_y, q.y() },
291 { C::ecc_r_is_inf,
static_cast<int>(r.is_infinity()) },
292 { C::ecc_r_x, r.x() },
293 { C::ecc_r_y, r.y() },
295 { C::ecc_result_infinity, 0 },
298 { C::ecc_x_match, 0 },
299 { C::ecc_y_match, 0 },
302 check_relation<ecc>(trace);
305TEST(EccAddConstrainingTest, EccAddingInfinity)
312 auto trace = TestTraceContainer({ {
313 { C::ecc_add_op, 1 },
314 { C::ecc_double_op, 0 },
316 { C::ecc_inv_2_p_y, (p.y() * 2).invert() },
317 { C::ecc_inv_x_diff, (q.x() - p.x()).invert() },
318 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
320 { C::ecc_lambda, (q.y() - p.y()) / (q.x() - p.x()) },
323 { C::ecc_p_is_inf,
static_cast<int>(p.is_infinity()) },
324 { C::ecc_p_x, p.x() },
325 { C::ecc_p_y, p.y() },
328 { C::ecc_q_is_inf,
static_cast<int>(q.is_infinity()) },
329 { C::ecc_q_x, q.x() },
330 { C::ecc_q_y, q.y() },
333 { C::ecc_r_is_inf,
static_cast<int>(r.is_infinity()) },
334 { C::ecc_r_x, r.x() },
335 { C::ecc_r_y, r.y() },
337 { C::ecc_result_infinity, 0 },
340 { C::ecc_x_match, 0 },
341 { C::ecc_y_match, 0 },
345 check_relation<ecc>(trace);
348TEST(EccAddConstrainingTest, EccDoublingInf)
355 auto trace = TestTraceContainer({ {
356 { C::ecc_add_op, 0 },
357 { C::ecc_double_op, 1 },
366 { C::ecc_p_is_inf,
static_cast<int>(p.is_infinity()) },
367 { C::ecc_p_x, p.x() },
368 { C::ecc_p_y, p.y() },
371 { C::ecc_q_is_inf,
static_cast<int>(p.is_infinity()) },
372 { C::ecc_q_x, p.x() },
373 { C::ecc_q_y, p.y() },
376 { C::ecc_r_is_inf,
static_cast<int>(r.is_infinity()) },
377 { C::ecc_r_x, r.x() },
378 { C::ecc_r_y, r.y() },
380 { C::ecc_result_infinity, 1 },
383 { C::ecc_x_match, 1 },
384 { C::ecc_y_match, 1 },
388 check_relation<ecc>(trace);
391TEST(EccAddConstrainingTest, EccTwoOps)
396 auto trace = TestTraceContainer({ {
397 { C::ecc_add_op, 1 },
398 { C::ecc_double_op, 0 },
401 { C::ecc_inv_x_diff, (q.x() - p.x()).invert() },
402 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
404 { C::ecc_lambda, (q.y() - p.y()) / (q.x() - p.x()) },
407 { C::ecc_p_is_inf,
static_cast<int>(p.is_infinity()) },
408 { C::ecc_p_x, p.x() },
409 { C::ecc_p_y, p.y() },
412 { C::ecc_q_is_inf,
static_cast<int>(q.is_infinity()) },
413 { C::ecc_q_x, q.x() },
414 { C::ecc_q_y, q.y() },
417 { C::ecc_r_is_inf,
static_cast<int>(r1.is_infinity()) },
418 { C::ecc_r_x, r1.x() },
419 { C::ecc_r_y, r1.y() },
421 { C::ecc_result_infinity, 0 },
424 { C::ecc_use_computed_result, 1 },
425 { C::ecc_x_match, 0 },
426 { C::ecc_y_match, 0 },
430 { C::ecc_add_op, 0 },
431 { C::ecc_double_op, 1 },
433 { C::ecc_inv_2_p_y, (r1.y() * 2).invert() },
437 { C::ecc_lambda, (r1.x() * r1.x() * 3) / (r1.y() * 2) },
440 { C::ecc_p_is_inf,
static_cast<int>(r1.is_infinity()) },
441 { C::ecc_p_x, r1.x() },
442 { C::ecc_p_y, r1.y() },
445 { C::ecc_q_is_inf,
static_cast<int>(r1.is_infinity()) },
446 { C::ecc_q_x, r1.x() },
447 { C::ecc_q_y, r1.y() },
450 { C::ecc_r_is_inf,
static_cast<int>(r2.is_infinity()) },
451 { C::ecc_r_x, r2.x() },
452 { C::ecc_r_y, r2.y() },
454 { C::ecc_result_infinity, 0 },
457 { C::ecc_use_computed_result, 1 },
458 { C::ecc_x_match, 1 },
459 { C::ecc_y_match, 1 },
463 check_relation<ecc>(trace);
466TEST(EccAddConstrainingTest, EccNegativeBadAdd)
470 FF r_x(
"0x20f096ae3de9aea007e0b94a0274b2443d6682d1901f6909f284ec967bc169be");
471 FF r_y(
"0x27948713833bb314e828f2b6f45f408da6564a3ac03b9e430a9c6634bb849ef2");
474 auto trace = TestTraceContainer({ {
475 { C::ecc_add_op, 1 },
476 { C::ecc_double_op, 0 },
479 { C::ecc_inv_x_diff, (q.x() - p.x()).invert() },
480 { C::ecc_inv_y_diff, (q.y() - p.y()).invert() },
482 { C::ecc_lambda, (q.y() - p.y()) / (q.x() - p.x()) },
485 { C::ecc_p_is_inf,
static_cast<int>(p.is_infinity()) },
486 { C::ecc_p_x, p.x() },
487 { C::ecc_p_y, p.y() },
490 { C::ecc_q_is_inf,
static_cast<int>(q.is_infinity()) },
491 { C::ecc_q_x, q.x() },
492 { C::ecc_q_y, q.y() },
495 { C::ecc_r_is_inf,
static_cast<int>(r.is_infinity()) },
496 { C::ecc_r_x, r.x() },
497 { C::ecc_r_y, r.y() },
499 { C::ecc_result_infinity, 0 },
502 { C::ecc_x_match, 0 },
503 { C::ecc_y_match, 0 },
510TEST(EccAddConstrainingTest, EccNegativeBadDouble)
514 FF r_x(
"0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6");
515 FF r_y(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
518 auto trace = TestTraceContainer({ {
519 { C::ecc_add_op, 0 },
520 { C::ecc_double_op, 1 },
522 { C::ecc_inv_2_p_y, (p.y() * 2).invert() },
526 { C::ecc_lambda, (p.x() * p.x() * 3) / (p.y() * 2) },
529 { C::ecc_p_is_inf,
static_cast<int>(p.is_infinity()) },
530 { C::ecc_p_x, p.x() },
531 { C::ecc_p_y, p.y() },
534 { C::ecc_q_is_inf,
static_cast<int>(p.is_infinity()) },
535 { C::ecc_q_x, p.x() },
536 { C::ecc_q_y, p.y() },
539 { C::ecc_r_is_inf,
static_cast<int>(r.is_infinity()) },
540 { C::ecc_r_x, r.x() },
541 { C::ecc_r_y, r.y() },
543 { C::ecc_result_infinity, 0 },
546 { C::ecc_x_match, 1 },
547 { C::ecc_y_match, 1 },
554TEST(ScalarMulConstrainingTest, ScalarMulEmptyRow)
559TEST(ScalarMulConstrainingTest, MulByOne)
563 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
564 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
565 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
568 StrictMock<MockGreaterThan>
gt;
569 PureToRadix to_radix_simulator = PureToRadix();
573 ecc_add_event_emitter,
574 scalar_mul_event_emitter,
575 ecc_add_memory_event_emitter);
578 ecc_simulator.scalar_mul(p, scalar);
580 TestTraceContainer
trace({
581 { { C::precomputed_first_row, 1 } },
584 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
586 check_relation<scalar_mul>(trace);
589TEST(ScalarMulConstrainingTest, BasicMul)
593 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
594 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
595 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
598 StrictMock<MockGreaterThan>
gt;
599 PureToRadix to_radix_simulator = PureToRadix();
603 ecc_add_event_emitter,
604 scalar_mul_event_emitter,
605 ecc_add_memory_event_emitter);
607 FF scalar =
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
608 ecc_simulator.scalar_mul(p, scalar);
610 TestTraceContainer
trace({
611 { { C::precomputed_first_row, 1 } },
614 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
616 check_relation<scalar_mul>(trace);
620TEST(ScalarMulConstrainingTest, MulByZero)
624 EventEmitter<EccAddEvent> ecc_add_event_emitter;
625 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
626 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
629 StrictMock<MockGreaterThan>
gt;
630 PureToRadix to_radix_simulator = PureToRadix();
634 ecc_add_event_emitter,
635 scalar_mul_event_emitter,
636 ecc_add_memory_event_emitter);
643 ASSERT_TRUE(result.is_infinity());
645 TestTraceContainer
trace({
646 { { C::precomputed_first_row, 1 } },
649 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
650 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
653 check_relation<scalar_mul>(trace);
654 check_relation<ecc>(trace);
658TEST(ScalarMulConstrainingTest, MulByLargeScalar)
662 EventEmitter<EccAddEvent> ecc_add_event_emitter;
663 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
664 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
667 StrictMock<MockGreaterThan>
gt;
668 PureToRadix to_radix_simulator = PureToRadix();
672 ecc_add_event_emitter,
673 scalar_mul_event_emitter,
674 ecc_add_memory_event_emitter);
678 FF scalar =
FF(
"0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593efffffff");
686 TestTraceContainer
trace({
687 { { C::precomputed_first_row, 1 } },
690 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
691 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
694 check_relation<scalar_mul>(trace);
695 check_relation<ecc>(trace);
698TEST(ScalarMulConstrainingTest, MultipleInvocations)
702 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
703 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
704 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
707 StrictMock<MockGreaterThan>
gt;
708 PureToRadix to_radix_simulator = PureToRadix();
712 ecc_add_event_emitter,
713 scalar_mul_event_emitter,
714 ecc_add_memory_event_emitter);
716 ecc_simulator.scalar_mul(p,
FF(
"0x2b01df0ef6d941a826bea23bece8243cbcdc159d5e97fbaa2171f028e05ba9b6"));
717 ecc_simulator.scalar_mul(q,
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09"));
719 TestTraceContainer
trace({
720 { { C::precomputed_first_row, 1 } },
723 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
725 check_relation<scalar_mul>(trace);
728TEST(ScalarMulConstrainingTest, MulInteractions)
732 EventEmitter<EccAddEvent> ecc_add_event_emitter;
733 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
734 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
735 EventEmitter<ToRadixEvent> to_radix_event_emitter;
736 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
739 StrictMock<MockGreaterThan>
gt;
740 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
744 ecc_add_event_emitter,
745 scalar_mul_event_emitter,
746 ecc_add_memory_event_emitter);
748 FF scalar =
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
749 ecc_simulator.scalar_mul(p, scalar);
751 TestTraceContainer
trace({
752 { { C::precomputed_first_row, 1 } },
755 ToRadixTraceBuilder to_radix_builder;
756 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
757 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
758 to_radix_builder.
process(to_radix_event_emitter.dump_events(), trace);
766TEST(ScalarMulConstrainingTest, MulAddInteractionsInfinity)
770 EventEmitter<EccAddEvent> ecc_add_event_emitter;
771 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
772 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
775 StrictMock<MockGreaterThan>
gt;
776 PureToRadix to_radix_simulator = PureToRadix();
780 ecc_add_event_emitter,
781 scalar_mul_event_emitter,
782 ecc_add_memory_event_emitter);
785 ASSERT_TRUE(result.is_infinity());
787 TestTraceContainer
trace({
788 { { C::precomputed_first_row, 1 } },
791 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
792 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
794 check_interaction<EccTraceBuilder, lookup_scalar_mul_double_settings, lookup_scalar_mul_add_settings>(trace);
796 check_relation<scalar_mul>(trace);
797 check_relation<ecc>(trace);
800TEST(ScalarMulConstrainingTest, MulAddInteractionsInfinityRep)
804 EventEmitter<EccAddEvent> ecc_add_event_emitter;
805 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
806 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
809 StrictMock<MockGreaterThan>
gt;
810 PureToRadix to_radix_simulator = PureToRadix();
814 ecc_add_event_emitter,
815 scalar_mul_event_emitter,
816 ecc_add_memory_event_emitter);
824 ASSERT_TRUE(result.is_infinity());
825 result = ecc_simulator.scalar_mul(inf_alt,
FF(10));
826 ASSERT_TRUE(result.is_infinity());
828 TestTraceContainer
trace({
829 { { C::precomputed_first_row, 1 } },
832 auto scalar_mul_events = scalar_mul_event_emitter.dump_events();
834 for (
auto&
event : scalar_mul_events) {
835 EXPECT_EQ(
event.point.x(), inf.x());
836 EXPECT_EQ(
event.point.y(), inf.y());
839 builder.process_scalar_mul(scalar_mul_events, trace);
840 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
842 check_interaction<EccTraceBuilder, lookup_scalar_mul_double_settings, lookup_scalar_mul_add_settings>(trace);
844 check_relation<scalar_mul>(trace);
845 check_relation<ecc>(trace);
848TEST(ScalarMulConstrainingTest, NegativeMulAddInteractions)
852 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
853 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
854 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
857 StrictMock<MockGreaterThan>
gt;
858 PureToRadix to_radix_simulator = PureToRadix();
862 ecc_add_event_emitter,
863 scalar_mul_event_emitter,
864 ecc_add_memory_event_emitter);
866 FF scalar =
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
867 ecc_simulator.scalar_mul(p, scalar);
869 TestTraceContainer
trace({
870 { { C::precomputed_first_row, 1 } },
873 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
876 "Failed.*SCALAR_MUL_DOUBLE. Could not find tuple in destination.");
878 "Failed.*SCALAR_MUL_ADD. Could not find tuple in destination.");
881TEST(ScalarMulConstrainingTest, NegativeMulRadixInteractions)
885 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
886 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
887 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
890 StrictMock<MockGreaterThan>
gt;
891 PureToRadix to_radix_simulator = PureToRadix();
895 ecc_add_event_emitter,
896 scalar_mul_event_emitter,
897 ecc_add_memory_event_emitter);
899 FF scalar =
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
900 ecc_simulator.scalar_mul(p, scalar);
902 TestTraceContainer
trace({
903 { { C::precomputed_first_row, 1 } },
906 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
909 "Failed.*SCALAR_MUL_TO_RADIX. Could not find tuple in destination.");
911 check_relation<scalar_mul>(trace);
914TEST(ScalarMulConstrainingTest, NegativeDisableSel)
918 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
919 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
920 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
923 StrictMock<MockGreaterThan>
gt;
924 PureToRadix to_radix_simulator = PureToRadix();
928 ecc_add_event_emitter,
929 scalar_mul_event_emitter,
930 ecc_add_memory_event_emitter);
932 FF scalar =
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
933 ecc_simulator.scalar_mul(p, scalar);
935 TestTraceContainer
trace({
936 { { C::precomputed_first_row, 1 } },
939 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
941 trace.
set(Column::scalar_mul_sel, 5, 0);
943 "SELECTOR_CONSISTENCY");
946TEST(ScalarMulConstrainingTest, NegativeEnableStartFirstRow)
950 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
951 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
952 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
955 StrictMock<MockGreaterThan>
gt;
956 PureToRadix to_radix_simulator = PureToRadix();
960 ecc_add_event_emitter,
961 scalar_mul_event_emitter,
962 ecc_add_memory_event_emitter);
964 FF scalar =
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
965 ecc_simulator.scalar_mul(p, scalar);
967 TestTraceContainer
trace({
968 { { C::precomputed_first_row, 1 } },
971 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
973 trace.
set(Column::scalar_mul_start, 0, 1);
977TEST(ScalarMulConstrainingTest, NegativeMutateScalarOnEnd)
981 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
982 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
983 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
986 StrictMock<MockGreaterThan>
gt;
987 PureToRadix to_radix_simulator = PureToRadix();
991 ecc_add_event_emitter,
992 scalar_mul_event_emitter,
993 ecc_add_memory_event_emitter);
995 FF scalar =
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
996 ecc_simulator.scalar_mul(p, scalar);
998 TestTraceContainer
trace({
999 { { C::precomputed_first_row, 1 } },
1002 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
1004 trace.
set(Column::scalar_mul_scalar, 254, 27);
1006 "INPUT_CONSISTENCY_SCALAR");
1009TEST(ScalarMulConstrainingTest, NegativeMutatePointXOnEnd)
1013 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
1014 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
1015 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
1018 StrictMock<MockGreaterThan>
gt;
1019 PureToRadix to_radix_simulator = PureToRadix();
1023 ecc_add_event_emitter,
1024 scalar_mul_event_emitter,
1025 ecc_add_memory_event_emitter);
1027 FF scalar =
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
1028 ecc_simulator.scalar_mul(p, scalar);
1030 TestTraceContainer
trace({
1031 { { C::precomputed_first_row, 1 } },
1034 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
1036 trace.
set(Column::scalar_mul_point_x, 254, q.x());
1039 "INPUT_CONSISTENCY_X");
1042TEST(ScalarMulConstrainingTest, NegativeMutatePointYOnEnd)
1046 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
1047 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
1048 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
1051 StrictMock<MockGreaterThan>
gt;
1052 PureToRadix to_radix_simulator = PureToRadix();
1056 ecc_add_event_emitter,
1057 scalar_mul_event_emitter,
1058 ecc_add_memory_event_emitter);
1060 FF scalar =
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
1061 ecc_simulator.scalar_mul(p, scalar);
1063 TestTraceContainer
trace({
1064 { { C::precomputed_first_row, 1 } },
1067 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
1069 trace.
set(Column::scalar_mul_point_y, 254, q.y());
1072 "INPUT_CONSISTENCY_Y");
1075TEST(ScalarMulConstrainingTest, NegativeMutatePointInfOnEnd)
1079 NoopEventEmitter<EccAddEvent> ecc_add_event_emitter;
1080 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
1081 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
1084 StrictMock<MockGreaterThan>
gt;
1085 PureToRadix to_radix_simulator = PureToRadix();
1089 ecc_add_event_emitter,
1090 scalar_mul_event_emitter,
1091 ecc_add_memory_event_emitter);
1093 FF scalar =
FF(
"0x0cc4c71e882bc62b7b3d1964a8540cb5211339dfcddd2e095fd444bf1aed4f09");
1094 ecc_simulator.scalar_mul(p, scalar);
1096 TestTraceContainer
trace({
1097 { { C::precomputed_first_row, 1 } },
1100 builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
1102 trace.
set(Column::scalar_mul_point_inf, 254, 1);
1105 "INPUT_CONSISTENCY_INF");
1112TEST(EccAddMemoryConstrainingTest, EccAddMemoryEmptyRow)
1117TEST(EccAddMemoryConstrainingTest, EccAddMemory)
1119 TestTraceContainer
trace;
1123 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
1124 EventEmitter<EccAddEvent> ecc_add_event_emitter;
1125 NoopEventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
1126 NoopEventEmitter<ToRadixEvent> to_radix_event_emitter;
1130 .WillRepeatedly(Return(0));
1132 PureToRadix to_radix_simulator = PureToRadix();
1136 ecc_add_event_emitter,
1137 scalar_mul_event_emitter,
1138 ecc_add_memory_event_emitter);
1142 builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(), trace);
1143 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
1145 check_relation<mem_aware_ecc>(trace);
1148TEST(EccAddMemoryConstrainingTest, EccAddMemoryInteractions)
1156 .WillRepeatedly(Return(0));
1158 PureToRadix to_radix_simulator = PureToRadix();
1160 EventEmitter<EccAddEvent> ecc_add_event_emitter;
1161 NoopEventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
1162 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
1163 NoopEventEmitter<ToRadixEvent> to_radix_event_emitter;
1167 ecc_add_event_emitter,
1168 scalar_mul_event_emitter,
1169 ecc_add_memory_event_emitter);
1175 TestTraceContainer
trace = TestTraceContainer({
1179 { C::execution_sel, 1 },
1180 { C::execution_sel_exec_dispatch_ecc_add, 1 },
1182 { C::execution_register_0_, p.x() },
1183 { C::execution_register_1_, p.y() },
1184 { C::execution_register_2_, p.is_infinity() ? 1 : 0 },
1185 { C::execution_register_3_, q.x() },
1186 { C::execution_register_4_, q.y() },
1187 { C::execution_register_5_, q.is_infinity() ? 1 : 0 },
1195 { C::memory_value, result.x() },
1196 { C::memory_sel, 1 },
1197 { C::memory_rw, 1 },
1203 { C::memory_value, result.y() },
1204 { C::memory_sel, 1 },
1205 { C::memory_rw, 1 },
1211 { C::memory_value, result.is_infinity() },
1212 { C::memory_sel, 1 },
1213 { C::memory_rw, 1 },
1220 builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(),
trace);
1221 builder.process_add(ecc_add_event_emitter.dump_events(),
trace);
1223 check_all_interactions<EccTraceBuilder>(trace);
1224 check_relation<mem_aware_ecc>(trace);
1227TEST(EccAddMemoryConstrainingTest, EccAddMemoryInvalidDstRange)
1233 NoopEventEmitter<ToRadixEvent> to_radix_event_emitter;
1234 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
1235 EventEmitter<EccAddEvent> ecc_add_event_emitter;
1236 NoopEventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
1240 .WillRepeatedly(Return(0));
1242 PureToRadix to_radix_simulator = PureToRadix();
1247 ecc_add_event_emitter,
1248 scalar_mul_event_emitter,
1249 ecc_add_memory_event_emitter);
1253 TestTraceContainer
trace = TestTraceContainer({
1257 { C::execution_sel, 1 },
1258 { C::execution_sel_exec_dispatch_ecc_add, 1 },
1260 { C::execution_register_0_, p.x() },
1261 { C::execution_register_1_, p.y() },
1262 { C::execution_register_2_, p.is_infinity() ? 1 : 0 },
1263 { C::execution_register_3_, q.x() },
1264 { C::execution_register_4_, q.y() },
1265 { C::execution_register_5_, q.is_infinity() ? 1 : 0 },
1266 { C::execution_sel_opcode_error, 1 },
1269 { C::gt_input_a,
static_cast<uint64_t
>(
dst_address) + 2 },
1277 builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(), trace);
1278 EXPECT_EQ(ecc_add_event_emitter.get_events().size(), 0);
1280 check_all_interactions<EccTraceBuilder>(trace);
1281 check_relation<mem_aware_ecc>(trace);
1284TEST(EccAddMemoryConstrainingTest, EccAddMemoryPointError)
1289 EventEmitter<EccAddEvent> ecc_add_event_emitter;
1290 NoopEventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
1291 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
1295 .WillRepeatedly(Return(0));
1297 PureToRadix to_radix_simulator = PureToRadix();
1302 ecc_add_event_emitter,
1303 scalar_mul_event_emitter,
1304 ecc_add_memory_event_emitter);
1307 FF p_x(
"0x0000000000063d46918a156cae92db1bcbc4072a27ec81dc82ea959abdbcf16a");
1308 FF p_y(
"0x00000000000c1370462c74775765d07fc21fd1093cc988149d3aa763bb3dbb60");
1315 TestTraceContainer
trace = TestTraceContainer({
1319 { C::execution_sel, 1 },
1320 { C::execution_sel_exec_dispatch_ecc_add, 1 },
1322 { C::execution_register_0_, p.x() },
1323 { C::execution_register_1_, p.y() },
1324 { C::execution_register_2_, p.is_infinity() ? 1 : 0 },
1325 { C::execution_register_3_, q.x() },
1326 { C::execution_register_4_, q.y() },
1327 { C::execution_register_5_, q.is_infinity() ? 1 : 0 },
1328 { C::execution_sel_opcode_error, 1 },
1337 EXPECT_THROW(ecc_simulator.add(memory, p, q,
dst_address), simulation::EccException);
1339 builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(), trace);
1341 EXPECT_EQ(ecc_add_event_emitter.get_events().size(), 0);
1343 check_all_interactions<EccTraceBuilder>(trace);
1344 check_relation<mem_aware_ecc>(trace);
1347TEST(EccAddMemoryConstrainingTest, InfinityRepresentations)
1352 EventEmitter<EccAddEvent> ecc_add_event_emitter;
1353 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
1354 EventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
1358 .WillRepeatedly(Return(0));
1360 PureToRadix to_radix_simulator = PureToRadix();
1364 ecc_add_event_emitter,
1365 scalar_mul_event_emitter,
1366 ecc_add_memory_event_emitter);
1374 TestTraceContainer
trace;
1381 ecc_simulator.add(memory, inf, inf_alt,
dst_address);
1383 ecc_simulator.add(memory, inf, inf_bb,
dst_address + 3);
1385 builder.process_add(ecc_add_event_emitter.dump_events(), trace);
1386 check_relation<ecc>(trace);
1387 EXPECT_EQ(
trace.
get(C::ecc_double_op, 0), 1);
1392 { C::execution_sel, 1 },
1393 { C::execution_sel_exec_dispatch_ecc_add, 1 },
1395 { C::execution_register_0_, inf.x() },
1396 { C::execution_register_1_, inf.y() },
1397 { C::execution_register_2_, inf.is_infinity() ? 1 : 0 },
1398 { C::execution_register_3_, inf_alt.x() },
1399 { C::execution_register_4_, inf_alt.y() },
1400 { C::execution_register_5_, inf_alt.is_infinity() ? 1 : 0 },
1405 { C::gt_res, 0 } } });
1408 { C::execution_sel, 1 },
1409 { C::execution_sel_exec_dispatch_ecc_add, 1 },
1411 { C::execution_register_0_, inf.x() },
1412 { C::execution_register_1_, inf.y() },
1413 { C::execution_register_2_, inf.is_infinity() ? 1 : 0 },
1414 { C::execution_register_3_, inf_bb.x() },
1415 { C::execution_register_4_, inf_bb.y() },
1416 { C::execution_register_5_, inf_bb.is_infinity() ? 1 : 0 },
1421 { C::gt_res, 0 } } });
1423 builder.process_add_with_memory(ecc_add_memory_event_emitter.dump_events(),
trace);
1426 EXPECT_EQ(
trace.
get(C::ecc_add_mem_q_x, 1), inf_bb.x());
1427 EXPECT_EQ(
trace.
get(C::ecc_add_mem_q_y, 1), inf_bb.y());
1429 EXPECT_EQ(
trace.
get(C::ecc_add_mem_q_x_n, 1), 0);
1430 EXPECT_EQ(
trace.
get(C::ecc_add_mem_q_y_n, 1), 0);
1431 check_relation<mem_aware_ecc>(trace);
1432 check_relation<ecc>(trace);
1433 check_all_interactions<EccTraceBuilder>(trace);
1434 check_interaction<tracegen::ExecutionTraceBuilder, bb::avm2::perm_execution_dispatch_to_ecc_add_settings>(trace);
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
#define AVM_HIGHEST_MEM_ADDRESS
static const StandardAffinePoint & infinity()
static constexpr size_t SR_OUTPUT_X_COORD
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)
Process the ALU events and populate the ALU relevant columns in the trace.
const FF & get(Column col, uint32_t row) const
uint32_t get_num_rows() const
void set(Column col, uint32_t row, const FF &value)
static constexpr affine_element infinity()
ExecutionIdManager execution_id_manager
void check_interaction(tracegen::TestTraceContainer &trace)
TEST(AvmFixedVKTests, FixedVKCommitments)
Test that the fixed VK commitments agree with the ones computed from precomputed columns.
TestTraceContainer empty_trace()
lookup_settings< lookup_scalar_mul_double_settings_ > lookup_scalar_mul_double_settings
StandardAffinePoint< AvmFlavorSettings::EmbeddedCurve::AffineElement > EmbeddedCurvePoint
AvmFlavorSettings::G1::Fq Fq
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
simulation::PublicDataTreeReadWriteEvent event
static constexpr field zero()