1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
43using ::testing::NiceMock;
45using testing::TestMemoryTree;
47using simulation::DeduplicatingEventEmitter;
48using simulation::EventEmitter;
49using simulation::ExecutionIdManager;
50using simulation::FieldGreaterThan;
51using simulation::FieldGreaterThanEvent;
52using simulation::MerkleCheck;
53using simulation::MerkleCheckEvent;
54using simulation::MockGreaterThan;
55using simulation::Poseidon2;
56using simulation::Poseidon2HashEvent;
57using simulation::Poseidon2PermutationEvent;
58using simulation::Poseidon2PermutationMemoryEvent;
59using simulation::PublicDataTreeCheck;
62using simulation::RangeCheck;
63using simulation::RangeCheckEvent;
67using tracegen::ExecutionTraceBuilder;
68using tracegen::FieldGreaterThanTraceBuilder;
69using tracegen::MerkleCheckTraceBuilder;
70using tracegen::Poseidon2TraceBuilder;
71using tracegen::PrecomputedTraceBuilder;
72using tracegen::PublicDataTreeTraceBuilder;
73using tracegen::PublicInputsTraceBuilder;
74using tracegen::RangeCheckTraceBuilder;
75using tracegen::TestTraceContainer;
85class PublicDataTreeCheckConstrainingTest :
public ::testing::Test {
87 PublicDataTreeCheckConstrainingTest()
97 Poseidon2(execution_id_manager, mock_gt, hash_event_emitter, perm_event_emitter, perm_mem_event_emitter);
125class PublicDataReadPositiveTests :
public PublicDataTreeCheckConstrainingTest,
126 public ::testing::WithParamInterface<TestParams> {};
128TEST_P(PublicDataReadPositiveTests, Positive)
130 const auto& param = GetParam();
132 auto test_public_inputs = testing::PublicInputsBuilder().build();
134 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
143 EventEmitter<PublicDataTreeCheckEvent> public_data_tree_check_event_emitter;
144 PublicDataTreeCheck public_data_tree_check_simulator(
147 TestTraceContainer
trace({ { { C::precomputed_first_row, 1 } } });
150 MerkleCheckTraceBuilder merkle_check_builder;
154 PublicDataTreeTraceBuilder public_data_tree_read_builder;
157 uint64_t leaf_index = 30;
158 std::vector<FF> sibling_path;
159 sibling_path.reserve(PUBLIC_DATA_TREE_HEIGHT);
160 for (
size_t i = 0; i < PUBLIC_DATA_TREE_HEIGHT; ++i) {
161 sibling_path.emplace_back(i);
165 public_data_tree_check_simulator.assert_read(param.slot,
171 AppendOnlyTreeSnapshot{
173 .next_available_leaf_index = 128,
182 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
184 public_data_tree_read_builder.process(public_data_tree_check_event_emitter.dump_events(), trace);
186 check_all_interactions<PublicDataTreeTraceBuilder>(trace);
188 check_relation<public_data_check>(trace);
189 check_relation<public_data_squash>(trace);
193 PublicDataReadPositiveTests,
194 ::testing::ValuesIn(positive_tests));
196TEST(PublicDataTreeConstrainingTest, NegativeStartCondition)
199 TestTraceContainer
trace({ {
200 { C::public_data_check_sel, 0 },
201 { C::precomputed_first_row, 1 },
204 { C::public_data_check_sel, 1 },
207 { C::public_data_check_sel, 1 },
213 trace.
set(C::precomputed_first_row, 0, 0);
219TEST(PublicDataTreeConstrainingTest, NegativeExistsFlagCheck)
223 TestTraceContainer
trace({
224 { { C::public_data_check_sel, 1 },
225 { C::public_data_check_leaf_slot, 27 },
226 { C::public_data_check_low_leaf_slot, 27 },
227 { C::public_data_check_leaf_slot_low_leaf_slot_diff_inv, 0 },
228 { C::public_data_check_leaf_not_exists, 0 } },
229 { { C::public_data_check_sel, 1 },
230 { C::public_data_check_leaf_slot, 28 },
231 { C::public_data_check_low_leaf_slot, 27 },
232 { C::public_data_check_leaf_slot_low_leaf_slot_diff_inv,
FF(1).invert() },
233 { C::public_data_check_leaf_not_exists, 1 } },
238 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
243 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
244 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
250TEST(PublicDataTreeConstrainingTest, NegativeNextSlotIsZero)
254 TestTraceContainer
trace({
256 { C::public_data_check_leaf_not_exists, 1 },
257 { C::public_data_check_low_leaf_next_slot, 0 },
258 { C::public_data_check_next_slot_inv, 0 },
259 { C::public_data_check_next_slot_is_nonzero, 0 },
262 { C::public_data_check_leaf_not_exists, 1 },
263 { C::public_data_check_low_leaf_next_slot, 1 },
264 { C::public_data_check_next_slot_inv,
FF(1).invert() },
265 { C::public_data_check_next_slot_is_nonzero, 1 },
271 trace.
set(C::public_data_check_next_slot_is_nonzero, 0, 1);
276 trace.
set(C::public_data_check_next_slot_is_nonzero, 0, 0);
277 trace.
set(C::public_data_check_next_slot_is_nonzero, 1, 0);
283TEST(PublicDataTreeConstrainingTest, NegativeValueIsCorrect)
287 TestTraceContainer
trace({
289 { C::public_data_check_low_leaf_value, 27 },
290 { C::public_data_check_leaf_not_exists, 0 },
291 { C::public_data_check_value, 27 },
294 { C::public_data_check_low_leaf_value, 27 },
295 { C::public_data_check_leaf_not_exists, 1 },
296 { C::public_data_check_value, 0 },
303 trace.
set(C::public_data_check_value, 0, 0);
308 trace.
set(C::public_data_check_value, 0, 27);
310 trace.
set(C::public_data_check_value, 1, 27);
316TEST_F(PublicDataTreeCheckConstrainingTest, PositiveWriteExists)
321 TestMemoryTree<aztec::PublicDataMerkleHashPolicy> public_data_tree(8, PUBLIC_DATA_TREE_HEIGHT);
323 AvmAccumulatedData accumulated_data = {};
324 accumulated_data.public_data_writes[0] = PublicDataWrite{
325 .leaf_slot = leaf_slot,
329 auto test_public_inputs = testing::PublicInputsBuilder()
330 .set_accumulated_data(accumulated_data)
331 .set_accumulated_data_array_lengths({ .public_data_writes = 1 })
334 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
343 EventEmitter<PublicDataTreeCheckEvent> public_data_tree_check_event_emitter;
344 PublicDataTreeCheck public_data_tree_check_simulator(
347 TestTraceContainer
trace({ { { C::precomputed_first_row, 1 } } });
350 MerkleCheckTraceBuilder merkle_check_builder;
354 PublicDataTreeTraceBuilder public_data_tree_builder;
358 uint64_t low_leaf_index = 30;
359 public_data_tree.update_element(low_leaf_index, low_leaf_hash);
361 AppendOnlyTreeSnapshot prev_snapshot =
362 AppendOnlyTreeSnapshot{ .root = public_data_tree.root(), .next_available_leaf_index = 128 };
363 std::vector<FF> low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
366 updated_low_leaf.leaf.
value = new_value;
367 FF updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
368 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
370 FF intermediate_root = public_data_tree.root();
371 std::vector<FF> insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.next_available_leaf_index);
374 AppendOnlyTreeSnapshot next_snapshot =
375 AppendOnlyTreeSnapshot{ .root = intermediate_root,
376 .next_available_leaf_index = prev_snapshot.next_available_leaf_index };
378 AppendOnlyTreeSnapshot result_snapshot = public_data_tree_check_simulator.write(
slot,
383 low_leaf_sibling_path,
385 insertion_sibling_path,
387 EXPECT_EQ(next_snapshot, result_snapshot);
395 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
397 public_data_tree_builder.process(public_data_tree_check_event_emitter.dump_events(), trace);
399 check_relation<public_data_check>(trace);
400 check_relation<public_data_squash>(trace);
402 check_all_interactions<PublicDataTreeTraceBuilder>(trace);
405TEST_F(PublicDataTreeCheckConstrainingTest, PositiveSquashing)
428 leaf_slot = leaf_slot_a;
429 dummy_leaf_slot = leaf_slot_b;
433 leaf_slot = leaf_slot_b;
434 dummy_leaf_slot = leaf_slot_a;
438 FF updated_value = 28;
439 FF dummy_leaf_value = 0;
443 ASSERT_GT(dummy_leaf_slot, leaf_slot + 1);
445 FF low_leaf_slot = 40;
446 TestMemoryTree<aztec::PublicDataMerkleHashPolicy> public_data_tree(8, PUBLIC_DATA_TREE_HEIGHT);
448 AvmAccumulatedData accumulated_data = {};
449 accumulated_data.public_data_writes[0] = PublicDataWrite{
450 .leaf_slot = leaf_slot,
451 .value = updated_value,
454 accumulated_data.public_data_writes[1] = PublicDataWrite{
455 .leaf_slot = dummy_leaf_slot,
456 .value = dummy_leaf_value,
459 auto test_public_inputs = testing::PublicInputsBuilder()
460 .set_accumulated_data(accumulated_data)
461 .set_accumulated_data_array_lengths({ .public_data_writes = 2 })
464 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
473 EventEmitter<PublicDataTreeCheckEvent> public_data_tree_check_event_emitter;
474 PublicDataTreeCheck public_data_tree_check_simulator(
477 TestTraceContainer
trace({ { { C::precomputed_first_row, 1 } } });
480 MerkleCheckTraceBuilder merkle_check_builder;
484 PublicDataTreeTraceBuilder public_data_tree_read_builder;
489 uint64_t low_leaf_index = 30;
490 public_data_tree.update_element(low_leaf_index, low_leaf_hash);
492 uint64_t second_low_leaf_index = 31;
493 FF second_low_leaf_slot = leaf_slot + 1;
497 FF second_low_leaf_hash = UnconstrainedPoseidon2::hash(second_low_leaf.get_hash_inputs());
498 public_data_tree.update_element(second_low_leaf_index, second_low_leaf_hash);
500 AppendOnlyTreeSnapshot prev_snapshot =
501 AppendOnlyTreeSnapshot{ .root = public_data_tree.root(), .next_available_leaf_index = 128 };
502 std::vector<FF> low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
506 updated_low_leaf.nextIndex = prev_snapshot.next_available_leaf_index;
507 updated_low_leaf.nextKey = leaf_slot;
508 FF updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
509 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
511 std::vector<FF> insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.next_available_leaf_index);
515 FF new_leaf_hash = UnconstrainedPoseidon2::hash(new_leaf.get_hash_inputs());
517 uint64_t value_to_be_updated_leaf_index = prev_snapshot.next_available_leaf_index;
518 public_data_tree.update_element(value_to_be_updated_leaf_index, new_leaf_hash);
520 AppendOnlyTreeSnapshot next_snapshot =
521 AppendOnlyTreeSnapshot{ .root = public_data_tree.root(),
522 .next_available_leaf_index = prev_snapshot.next_available_leaf_index + 1 };
524 AppendOnlyTreeSnapshot snapshot_after_insertion = public_data_tree_check_simulator.write(
slot,
529 low_leaf_sibling_path,
531 insertion_sibling_path,
533 EXPECT_EQ(next_snapshot, snapshot_after_insertion);
537 prev_snapshot = snapshot_after_insertion;
540 low_leaf_hash = second_low_leaf_hash;
541 low_leaf_index = second_low_leaf_index;
542 low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
545 updated_low_leaf.nextIndex = prev_snapshot.next_available_leaf_index;
546 updated_low_leaf.nextKey = dummy_leaf_slot;
547 updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
548 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
549 insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.next_available_leaf_index);
553 new_leaf_hash = UnconstrainedPoseidon2::hash(new_leaf.get_hash_inputs());
555 uint64_t dummy_leaf_index = prev_snapshot.next_available_leaf_index;
556 public_data_tree.update_element(dummy_leaf_index, new_leaf_hash);
558 next_snapshot = AppendOnlyTreeSnapshot{ .root = public_data_tree.root(),
559 .next_available_leaf_index = prev_snapshot.next_available_leaf_index + 1 };
561 AppendOnlyTreeSnapshot snapshot_after_dummy_insertion =
562 public_data_tree_check_simulator.write(dummy_slot,
567 low_leaf_sibling_path,
569 insertion_sibling_path,
571 EXPECT_EQ(next_snapshot, snapshot_after_dummy_insertion);
575 low_leaf_index = value_to_be_updated_leaf_index;
576 prev_snapshot = snapshot_after_dummy_insertion;
579 low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
582 updated_low_leaf.leaf.
value = updated_value;
583 updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
584 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
585 insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.next_available_leaf_index);
588 next_snapshot = AppendOnlyTreeSnapshot{ .root = public_data_tree.root(),
589 .next_available_leaf_index = prev_snapshot.next_available_leaf_index };
590 AppendOnlyTreeSnapshot snapshot_after_update = public_data_tree_check_simulator.write(
slot,
595 low_leaf_sibling_path,
597 insertion_sibling_path,
599 EXPECT_EQ(next_snapshot, snapshot_after_update);
601 ASSERT_LE(test_public_inputs.accumulated_data_array_lengths.public_data_writes,
602 test_public_inputs.accumulated_data.public_data_writes.size());
604 std::vector<FF> written_slots;
605 std::ranges::transform(test_public_inputs.accumulated_data.public_data_writes,
607 [](
const PublicDataWrite&
write) { return write.leaf_slot; });
609 public_data_tree_check_simulator.generate_ff_gt_events_for_squashing(written_slots);
617 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
619 public_data_tree_read_builder.process(public_data_tree_check_event_emitter.dump_events(), trace);
621 check_relation<public_data_check>(trace);
622 check_relation<public_data_squash>(trace);
624 check_all_interactions<PublicDataTreeTraceBuilder>(trace);
627TEST(PublicDataTreeConstrainingTest, NegativeLowLeafValueUpdate)
630 TestTraceContainer
trace({
632 { C::public_data_check_write, 1 },
633 { C::public_data_check_leaf_not_exists, 0 },
634 { C::public_data_check_low_leaf_value, 27 },
635 { C::public_data_check_value, 28 },
636 { C::public_data_check_updated_low_leaf_value, 28 },
639 { C::public_data_check_write, 1 },
640 { C::public_data_check_leaf_not_exists, 1 },
641 { C::public_data_check_low_leaf_value, 27 },
642 { C::public_data_check_value, 28 },
643 { C::public_data_check_updated_low_leaf_value, 27 },
650 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
655 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
657 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
663TEST(PublicDataTreeConstrainingTest, NegativeLowLeafNextIndexUpdate)
667 TestTraceContainer
trace({
669 { C::public_data_check_write, 1 },
670 { C::public_data_check_leaf_not_exists, 0 },
671 { C::public_data_check_low_leaf_next_index, 27 },
672 { C::public_data_check_tree_size_before_write, 128 },
673 { C::public_data_check_updated_low_leaf_next_index, 27 },
676 { C::public_data_check_write, 1 },
677 { C::public_data_check_leaf_not_exists, 1 },
678 { C::public_data_check_low_leaf_next_index, 27 },
679 { C::public_data_check_tree_size_before_write, 128 },
680 { C::public_data_check_updated_low_leaf_next_index, 128 },
687 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
693 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
695 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
702TEST(PublicDataTreeConstrainingTest, NegativeLowLeafNextSlotUpdate)
706 TestTraceContainer
trace({
708 { C::public_data_check_write, 1 },
709 { C::public_data_check_leaf_not_exists, 0 },
710 { C::public_data_check_low_leaf_next_slot, 27 },
711 { C::public_data_check_leaf_slot, 28 },
712 { C::public_data_check_updated_low_leaf_next_slot, 27 },
715 { C::public_data_check_write, 1 },
716 { C::public_data_check_leaf_not_exists, 1 },
717 { C::public_data_check_low_leaf_next_slot, 27 },
718 { C::public_data_check_leaf_slot, 28 },
719 { C::public_data_check_updated_low_leaf_next_slot, 28 },
726 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
732 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
734 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
741TEST(PublicDataTreeConstrainingTest, NegativeUpdateRootValidation)
744 TestTraceContainer
trace({
746 { C::public_data_check_write, 1 },
747 { C::public_data_check_leaf_not_exists, 0 },
748 { C::public_data_check_intermediate_root, 28 },
749 { C::public_data_check_write_root, 28 },
752 { C::public_data_check_write, 1 },
753 { C::public_data_check_leaf_not_exists, 1 },
754 { C::public_data_check_intermediate_root, 28 },
755 { C::public_data_check_write_root, 30 },
762 trace.
set(C::public_data_check_write_root, 0, 30);
768TEST(PublicDataTreeConstrainingTest, NegativeSetProtocolWrite)
771 TestTraceContainer
trace({ {
772 { C::public_data_check_sel, 1 },
773 { C::public_data_check_write, 1 },
774 { C::public_data_check_protocol_write, 1 },
780 trace.
set(C::public_data_check_protocol_write, 0, 0);
785 trace.
set(C::public_data_check_non_protocol_write, 0, 1);
789 trace.
set(C::public_data_check_protocol_write, 0, 1);
796TEST(PublicDataTreeConstrainingTest, NegativeReadInteractionRequiresWriteZero)
803 TestTraceContainer
trace({
806 { C::execution_sel_execute_sload, 1 },
807 { C::execution_register_0_,
slot },
808 { C::execution_register_1_,
address },
809 { C::execution_register_2_,
value },
810 { C::execution_prev_public_data_tree_root, root },
814 { C::public_data_check_sel, 1 },
815 { C::public_data_check_slot,
slot },
816 { C::public_data_check_address,
address },
817 { C::public_data_check_value,
value },
818 { C::public_data_check_root, root },
819 { C::public_data_check_write, 0 },
823 check_interaction<ExecutionTraceBuilder, lookup_sload_storage_read_settings>(trace);
826 trace.
set(C::public_data_check_write, 1, 1);
829 "Failed.*LOOKUP_SLOAD_STORAGE_READ. Could not find tuple in destination.");
835TEST(PublicDataTreeConstrainingTest, NegativeWriteInteractionRequiresWriteOne)
840 FF root_before = 100;
842 FF size_before = 128;
846 TestTraceContainer
trace({
849 { C::execution_sel_write_public_data, 1 },
850 { C::execution_register_0_,
value },
851 { C::execution_contract_address,
address },
852 { C::execution_register_1_,
slot },
853 { C::execution_discard, 0 },
854 { C::execution_prev_public_data_tree_root, root_before },
855 { C::execution_public_data_tree_root, root_after },
856 { C::execution_prev_public_data_tree_size, size_before },
857 { C::execution_public_data_tree_size, size_after },
858 { C::execution_clk, clk },
862 { C::public_data_check_sel, 1 },
863 { C::public_data_check_write, 1 },
864 { C::public_data_check_non_protocol_write, 1 },
865 { C::public_data_check_value,
value },
866 { C::public_data_check_address,
address },
867 { C::public_data_check_slot,
slot },
868 { C::public_data_check_discard, 0 },
869 { C::public_data_check_root, root_before },
870 { C::public_data_check_write_root, root_after },
871 { C::public_data_check_tree_size_before_write, size_before },
872 { C::public_data_check_tree_size_after_write, size_after },
873 { C::public_data_check_clk, clk },
883 trace.
set(C::public_data_check_write, 1, 0);
888 "Failed setting selectors for PERM_SSTORE_STORAGE_WRITE");
891TEST(PublicDataTreeConstrainingTest, NegativeWriteIdxInitialValue)
895 TestTraceContainer
trace(
897 { C::public_data_check_sel, 0 },
900 { C::public_data_check_sel, 1 },
901 { C::public_data_check_write_idx, AVM_PUBLIC_INPUTS_AVM_ACCUMULATED_DATA_PUBLIC_DATA_WRITES_ROW_IDX },
907 trace.
set(C::public_data_check_write_idx, 1, 27);
913TEST(PublicDataTreeConstrainingTest, NegativeWriteIdxIncrement)
916 TestTraceContainer
trace({
918 { C::public_data_check_not_end, 1 },
919 { C::public_data_check_write_idx, 5 },
920 { C::public_data_check_sel_write_to_public_inputs, 1 },
923 { C::public_data_check_not_end, 1 },
924 { C::public_data_check_write_idx, 6 },
925 { C::public_data_check_sel_write_to_public_inputs, 0 },
928 { C::public_data_check_write_idx, 6 },
935 trace.
set(C::public_data_check_sel_write_to_public_inputs, 0, 0);
941 trace.
set(C::public_data_check_sel_write_to_public_inputs, 0, 1);
942 trace.
set(C::public_data_check_sel_write_to_public_inputs, 1, 1);
949TEST(PublicDataTreeConstrainingTest, NegativeClockDiffDecomposition)
952 TestTraceContainer
trace({
954 { C::public_data_check_not_end, 1 },
955 { C::public_data_check_clk, 12 << 28 },
956 { C::public_data_check_clk_diff_lo, 234 },
957 { C::public_data_check_clk_diff_hi, 1 << 12 },
960 { C::public_data_check_clk, (13 << 28) + 234 },
967 trace.
set(C::public_data_check_clk_diff_lo, 0,
trace.
get(C::public_data_check_clk_diff_lo, 0) + 1);
973 trace.
set(C::public_data_check_clk_diff_lo, 0,
trace.
get(C::public_data_check_clk_diff_lo, 0) - 1);
976 trace.
set(C::public_data_check_clk_diff_hi, 0,
trace.
get(C::public_data_check_clk_diff_hi, 0) + 1);
983TEST(PublicDataTreeConstrainingTest, NegativeOutOfRangeClockDiff)
985 TestTraceContainer
trace({
987 { C::public_data_check_not_end, 1 },
988 { C::public_data_check_clk_diff_lo, UINT16_MAX },
989 { C::public_data_check_clk_diff_hi, UINT16_MAX },
993 PrecomputedTraceBuilder precomputed_trace_builder;
994 precomputed_trace_builder.process_sel_range_16(trace);
995 precomputed_trace_builder.process_misc(trace, 1 << 16);
1002 trace.
set(C::public_data_check_clk_diff_lo, 0, UINT16_MAX + 1);
1005 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_check_clk_diff_range_lo_settings>(trace)),
1006 "Failed.*LOOKUP_PUBLIC_DATA_CHECK_CLK_DIFF_RANGE_LO. Could not find tuple in destination.");
1009 trace.
set(C::public_data_check_clk_diff_hi, 0, UINT16_MAX + 1);
1012 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_check_clk_diff_range_hi_settings>(trace)),
1013 "Failed.*LOOKUP_PUBLIC_DATA_CHECK_CLK_DIFF_RANGE_HI. Could not find tuple in destination.");
1018TEST(PublicDataTreeConstrainingTest, SquashingNegativeStartCondition)
1021 TestTraceContainer
trace({ {
1022 { C::public_data_squash_sel, 0 },
1023 { C::precomputed_first_row, 1 },
1026 { C::public_data_squash_sel, 1 },
1029 { C::public_data_squash_sel, 1 },
1035 trace.
set(C::precomputed_first_row, 0, 0);
1041TEST(PublicDataTreeConstrainingTest, SquashingNegativeCheckClockCondition)
1048 TestTraceContainer
trace({ {
1049 { C::public_data_squash_sel, 1 },
1050 { C::public_data_squash_check_clock, 1 },
1051 { C::public_data_squash_leaf_slot_increase, 0 },
1054 { C::public_data_squash_sel, 1 },
1055 { C::public_data_squash_check_clock, 0 },
1056 { C::public_data_squash_leaf_slot_increase, 0 },
1062 trace.
set(C::public_data_squash_check_clock, 0, 0);
1067 trace.
set(C::public_data_squash_check_clock, 0, 1);
1070 trace.
set(C::public_data_squash_leaf_slot_increase, 0, 1);
1075 trace.
set(C::public_data_squash_leaf_slot_increase, 0, 0);
1078 trace.
set(C::public_data_squash_sel, 1, 0);
1084TEST(PublicDataTreeConstrainingTest, SquashingNegativeCheckSameLeafSlot)
1087 TestTraceContainer
trace({ {
1088 { C::public_data_squash_check_clock, 0 },
1089 { C::public_data_squash_leaf_slot, 27 },
1092 { C::public_data_squash_check_clock, 0 },
1093 { C::public_data_squash_leaf_slot, 40 },
1099 trace.
set(C::public_data_squash_check_clock, 0, 1);
1105TEST(PublicDataTreeConstrainingTest, SquashingNegativeFinalValuePropagation)
1108 TestTraceContainer
trace({ {
1109 { C::public_data_squash_sel, 1 },
1110 { C::public_data_squash_check_clock, 1 },
1111 { C::public_data_squash_final_value, 27 },
1114 { C::public_data_squash_sel, 1 },
1115 { C::public_data_squash_check_clock, 0 },
1116 { C::public_data_squash_final_value, 27 },
1122 trace.
set(C::public_data_squash_final_value, 1, 28);
1129TEST(PublicDataTreeConstrainingTest, SquashingNegativeFinalValueCheck)
1133 TestTraceContainer
trace({ {
1134 { C::public_data_squash_sel, 1 },
1135 { C::public_data_squash_final_value, 27 },
1136 { C::public_data_squash_value, 99 },
1139 { C::public_data_squash_sel, 1 },
1140 { C::public_data_squash_final_value, 27 },
1141 { C::public_data_squash_leaf_slot_increase, 1 },
1142 { C::public_data_squash_value, 27 },
1145 { C::public_data_squash_sel, 1 },
1146 { C::public_data_squash_final_value, 42 },
1147 { C::public_data_squash_value, 42 },
1153 trace.
set(C::public_data_squash_value, 2, 99);
1158 trace.
set(C::public_data_squash_value, 2, 42);
1161 trace.
set(C::public_data_squash_value, 1, 99);
1165 trace.
set(C::public_data_squash_value, 1, 27);
1168TEST(PublicDataTreeConstrainingTest, SquashingNegativeLeafSlotIncrease)
1172 TestTraceContainer
trace({ {
1173 { C::public_data_squash_leaf_slot_increase, 1 },
1175 { C::public_data_squash_sel, 1 },
1178 { C::public_data_squash_leaf_slot_increase, 0 },
1179 { C::public_data_squash_leaf_slot,
FF::modulus - 1 },
1180 { C::public_data_squash_sel, 1 },
1186 { C::ff_gt_sel_gt, 1 },
1189 { C::ff_gt_result, 1 },
1194 { C::ff_gt_sel_gt, 1 },
1197 { C::ff_gt_result, 0 },
1202 { C::ff_gt_sel_gt, 1 },
1205 { C::ff_gt_result, 0 },
1208 check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_leaf_slot_increase_ff_gt_settings>(trace);
1214 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_leaf_slot_increase_ff_gt_settings>(
1216 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_LEAF_SLOT_INCREASE_FF_GT. Could not find tuple in destination.");
1222 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_leaf_slot_increase_ff_gt_settings>(
1224 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_LEAF_SLOT_INCREASE_FF_GT. Could not find tuple in destination.");
1227TEST(PublicDataTreeConstrainingTest, SquashingNegativeClockDecomposition)
1230 TestTraceContainer
trace({
1232 { C::public_data_squash_sel, 1 },
1233 { C::public_data_squash_check_clock, 1 },
1234 { C::public_data_squash_clk, 1 << 25 },
1235 { C::public_data_squash_clk_diff_lo, 37 },
1236 { C::public_data_squash_clk_diff_hi, 12 },
1239 { C::public_data_squash_sel, 1 },
1240 { C::public_data_squash_clk, (1 << 25) + (12 << 16) + 38 },
1247 trace.
set(C::public_data_squash_clk_diff_lo, 0,
trace.
get(C::public_data_squash_clk_diff_lo, 0) + 1);
1253 trace.
set(C::public_data_squash_clk_diff_lo, 0,
trace.
get(C::public_data_squash_clk_diff_lo, 0) - 1);
1256 trace.
set(C::public_data_squash_clk_diff_hi, 0,
trace.
get(C::public_data_squash_clk_diff_hi, 0) + 1);
1263TEST(PublicDataTreeConstrainingTest, SquashingNegativeOutOfRangeClockDiff)
1265 TestTraceContainer
trace({
1267 { C::public_data_squash_sel, 1 },
1268 { C::public_data_squash_check_clock, 1 },
1269 { C::public_data_squash_clk, 1 << 25 },
1270 { C::public_data_squash_clk_diff_lo, UINT16_MAX },
1271 { C::public_data_squash_clk_diff_hi, UINT16_MAX },
1275 PrecomputedTraceBuilder precomputed_trace_builder;
1276 precomputed_trace_builder.process_sel_range_16(trace);
1277 precomputed_trace_builder.process_misc(trace, 1 << 16);
1284 trace.
set(C::public_data_squash_clk_diff_lo, 0, UINT16_MAX + 1);
1287 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_clk_diff_range_lo_settings>(trace)),
1288 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_CLK_DIFF_RANGE_LO. Could not find tuple in destination.");
1291 trace.
set(C::public_data_squash_clk_diff_hi, 0, UINT16_MAX + 1);
1294 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_clk_diff_range_hi_settings>(trace)),
1295 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_CLK_DIFF_RANGE_HI. Could not find tuple in destination.");
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
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
INSTANTIATE_TEST_SUITE_P(All, KernelIOTamperingTests, testing::Values(KernelIOField::PAIRING_INPUTS, KernelIOField::ACCUMULATOR_HASH, KernelIOField::KERNEL_RETURN_DATA, KernelIOField::APP_RETURN_DATA, KernelIOField::ECC_OP_HASH), [](const testing::TestParamInfo< KernelIOField > &info) { switch(info.param) { case KernelIOField::PAIRING_INPUTS:return "PairingInputs";case KernelIOField::ACCUMULATOR_HASH:return "AccumulatorHash";case KernelIOField::KERNEL_RETURN_DATA:return "KernelReturnData";case KernelIOField::APP_RETURN_DATA:return "AppReturnData";case KernelIOField::ECC_OP_HASH:return "EccOpHash";} return "Unknown";})
TEST_P(KernelIOTamperingTests, CausesVerificationFailure)
static constexpr size_t SR_CLK_DIFF_DECOMP
static std::string get_subrelation_label(size_t index)
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_TRACE_CONTINUITY
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 std::string get_subrelation_label(size_t index)
static constexpr size_t SR_CLK_DIFF_DECOMP
static constexpr size_t SR_CHECK_CLOCK_CONDITION
static constexpr size_t SR_TRACE_CONTINUITY
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)
Populate miscellaneous precomputed columns: first_row selector and idx (row index).
void process_sel_range_16(TraceContainer &trace)
Generate a selector column that activates the first 2^16 (65536) rows.
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, bool use_atomic_limbs=false)
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_F(AvmRecursiveTests, TwoLayerAvmRecursion)
A test of the Two Layer AVM recursive verifier.
void check_multipermutation_interaction(tracegen::TestTraceContainer &trace)
void check_interaction(tracegen::TestTraceContainer &trace)
TEST(AvmFixedVKTests, FixedVKCommitments)
Test that the fixed VK commitments agree with the ones computed from precomputed columns.
std::variant< PublicDataTreeReadWriteEvent, CheckPointEventType > PublicDataTreeCheckEvent
IndexedLeaf< PublicDataLeafValue > PublicDataTreeLeafPreimage
::bb::crypto::merkle_tree::PublicDataLeafValue PublicDataLeafValue
FF unconstrained_root_from_path(uint64_t domain_separator, const FF &leaf_value, const uint64_t leaf_index, std::span< const FF > path)
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
permutation_settings< perm_tx_balance_update_settings_ > perm_tx_balance_update_settings
lookup_settings< lookup_public_data_squash_clk_diff_range_lo_settings_ > lookup_public_data_squash_clk_diff_range_lo_settings
permutation_settings< perm_sstore_storage_write_settings_ > perm_sstore_storage_write_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)
::testing::Types< TestParam< curve::BN254, 9 >, TestParam< curve::BN254, CHONK_MAX_NUM_CIRCUITS >, TestParam< stdlib::bn254< MegaCircuitBuilder >, 9 >, TestParam< stdlib::bn254< MegaCircuitBuilder >, CHONK_MAX_NUM_CIRCUITS > > TestParams
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