2#include <gmock/gmock.h>
3#include <gtest/gtest.h>
30using ::testing::Return;
31using ::testing::StrictMock;
33using tracegen::ExecutionTraceBuilder;
34using tracegen::GreaterThanTraceBuilder;
35using tracegen::PrecomputedTraceBuilder;
36using tracegen::TestTraceContainer;
37using tracegen::ToRadixTraceBuilder;
43using ToRadixSimulator = simulation::ToRadix;
45using simulation::EventEmitter;
46using simulation::GreaterThan;
47using simulation::GreaterThanEvent;
48using simulation::MockExecutionIdManager;
49using simulation::MockFieldGreaterThan;
50using simulation::NoopEventEmitter;
51using simulation::PureGreaterThan;
52using simulation::RangeCheck;
53using simulation::RangeCheckEvent;
54using simulation::ToRadixEvent;
55using simulation::ToRadixMemoryEvent;
59TEST(ToRadixConstrainingTest, EmptyRow)
64TEST(ToRadixConstrainingTest, ToLeBitsBasicTest)
66 EventEmitter<ToRadixEvent> to_radix_event_emitter;
67 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
71 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
73 auto [bits, truncated] = to_radix_simulator.to_le_bits(
FF::one(), 254);
75 EXPECT_EQ(bits.size(), 254);
76 EXPECT_FALSE(truncated);
78 TestTraceContainer
trace({
79 { { C::precomputed_first_row, 1 } },
85 check_relation<to_radix>(trace);
88TEST(ToRadixConstrainingTest, ToLeBitsPMinusOne)
90 EventEmitter<ToRadixEvent> to_radix_event_emitter;
91 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
95 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
97 auto [bits, truncated] = to_radix_simulator.to_le_bits(
FF::neg_one(), 254);
99 EXPECT_EQ(bits.size(), 254);
100 EXPECT_FALSE(truncated);
102 TestTraceContainer
trace({
103 { { C::precomputed_first_row, 1 } },
109 check_relation<to_radix>(trace);
112TEST(ToRadixConstrainingTest, ToLeBitsShortest)
114 EventEmitter<ToRadixEvent> to_radix_event_emitter;
115 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
119 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
121 auto [bits, truncated] = to_radix_simulator.to_le_bits(
FF::one(), 1);
123 EXPECT_EQ(bits.size(), 1);
124 EXPECT_FALSE(truncated);
126 TestTraceContainer
trace({
127 { { C::precomputed_first_row, 1 } },
133 check_relation<to_radix>(trace);
136TEST(ToRadixConstrainingTest, ToLeBitsPadded)
138 EventEmitter<ToRadixEvent> to_radix_event_emitter;
139 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
143 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
145 auto [bits, truncated] = to_radix_simulator.to_le_bits(
FF::one(), 500);
147 EXPECT_EQ(bits.size(), 500);
148 EXPECT_FALSE(truncated);
150 TestTraceContainer
trace({
151 { { C::precomputed_first_row, 1 } },
157 check_relation<to_radix>(trace);
160TEST(ToRadixConstrainingTest, ToLeRadixBasic)
162 EventEmitter<ToRadixEvent> to_radix_event_emitter;
163 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
167 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
170 auto [bytes, truncated] = to_radix_simulator.to_le_radix(
value, 32, 256);
174 std::reverse(expected_bytes.begin(), expected_bytes.end());
175 EXPECT_EQ(bytes, expected_bytes);
176 EXPECT_FALSE(truncated);
178 TestTraceContainer
trace({
179 { { C::precomputed_first_row, 1 } },
185 check_relation<to_radix>(trace);
188TEST(ToRadixConstrainingTest, ToLeRadixPMinusOne)
190 EventEmitter<ToRadixEvent> to_radix_event_emitter;
191 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
195 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
198 auto [bytes, truncated] = to_radix_simulator.to_le_radix(
value, 32, 256);
202 std::reverse(expected_bytes.begin(), expected_bytes.end());
203 EXPECT_EQ(bytes, expected_bytes);
204 EXPECT_FALSE(truncated);
206 TestTraceContainer
trace({
207 { { C::precomputed_first_row, 1 } },
213 check_relation<to_radix>(trace);
216TEST(ToRadixConstrainingTest, ToLeRadixOneByte)
218 EventEmitter<ToRadixEvent> to_radix_event_emitter;
219 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
223 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
225 auto [bytes, truncated] = to_radix_simulator.to_le_radix(
FF::one(), 1, 256);
227 std::vector<uint8_t> expected_bytes = { 1 };
228 EXPECT_EQ(bytes, expected_bytes);
229 EXPECT_FALSE(truncated);
231 TestTraceContainer
trace({
232 { { C::precomputed_first_row, 1 } },
238 check_relation<to_radix>(trace);
241TEST(ToRadixConstrainingTest, ToLeRadixPadded)
243 EventEmitter<ToRadixEvent> to_radix_event_emitter;
244 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
248 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
251 auto [bytes, truncated] = to_radix_simulator.to_le_radix(
value, 64, 256);
255 std::reverse(expected_bytes.begin(), expected_bytes.end());
256 expected_bytes.resize(64);
257 EXPECT_EQ(bytes, expected_bytes);
258 EXPECT_FALSE(truncated);
260 TestTraceContainer
trace({
261 { { C::precomputed_first_row, 1 } },
267 check_relation<to_radix>(trace);
270TEST(ToRadixConstrainingTest, ToLeBitsInteractions)
272 EventEmitter<ToRadixEvent> to_radix_event_emitter;
273 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
277 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
281 TestTraceContainer
trace({
282 { { C::precomputed_first_row, 1 } },
285 ToRadixTraceBuilder to_radix_builder;
286 to_radix_builder.process(to_radix_event_emitter.dump_events(), trace);
300 check_relation<to_radix>(trace);
303TEST(ToRadixConstrainingTest, ToLeRadixInteractions)
305 EventEmitter<ToRadixEvent> to_radix_event_emitter;
306 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
310 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
312 to_radix_simulator.to_le_radix(
FF::neg_one(), 32, 256);
314 TestTraceContainer
trace({
315 { { C::precomputed_first_row, 1 } },
318 ToRadixTraceBuilder to_radix_builder;
319 to_radix_builder.process(to_radix_event_emitter.dump_events(), trace);
334 check_relation<to_radix>(trace);
337TEST(ToRadixConstrainingTest, NegativeOverflowCheck)
339 TestTraceContainer
trace({
340 { { C::precomputed_first_row, 1 } },
343 std::vector<uint8_t> modulus_le_bits(256, 0);
344 for (
size_t i = 0; i < 256; i++) {
348 ToRadixEvent
event = { .value =
FF::zero(), .radix = 2, .limbs = modulus_le_bits };
357TEST(ToRadixConstrainingTest, NegativeConsistency)
359 EventEmitter<ToRadixEvent> to_radix_event_emitter;
360 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
364 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
366 to_radix_simulator.to_le_radix(
FF(256), 32, 256);
368 TestTraceContainer
trace({
369 { { C::precomputed_first_row, 1 } },
376 trace.
set(Column::to_radix_sel, 6, 0);
379 "SELECTOR_CONSISTENCY");
382 trace.
set(Column::to_radix_radix, 5, 200);
385 "CONSTANT_CONSISTENCY_RADIX");
388 trace.
set(Column::to_radix_value, 4, 27);
391 "CONSTANT_CONSISTENCY_VALUE");
394 trace.
set(Column::to_radix_safe_limbs, 3, 200);
397 "CONSTANT_CONSISTENCY_SAFE_LIMBS");
404TEST(ToRadixMemoryConstrainingTest, EmptyRow)
409TEST(ToRadixMemoryConstrainingTest, BasicTest)
414 uint32_t num_limbs = 4;
417 TestTraceContainer
trace = TestTraceContainer({
420 { C::precomputed_first_row, 1 },
423 { C::gt_input_a,
dst_addr + num_limbs },
424 { C::gt_input_b, MAX_MEM },
427 { C::execution_sel, 1 },
428 { C::execution_sel_exec_dispatch_to_radix, 1 },
429 { C::execution_register_0_,
value },
430 { C::execution_register_1_, radix },
431 { C::execution_register_2_, num_limbs },
432 { C::execution_register_3_, 0 },
439 { C::to_radix_mem_sel, 1 },
440 { C::to_radix_mem_max_mem_size, MAX_MEM },
441 { C::to_radix_mem_two, 2 },
442 { C::to_radix_mem_two_five_six, 256 },
444 { C::to_radix_mem_execution_clk, 0 },
445 { C::to_radix_mem_space_id, 0 },
446 { C::to_radix_mem_dst_addr,
dst_addr },
447 { C::to_radix_mem_write_addr_upper_bound,
dst_addr + num_limbs },
449 { C::to_radix_mem_value_to_decompose,
value },
450 { C::to_radix_mem_radix, radix },
451 { C::to_radix_mem_num_limbs, num_limbs },
452 { C::to_radix_mem_is_output_bits, 0 },
454 { C::to_radix_mem_start, 1 },
455 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).
invert() },
457 { C::to_radix_mem_sel_num_limbs_is_zero, 0 },
458 { C::to_radix_mem_num_limbs_inv,
FF(num_limbs).
invert() },
459 { C::to_radix_mem_sel_value_is_zero, 0 },
462 { C::to_radix_mem_limb_value, 1 },
463 { C::to_radix_mem_sel_should_decompose, 1 },
464 { C::to_radix_mem_sel_should_write_mem, 1 },
465 { C::to_radix_mem_limb_index_to_lookup, num_limbs - 1 },
466 { C::to_radix_mem_value_found, 1 },
467 { C::to_radix_mem_output_tag,
static_cast<uint8_t
>(
MemoryTag::U8) },
471 { C::gt_input_a, 2 },
472 { C::gt_input_b, radix },
477 { C::to_radix_mem_sel, 1 },
479 { C::to_radix_mem_execution_clk, 0 },
480 { C::to_radix_mem_space_id, 0 },
481 { C::to_radix_mem_dst_addr,
dst_addr + 1 },
483 { C::to_radix_mem_value_to_decompose,
value },
484 { C::to_radix_mem_radix, radix },
485 { C::to_radix_mem_num_limbs, num_limbs - 1 },
486 { C::to_radix_mem_is_output_bits, 0 },
489 { C::to_radix_mem_num_limbs_minus_one_inv,
FF(num_limbs - 2).
invert() },
491 { C::to_radix_mem_limb_value, 3 },
492 { C::to_radix_mem_sel_should_decompose, 1 },
493 { C::to_radix_mem_sel_should_write_mem, 1 },
494 { C::to_radix_mem_limb_index_to_lookup, num_limbs - 2 },
495 { C::to_radix_mem_output_tag,
static_cast<uint8_t
>(
MemoryTag::U8) },
498 { C::gt_input_a, radix },
499 { C::gt_input_b, 256 },
504 { C::to_radix_mem_sel, 1 },
506 { C::to_radix_mem_execution_clk, 0 },
507 { C::to_radix_mem_space_id, 0 },
508 { C::to_radix_mem_dst_addr,
dst_addr + 2 },
510 { C::to_radix_mem_value_to_decompose,
value },
511 { C::to_radix_mem_radix, radix },
512 { C::to_radix_mem_num_limbs, num_limbs - 2 },
513 { C::to_radix_mem_is_output_bits, 0 },
516 { C::to_radix_mem_num_limbs_minus_one_inv,
FF(num_limbs - 3).
invert() },
518 { C::to_radix_mem_limb_value, 3 },
519 { C::to_radix_mem_sel_should_decompose, 1 },
520 { C::to_radix_mem_sel_should_write_mem, 1 },
521 { C::to_radix_mem_limb_index_to_lookup, num_limbs - 3 },
522 { C::to_radix_mem_output_tag,
static_cast<uint8_t
>(
MemoryTag::U8) },
526 { C::to_radix_mem_sel, 1 },
528 { C::to_radix_mem_execution_clk, 0 },
529 { C::to_radix_mem_space_id, 0 },
530 { C::to_radix_mem_dst_addr, 13 },
532 { C::to_radix_mem_value_to_decompose,
value },
533 { C::to_radix_mem_radix, radix },
534 { C::to_radix_mem_num_limbs, num_limbs - 3 },
535 { C::to_radix_mem_is_output_bits, 0 },
537 { C::to_radix_mem_last, 1 },
539 { C::to_radix_mem_limb_value, 7 },
540 { C::to_radix_mem_sel_should_decompose, 1 },
541 { C::to_radix_mem_sel_should_write_mem, 1 },
542 { C::to_radix_mem_limb_index_to_lookup, num_limbs - 4 },
543 { C::to_radix_mem_output_tag,
static_cast<uint8_t
>(
MemoryTag::U8) },
554 { value_addr, MemoryValue::from<FF>(
value) },
555 { radix_addr, MemoryValue::from<uint32_t>(radix) },
556 { num_limbs_addr, MemoryValue::from<uint32_t>(num_limbs) },
557 { is_output_bits_addr, MemoryValue::from<uint1_t>(
false) },
558 {
dst_addr, MemoryValue::from<uint8_t>(1) },
559 {
dst_addr + 1, MemoryValue::from<uint8_t>(3) },
560 {
dst_addr + 2, MemoryValue::from<uint8_t>(3) },
561 {
dst_addr + 3, MemoryValue::from<uint8_t>(7) },
564 for (uint32_t i = 0; i < memory_values.size(); ++i) {
565 const auto& [addr,
value] = memory_values[i];
568 { { C::memory_sel, 1 },
569 { C::memory_space_id, 0 },
570 { C::memory_address, addr },
571 { C::memory_value,
value.as_ff() },
572 { C::memory_tag,
static_cast<uint8_t
>(
value.get_tag()) },
573 { C::memory_rw, i > 3 ? 1 : 0 } },
577 EventEmitter<ToRadixEvent> to_radix_event_emitter;
578 NoopEventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
582 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
585 to_radix_simulator.to_le_radix(
value, num_limbs, radix);
588 auto events = to_radix_event_emitter.get_events();
596 check_relation<to_radix_mem>(trace);
597 check_all_interactions<ToRadixTraceBuilder>(trace);
600 trace.
set(Column::to_radix_mem_sel_should_write_mem, 2, 0);
602 "SEL_SHOULD_WRITE_MEM_CONTINUITY");
605 trace.
set(Column::to_radix_mem_sel_should_decompose, 2, 0);
607 "SEL_SHOULD_DECOMPOSE_CONTINUITY");
610TEST(ToRadixMemoryConstrainingTest, DstOutOfRange)
615 uint32_t num_limbs = 2;
616 auto dst_addr =
static_cast<uint64_t
>(MAX_MEM - 1);
618 TestTraceContainer
trace = TestTraceContainer({
621 { C::precomputed_first_row, 1 },
624 { C::gt_input_a,
dst_addr + num_limbs },
625 { C::gt_input_b, MAX_MEM },
631 { C::execution_sel, 1 },
632 { C::execution_sel_exec_dispatch_to_radix, 1 },
633 { C::execution_register_0_,
value },
634 { C::execution_register_1_, radix },
635 { C::execution_register_2_, num_limbs },
636 { C::execution_register_3_, 0 },
638 { C::execution_sel_opcode_error, 1 },
641 { C::to_radix_mem_sel, 1 },
642 { C::to_radix_mem_max_mem_size, MAX_MEM },
643 { C::to_radix_mem_two, 2 },
644 { C::to_radix_mem_two_five_six, 256 },
646 { C::to_radix_mem_execution_clk, 0 },
647 { C::to_radix_mem_space_id, 0 },
648 { C::to_radix_mem_dst_addr,
dst_addr },
649 { C::to_radix_mem_write_addr_upper_bound,
dst_addr + num_limbs },
651 { C::to_radix_mem_value_to_decompose,
value },
652 { C::to_radix_mem_radix, radix },
653 { C::to_radix_mem_num_limbs, num_limbs },
654 { C::to_radix_mem_is_output_bits, 0 },
656 { C::to_radix_mem_sel_dst_out_of_range_err, 1 },
657 { C::to_radix_mem_input_validation_error, 1 },
658 { C::to_radix_mem_err, 1 },
660 { C::to_radix_mem_start, 1 },
661 { C::to_radix_mem_last, 1 },
662 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).
invert() },
664 { C::to_radix_mem_sel_num_limbs_is_zero, 0 },
665 { C::to_radix_mem_num_limbs_inv,
FF(num_limbs).
invert() },
666 { C::to_radix_mem_sel_value_is_zero, 0 },
671 check_relation<to_radix_mem>(trace);
672 check_interaction<ToRadixTraceBuilder, lookup_to_radix_mem_check_dst_addr_in_range_settings>(trace);
673 check_interaction<ExecutionTraceBuilder, perm_execution_dispatch_to_to_radix_settings>(trace);
676TEST(ToRadixMemoryConstrainingTest, InvalidRadix)
681 uint32_t num_limbs = 2;
684 TestTraceContainer
trace = TestTraceContainer({
687 { C::precomputed_first_row, 1 },
690 { C::gt_input_a, 2 },
691 { C::gt_input_b, radix },
696 { C::to_radix_mem_sel, 1 },
697 { C::to_radix_mem_max_mem_size, MAX_MEM },
698 { C::to_radix_mem_two, 2 },
699 { C::to_radix_mem_two_five_six, 256 },
701 { C::to_radix_mem_execution_clk, 0 },
702 { C::to_radix_mem_space_id, 0 },
703 { C::to_radix_mem_dst_addr,
dst_addr },
704 { C::to_radix_mem_write_addr_upper_bound,
dst_addr + num_limbs },
706 { C::to_radix_mem_value_to_decompose,
value },
707 { C::to_radix_mem_radix, radix },
708 { C::to_radix_mem_num_limbs, num_limbs },
709 { C::to_radix_mem_is_output_bits, 0 },
711 { C::to_radix_mem_sel_radix_lt_2_err, 1 },
712 { C::to_radix_mem_input_validation_error, 1 },
713 { C::to_radix_mem_err, 1 },
715 { C::to_radix_mem_start, 1 },
716 { C::to_radix_mem_last, 1 },
717 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).
invert() },
719 { C::to_radix_mem_sel_num_limbs_is_zero, 0 },
720 { C::to_radix_mem_num_limbs_inv,
FF(num_limbs).
invert() },
721 { C::to_radix_mem_sel_value_is_zero, 0 },
725 check_relation<to_radix_mem>(trace);
726 check_interaction<ToRadixTraceBuilder, lookup_to_radix_mem_check_radix_lt_2_settings>(trace);
729TEST(ToRadixMemoryConstrainingTest, InvalidBitwiseRadix)
734 uint32_t num_limbs = 2;
736 bool is_output_bits =
true;
738 TestTraceContainer
trace = TestTraceContainer({
741 { C::precomputed_first_row, 1 },
744 { C::gt_input_a, 2 },
745 { C::gt_input_b, radix },
750 { C::to_radix_mem_sel, 1 },
751 { C::to_radix_mem_max_mem_size, MAX_MEM },
752 { C::to_radix_mem_two, 2 },
753 { C::to_radix_mem_two_five_six, 256 },
755 { C::to_radix_mem_execution_clk, 0 },
756 { C::to_radix_mem_space_id, 0 },
757 { C::to_radix_mem_dst_addr,
dst_addr },
758 { C::to_radix_mem_write_addr_upper_bound,
dst_addr + num_limbs },
760 { C::to_radix_mem_value_to_decompose,
value },
761 { C::to_radix_mem_radix, radix },
762 { C::to_radix_mem_num_limbs, num_limbs },
763 { C::to_radix_mem_is_output_bits, is_output_bits ? 1 : 0 },
765 { C::to_radix_mem_sel_invalid_bitwise_radix, 1 },
766 { C::to_radix_mem_input_validation_error, 1 },
767 { C::to_radix_mem_err, 1 },
769 { C::to_radix_mem_start, 1 },
770 { C::to_radix_mem_last, 1 },
771 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).
invert() },
773 { C::to_radix_mem_sel_num_limbs_is_zero, 0 },
774 { C::to_radix_mem_num_limbs_inv,
FF(num_limbs).
invert() },
775 { C::to_radix_mem_sel_value_is_zero, 0 },
779 check_relation<to_radix_mem>(trace);
780 check_interaction<ToRadixTraceBuilder, lookup_to_radix_mem_check_radix_lt_2_settings>(trace);
783TEST(ToRadixMemoryConstrainingTest, InvalidNumLimbsForValue)
788 uint32_t num_limbs = 0;
790 bool is_output_bits =
false;
792 TestTraceContainer
trace = TestTraceContainer({
795 { C::precomputed_first_row, 1 },
798 { C::gt_input_a, 2 },
799 { C::gt_input_b, radix },
804 { C::to_radix_mem_sel, 1 },
805 { C::to_radix_mem_max_mem_size, MAX_MEM },
806 { C::to_radix_mem_two, 2 },
807 { C::to_radix_mem_two_five_six, 256 },
809 { C::to_radix_mem_execution_clk, 0 },
810 { C::to_radix_mem_space_id, 0 },
811 { C::to_radix_mem_dst_addr,
dst_addr },
812 { C::to_radix_mem_write_addr_upper_bound,
dst_addr + num_limbs },
814 { C::to_radix_mem_value_to_decompose,
value },
815 { C::to_radix_mem_radix, radix },
816 { C::to_radix_mem_num_limbs, num_limbs },
817 { C::to_radix_mem_is_output_bits, is_output_bits ? 1 : 0 },
819 { C::to_radix_mem_sel_invalid_num_limbs_err, 1 },
820 { C::to_radix_mem_input_validation_error, 1 },
821 { C::to_radix_mem_err, 1 },
823 { C::to_radix_mem_start, 1 },
824 { C::to_radix_mem_last, 1 },
825 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).
invert() },
827 { C::to_radix_mem_sel_num_limbs_is_zero, 1 },
828 { C::to_radix_mem_num_limbs_inv, 0 },
829 { C::to_radix_mem_sel_value_is_zero, 0 },
833 check_relation<to_radix_mem>(trace);
834 check_interaction<ToRadixTraceBuilder, lookup_to_radix_mem_check_radix_lt_2_settings>(trace);
837TEST(ToRadixMemoryConstrainingTest, TruncationError)
842 uint32_t num_limbs = 3;
844 bool is_output_bits =
false;
846 TestTraceContainer
trace = TestTraceContainer({
849 { C::precomputed_first_row, 1 },
852 { C::gt_input_a, 2 },
853 { C::gt_input_b, radix },
858 { C::to_radix_mem_sel, 1 },
859 { C::to_radix_mem_max_mem_size, MAX_MEM },
860 { C::to_radix_mem_two, 2 },
861 { C::to_radix_mem_two_five_six, 256 },
863 { C::to_radix_mem_execution_clk, 0 },
864 { C::to_radix_mem_space_id, 0 },
865 { C::to_radix_mem_dst_addr,
dst_addr },
866 { C::to_radix_mem_write_addr_upper_bound,
dst_addr + num_limbs },
868 { C::to_radix_mem_value_to_decompose,
value },
869 { C::to_radix_mem_radix, radix },
870 { C::to_radix_mem_num_limbs, num_limbs },
871 { C::to_radix_mem_is_output_bits, is_output_bits ? 1 : 0 },
873 { C::to_radix_mem_sel_truncation_error, 1 },
874 { C::to_radix_mem_err, 1 },
876 { C::to_radix_mem_start, 1 },
877 { C::to_radix_mem_last, 1 },
878 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).
invert() },
880 { C::to_radix_mem_sel_should_decompose, 1 },
881 { C::to_radix_mem_limb_index_to_lookup, num_limbs - 1 },
882 { C::to_radix_mem_limb_value, 3 },
883 { C::to_radix_mem_value_found, 0 },
885 { C::to_radix_mem_num_limbs_inv,
FF(num_limbs).
invert() },
886 { C::to_radix_mem_sel_value_is_zero, 0 },
890 check_relation<to_radix_mem>(trace);
891 check_interaction<ToRadixTraceBuilder, lookup_to_radix_mem_check_radix_lt_2_settings>(trace);
894 trace.
set(C::to_radix_mem_sel_truncation_error, 1, 0);
897 trace.
set(C::to_radix_mem_sel_truncation_error, 1, 1);
900 trace.
set(C::to_radix_mem_value_found, 1, 1);
905TEST(ToRadixMemoryConstrainingTest, ZeroNumLimbsAndZeroValueIsNoop)
910 uint32_t num_limbs = 0;
912 bool is_output_bits =
false;
914 TestTraceContainer
trace = TestTraceContainer({
917 { C::precomputed_first_row, 1 },
920 { C::gt_input_a, 2 },
921 { C::gt_input_b, radix },
926 { C::to_radix_mem_sel, 1 },
927 { C::to_radix_mem_max_mem_size, MAX_MEM },
928 { C::to_radix_mem_two, 2 },
929 { C::to_radix_mem_two_five_six, 256 },
931 { C::to_radix_mem_execution_clk, 0 },
932 { C::to_radix_mem_space_id, 0 },
933 { C::to_radix_mem_dst_addr,
dst_addr },
934 { C::to_radix_mem_write_addr_upper_bound,
dst_addr + num_limbs },
936 { C::to_radix_mem_value_to_decompose,
value },
937 { C::to_radix_mem_radix, radix },
938 { C::to_radix_mem_num_limbs, num_limbs },
939 { C::to_radix_mem_is_output_bits, is_output_bits ? 1 : 0 },
941 { C::to_radix_mem_start, 1 },
942 { C::to_radix_mem_last, 1 },
943 { C::to_radix_mem_num_limbs_minus_one_inv, num_limbs - 1 == 0 ? 0 :
FF(num_limbs - 1).
invert() },
945 { C::to_radix_mem_sel_num_limbs_is_zero, 1 },
946 { C::to_radix_mem_num_limbs_inv, 0 },
947 { C::to_radix_mem_sel_value_is_zero, 1 },
948 { C::to_radix_mem_value_inv, 0 },
951 check_relation<to_radix_mem>(trace);
952 check_interaction<ToRadixTraceBuilder, lookup_to_radix_mem_check_radix_lt_2_settings>(trace);
955TEST(ToRadixMemoryConstrainingTest, ComplexTest)
957 EventEmitter<ToRadixEvent> to_radix_event_emitter;
958 EventEmitter<ToRadixMemoryEvent> to_radix_mem_event_emitter;
962 simulation::MemoryStore
memory;
964 StrictMock<MockFieldGreaterThan>
field_gt;
968 ToRadixSimulator to_radix_simulator(
execution_id_manager, gt, to_radix_event_emitter, to_radix_mem_event_emitter);
972 uint32_t num_limbs = 256;
974 bool is_output_bits =
true;
976 to_radix_simulator.to_be_radix(memory,
value, radix, num_limbs, is_output_bits,
dst_addr);
977 to_radix_simulator.to_be_radix(
978 memory,
FF(1337), 10, 6,
false, 0xdeadbeef);
980 TestTraceContainer
trace;
983 builder.process_with_memory(to_radix_mem_event_emitter.dump_events(), trace);
993 check_relation<to_radix>(trace);
994 check_relation<to_radix_mem>(trace);
DeduplicatingEventEmitter< GreaterThanEvent > gt_emitter
FieldGreaterThan field_gt
DeduplicatingEventEmitter< RangeCheckEvent > range_check_emitter
static constexpr size_t SR_SEL_SHOULD_WRITE_MEM_CONTINUITY
static constexpr size_t SR_SEL_SHOULD_DECOMPOSE_CONTINUITY
static constexpr size_t SR_TRUNCATION_ERROR
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
void process(const simulation::EventEmitterInterface< simulation::AluEvent >::Container &events, TraceContainer &trace)
Process the ALU events and populate the ALU relevant columns in the trace.
void process(const simulation::EventEmitterInterface< simulation::GreaterThanEvent >::Container &events, TraceContainer &trace)
void process_to_radix_p_decompositions(TraceContainer &trace)
void process_to_radix_safe_limbs(TraceContainer &trace)
void process_misc(TraceContainer &trace, const uint32_t num_rows=MAX_AVM_TRACE_SIZE)
void process_sel_range_8(TraceContainer &trace)
uint32_t get_num_rows() const
void set(Column col, uint32_t row, const FF &value)
constexpr bool get_bit(uint64_t bit_index) const
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
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
static constexpr field neg_one()
static constexpr field one()
static constexpr uint256_t modulus
constexpr field invert() const noexcept
BB_INLINE std::vector< uint8_t > to_buffer() const
static constexpr field zero()