Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
indexed_tree_check_trace.test.cpp
Go to the documentation of this file.
2
3#include <cstdint>
4#include <gmock/gmock.h>
5#include <gtest/gtest.h>
6
29
30namespace bb::avm2::tracegen {
31namespace {
32
33using ::testing::NiceMock;
34
35using testing::TestMemoryTree;
36
37using simulation::DeduplicatingEventEmitter;
38using simulation::EventEmitter;
39using simulation::ExecutionIdManager;
40using simulation::FieldGreaterThan;
41using simulation::FieldGreaterThanEvent;
42using simulation::IndexedTreeCheck;
44using simulation::IndexedTreeLeafData;
45using simulation::IndexedTreeSiloingParameters;
46using simulation::MerkleCheck;
47using simulation::MerkleCheckEvent;
48using simulation::MockGreaterThan;
49using simulation::MockRangeCheck;
50using simulation::Poseidon2;
51using simulation::Poseidon2HashEvent;
52using simulation::Poseidon2PermutationEvent;
53using simulation::Poseidon2PermutationMemoryEvent;
55
57
59using C = Column;
61
62constexpr size_t TREE_HEIGHT = 8;
63
64class IndexedTreeCheckTracegenTest : public ::testing::Test {
65 protected:
66 IndexedTreeCheckTracegenTest()
68
69 EventEmitter<Poseidon2HashEvent> hash_event_emitter;
70 EventEmitter<Poseidon2PermutationEvent> perm_event_emitter;
71 EventEmitter<Poseidon2PermutationMemoryEvent> perm_mem_event_emitter;
72
73 ExecutionIdManager execution_id_manager;
74 NiceMock<MockGreaterThan> mock_gt;
76 Poseidon2(execution_id_manager, mock_gt, hash_event_emitter, perm_event_emitter, perm_mem_event_emitter);
77};
78
79struct TestParams {
81 bool exists;
82 IndexedTreeLeafData low_leaf;
83};
84
85std::vector<TestParams> positive_read_tests = {
86 // Exists = true, leaf points to infinity
87 TestParams{ .value = 42, .exists = true, .low_leaf = { .value = 42, .next_value = 0, .next_index = 0 } },
88 // Exists = true, leaf points to higher value
89 TestParams{ .value = 42, .exists = true, .low_leaf = { .value = 42, .next_value = 50, .next_index = 28 } },
90 // Exists = false, low leaf points to infinity
91 TestParams{ .value = 42, .exists = false, .low_leaf = { .value = 10, .next_value = 0, .next_index = 0 } },
92 // Exists = false, low leaf points to higher value
93 TestParams{ .value = 42, .exists = false, .low_leaf = { .value = 10, .next_value = 50, .next_index = 28 } }
94};
95
96class ReadInteractionsTests : public IndexedTreeCheckTracegenTest, public ::testing::WithParamInterface<TestParams> {};
97
98TEST_P(ReadInteractionsTests, PositiveWithInteractions)
99{
100 const auto& param = GetParam();
101
102 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
103 MerkleCheck merkle_check(poseidon2, merkle_event_emitter);
104
105 NiceMock<MockRangeCheck> range_check;
106
107 DeduplicatingEventEmitter<FieldGreaterThanEvent> field_gt_event_emitter;
108 FieldGreaterThan field_gt(range_check, field_gt_event_emitter);
109
110 EventEmitter<IndexedTreeCheckEvent> indexed_tree_check_event_emitter;
111 IndexedTreeCheck indexed_tree_check(
113
114 TestTraceContainer trace({ { { C::precomputed_first_row, 1 } } });
115 Poseidon2TraceBuilder poseidon2_builder;
116 MerkleCheckTraceBuilder merkle_check_builder;
117 FieldGreaterThanTraceBuilder field_gt_builder;
118 IndexedTreeCheckTraceBuilder indexed_tree_check_builder;
119
120 FF low_leaf_hash = poseidon2.hash(param.low_leaf.get_hash_inputs());
121 uint64_t leaf_index = 30;
122 std::vector<FF> sibling_path;
123 sibling_path.reserve(TREE_HEIGHT);
124 for (size_t i = 0; i < TREE_HEIGHT; ++i) {
125 sibling_path.emplace_back(i);
126 }
127 FF root = unconstrained_root_from_path(DOM_SEP__NULLIFIER_MERKLE, low_leaf_hash, leaf_index, sibling_path);
128
129 indexed_tree_check.assert_read(param.value,
131 param.exists,
132 param.low_leaf,
133 leaf_index,
134 sibling_path,
135 AppendOnlyTreeSnapshot{ .root = root });
136
138 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
139 field_gt_builder.process(field_gt_event_emitter.dump_events(), trace);
141
142 check_interaction<IndexedTreeCheckTraceBuilder,
151}
152
153INSTANTIATE_TEST_SUITE_P(IndexedTreeCheckTracegenTest, ReadInteractionsTests, ::testing::ValuesIn(positive_read_tests));
154
155TEST_F(IndexedTreeCheckTracegenTest, WriteWithInteractions)
156{
157 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
158 MerkleCheck merkle_check(poseidon2, merkle_event_emitter);
159
160 NiceMock<MockRangeCheck> range_check;
161
162 DeduplicatingEventEmitter<FieldGreaterThanEvent> field_gt_event_emitter;
163 FieldGreaterThan field_gt(range_check, field_gt_event_emitter);
164
165 EventEmitter<IndexedTreeCheckEvent> indexed_tree_check_event_emitter;
166 IndexedTreeCheck indexed_tree_check(
168
169 TestTraceContainer trace({ { { C::precomputed_first_row, 1 } } });
170 Poseidon2TraceBuilder poseidon2_builder;
171 MerkleCheckTraceBuilder merkle_check_builder;
172 FieldGreaterThanTraceBuilder field_gt_builder;
173 IndexedTreeCheckTraceBuilder indexed_tree_check_builder;
174
175 AztecAddress contract_address = AztecAddress(1);
176 FF value = 100;
177 FF siloing_separator = 42;
178 FF siloed_value = RawPoseidon2::hash({ siloing_separator, contract_address, value });
179 FF low_value = 40;
180 TestMemoryTree<aztec::NullifierMerkleHashPolicy> tree(8, TREE_HEIGHT);
181
182 IndexedTreeLeafData low_leaf = { .value = low_value, .next_value = siloed_value + 1, .next_index = 10 };
183 FF low_leaf_hash = RawPoseidon2::hash(low_leaf.get_hash_inputs());
184 uint64_t low_leaf_index = 0;
185 tree.update_element(low_leaf_index, low_leaf_hash);
186
187 AppendOnlyTreeSnapshot prev_snapshot =
188 AppendOnlyTreeSnapshot{ .root = tree.root(), .next_available_leaf_index = 128 };
189 std::vector<FF> low_leaf_sibling_path = tree.get_sibling_path(low_leaf_index);
190
191 IndexedTreeLeafData updated_low_leaf = low_leaf;
192 updated_low_leaf.next_index = prev_snapshot.next_available_leaf_index;
193 updated_low_leaf.next_value = siloed_value;
194 FF updated_low_leaf_hash = RawPoseidon2::hash(updated_low_leaf.get_hash_inputs());
195 tree.update_element(low_leaf_index, updated_low_leaf_hash);
196
197 std::vector<FF> insertion_sibling_path = tree.get_sibling_path(prev_snapshot.next_available_leaf_index);
198
199 IndexedTreeLeafData new_leaf = { .value = siloed_value,
200 .next_value = low_leaf.next_value,
201 .next_index = low_leaf.next_index };
202 FF new_leaf_hash = RawPoseidon2::hash(new_leaf.get_hash_inputs());
203 tree.update_element(prev_snapshot.next_available_leaf_index, new_leaf_hash);
204
205 IndexedTreeSiloingParameters siloing_params = {
206 .address = contract_address,
207 .siloing_separator = siloing_separator,
208 };
209
211 siloing_params,
212 0,
213 low_leaf,
214 low_leaf_index,
215 low_leaf_sibling_path,
216 prev_snapshot,
217 insertion_sibling_path);
218
220 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
221 field_gt_builder.process(field_gt_event_emitter.dump_events(), trace);
223
224 // Not checking all interactions due to the public inputs interaction, which needs to be checked in an e2e test
225 check_interaction<IndexedTreeCheckTraceBuilder,
234}
235
236} // namespace
237} // namespace bb::avm2::tracegen
#define DOM_SEP__NULLIFIER_MERKLE
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
IndexedTreeCheckTraceBuilder indexed_tree_check_builder
MerkleCheck merkle_check
IndexedTreeCheck indexed_tree_check
EventEmitter< simulation::IndexedTreeCheckEvent > indexed_tree_check_event_emitter
RangeCheck range_check
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)
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(const simulation::EventEmitterInterface< simulation::IndexedTreeCheckEvent >::Container &events, TraceContainer &trace)
Process generic indexed tree check events and populate the relevant columns in the trace.
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...
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
FieldGreaterThanTraceBuilder field_gt_builder
Definition alu.test.cpp:122
ExecutionIdManager execution_id_manager
TestTraceContainer trace
IndexedTreeLeafData low_leaf
void check_interaction(tracegen::TestTraceContainer &trace)
std::variant< IndexedTreeReadWriteEvent, CheckPointEventType > IndexedTreeCheckEvent
FF unconstrained_root_from_path(uint64_t domain_separator, const FF &leaf_value, const uint64_t leaf_index, std::span< const FF > path)
Definition merkle.cpp:12
bb::crypto::Poseidon2< bb::crypto::Poseidon2Bn254ScalarFieldParams > Poseidon2
lookup_settings< lookup_indexed_tree_check_silo_poseidon2_settings_ > lookup_indexed_tree_check_silo_poseidon2_settings
lookup_settings< lookup_indexed_tree_check_low_leaf_value_validation_settings_ > lookup_indexed_tree_check_low_leaf_value_validation_settings
lookup_settings< lookup_indexed_tree_check_low_leaf_poseidon2_settings_ > lookup_indexed_tree_check_low_leaf_poseidon2_settings
lookup_settings< lookup_indexed_tree_check_updated_low_leaf_poseidon2_settings_ > lookup_indexed_tree_check_updated_low_leaf_poseidon2_settings
lookup_settings< lookup_indexed_tree_check_low_leaf_next_value_validation_settings_ > lookup_indexed_tree_check_low_leaf_next_value_validation_settings
lookup_settings< lookup_indexed_tree_check_low_leaf_merkle_check_settings_ > lookup_indexed_tree_check_low_leaf_merkle_check_settings
lookup_settings< lookup_indexed_tree_check_new_leaf_poseidon2_settings_ > lookup_indexed_tree_check_new_leaf_poseidon2_settings
lookup_settings< lookup_indexed_tree_check_new_leaf_merkle_check_settings_ > lookup_indexed_tree_check_new_leaf_merkle_check_settings
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:155
::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
Definition tuple.hpp:13
NoopEventEmitter< FieldGreaterThanEvent > field_gt_event_emitter