1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
38using ::testing::NiceMock;
39using ::testing::TestWithParam;
41using testing::TestMemoryTree;
43using simulation::DeduplicatingEventEmitter;
44using simulation::EventEmitter;
45using simulation::ExecutionIdManager;
46using simulation::FieldGreaterThan;
47using simulation::FieldGreaterThanEvent;
48using simulation::MerkleCheck;
49using simulation::MerkleCheckEvent;
50using simulation::MockGreaterThan;
51using simulation::Poseidon2;
52using simulation::Poseidon2HashEvent;
53using simulation::Poseidon2PermutationEvent;
54using simulation::Poseidon2PermutationMemoryEvent;
55using simulation::PublicDataTreeCheck;
58using simulation::RangeCheck;
59using simulation::RangeCheckEvent;
63using tracegen::FieldGreaterThanTraceBuilder;
64using tracegen::MerkleCheckTraceBuilder;
65using tracegen::Poseidon2TraceBuilder;
66using tracegen::PrecomputedTraceBuilder;
67using tracegen::PublicDataTreeTraceBuilder;
68using tracegen::PublicInputsTraceBuilder;
69using tracegen::RangeCheckTraceBuilder;
70using tracegen::TestTraceContainer;
80class PublicDataTreeCheckConstrainingTest :
public ::testing::Test {
82 PublicDataTreeCheckConstrainingTest()
92 Poseidon2(execution_id_manager, mock_gt, hash_event_emitter, perm_event_emitter, perm_mem_event_emitter);
103 TestParams{ .slot = 42,
120class PublicDataReadPositiveTests :
public PublicDataTreeCheckConstrainingTest,
121 public ::testing::WithParamInterface<TestParams> {};
123TEST_P(PublicDataReadPositiveTests, Positive)
125 const auto& param = GetParam();
127 auto test_public_inputs = testing::PublicInputsBuilder().build();
129 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
138 EventEmitter<PublicDataTreeCheckEvent> public_data_tree_check_event_emitter;
139 PublicDataTreeCheck public_data_tree_check_simulator(
142 TestTraceContainer
trace({ { { C::precomputed_first_row, 1 } } });
145 MerkleCheckTraceBuilder merkle_check_builder;
149 PublicDataTreeTraceBuilder public_data_tree_read_builder;
152 uint64_t leaf_index = 30;
153 std::vector<FF> sibling_path;
156 sibling_path.emplace_back(i);
160 public_data_tree_check_simulator.assert_read(param.slot,
166 AppendOnlyTreeSnapshot{
168 .next_available_leaf_index = 128,
177 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
179 public_data_tree_read_builder.process(public_data_tree_check_event_emitter.dump_events(), trace);
181 check_all_interactions<PublicDataTreeTraceBuilder>(trace);
183 check_relation<public_data_check>(trace);
184 check_relation<public_data_squash>(trace);
188 PublicDataReadPositiveTests,
189 ::testing::ValuesIn(positive_tests));
191TEST(PublicDataTreeConstrainingTest, NegativeStartCondition)
194 TestTraceContainer
trace({ {
195 { C::public_data_check_sel, 0 },
196 { C::precomputed_first_row, 1 },
199 { C::public_data_check_sel, 1 },
202 { C::public_data_check_sel, 1 },
208 trace.
set(C::precomputed_first_row, 0, 0);
214TEST(PublicDataTreeConstrainingTest, NegativeExistsFlagCheck)
218 TestTraceContainer
trace({
219 { { C::public_data_check_sel, 1 },
220 { C::public_data_check_leaf_slot, 27 },
221 { C::public_data_check_low_leaf_slot, 27 },
222 { C::public_data_check_leaf_slot_low_leaf_slot_diff_inv, 0 },
223 { C::public_data_check_leaf_not_exists, 0 } },
224 { { C::public_data_check_sel, 1 },
225 { C::public_data_check_leaf_slot, 28 },
226 { C::public_data_check_low_leaf_slot, 27 },
227 { C::public_data_check_leaf_slot_low_leaf_slot_diff_inv,
FF(1).invert() },
228 { C::public_data_check_leaf_not_exists, 1 } },
233 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
236 "EXISTS_FLAG_CHECK");
238 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
239 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
242 "EXISTS_FLAG_CHECK");
245TEST(PublicDataTreeConstrainingTest, NegativeNextSlotIsZero)
249 TestTraceContainer
trace({
251 { C::public_data_check_leaf_not_exists, 1 },
252 { C::public_data_check_low_leaf_next_slot, 0 },
253 { C::public_data_check_next_slot_inv, 0 },
254 { C::public_data_check_next_slot_is_nonzero, 0 },
257 { C::public_data_check_leaf_not_exists, 1 },
258 { C::public_data_check_low_leaf_next_slot, 1 },
259 { C::public_data_check_next_slot_inv,
FF(1).invert() },
260 { C::public_data_check_next_slot_is_nonzero, 1 },
266 trace.
set(C::public_data_check_next_slot_is_nonzero, 0, 1);
269 "NEXT_SLOT_IS_ZERO_CHECK");
271 trace.
set(C::public_data_check_next_slot_is_nonzero, 0, 0);
272 trace.
set(C::public_data_check_next_slot_is_nonzero, 1, 0);
275 "NEXT_SLOT_IS_ZERO_CHECK");
278TEST(PublicDataTreeConstrainingTest, NegativeValueIsCorrect)
282 TestTraceContainer
trace({
284 { C::public_data_check_low_leaf_value, 27 },
285 { C::public_data_check_leaf_not_exists, 0 },
286 { C::public_data_check_value, 27 },
289 { C::public_data_check_low_leaf_value, 27 },
290 { C::public_data_check_leaf_not_exists, 1 },
291 { C::public_data_check_value, 0 },
298 trace.
set(C::public_data_check_value, 0, 0);
303 trace.
set(C::public_data_check_value, 0, 27);
305 trace.
set(C::public_data_check_value, 1, 27);
311TEST_F(PublicDataTreeCheckConstrainingTest, PositiveWriteExists)
318 AvmAccumulatedData accumulated_data = {};
319 accumulated_data.public_data_writes[0] = PublicDataWrite{
320 .leaf_slot = leaf_slot,
324 auto test_public_inputs = testing::PublicInputsBuilder()
325 .set_accumulated_data(accumulated_data)
326 .set_accumulated_data_array_lengths({ .public_data_writes = 1 })
329 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
338 EventEmitter<PublicDataTreeCheckEvent> public_data_tree_check_event_emitter;
339 PublicDataTreeCheck public_data_tree_check_simulator(
342 TestTraceContainer
trace({ { { C::precomputed_first_row, 1 } } });
345 MerkleCheckTraceBuilder merkle_check_builder;
349 PublicDataTreeTraceBuilder public_data_tree_builder;
353 uint64_t low_leaf_index = 30;
354 public_data_tree.update_element(low_leaf_index, low_leaf_hash);
356 AppendOnlyTreeSnapshot prev_snapshot =
357 AppendOnlyTreeSnapshot{ .root = public_data_tree.root(), .next_available_leaf_index = 128 };
358 std::vector<FF> low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
361 updated_low_leaf.leaf.
value = new_value;
362 FF updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
363 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
365 FF intermediate_root = public_data_tree.root();
366 std::vector<FF> insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.next_available_leaf_index);
369 AppendOnlyTreeSnapshot next_snapshot =
370 AppendOnlyTreeSnapshot{ .root = intermediate_root,
371 .next_available_leaf_index = prev_snapshot.next_available_leaf_index };
373 AppendOnlyTreeSnapshot result_snapshot = public_data_tree_check_simulator.write(
slot,
378 low_leaf_sibling_path,
380 insertion_sibling_path,
382 EXPECT_EQ(next_snapshot, result_snapshot);
390 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
392 public_data_tree_builder.process(public_data_tree_check_event_emitter.dump_events(), trace);
394 check_relation<public_data_check>(trace);
395 check_relation<public_data_squash>(trace);
397 check_all_interactions<PublicDataTreeTraceBuilder>(trace);
400TEST_F(PublicDataTreeCheckConstrainingTest, PositiveSquashing)
423 leaf_slot = leaf_slot_a;
424 dummy_leaf_slot = leaf_slot_b;
428 leaf_slot = leaf_slot_b;
429 dummy_leaf_slot = leaf_slot_a;
433 FF updated_value = 28;
434 FF dummy_leaf_value = 0;
438 ASSERT_GT(dummy_leaf_slot, leaf_slot + 1);
440 FF low_leaf_slot = 40;
443 AvmAccumulatedData accumulated_data = {};
444 accumulated_data.public_data_writes[0] = PublicDataWrite{
445 .leaf_slot = leaf_slot,
446 .value = updated_value,
449 accumulated_data.public_data_writes[1] = PublicDataWrite{
450 .leaf_slot = dummy_leaf_slot,
451 .value = dummy_leaf_value,
454 auto test_public_inputs = testing::PublicInputsBuilder()
455 .set_accumulated_data(accumulated_data)
456 .set_accumulated_data_array_lengths({ .public_data_writes = 2 })
459 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
468 EventEmitter<PublicDataTreeCheckEvent> public_data_tree_check_event_emitter;
469 PublicDataTreeCheck public_data_tree_check_simulator(
472 TestTraceContainer
trace({ { { C::precomputed_first_row, 1 } } });
475 MerkleCheckTraceBuilder merkle_check_builder;
479 PublicDataTreeTraceBuilder public_data_tree_read_builder;
484 uint64_t low_leaf_index = 30;
485 public_data_tree.update_element(low_leaf_index, low_leaf_hash);
487 uint64_t second_low_leaf_index = 31;
488 FF second_low_leaf_slot = leaf_slot + 1;
492 FF second_low_leaf_hash = UnconstrainedPoseidon2::hash(second_low_leaf.get_hash_inputs());
493 public_data_tree.update_element(second_low_leaf_index, second_low_leaf_hash);
495 AppendOnlyTreeSnapshot prev_snapshot =
496 AppendOnlyTreeSnapshot{ .root = public_data_tree.root(), .next_available_leaf_index = 128 };
497 std::vector<FF> low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
501 updated_low_leaf.nextIndex = prev_snapshot.next_available_leaf_index;
502 updated_low_leaf.nextKey = leaf_slot;
503 FF updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
504 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
506 std::vector<FF> insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.next_available_leaf_index);
510 FF new_leaf_hash = UnconstrainedPoseidon2::hash(new_leaf.get_hash_inputs());
512 uint64_t value_to_be_updated_leaf_index = prev_snapshot.next_available_leaf_index;
513 public_data_tree.update_element(value_to_be_updated_leaf_index, new_leaf_hash);
515 AppendOnlyTreeSnapshot next_snapshot =
516 AppendOnlyTreeSnapshot{ .root = public_data_tree.root(),
517 .next_available_leaf_index = prev_snapshot.next_available_leaf_index + 1 };
519 AppendOnlyTreeSnapshot snapshot_after_insertion = public_data_tree_check_simulator.write(
slot,
524 low_leaf_sibling_path,
526 insertion_sibling_path,
528 EXPECT_EQ(next_snapshot, snapshot_after_insertion);
532 prev_snapshot = snapshot_after_insertion;
535 low_leaf_hash = second_low_leaf_hash;
536 low_leaf_index = second_low_leaf_index;
537 low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
540 updated_low_leaf.nextIndex = prev_snapshot.next_available_leaf_index;
541 updated_low_leaf.nextKey = dummy_leaf_slot;
542 updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
543 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
544 insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.next_available_leaf_index);
548 new_leaf_hash = UnconstrainedPoseidon2::hash(new_leaf.get_hash_inputs());
550 uint64_t dummy_leaf_index = prev_snapshot.next_available_leaf_index;
551 public_data_tree.update_element(dummy_leaf_index, new_leaf_hash);
553 next_snapshot = AppendOnlyTreeSnapshot{ .root = public_data_tree.root(),
554 .next_available_leaf_index = prev_snapshot.next_available_leaf_index + 1 };
556 AppendOnlyTreeSnapshot snapshot_after_dummy_insertion =
557 public_data_tree_check_simulator.write(dummy_slot,
562 low_leaf_sibling_path,
564 insertion_sibling_path,
566 EXPECT_EQ(next_snapshot, snapshot_after_dummy_insertion);
570 low_leaf_index = value_to_be_updated_leaf_index;
571 prev_snapshot = snapshot_after_dummy_insertion;
574 low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
577 updated_low_leaf.leaf.
value = updated_value;
578 updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
579 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
580 insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.next_available_leaf_index);
583 next_snapshot = AppendOnlyTreeSnapshot{ .root = public_data_tree.root(),
584 .next_available_leaf_index = prev_snapshot.next_available_leaf_index };
585 AppendOnlyTreeSnapshot snapshot_after_update = public_data_tree_check_simulator.write(
slot,
590 low_leaf_sibling_path,
592 insertion_sibling_path,
594 EXPECT_EQ(next_snapshot, snapshot_after_update);
596 ASSERT_LE(test_public_inputs.accumulated_data_array_lengths.public_data_writes,
597 test_public_inputs.accumulated_data.public_data_writes.size());
599 std::vector<FF> written_slots;
600 std::ranges::transform(test_public_inputs.accumulated_data.public_data_writes,
602 [](
const PublicDataWrite&
write) { return write.leaf_slot; });
604 public_data_tree_check_simulator.generate_ff_gt_events_for_squashing(written_slots);
612 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
614 public_data_tree_read_builder.process(public_data_tree_check_event_emitter.dump_events(), trace);
616 check_relation<public_data_check>(trace);
617 check_relation<public_data_squash>(trace);
619 check_all_interactions<PublicDataTreeTraceBuilder>(trace);
622TEST(PublicDataTreeConstrainingTest, NegativeLowLeafValueUpdate)
625 TestTraceContainer
trace({
627 { C::public_data_check_write, 1 },
628 { C::public_data_check_leaf_not_exists, 0 },
629 { C::public_data_check_low_leaf_value, 27 },
630 { C::public_data_check_value, 28 },
631 { C::public_data_check_updated_low_leaf_value, 28 },
634 { C::public_data_check_write, 1 },
635 { C::public_data_check_leaf_not_exists, 1 },
636 { C::public_data_check_low_leaf_value, 27 },
637 { C::public_data_check_value, 28 },
638 { C::public_data_check_updated_low_leaf_value, 27 },
645 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
648 "LOW_LEAF_VALUE_UPDATE");
650 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
652 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
655 "LOW_LEAF_VALUE_UPDATE");
658TEST(PublicDataTreeConstrainingTest, NegativeLowLeafNextIndexUpdate)
662 TestTraceContainer
trace({
664 { C::public_data_check_write, 1 },
665 { C::public_data_check_leaf_not_exists, 0 },
666 { C::public_data_check_low_leaf_next_index, 27 },
667 { C::public_data_check_tree_size_before_write, 128 },
668 { C::public_data_check_updated_low_leaf_next_index, 27 },
671 { C::public_data_check_write, 1 },
672 { C::public_data_check_leaf_not_exists, 1 },
673 { C::public_data_check_low_leaf_next_index, 27 },
674 { C::public_data_check_tree_size_before_write, 128 },
675 { C::public_data_check_updated_low_leaf_next_index, 128 },
682 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
686 "LOW_LEAF_NEXT_INDEX_UPDATE");
688 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
690 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
694 "LOW_LEAF_NEXT_INDEX_UPDATE");
697TEST(PublicDataTreeConstrainingTest, NegativeLowLeafNextSlotUpdate)
701 TestTraceContainer
trace({
703 { C::public_data_check_write, 1 },
704 { C::public_data_check_leaf_not_exists, 0 },
705 { C::public_data_check_low_leaf_next_slot, 27 },
706 { C::public_data_check_leaf_slot, 28 },
707 { C::public_data_check_updated_low_leaf_next_slot, 27 },
710 { C::public_data_check_write, 1 },
711 { C::public_data_check_leaf_not_exists, 1 },
712 { C::public_data_check_low_leaf_next_slot, 27 },
713 { C::public_data_check_leaf_slot, 28 },
714 { C::public_data_check_updated_low_leaf_next_slot, 28 },
721 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
724 "LOW_LEAF_NEXT_SLOT_UPDATE");
726 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
728 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
731 "LOW_LEAF_NEXT_SLOT_UPDATE");
734TEST(PublicDataTreeConstrainingTest, NegativeUpdateRootValidation)
737 TestTraceContainer
trace({
739 { C::public_data_check_write, 1 },
740 { C::public_data_check_leaf_not_exists, 0 },
741 { C::public_data_check_intermediate_root, 28 },
742 { C::public_data_check_write_root, 28 },
745 { C::public_data_check_write, 1 },
746 { C::public_data_check_leaf_not_exists, 1 },
747 { C::public_data_check_intermediate_root, 28 },
748 { C::public_data_check_write_root, 30 },
755 trace.
set(C::public_data_check_write_root, 0, 30);
758 "UPDATE_ROOT_VALIDATION");
761TEST(PublicDataTreeConstrainingTest, NegativeSetProtocolWrite)
764 TestTraceContainer
trace({ {
765 { C::public_data_check_sel, 1 },
766 { C::public_data_check_write, 1 },
767 { C::public_data_check_protocol_write, 1 },
773 trace.
set(C::public_data_check_protocol_write, 0, 0);
776 "PROTOCOL_WRITE_CHECK");
778 trace.
set(C::public_data_check_non_protocol_write, 0, 1);
782 trace.
set(C::public_data_check_protocol_write, 0, 1);
784 "PROTOCOL_WRITE_CHECK");
787TEST(PublicDataTreeConstrainingTest, NegativeWriteIdxInitialValue)
791 TestTraceContainer
trace(
793 { C::public_data_check_sel, 0 },
796 { C::public_data_check_sel, 1 },
803 trace.
set(C::public_data_check_write_idx, 1, 27);
806 "WRITE_IDX_INITIAL_VALUE");
809TEST(PublicDataTreeConstrainingTest, NegativeWriteIdxIncrement)
812 TestTraceContainer
trace({
814 { C::public_data_check_not_end, 1 },
815 { C::public_data_check_write_idx, 5 },
816 { C::public_data_check_should_write_to_public_inputs, 1 },
819 { C::public_data_check_not_end, 1 },
820 { C::public_data_check_write_idx, 6 },
821 { C::public_data_check_should_write_to_public_inputs, 0 },
824 { C::public_data_check_write_idx, 6 },
831 trace.
set(C::public_data_check_should_write_to_public_inputs, 0, 0);
834 "WRITE_IDX_INCREMENT");
837 trace.
set(C::public_data_check_should_write_to_public_inputs, 0, 1);
838 trace.
set(C::public_data_check_should_write_to_public_inputs, 1, 1);
841 "WRITE_IDX_INCREMENT");
845TEST(PublicDataTreeConstrainingTest, NegativeClockDiffDecomposition)
848 TestTraceContainer
trace({
850 { C::public_data_check_not_end, 1 },
851 { C::public_data_check_clk, 12 << 28 },
852 { C::public_data_check_clk_diff_lo, 234 },
853 { C::public_data_check_clk_diff_hi, 1 << 12 },
856 { C::public_data_check_clk, (13 << 28) + 234 },
863 trace.
set(C::public_data_check_clk_diff_lo, 0,
trace.
get(C::public_data_check_clk_diff_lo, 0) + 1);
869 trace.
set(C::public_data_check_clk_diff_lo, 0,
trace.
get(C::public_data_check_clk_diff_lo, 0) - 1);
872 trace.
set(C::public_data_check_clk_diff_hi, 0,
trace.
get(C::public_data_check_clk_diff_hi, 0) + 1);
879TEST(PublicDataTreeConstrainingTest, NegativeOutOfRangeClockDiff)
881 TestTraceContainer
trace({
883 { C::public_data_check_not_end, 1 },
884 { C::public_data_check_clk_diff_lo, UINT16_MAX },
885 { C::public_data_check_clk_diff_hi, UINT16_MAX },
889 PrecomputedTraceBuilder precomputed_trace_builder;
890 precomputed_trace_builder.process_sel_range_16(trace);
891 precomputed_trace_builder.process_misc(trace, 1 << 16);
898 trace.
set(C::public_data_check_clk_diff_lo, 0, UINT16_MAX + 1);
901 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_check_clk_diff_range_lo_settings>(trace)),
902 "Failed.*LOOKUP_PUBLIC_DATA_CHECK_CLK_DIFF_RANGE_LO. Could not find tuple in destination.");
905 trace.
set(C::public_data_check_clk_diff_hi, 0, UINT16_MAX + 1);
908 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_check_clk_diff_range_hi_settings>(trace)),
909 "Failed.*LOOKUP_PUBLIC_DATA_CHECK_CLK_DIFF_RANGE_HI. Could not find tuple in destination.");
914TEST(PublicDataTreeConstrainingTest, SquashingNegativeStartCondition)
917 TestTraceContainer
trace({ {
918 { C::public_data_squash_sel, 0 },
919 { C::precomputed_first_row, 1 },
922 { C::public_data_squash_sel, 1 },
925 { C::public_data_squash_sel, 1 },
931 trace.
set(C::precomputed_first_row, 0, 0);
937TEST(PublicDataTreeConstrainingTest, SquashingNegativeCheckSameLeafSlot)
940 TestTraceContainer
trace({ {
941 { C::public_data_squash_sel, 1 },
942 { C::public_data_squash_leaf_slot_increase, 1 },
943 { C::public_data_squash_leaf_slot, 27 },
946 { C::public_data_squash_sel, 1 },
947 { C::public_data_squash_leaf_slot_increase, 0 },
948 { C::public_data_squash_leaf_slot, 40 },
954 trace.
set(C::public_data_squash_leaf_slot_increase, 0, 0);
957 "CHECK_SAME_LEAF_SLOT");
960TEST(PublicDataTreeConstrainingTest, SquashingNegativeFinalValuePropagation)
963 TestTraceContainer
trace({ {
964 { C::public_data_squash_sel, 1 },
965 { C::public_data_squash_check_clock, 1 },
966 { C::public_data_squash_final_value, 27 },
969 { C::public_data_squash_sel, 1 },
970 { C::public_data_squash_check_clock, 0 },
971 { C::public_data_squash_final_value, 27 },
977 trace.
set(C::public_data_squash_final_value, 1, 28);
980 "FINAL_VALUE_PROPAGATION");
983TEST(PublicDataTreeConstrainingTest, SquashingNegativeFinalValueCheck)
987 TestTraceContainer
trace({ {
988 { C::public_data_squash_sel, 1 },
989 { C::public_data_squash_final_value, 27 },
990 { C::public_data_squash_value, 99 },
993 { C::public_data_squash_sel, 1 },
994 { C::public_data_squash_final_value, 27 },
995 { C::public_data_squash_leaf_slot_increase, 1 },
996 { C::public_data_squash_value, 27 },
999 { C::public_data_squash_sel, 1 },
1000 { C::public_data_squash_final_value, 42 },
1001 { C::public_data_squash_value, 42 },
1007 trace.
set(C::public_data_squash_value, 2, 99);
1010 "FINAL_VALUE_CHECK");
1012 trace.
set(C::public_data_squash_value, 2, 42);
1015 trace.
set(C::public_data_squash_value, 1, 99);
1018 "FINAL_VALUE_CHECK");
1019 trace.
set(C::public_data_squash_value, 1, 27);
1022TEST(PublicDataTreeConstrainingTest, SquashingNegativeLeafSlotIncrease)
1026 TestTraceContainer
trace({ {
1027 { C::public_data_squash_leaf_slot_increase, 1 },
1029 { C::public_data_squash_sel, 1 },
1032 { C::public_data_squash_leaf_slot_increase, 0 },
1033 { C::public_data_squash_leaf_slot,
FF::modulus - 1 },
1034 { C::public_data_squash_sel, 1 },
1040 { C::ff_gt_sel_gt, 1 },
1043 { C::ff_gt_result, 1 },
1048 { C::ff_gt_sel_gt, 1 },
1051 { C::ff_gt_result, 0 },
1056 { C::ff_gt_sel_gt, 1 },
1059 { C::ff_gt_result, 0 },
1062 check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_leaf_slot_increase_ff_gt_settings>(trace);
1068 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_leaf_slot_increase_ff_gt_settings>(
1070 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_LEAF_SLOT_INCREASE_FF_GT. Could not find tuple in destination.");
1076 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_leaf_slot_increase_ff_gt_settings>(
1078 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_LEAF_SLOT_INCREASE_FF_GT. Could not find tuple in destination.");
1081TEST(PublicDataTreeConstrainingTest, SquashingNegativeClockDecomposition)
1084 TestTraceContainer
trace({
1086 { C::public_data_squash_sel, 1 },
1087 { C::public_data_squash_check_clock, 1 },
1088 { C::public_data_squash_clk, 1 << 25 },
1089 { C::public_data_squash_clk_diff_lo, 37 },
1090 { C::public_data_squash_clk_diff_hi, 12 },
1093 { C::public_data_squash_sel, 1 },
1094 { C::public_data_squash_clk, (1 << 25) + (12 << 16) + 37 },
1101 trace.
set(C::public_data_squash_clk_diff_lo, 0,
trace.
get(C::public_data_squash_clk_diff_lo, 0) + 1);
1107 trace.
set(C::public_data_squash_clk_diff_lo, 0,
trace.
get(C::public_data_squash_clk_diff_lo, 0) - 1);
1110 trace.
set(C::public_data_squash_clk_diff_hi, 0,
trace.
get(C::public_data_squash_clk_diff_hi, 0) + 1);
1117TEST(PublicDataTreeConstrainingTest, SquashingNegativeOutOfRangeClockDiff)
1119 TestTraceContainer
trace({
1121 { C::public_data_squash_sel, 1 },
1122 { C::public_data_squash_check_clock, 1 },
1123 { C::public_data_squash_clk, 1 << 25 },
1124 { C::public_data_squash_clk_diff_lo, UINT16_MAX },
1125 { C::public_data_squash_clk_diff_hi, UINT16_MAX },
1129 PrecomputedTraceBuilder precomputed_trace_builder;
1130 precomputed_trace_builder.process_sel_range_16(trace);
1131 precomputed_trace_builder.process_misc(trace, 1 << 16);
1138 trace.
set(C::public_data_squash_clk_diff_lo, 0, UINT16_MAX + 1);
1141 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_clk_diff_range_lo_settings>(trace)),
1142 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_CLK_DIFF_RANGE_LO. Could not find tuple in destination.");
1145 trace.
set(C::public_data_squash_clk_diff_hi, 0, UINT16_MAX + 1);
1148 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_clk_diff_range_hi_settings>(trace)),
1149 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_CLK_DIFF_RANGE_HI. Could not find tuple in destination.");
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
#define AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_PUBLIC_DATA_WRITES_ROW_IDX
#define PUBLIC_DATA_TREE_HEIGHT
StrictMock< MockGreaterThan > mock_gt
EventEmitter< Poseidon2PermutationMemoryEvent > perm_mem_event_emitter
EventEmitter< Poseidon2PermutationEvent > perm_event_emitter
EventEmitter< Poseidon2HashEvent > hash_event_emitter
Poseidon2TraceBuilder poseidon2_builder
FieldGreaterThan field_gt
EventEmitter< simulation::RangeCheckEvent > range_check_emitter
static constexpr size_t SR_CLK_DIFF_DECOMP
static constexpr size_t SR_START_CONDITION
static constexpr size_t SR_LOW_LEAF_NEXT_INDEX_UPDATE
static constexpr size_t SR_VALUE_IS_CORRECT
static constexpr size_t SR_EXISTS_FLAG_CHECK
static constexpr size_t SR_NEXT_SLOT_IS_ZERO_CHECK
static constexpr size_t SR_LOW_LEAF_VALUE_UPDATE
static constexpr size_t SR_PROTOCOL_WRITE_CHECK
static constexpr size_t SR_WRITE_IDX_INITIAL_VALUE
static constexpr size_t SR_UPDATE_ROOT_VALIDATION
static constexpr size_t SR_WRITE_IDX_INCREMENT
static constexpr size_t SR_LOW_LEAF_NEXT_SLOT_UPDATE
static constexpr size_t SR_CLK_DIFF_DECOMP
static constexpr size_t SR_START_CONDITION
static constexpr size_t SR_FINAL_VALUE_CHECK
static constexpr size_t SR_CHECK_SAME_LEAF_SLOT
static constexpr size_t SR_FINAL_VALUE_PROPAGATION
void process(const simulation::EventEmitterInterface< simulation::FieldGreaterThanEvent >::Container &events, TraceContainer &trace)
Processes FieldGreaterThanEvent events and generates trace rows for the ff_gt gadget.
void process_hash(const simulation::EventEmitterInterface< simulation::Poseidon2HashEvent >::Container &hash_events, TraceContainer &trace)
Processes the hash events for the Poseidon2 hash function. It populates the columns for the poseidon2...
void process_misc(TraceContainer &trace, const uint32_t num_rows=PRECOMPUTED_TRACE_SIZE)
void process_sel_range_16(TraceContainer &trace)
void process(const simulation::EventEmitterInterface< simulation::RangeCheckEvent >::Container &events, TraceContainer &trace)
Processes range check events and populates the trace with decomposed value columns.
const FF & get(Column col, uint32_t row) const
void set(Column col, uint32_t row, const FF &value)
Native Poseidon2 hash function implementation.
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
RangeCheckTraceBuilder range_check_builder
PrecomputedTraceBuilder precomputed_builder
FieldGreaterThanTraceBuilder field_gt_builder
ExecutionIdManager execution_id_manager
IndexedTreeLeafData low_leaf
TEST_P(AvmRecursiveTestsParameterized, TwoLayerAvmRecursion)
A test of the Two Layer AVM recursive verifier.
INSTANTIATE_TEST_SUITE_P(PaddingVariants, AvmRecursiveTestsParameterized, ::testing::Values(false, true), [](const auto &info) { return info.param ? "Padded" :"Unpadded";})
void check_interaction(tracegen::TestTraceContainer &trace)
TEST(AvmFixedVKTests, FixedVKCommitments)
Test that the fixed VK commitments agree with the ones computed from precomputed columns.
TEST_F(AvmRecursiveTests, TwoLayerAvmRecursionFailsWithWrongPIs)
std::variant< PublicDataTreeReadWriteEvent, CheckPointEventType > PublicDataTreeCheckEvent
IndexedLeaf< PublicDataLeafValue > PublicDataTreeLeafPreimage
FF unconstrained_root_from_path(const FF &leaf_value, const uint64_t leaf_index, std::span< const FF > path)
::bb::crypto::merkle_tree::PublicDataLeafValue PublicDataLeafValue
FF unconstrained_compute_leaf_slot(const AztecAddress &contract_address, const FF &slot)
lookup_settings< lookup_public_data_check_clk_diff_range_lo_settings_ > lookup_public_data_check_clk_diff_range_lo_settings
lookup_settings< lookup_public_data_squash_clk_diff_range_lo_settings_ > lookup_public_data_squash_clk_diff_range_lo_settings
lookup_settings< lookup_public_data_squash_clk_diff_range_hi_settings_ > lookup_public_data_squash_clk_diff_range_hi_settings
lookup_settings< lookup_public_data_check_clk_diff_range_hi_settings_ > lookup_public_data_check_clk_diff_range_hi_settings
void write(B &buf, field2< base_field, Params > const &value)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
NoopEventEmitter< FieldGreaterThanEvent > field_gt_event_emitter
std::vector< FF > get_hash_inputs() const
static constexpr field neg_one()
static constexpr uint256_t modulus
static constexpr uint256_t modulus_minus_two
tracegen::PublicInputsTraceBuilder public_inputs_builder