1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
27using ::testing::Return;
28using ::testing::StrictMock;
30using tracegen::GreaterThanTraceBuilder;
31using tracegen::PrecomputedTraceBuilder;
32using tracegen::TestTraceContainer;
33using tracegen::ToRadixTraceBuilder;
39using ToRadixSimulator = simulation::ToRadix;
41using simulation::EventEmitter;
42using simulation::FakeGreaterThan;
43using simulation::GreaterThan;
44using simulation::GreaterThanEvent;
45using simulation::MockExecutionIdManager;
46using simulation::MockFieldGreaterThan;
47using simulation::NoopEventEmitter;
48using simulation::RangeCheck;
49using simulation::RangeCheckEvent;
50using simulation::ToRadixEvent;
51using simulation::ToRadixMemoryEvent;
53TEST(ToRadixConstrainingTest, EmptyRow)
58TEST(ToRadixConstrainingTest, ToLeBitsBasicTest)
60 EventEmitter<ToRadixEvent> to_radix_event_emitter;
61 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
65 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
67 auto bits = to_radix_simulator.to_le_bits(FF::one(), 254);
69 EXPECT_EQ(bits.size(), 254);
72 { .precomputed_first_row = 1 },
76 builder.process(to_radix_event_emitter.dump_events(),
trace);
78 check_relation<to_radix>(
trace);
81TEST(ToRadixConstrainingTest, ToLeBitsPMinusOne)
83 EventEmitter<ToRadixEvent> to_radix_event_emitter;
84 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
88 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
90 auto bits = to_radix_simulator.to_le_bits(FF::neg_one(), 254);
92 EXPECT_EQ(bits.size(), 254);
95 { .precomputed_first_row = 1 },
99 builder.process(to_radix_event_emitter.dump_events(),
trace);
101 check_relation<to_radix>(
trace);
104TEST(ToRadixConstrainingTest, ToLeBitsShortest)
106 EventEmitter<ToRadixEvent> to_radix_event_emitter;
107 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
111 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
113 auto bits = to_radix_simulator.to_le_bits(FF::one(), 1);
115 EXPECT_EQ(bits.size(), 1);
118 { .precomputed_first_row = 1 },
122 builder.process(to_radix_event_emitter.dump_events(),
trace);
124 check_relation<to_radix>(
trace);
127TEST(ToRadixConstrainingTest, ToLeBitsPadded)
129 EventEmitter<ToRadixEvent> to_radix_event_emitter;
130 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
134 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
136 auto bits = to_radix_simulator.to_le_bits(FF::one(), 500);
138 EXPECT_EQ(bits.size(), 500);
141 { .precomputed_first_row = 1 },
145 builder.process(to_radix_event_emitter.dump_events(),
trace);
147 check_relation<to_radix>(
trace);
150TEST(ToRadixConstrainingTest, ToLeRadixBasic)
152 EventEmitter<ToRadixEvent> to_radix_event_emitter;
153 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
157 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
160 auto bytes = to_radix_simulator.to_le_radix(
value, 32, 256);
162 auto expected_bytes =
value.to_buffer();
164 std::reverse(expected_bytes.begin(), expected_bytes.end());
165 EXPECT_EQ(bytes, expected_bytes);
168 { .precomputed_first_row = 1 },
172 builder.process(to_radix_event_emitter.dump_events(),
trace);
174 check_relation<to_radix>(
trace);
177TEST(ToRadixConstrainingTest, ToLeRadixPMinusOne)
179 EventEmitter<ToRadixEvent> to_radix_event_emitter;
180 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
184 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
187 auto bytes = to_radix_simulator.to_le_radix(
value, 32, 256);
189 auto expected_bytes =
value.to_buffer();
191 std::reverse(expected_bytes.begin(), expected_bytes.end());
192 EXPECT_EQ(bytes, expected_bytes);
195 { .precomputed_first_row = 1 },
199 builder.process(to_radix_event_emitter.dump_events(),
trace);
201 check_relation<to_radix>(
trace);
204TEST(ToRadixConstrainingTest, ToLeRadixOneByte)
206 EventEmitter<ToRadixEvent> to_radix_event_emitter;
207 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
211 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
213 auto bytes = to_radix_simulator.to_le_radix(FF::one(), 1, 256);
215 std::vector<uint8_t> expected_bytes = { 1 };
216 EXPECT_EQ(bytes, expected_bytes);
219 { .precomputed_first_row = 1 },
223 builder.process(to_radix_event_emitter.dump_events(),
trace);
225 check_relation<to_radix>(
trace);
228TEST(ToRadixConstrainingTest, ToLeRadixPadded)
230 EventEmitter<ToRadixEvent> to_radix_event_emitter;
231 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
235 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
238 auto bytes = to_radix_simulator.to_le_radix(
value, 64, 256);
240 auto expected_bytes =
value.to_buffer();
242 std::reverse(expected_bytes.begin(), expected_bytes.end());
243 expected_bytes.resize(64);
244 EXPECT_EQ(bytes, expected_bytes);
247 { .precomputed_first_row = 1 },
251 builder.process(to_radix_event_emitter.dump_events(),
trace);
253 check_relation<to_radix>(
trace);
256TEST(ToRadixConstrainingTest, ToLeBitsInteractions)
258 EventEmitter<ToRadixEvent> to_radix_event_emitter;
259 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
263 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
265 to_radix_simulator.to_le_bits(FF::neg_one(), 254);
268 { .precomputed_first_row = 1 },
271 ToRadixTraceBuilder to_radix_builder;
272 to_radix_builder.process(to_radix_event_emitter.dump_events(),
trace);
286 check_relation<to_radix>(
trace);
289TEST(ToRadixConstrainingTest, ToLeRadixInteractions)
291 EventEmitter<ToRadixEvent> to_radix_event_emitter;
292 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
296 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
298 to_radix_simulator.to_le_radix(FF::neg_one(), 32, 256);
301 { .precomputed_first_row = 1 },
304 ToRadixTraceBuilder to_radix_builder;
305 to_radix_builder.process(to_radix_event_emitter.dump_events(),
trace);
320 check_relation<to_radix>(
trace);
323TEST(ToRadixConstrainingTest, NegativeOverflowCheck)
326 { .precomputed_first_row = 1 },
329 std::vector<uint8_t> modulus_le_bits(256, 0);
330 for (
size_t i = 0; i < 256; i++) {
331 modulus_le_bits[i] =
static_cast<uint8_t
>(FF::modulus.get_bit(i));
334 ToRadixEvent
event = { .value = FF::zero(), .radix = 2, .limbs = modulus_le_bits };
343TEST(ToRadixConstrainingTest, NegativeConsistency)
345 EventEmitter<ToRadixEvent> to_radix_event_emitter;
346 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
350 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
352 to_radix_simulator.to_le_radix(
FF(256), 32, 256);
355 { .precomputed_first_row = 1 },
359 builder.process(to_radix_event_emitter.dump_events(),
trace);
362 trace.
set(Column::to_radix_sel, 6, 0);
365 "SELECTOR_CONSISTENCY");
368 trace.
set(Column::to_radix_radix, 5, 200);
371 "CONSTANT_CONSISTENCY_RADIX");
374 trace.
set(Column::to_radix_value, 4, 27);
377 "CONSTANT_CONSISTENCY_VALUE");
380 trace.
set(Column::to_radix_safe_limbs, 3, 200);
383 "CONSTANT_CONSISTENCY_SAFE_LIMBS");
390TEST(ToRadixMemoryConstrainingTest, EmptyRow)
395TEST(ToRadixMemoryConstrainingTest, BasicTest)
400 uint32_t num_limbs = 4;
403 TestTraceContainer
trace = TestTraceContainer({
406 { C::precomputed_first_row, 1 },
409 { C::gt_input_a,
dst_addr + num_limbs - 1 },
413 { C::execution_sel, 1 },
414 { C::execution_sel_execute_to_radix, 1 },
415 { C::execution_register_0_,
value },
416 { C::execution_register_1_, radix },
417 { C::execution_register_2_, num_limbs },
418 { C::execution_register_3_, 0 },
425 { C::to_radix_mem_sel, 1 },
427 { C::to_radix_mem_two, 2 },
428 { C::to_radix_mem_two_five_six, 256 },
430 { C::to_radix_mem_execution_clk, 0 },
431 { C::to_radix_mem_space_id, 0 },
432 { C::to_radix_mem_dst_addr,
dst_addr },
433 { C::to_radix_mem_max_write_addr,
dst_addr + num_limbs - 1 },
435 { C::to_radix_mem_value_to_decompose,
value },
436 { C::to_radix_mem_radix, radix },
437 { C::to_radix_mem_num_limbs, num_limbs },
438 { C::to_radix_mem_is_output_bits, 0 },
440 { C::to_radix_mem_start, 1 },
441 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).invert() },
443 { C::to_radix_mem_sel_num_limbs_is_zero, 0 },
444 { C::to_radix_mem_num_limbs_inv,
FF(num_limbs).invert() },
445 { C::to_radix_mem_sel_value_is_zero, 0 },
446 { C::to_radix_mem_value_inv,
value.invert() },
448 { C::to_radix_mem_output_limb_value, 1 },
449 { C::to_radix_mem_sel_should_exec, 1 },
450 { C::to_radix_mem_limb_index_to_lookup, num_limbs - 1 },
451 { C::to_radix_mem_output_tag,
static_cast<uint8_t
>(
MemoryTag::U8) },
455 { C::gt_input_a, 2 },
456 { C::gt_input_b, radix },
461 { C::to_radix_mem_sel, 1 },
463 { C::to_radix_mem_execution_clk, 0 },
464 { C::to_radix_mem_space_id, 0 },
465 { C::to_radix_mem_dst_addr,
dst_addr + 1 },
467 { C::to_radix_mem_value_to_decompose,
value },
468 { C::to_radix_mem_radix, radix },
469 { C::to_radix_mem_num_limbs, num_limbs - 1 },
470 { C::to_radix_mem_is_output_bits, 0 },
473 { C::to_radix_mem_num_limbs_minus_one_inv,
FF(num_limbs - 2).invert() },
475 { C::to_radix_mem_output_limb_value, 3 },
476 { C::to_radix_mem_sel_should_exec, 1 },
477 { C::to_radix_mem_limb_index_to_lookup, num_limbs - 2 },
478 { C::to_radix_mem_output_tag,
static_cast<uint8_t
>(
MemoryTag::U8) },
481 { C::gt_input_a, radix },
482 { C::gt_input_b, 256 },
487 { C::to_radix_mem_sel, 1 },
489 { C::to_radix_mem_execution_clk, 0 },
490 { C::to_radix_mem_space_id, 0 },
491 { C::to_radix_mem_dst_addr,
dst_addr + 2 },
493 { C::to_radix_mem_value_to_decompose,
value },
494 { C::to_radix_mem_radix, radix },
495 { C::to_radix_mem_num_limbs, num_limbs - 2 },
496 { C::to_radix_mem_is_output_bits, 0 },
499 { C::to_radix_mem_num_limbs_minus_one_inv,
FF(num_limbs - 3).invert() },
501 { C::to_radix_mem_output_limb_value, 3 },
502 { C::to_radix_mem_sel_should_exec, 1 },
503 { C::to_radix_mem_limb_index_to_lookup, num_limbs - 3 },
504 { C::to_radix_mem_output_tag,
static_cast<uint8_t
>(
MemoryTag::U8) },
508 { C::to_radix_mem_sel, 1 },
510 { C::to_radix_mem_execution_clk, 0 },
511 { C::to_radix_mem_space_id, 0 },
512 { C::to_radix_mem_dst_addr, 13 },
514 { C::to_radix_mem_value_to_decompose,
value },
515 { C::to_radix_mem_radix, radix },
516 { C::to_radix_mem_num_limbs, num_limbs - 3 },
517 { C::to_radix_mem_is_output_bits, 0 },
519 { C::to_radix_mem_last, 1 },
521 { C::to_radix_mem_output_limb_value, 7 },
522 { C::to_radix_mem_sel_should_exec, 1 },
523 { C::to_radix_mem_limb_index_to_lookup, num_limbs - 4 },
524 { C::to_radix_mem_output_tag,
static_cast<uint8_t
>(
MemoryTag::U8) },
535 { value_addr, MemoryValue::from<FF>(
value) },
536 { radix_addr, MemoryValue::from<uint32_t>(radix) },
537 { num_limbs_addr, MemoryValue::from<uint32_t>(num_limbs) },
538 { is_output_bits_addr, MemoryValue::from<uint1_t>(
false) },
539 {
dst_addr, MemoryValue::from<uint8_t>(1) },
540 {
dst_addr + 1, MemoryValue::from<uint8_t>(3) },
541 {
dst_addr + 2, MemoryValue::from<uint8_t>(3) },
542 {
dst_addr + 3, MemoryValue::from<uint8_t>(7) },
545 for (uint32_t i = 0; i < memory_values.size(); ++i) {
546 const auto& [addr,
value] = memory_values[i];
549 { { C::memory_sel, 1 },
550 { C::memory_space_id, 0 },
551 { C::memory_address, addr },
552 { C::memory_value,
value.as_ff() },
553 { C::memory_tag,
static_cast<uint8_t
>(
value.get_tag()) },
554 { C::memory_rw, i > 3 ? 1 : 0 } },
558 EventEmitter<ToRadixEvent> to_radix_event_emitter;
559 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
563 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
566 to_radix_simulator.to_le_radix(
value, num_limbs, radix);
569 auto events = to_radix_event_emitter.get_events();
570 builder.process(to_radix_event_emitter.dump_events(),
trace);
577 check_relation<to_radix_mem>(
trace);
578 check_all_interactions<ToRadixTraceBuilder>(
trace);
581TEST(ToRadixMemoryConstrainingTest, DstOutOfRange)
586 uint32_t num_limbs = 2;
589 TestTraceContainer
trace = TestTraceContainer({
592 { C::precomputed_first_row, 1 },
595 { C::gt_input_a,
dst_addr + num_limbs - 1 },
602 { C::execution_sel, 1 },
603 { C::execution_sel_execute_to_radix, 1 },
604 { C::execution_register_0_,
value },
605 { C::execution_register_1_, radix },
606 { C::execution_register_2_, num_limbs },
607 { C::execution_register_3_, 0 },
609 { C::execution_sel_opcode_error, 1 },
612 { C::to_radix_mem_sel, 1 },
614 { C::to_radix_mem_two, 2 },
615 { C::to_radix_mem_two_five_six, 256 },
617 { C::to_radix_mem_execution_clk, 0 },
618 { C::to_radix_mem_space_id, 0 },
619 { C::to_radix_mem_dst_addr,
dst_addr },
620 { C::to_radix_mem_max_write_addr,
dst_addr + num_limbs - 1 },
622 { C::to_radix_mem_value_to_decompose,
value },
623 { C::to_radix_mem_radix, radix },
624 { C::to_radix_mem_num_limbs, num_limbs },
625 { C::to_radix_mem_is_output_bits, 0 },
627 { C::to_radix_mem_sel_dst_out_of_range_err, 1 },
628 { C::to_radix_mem_err, 1 },
630 { C::to_radix_mem_start, 1 },
631 { C::to_radix_mem_last, 1 },
632 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).invert() },
634 { C::to_radix_mem_sel_num_limbs_is_zero, 0 },
635 { C::to_radix_mem_num_limbs_inv,
FF(num_limbs).invert() },
636 { C::to_radix_mem_sel_value_is_zero, 0 },
637 { C::to_radix_mem_value_inv,
value.invert() },
639 { C::to_radix_mem_sel_should_exec, 0 },
643 check_relation<to_radix_mem>(
trace);
649TEST(ToRadixMemoryConstrainingTest, InvalidRadix)
654 uint32_t num_limbs = 2;
657 TestTraceContainer
trace = TestTraceContainer({
660 { C::precomputed_first_row, 1 },
663 { C::gt_input_a, 2 },
664 { C::gt_input_b, radix },
669 { C::to_radix_mem_sel, 1 },
671 { C::to_radix_mem_two, 2 },
672 { C::to_radix_mem_two_five_six, 256 },
674 { C::to_radix_mem_execution_clk, 0 },
675 { C::to_radix_mem_space_id, 0 },
676 { C::to_radix_mem_dst_addr,
dst_addr },
677 { C::to_radix_mem_max_write_addr,
dst_addr + num_limbs - 1 },
679 { C::to_radix_mem_value_to_decompose,
value },
680 { C::to_radix_mem_radix, radix },
681 { C::to_radix_mem_num_limbs, num_limbs },
682 { C::to_radix_mem_is_output_bits, 0 },
684 { C::to_radix_mem_sel_radix_lt_2_err, 1 },
685 { C::to_radix_mem_err, 1 },
687 { C::to_radix_mem_start, 1 },
688 { C::to_radix_mem_last, 1 },
689 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).invert() },
691 { C::to_radix_mem_sel_num_limbs_is_zero, 0 },
692 { C::to_radix_mem_num_limbs_inv,
FF(num_limbs).invert() },
693 { C::to_radix_mem_sel_value_is_zero, 0 },
694 { C::to_radix_mem_value_inv,
value.invert() },
696 { C::to_radix_mem_sel_should_exec, 0 },
699 check_relation<to_radix_mem>(
trace);
700 check_interaction<ToRadixTraceBuilder, lookup_to_radix_mem_check_radix_lt_2_settings>(
trace);
703TEST(ToRadixMemoryConstrainingTest, InvalidBitwiseRadix)
708 uint32_t num_limbs = 2;
710 bool is_output_bits =
true;
712 TestTraceContainer
trace = TestTraceContainer({
715 { C::precomputed_first_row, 1 },
718 { C::gt_input_a, 2 },
719 { C::gt_input_b, radix },
724 { C::to_radix_mem_sel, 1 },
726 { C::to_radix_mem_two, 2 },
727 { C::to_radix_mem_two_five_six, 256 },
729 { C::to_radix_mem_execution_clk, 0 },
730 { C::to_radix_mem_space_id, 0 },
731 { C::to_radix_mem_dst_addr,
dst_addr },
732 { C::to_radix_mem_max_write_addr,
dst_addr + num_limbs - 1 },
734 { C::to_radix_mem_value_to_decompose,
value },
735 { C::to_radix_mem_radix, radix },
736 { C::to_radix_mem_num_limbs, num_limbs },
737 { C::to_radix_mem_is_output_bits, is_output_bits ? 1 : 0 },
739 { C::to_radix_mem_sel_invalid_bitwise_radix, 1 },
740 { C::to_radix_mem_err, 1 },
742 { C::to_radix_mem_start, 1 },
743 { C::to_radix_mem_last, 1 },
744 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).invert() },
746 { C::to_radix_mem_sel_num_limbs_is_zero, 0 },
747 { C::to_radix_mem_num_limbs_inv,
FF(num_limbs).invert() },
748 { C::to_radix_mem_sel_value_is_zero, 0 },
749 { C::to_radix_mem_value_inv,
value.invert() },
751 { C::to_radix_mem_sel_should_exec, 0 },
754 check_relation<to_radix_mem>(
trace);
755 check_interaction<ToRadixTraceBuilder, lookup_to_radix_mem_check_radix_lt_2_settings>(
trace);
758TEST(ToRadixMemoryConstrainingTest, InvalidNumLimbsForValue)
763 uint32_t num_limbs = 0;
765 bool is_output_bits =
false;
767 TestTraceContainer
trace = TestTraceContainer({
770 { C::precomputed_first_row, 1 },
773 { C::gt_input_a, 2 },
774 { C::gt_input_b, radix },
779 { C::to_radix_mem_sel, 1 },
781 { C::to_radix_mem_two, 2 },
782 { C::to_radix_mem_two_five_six, 256 },
784 { C::to_radix_mem_execution_clk, 0 },
785 { C::to_radix_mem_space_id, 0 },
786 { C::to_radix_mem_dst_addr,
dst_addr },
787 { C::to_radix_mem_max_write_addr,
dst_addr + num_limbs - 1 },
789 { C::to_radix_mem_value_to_decompose,
value },
790 { C::to_radix_mem_radix, radix },
791 { C::to_radix_mem_num_limbs, num_limbs },
792 { C::to_radix_mem_is_output_bits, is_output_bits ? 1 : 0 },
794 { C::to_radix_mem_sel_invalid_num_limbs_err, 1 },
795 { C::to_radix_mem_err, 1 },
797 { C::to_radix_mem_start, 1 },
798 { C::to_radix_mem_last, 1 },
799 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).invert() },
801 { C::to_radix_mem_sel_num_limbs_is_zero, 1 },
802 { C::to_radix_mem_num_limbs_inv, 0 },
803 { C::to_radix_mem_sel_value_is_zero, 0 },
804 { C::to_radix_mem_value_inv,
value.invert() },
806 { C::to_radix_mem_sel_should_exec, 0 },
809 check_relation<to_radix_mem>(
trace);
810 check_interaction<ToRadixTraceBuilder, lookup_to_radix_mem_check_radix_lt_2_settings>(
trace);
813TEST(ToRadixMemoryConstrainingTest, ZeroNumLimbsAndZeroValueIsNoop)
818 uint32_t num_limbs = 0;
820 bool is_output_bits =
false;
822 TestTraceContainer
trace = TestTraceContainer({
825 { C::precomputed_first_row, 1 },
828 { C::gt_input_a, 2 },
829 { C::gt_input_b, radix },
834 { C::to_radix_mem_sel, 1 },
836 { C::to_radix_mem_two, 2 },
837 { C::to_radix_mem_two_five_six, 256 },
839 { C::to_radix_mem_execution_clk, 0 },
840 { C::to_radix_mem_space_id, 0 },
841 { C::to_radix_mem_dst_addr,
dst_addr },
842 { C::to_radix_mem_max_write_addr,
dst_addr + num_limbs - 1 },
844 { C::to_radix_mem_value_to_decompose,
value },
845 { C::to_radix_mem_radix, radix },
846 { C::to_radix_mem_num_limbs, num_limbs },
847 { C::to_radix_mem_is_output_bits, is_output_bits ? 1 : 0 },
849 { C::to_radix_mem_start, 1 },
850 { C::to_radix_mem_last, 1 },
851 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).invert() },
853 { C::to_radix_mem_sel_num_limbs_is_zero, 1 },
854 { C::to_radix_mem_num_limbs_inv, 0 },
855 { C::to_radix_mem_sel_value_is_zero, 1 },
856 { C::to_radix_mem_value_inv, 0 },
858 { C::to_radix_mem_sel_should_exec, 0 },
861 check_relation<to_radix_mem>(
trace);
862 check_interaction<ToRadixTraceBuilder, lookup_to_radix_mem_check_radix_lt_2_settings>(
trace);
865TEST(ToRadixMemoryConstrainingTest, ComplexTest)
867 EventEmitter<ToRadixEvent> to_radix_event_emitter;
868 EventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
869 EventEmitter<RangeCheckEvent> range_check_emitter;
870 EventEmitter<GreaterThanEvent> gt_emitter;
872 simulation::MemoryStore
memory;
874 StrictMock<MockFieldGreaterThan>
field_gt;
876 GreaterThan
gt(
field_gt, range_check, gt_emitter);
878 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
882 uint32_t num_limbs = 256;
884 bool is_output_bits =
true;
886 to_radix_simulator.to_be_radix(memory,
value, radix, num_limbs, is_output_bits,
dst_addr);
887 to_radix_simulator.to_be_radix(
888 memory,
FF(1337), 10, 2,
false, 0xdeadbeef);
890 TestTraceContainer
trace;
892 builder.process(to_radix_event_emitter.dump_events(),
trace);
893 builder.process_with_memory(to_radix_mem_event_emitter.dump_events(),
trace);
903 check_relation<to_radix>(
trace);
904 check_relation<to_radix_mem>(
trace);
#define AVM_HIGHEST_MEM_ADDRESS
static constexpr size_t SR_SELECTOR_CONSISTENCY
static constexpr size_t SR_OVERFLOW_CHECK
static constexpr size_t SR_CONSTANT_CONSISTENCY_SAFE_LIMBS
static constexpr size_t SR_CONSTANT_CONSISTENCY_RADIX
static constexpr size_t SR_CONSTANT_CONSISTENCY_VALUE
static TestTraceContainer from_rows(const std::vector< AvmFullRow > &rows)
uint32_t get_num_rows() const
void set(Column col, uint32_t row, const FF &value)
PrecomputedTraceBuilder precomputed_builder
GreaterThanTraceBuilder gt_builder
ExecutionIdManager execution_id_manager
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
void check_interaction(tracegen::TestTraceContainer &trace)
TEST(TxExecutionConstrainingTest, WriteTreeValue)
TestTraceContainer empty_trace()
lookup_settings< lookup_to_radix_limb_less_than_radix_range_settings_ > lookup_to_radix_limb_less_than_radix_range_settings
lookup_settings< lookup_to_radix_limb_p_diff_range_settings_ > lookup_to_radix_limb_p_diff_range_settings
permutation_settings< perm_to_radix_mem_dispatch_exec_to_radix_settings_ > perm_to_radix_mem_dispatch_exec_to_radix_settings
lookup_settings< lookup_to_radix_mem_check_dst_addr_in_range_settings_ > lookup_to_radix_mem_check_dst_addr_in_range_settings
lookup_settings< lookup_to_radix_mem_check_radix_lt_2_settings_ > lookup_to_radix_mem_check_radix_lt_2_settings
lookup_settings< lookup_to_radix_limb_range_settings_ > lookup_to_radix_limb_range_settings
lookup_settings< lookup_to_radix_mem_check_radix_gt_256_settings_ > lookup_to_radix_mem_check_radix_gt_256_settings
lookup_settings< lookup_to_radix_fetch_safe_limbs_settings_ > lookup_to_radix_fetch_safe_limbs_settings
lookup_settings< lookup_to_radix_mem_input_output_to_radix_settings_ > lookup_to_radix_mem_input_output_to_radix_settings
lookup_settings< lookup_to_radix_fetch_p_limb_settings_ > lookup_to_radix_fetch_p_limb_settings
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
NiceMock< MockFieldGreaterThan > field_gt