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;
130 MerkleCheck merkle_check(
poseidon2, merkle_event_emitter);
132 EventEmitter<RangeCheckEvent> range_check_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 .nextAvailableLeafIndex = 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.publicDataWrites[0] = PublicDataWrite{
320 .leafSlot = leaf_slot,
324 auto test_public_inputs = testing::PublicInputsBuilder()
325 .set_accumulated_data(accumulated_data)
326 .set_accumulated_data_array_lengths({ .publicDataWrites = 1 })
329 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
330 MerkleCheck merkle_check(
poseidon2, merkle_event_emitter);
332 EventEmitter<RangeCheckEvent> range_check_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(), .nextAvailableLeafIndex = 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.nextAvailableLeafIndex);
369 AppendOnlyTreeSnapshot next_snapshot =
370 AppendOnlyTreeSnapshot{ .root = intermediate_root,
371 .nextAvailableLeafIndex = prev_snapshot.nextAvailableLeafIndex };
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)
410 FF updated_value = 28;
414 FF dummy_leaf_value = 0;
418 ASSERT_GT(dummy_leaf_slot, leaf_slot + 1);
420 FF low_leaf_slot = 40;
423 AvmAccumulatedData accumulated_data = {};
424 accumulated_data.publicDataWrites[0] = PublicDataWrite{
425 .leafSlot = leaf_slot,
426 .value = updated_value,
429 accumulated_data.publicDataWrites[1] = PublicDataWrite{
430 .leafSlot = dummy_leaf_slot,
431 .value = dummy_leaf_value,
434 auto test_public_inputs = testing::PublicInputsBuilder()
435 .set_accumulated_data(accumulated_data)
436 .set_accumulated_data_array_lengths({ .publicDataWrites = 2 })
439 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
440 MerkleCheck merkle_check(
poseidon2, merkle_event_emitter);
442 EventEmitter<RangeCheckEvent> range_check_emitter;
448 EventEmitter<PublicDataTreeCheckEvent> public_data_tree_check_event_emitter;
449 PublicDataTreeCheck public_data_tree_check_simulator(
452 TestTraceContainer
trace({ { { C::precomputed_first_row, 1 } } });
455 MerkleCheckTraceBuilder merkle_check_builder;
459 PublicDataTreeTraceBuilder public_data_tree_read_builder;
464 uint64_t low_leaf_index = 30;
465 public_data_tree.update_element(low_leaf_index, low_leaf_hash);
467 uint64_t second_low_leaf_index = 31;
468 FF second_low_leaf_slot = leaf_slot + 1;
472 FF second_low_leaf_hash = UnconstrainedPoseidon2::hash(second_low_leaf.get_hash_inputs());
473 public_data_tree.update_element(second_low_leaf_index, second_low_leaf_hash);
475 AppendOnlyTreeSnapshot prev_snapshot =
476 AppendOnlyTreeSnapshot{ .root = public_data_tree.root(), .nextAvailableLeafIndex = 128 };
477 std::vector<FF> low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
481 updated_low_leaf.
nextIndex = prev_snapshot.nextAvailableLeafIndex;
482 updated_low_leaf.nextKey = leaf_slot;
483 FF updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
484 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
486 std::vector<FF> insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.nextAvailableLeafIndex);
490 FF new_leaf_hash = UnconstrainedPoseidon2::hash(new_leaf.get_hash_inputs());
492 uint64_t value_to_be_updated_leaf_index = prev_snapshot.nextAvailableLeafIndex;
493 public_data_tree.update_element(value_to_be_updated_leaf_index, new_leaf_hash);
495 AppendOnlyTreeSnapshot next_snapshot =
496 AppendOnlyTreeSnapshot{ .root = public_data_tree.root(),
497 .nextAvailableLeafIndex = prev_snapshot.nextAvailableLeafIndex + 1 };
499 AppendOnlyTreeSnapshot snapshot_after_insertion = public_data_tree_check_simulator.write(
slot,
504 low_leaf_sibling_path,
506 insertion_sibling_path,
508 EXPECT_EQ(next_snapshot, snapshot_after_insertion);
512 prev_snapshot = snapshot_after_insertion;
515 low_leaf_hash = second_low_leaf_hash;
516 low_leaf_index = second_low_leaf_index;
517 low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
520 updated_low_leaf.
nextIndex = prev_snapshot.nextAvailableLeafIndex;
521 updated_low_leaf.nextKey = dummy_leaf_slot;
522 updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
523 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
524 insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.nextAvailableLeafIndex);
528 new_leaf_hash = UnconstrainedPoseidon2::hash(new_leaf.get_hash_inputs());
530 uint64_t dummy_leaf_index = prev_snapshot.nextAvailableLeafIndex;
531 public_data_tree.update_element(dummy_leaf_index, new_leaf_hash);
533 next_snapshot = AppendOnlyTreeSnapshot{ .root = public_data_tree.root(),
534 .nextAvailableLeafIndex = prev_snapshot.nextAvailableLeafIndex + 1 };
536 AppendOnlyTreeSnapshot snapshot_after_dummy_insertion =
537 public_data_tree_check_simulator.write(dummy_slot,
542 low_leaf_sibling_path,
544 insertion_sibling_path,
546 EXPECT_EQ(next_snapshot, snapshot_after_dummy_insertion);
550 low_leaf_index = value_to_be_updated_leaf_index;
551 prev_snapshot = snapshot_after_dummy_insertion;
554 low_leaf_sibling_path = public_data_tree.get_sibling_path(low_leaf_index);
557 updated_low_leaf.
leaf.value = updated_value;
558 updated_low_leaf_hash = UnconstrainedPoseidon2::hash(updated_low_leaf.get_hash_inputs());
559 public_data_tree.update_element(low_leaf_index, updated_low_leaf_hash);
560 insertion_sibling_path = public_data_tree.get_sibling_path(prev_snapshot.nextAvailableLeafIndex);
563 next_snapshot = AppendOnlyTreeSnapshot{ .root = public_data_tree.root(),
564 .nextAvailableLeafIndex = prev_snapshot.nextAvailableLeafIndex };
565 AppendOnlyTreeSnapshot snapshot_after_update = public_data_tree_check_simulator.write(
slot,
570 low_leaf_sibling_path,
572 insertion_sibling_path,
574 EXPECT_EQ(next_snapshot, snapshot_after_update);
576 ASSERT_LE(test_public_inputs.accumulatedDataArrayLengths.publicDataWrites,
577 test_public_inputs.accumulatedData.publicDataWrites.size());
579 const auto* public_data_writes_start = test_public_inputs.accumulatedData.publicDataWrites.begin();
581 public_data_writes_start,
582 public_data_writes_start + test_public_inputs.accumulatedDataArrayLengths.publicDataWrites);
584 public_data_tree_check_simulator.generate_ff_gt_events_for_squashing(public_data_writes);
592 merkle_check_builder.process(merkle_event_emitter.dump_events(),
trace);
594 public_data_tree_read_builder.process(public_data_tree_check_event_emitter.dump_events(),
trace);
596 check_relation<public_data_check>(
trace);
597 check_relation<public_data_squash>(
trace);
599 check_all_interactions<PublicDataTreeTraceBuilder>(
trace);
602TEST(PublicDataTreeConstrainingTest, NegativeLowLeafValueUpdate)
605 TestTraceContainer
trace({
607 { C::public_data_check_write, 1 },
608 { C::public_data_check_leaf_not_exists, 0 },
609 { C::public_data_check_low_leaf_value, 27 },
610 { C::public_data_check_value, 28 },
611 { C::public_data_check_updated_low_leaf_value, 28 },
614 { C::public_data_check_write, 1 },
615 { C::public_data_check_leaf_not_exists, 1 },
616 { C::public_data_check_low_leaf_value, 27 },
617 { C::public_data_check_value, 28 },
618 { C::public_data_check_updated_low_leaf_value, 27 },
625 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
628 "LOW_LEAF_VALUE_UPDATE");
630 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
632 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
635 "LOW_LEAF_VALUE_UPDATE");
638TEST(PublicDataTreeConstrainingTest, NegativeLowLeafNextIndexUpdate)
642 TestTraceContainer
trace({
644 { C::public_data_check_write, 1 },
645 { C::public_data_check_leaf_not_exists, 0 },
646 { C::public_data_check_low_leaf_next_index, 27 },
647 { C::public_data_check_tree_size_before_write, 128 },
648 { C::public_data_check_updated_low_leaf_next_index, 27 },
651 { C::public_data_check_write, 1 },
652 { C::public_data_check_leaf_not_exists, 1 },
653 { C::public_data_check_low_leaf_next_index, 27 },
654 { C::public_data_check_tree_size_before_write, 128 },
655 { C::public_data_check_updated_low_leaf_next_index, 128 },
662 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
666 "LOW_LEAF_NEXT_INDEX_UPDATE");
668 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
670 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
674 "LOW_LEAF_NEXT_INDEX_UPDATE");
677TEST(PublicDataTreeConstrainingTest, NegativeLowLeafNextSlotUpdate)
681 TestTraceContainer
trace({
683 { C::public_data_check_write, 1 },
684 { C::public_data_check_leaf_not_exists, 0 },
685 { C::public_data_check_low_leaf_next_slot, 27 },
686 { C::public_data_check_leaf_slot, 28 },
687 { C::public_data_check_updated_low_leaf_next_slot, 27 },
690 { C::public_data_check_write, 1 },
691 { C::public_data_check_leaf_not_exists, 1 },
692 { C::public_data_check_low_leaf_next_slot, 27 },
693 { C::public_data_check_leaf_slot, 28 },
694 { C::public_data_check_updated_low_leaf_next_slot, 28 },
701 trace.
set(C::public_data_check_leaf_not_exists, 0, 1);
704 "LOW_LEAF_NEXT_SLOT_UPDATE");
706 trace.
set(C::public_data_check_leaf_not_exists, 0, 0);
708 trace.
set(C::public_data_check_leaf_not_exists, 1, 0);
711 "LOW_LEAF_NEXT_SLOT_UPDATE");
714TEST(PublicDataTreeConstrainingTest, NegativeUpdateRootValidation)
717 TestTraceContainer
trace({
719 { C::public_data_check_write, 1 },
720 { C::public_data_check_leaf_not_exists, 0 },
721 { C::public_data_check_intermediate_root, 28 },
722 { C::public_data_check_write_root, 28 },
725 { C::public_data_check_write, 1 },
726 { C::public_data_check_leaf_not_exists, 1 },
727 { C::public_data_check_intermediate_root, 28 },
728 { C::public_data_check_write_root, 30 },
735 trace.
set(C::public_data_check_write_root, 0, 30);
738 "UPDATE_ROOT_VALIDATION");
741TEST(PublicDataTreeConstrainingTest, NegativeSetProtocolWrite)
744 TestTraceContainer
trace({ {
745 { C::public_data_check_sel, 1 },
746 { C::public_data_check_write, 1 },
747 { C::public_data_check_protocol_write, 1 },
753 trace.
set(C::public_data_check_protocol_write, 0, 0);
756 "PROTOCOL_WRITE_CHECK");
758 trace.
set(C::public_data_check_non_protocol_write, 0, 1);
762 trace.
set(C::public_data_check_protocol_write, 0, 1);
764 "PROTOCOL_WRITE_CHECK");
767TEST(PublicDataTreeConstrainingTest, NegativeWriteIdxInitialValue)
771 TestTraceContainer
trace(
773 { C::public_data_check_sel, 0 },
776 { C::public_data_check_sel, 1 },
783 trace.
set(C::public_data_check_write_idx, 1, 27);
786 "WRITE_IDX_INITIAL_VALUE");
789TEST(PublicDataTreeConstrainingTest, NegativeWriteIdxIncrement)
792 TestTraceContainer
trace({
794 { C::public_data_check_not_end, 1 },
795 { C::public_data_check_write_idx, 5 },
796 { C::public_data_check_should_write_to_public_inputs, 1 },
799 { C::public_data_check_not_end, 1 },
800 { C::public_data_check_write_idx, 6 },
801 { C::public_data_check_should_write_to_public_inputs, 0 },
804 { C::public_data_check_write_idx, 6 },
811 trace.
set(C::public_data_check_should_write_to_public_inputs, 0, 0);
814 "WRITE_IDX_INCREMENT");
817 trace.
set(C::public_data_check_should_write_to_public_inputs, 0, 1);
818 trace.
set(C::public_data_check_should_write_to_public_inputs, 1, 1);
821 "WRITE_IDX_INCREMENT");
825TEST(PublicDataTreeConstrainingTest, NegativeClockDiffDecomposition)
828 TestTraceContainer
trace({
830 { C::public_data_check_not_end, 1 },
831 { C::public_data_check_clk, 12 << 28 },
832 { C::public_data_check_clk_diff_lo, 234 },
833 { C::public_data_check_clk_diff_hi, 1 << 12 },
836 { C::public_data_check_clk, (13 << 28) + 234 },
843 trace.
set(C::public_data_check_clk_diff_lo, 0,
trace.
get(C::public_data_check_clk_diff_lo, 0) + 1);
849 trace.
set(C::public_data_check_clk_diff_lo, 0,
trace.
get(C::public_data_check_clk_diff_lo, 0) - 1);
852 trace.
set(C::public_data_check_clk_diff_hi, 0,
trace.
get(C::public_data_check_clk_diff_hi, 0) + 1);
859TEST(PublicDataTreeConstrainingTest, NegativeOutOfRangeClockDiff)
861 TestTraceContainer
trace({
863 { C::public_data_check_not_end, 1 },
864 { C::public_data_check_clk_diff_lo, UINT16_MAX },
865 { C::public_data_check_clk_diff_hi, UINT16_MAX },
869 PrecomputedTraceBuilder precomputed_trace_builder;
870 precomputed_trace_builder.process_sel_range_16(
trace);
871 precomputed_trace_builder.process_misc(
trace, 1 << 16);
878 trace.
set(C::public_data_check_clk_diff_lo, 0, UINT16_MAX + 1);
881 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_check_clk_diff_range_lo_settings>(
trace)),
882 "Failed.*LOOKUP_PUBLIC_DATA_CHECK_CLK_DIFF_RANGE_LO. Could not find tuple in destination.");
885 trace.
set(C::public_data_check_clk_diff_hi, 0, UINT16_MAX + 1);
888 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_check_clk_diff_range_hi_settings>(
trace)),
889 "Failed.*LOOKUP_PUBLIC_DATA_CHECK_CLK_DIFF_RANGE_HI. Could not find tuple in destination.");
894TEST(PublicDataTreeConstrainingTest, SquashingNegativeStartCondition)
897 TestTraceContainer
trace({ {
898 { C::public_data_squash_sel, 0 },
899 { C::precomputed_first_row, 1 },
902 { C::public_data_squash_sel, 1 },
905 { C::public_data_squash_sel, 1 },
911 trace.
set(C::precomputed_first_row, 0, 0);
917TEST(PublicDataTreeConstrainingTest, SquashingNegativeCheckSameLeafSlot)
920 TestTraceContainer
trace({ {
921 { C::public_data_squash_sel, 1 },
922 { C::public_data_squash_leaf_slot_increase, 1 },
923 { C::public_data_squash_leaf_slot, 27 },
926 { C::public_data_squash_sel, 1 },
927 { C::public_data_squash_leaf_slot_increase, 0 },
928 { C::public_data_squash_leaf_slot, 40 },
934 trace.
set(C::public_data_squash_leaf_slot_increase, 0, 0);
937 "CHECK_SAME_LEAF_SLOT");
940TEST(PublicDataTreeConstrainingTest, SquashingNegativeFinalValuePropagation)
943 TestTraceContainer
trace({ {
944 { C::public_data_squash_sel, 1 },
945 { C::public_data_squash_check_clock, 1 },
946 { C::public_data_squash_final_value, 27 },
949 { C::public_data_squash_sel, 1 },
950 { C::public_data_squash_check_clock, 0 },
951 { C::public_data_squash_final_value, 27 },
957 trace.
set(C::public_data_squash_final_value, 1, 28);
960 "FINAL_VALUE_PROPAGATION");
963TEST(PublicDataTreeConstrainingTest, SquashingNegativeFinalValueCheck)
967 TestTraceContainer
trace({ {
968 { C::public_data_squash_sel, 1 },
969 { C::public_data_squash_final_value, 27 },
970 { C::public_data_squash_value, 99 },
973 { C::public_data_squash_sel, 1 },
974 { C::public_data_squash_final_value, 27 },
975 { C::public_data_squash_leaf_slot_increase, 1 },
976 { C::public_data_squash_value, 27 },
979 { C::public_data_squash_sel, 1 },
980 { C::public_data_squash_final_value, 42 },
981 { C::public_data_squash_value, 42 },
987 trace.
set(C::public_data_squash_value, 2, 99);
990 "FINAL_VALUE_CHECK");
992 trace.
set(C::public_data_squash_value, 2, 42);
995 trace.
set(C::public_data_squash_value, 1, 99);
998 "FINAL_VALUE_CHECK");
999 trace.
set(C::public_data_squash_value, 1, 27);
1002TEST(PublicDataTreeConstrainingTest, SquashingNegativeLeafSlotIncrease)
1006 TestTraceContainer
trace({ {
1007 { C::public_data_squash_leaf_slot_increase, 1 },
1008 { C::public_data_squash_leaf_slot, FF::modulus_minus_two },
1009 { C::public_data_squash_sel, 1 },
1012 { C::public_data_squash_leaf_slot_increase, 0 },
1013 { C::public_data_squash_leaf_slot, FF::modulus - 1 },
1014 { C::public_data_squash_sel, 1 },
1020 { C::ff_gt_sel_gt, 1 },
1021 { C::ff_gt_a, FF::modulus - 1 },
1022 { C::ff_gt_b, FF::modulus_minus_two },
1023 { C::ff_gt_result, 1 },
1028 { C::ff_gt_sel_gt, 1 },
1029 { C::ff_gt_a, FF::modulus_minus_two },
1030 { C::ff_gt_b, FF::modulus_minus_two },
1031 { C::ff_gt_result, 0 },
1036 { C::ff_gt_sel_gt, 1 },
1037 { C::ff_gt_a, FF::modulus_minus_two },
1038 { C::ff_gt_b, FF::modulus - 3 },
1039 { C::ff_gt_result, 0 },
1042 check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_leaf_slot_increase_ff_gt_settings>(
trace);
1045 trace.
set(C::public_data_squash_leaf_slot, 1, FF::modulus_minus_two);
1048 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_leaf_slot_increase_ff_gt_settings>(
1050 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_LEAF_SLOT_INCREASE_FF_GT. Could not find tuple in destination.");
1053 trace.
set(C::public_data_squash_leaf_slot, 1, FF::modulus - 3);
1056 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_leaf_slot_increase_ff_gt_settings>(
1058 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_LEAF_SLOT_INCREASE_FF_GT. Could not find tuple in destination.");
1061TEST(PublicDataTreeConstrainingTest, SquashingNegativeClockDecomposition)
1064 TestTraceContainer
trace({
1066 { C::public_data_squash_sel, 1 },
1067 { C::public_data_squash_check_clock, 1 },
1068 { C::public_data_squash_clk, 1 << 25 },
1069 { C::public_data_squash_clk_diff_lo, 37 },
1070 { C::public_data_squash_clk_diff_hi, 12 },
1073 { C::public_data_squash_sel, 1 },
1074 { C::public_data_squash_clk, (1 << 25) + (12 << 16) + 37 },
1081 trace.
set(C::public_data_squash_clk_diff_lo, 0,
trace.
get(C::public_data_squash_clk_diff_lo, 0) + 1);
1087 trace.
set(C::public_data_squash_clk_diff_lo, 0,
trace.
get(C::public_data_squash_clk_diff_lo, 0) - 1);
1090 trace.
set(C::public_data_squash_clk_diff_hi, 0,
trace.
get(C::public_data_squash_clk_diff_hi, 0) + 1);
1097TEST(PublicDataTreeConstrainingTest, SquashingNegativeOutOfRangeClockDiff)
1099 TestTraceContainer
trace({
1101 { C::public_data_squash_sel, 1 },
1102 { C::public_data_squash_check_clock, 1 },
1103 { C::public_data_squash_clk, 1 << 25 },
1104 { C::public_data_squash_clk_diff_lo, UINT16_MAX },
1105 { C::public_data_squash_clk_diff_hi, UINT16_MAX },
1109 PrecomputedTraceBuilder precomputed_trace_builder;
1110 precomputed_trace_builder.process_sel_range_16(
trace);
1111 precomputed_trace_builder.process_misc(
trace, 1 << 16);
1118 trace.
set(C::public_data_squash_clk_diff_lo, 0, UINT16_MAX + 1);
1121 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_clk_diff_range_lo_settings>(
trace)),
1122 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_CLK_DIFF_RANGE_LO. Could not find tuple in destination.");
1125 trace.
set(C::public_data_squash_clk_diff_hi, 0, UINT16_MAX + 1);
1128 (check_interaction<PublicDataTreeTraceBuilder, lookup_public_data_squash_clk_diff_range_hi_settings>(
trace)),
1129 "Failed.*LOOKUP_PUBLIC_DATA_SQUASH_CLK_DIFF_RANGE_HI. Could not find tuple in destination.");
INSTANTIATE_TEST_SUITE_P(AcirTests, AcirIntegrationSingleTest, testing::Values("a_1327_concrete_in_generic", "a_1_mul", "a_2_div", "a_3_add", "a_4_sub", "a_5_over", "a_6", "a_6_array", "a_7", "a_7_function", "aes128_encrypt", "arithmetic_binary_operations", "array_dynamic", "array_dynamic_blackbox_input", "array_dynamic_main_output", "array_dynamic_nested_blackbox_input", "array_eq", "array_if_cond_simple", "array_len", "array_neq", "array_sort", "array_to_slice", "array_to_slice_constant_length", "assert", "assert_statement", "assign_ex", "bigint", "bit_and", "bit_not", "bit_shifts_comptime", "bit_shifts_runtime", "blake3", "bool_not", "bool_or", "break_and_continue", "brillig_acir_as_brillig", "brillig_array_eq", "brillig_array_to_slice", "brillig_arrays", "brillig_assert", "brillig_bit_shifts_runtime", "brillig_blake2s", "brillig_blake3", "brillig_calls", "brillig_calls_array", "brillig_calls_conditionals", "brillig_conditional", "brillig_cow", "brillig_cow_assign", "brillig_cow_regression", "brillig_ecdsa_secp256k1", "brillig_ecdsa_secp256r1", "brillig_embedded_curve", "brillig_fns_as_values", "brillig_hash_to_field", "brillig_identity_function", "brillig_keccak", "brillig_loop", "brillig_nested_arrays", "brillig_not", "brillig_oracle", "brillig_pedersen", "brillig_recursion", "brillig_references", "brillig_schnorr", "brillig_sha256", "brillig_signed_cmp", "brillig_signed_div", "brillig_slices", "brillig_to_be_bytes", "brillig_to_bits", "brillig_to_bytes_integration", "brillig_to_le_bytes", "brillig_top_level", "brillig_uninitialized_arrays", "brillig_wrapping", "cast_bool", "closures_mut_ref", "conditional_1", "conditional_2", "conditional_regression_421", "conditional_regression_547", "conditional_regression_661", "conditional_regression_short_circuit", "conditional_regression_underflow", "custom_entry", "databus", "debug_logs", "diamond_deps_0", "double_verify_nested_proof", "double_verify_proof", "ecdsa_secp256k1", "ecdsa_secp256r1", "ecdsa_secp256r1_3x", "eddsa", "embedded_curve_ops", "field_attribute", "generics", "global_consts", "hash_to_field", "hashmap", "higher_order_functions", "if_else_chain", "import", "inline_never_basic", "integer_array_indexing", "keccak256", "main_bool_arg", "main_return", "merkle_insert", "missing_closure_env", "modules", "modules_more", "modulus", "nested_array_dynamic", "nested_array_dynamic_simple", "nested_array_in_slice", "nested_arrays_from_brillig", "no_predicates_basic", "no_predicates_brillig", "no_predicates_numeric_generic_poseidon", "operator_overloading", "pedersen_check", "pedersen_commitment", "pedersen_hash", "poseidon_bn254_hash", "poseidonsponge_x5_254", "pred_eq", "prelude", "references", "regression", "regression_2660", "regression_3051", "regression_3394", "regression_3607", "regression_3889", "regression_4088", "regression_4124", "regression_4202", "regression_4449", "regression_4709", "regression_5045", "regression_capacity_tracker", "regression_mem_op_predicate", "regression_method_cannot_be_found", "regression_struct_array_conditional", "schnorr", "sha256", "sha2_byte", "side_effects_constrain_array", "signed_arithmetic", "signed_comparison", "signed_division", "simple_2d_array", "simple_add_and_ret_arr", "simple_array_param", "simple_bitwise", "simple_comparison", "simple_mut", "simple_not", "simple_print", "simple_program_addition", "simple_radix", "simple_shield", "simple_shift_left_right", "slice_coercion", "slice_dynamic_index", "slice_loop", "slices", "strings", "struct", "struct_array_inputs", "struct_fields_ordering", "struct_inputs", "submodules", "to_be_bytes", "to_bytes_consistent", "to_bytes_integration", "to_le_bytes", "trait_as_return_type", "trait_impl_base_type", "traits_in_crates_1", "traits_in_crates_2", "tuple_inputs", "tuples", "type_aliases", "u128", "u16_support", "unconstrained_empty", "unit_value", "unsafe_range_constraint", "witness_compression", "xor"))
TEST_P(AcirIntegrationSingleTest, DISABLED_ProveAndVerifyProgram)
#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
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)
void process_hash(const simulation::EventEmitterInterface< simulation::Poseidon2HashEvent >::Container &hash_events, TraceContainer &trace)
void process_misc(TraceContainer &trace, const uint32_t num_rows=MAX_AVM_TRACE_SIZE)
void process_sel_range_16(TraceContainer &trace)
void process(const simulation::EventEmitterInterface< simulation::RangeCheckEvent >::Container &events, TraceContainer &trace)
const FF & get(Column col, uint32_t row) const
void set(Column col, uint32_t row, const FF &value)
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
Implements a parallelized batch insertion indexed tree Accepts template argument of the type of store...
RangeCheckTraceBuilder range_check_builder
PrecomputedTraceBuilder precomputed_builder
FieldGreaterThanTraceBuilder field_gt_builder
ExecutionIdManager execution_id_manager
NullifierTreeLeafPreimage low_leaf
AztecAddress contract_address
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
TEST_F(AvmRecursiveTests, GoblinRecursion)
A test of the Goblinized AVM recursive verifier.
void check_interaction(tracegen::TestTraceContainer &trace)
TEST(TxExecutionConstrainingTest, WriteTreeValue)
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
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
FieldGreaterThan field_gt
NoopEventEmitter< FieldGreaterThanEvent > field_gt_event_emitter
std::vector< fr > get_hash_inputs() const
tracegen::PublicInputsTraceBuilder public_inputs_builder