Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
nullifier_tree_check_trace.test.cpp
Go to the documentation of this file.
2
3#include <cmath>
4#include <cstdint>
5#include <gmock/gmock.h>
6#include <gtest/gtest.h>
7
31
32namespace bb::avm2::tracegen {
33namespace {
34
35using ::testing::NiceMock;
36
37using testing::TestMemoryTree;
38
39using simulation::DeduplicatingEventEmitter;
40using simulation::EventEmitter;
41using simulation::ExecutionIdManager;
42using simulation::FieldGreaterThan;
43using simulation::FieldGreaterThanEvent;
44using simulation::MerkleCheck;
45using simulation::MerkleCheckEvent;
46using simulation::MockGreaterThan;
47using simulation::MockRangeCheck;
48using simulation::NullifierTreeCheck;
51using simulation::Poseidon2;
52using simulation::Poseidon2HashEvent;
53using simulation::Poseidon2PermutationEvent;
54using simulation::Poseidon2PermutationMemoryEvent;
56
58
60using C = Column;
63
64class NullifierTreeCheckTracegenTest : public ::testing::Test {
65 protected:
66 NullifierTreeCheckTracegenTest()
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;
83};
84
85std::vector<TestParams> positive_read_tests = {
86 // Exists = true, leaf pointers to infinity
87 TestParams{ .nullifier = 42, .exists = true, .low_leaf = NullifierTreeLeafPreimage(NullifierLeafValue(42), 0, 0) },
88 // Exists = true, leaf points to higher value
89 TestParams{
90 .nullifier = 42, .exists = true, .low_leaf = NullifierTreeLeafPreimage(NullifierLeafValue(42), 28, 50) },
91 // Exists = false, low leaf points to infinity
92 TestParams{ .nullifier = 42, .exists = false, .low_leaf = NullifierTreeLeafPreimage(NullifierLeafValue(10), 0, 0) },
93 // Exists = false, low leaf points to higher value
94 TestParams{
95 .nullifier = 42, .exists = false, .low_leaf = NullifierTreeLeafPreimage(NullifierLeafValue(10), 28, 50) }
96};
97
98class NullifierReadInteractionsTests : public NullifierTreeCheckTracegenTest,
99 public ::testing::WithParamInterface<TestParams> {};
100
101TEST_P(NullifierReadInteractionsTests, PositiveWithInteractions)
102{
103 const auto& param = GetParam();
104
105 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
106 MerkleCheck merkle_check(poseidon2, merkle_event_emitter);
107
108 NiceMock<MockRangeCheck> range_check;
109
110 DeduplicatingEventEmitter<FieldGreaterThanEvent> field_gt_event_emitter;
111 FieldGreaterThan field_gt(range_check, field_gt_event_emitter);
112
113 EventEmitter<NullifierTreeCheckEvent> nullifier_tree_check_event_emitter;
114 NullifierTreeCheck nullifier_tree_check_simulator(
115 poseidon2, merkle_check, field_gt, nullifier_tree_check_event_emitter);
116
117 TestTraceContainer trace({ { { C::precomputed_first_row, 1 } } });
118 Poseidon2TraceBuilder poseidon2_builder;
119 MerkleCheckTraceBuilder merkle_check_builder;
120 FieldGreaterThanTraceBuilder field_gt_builder;
121 NullifierTreeCheckTraceBuilder nullifier_tree_check_builder;
122
123 FF low_leaf_hash = poseidon2.hash(param.low_leaf.get_hash_inputs());
124 uint64_t leaf_index = 30;
125 std::vector<FF> sibling_path;
126 sibling_path.reserve(NULLIFIER_TREE_HEIGHT);
127 for (size_t i = 0; i < NULLIFIER_TREE_HEIGHT; ++i) {
128 sibling_path.emplace_back(i);
129 }
130 FF root = unconstrained_root_from_path(low_leaf_hash, leaf_index, sibling_path);
131
132 nullifier_tree_check_simulator.assert_read(param.nullifier,
133 /*contract_address*/ std::nullopt,
134 param.exists,
135 param.low_leaf,
136 leaf_index,
137 sibling_path,
138 AppendOnlyTreeSnapshot{ .root = root });
139
141 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
143 nullifier_tree_check_builder.process(nullifier_tree_check_event_emitter.dump_events(), trace);
144
145 check_interaction<NullifierTreeCheckTraceBuilder,
154}
155
156INSTANTIATE_TEST_SUITE_P(NullifierTreeCheckTracegenTest,
157 NullifierReadInteractionsTests,
158 ::testing::ValuesIn(positive_read_tests));
159
160TEST_F(NullifierTreeCheckTracegenTest, WriteWithInteractions)
161{
162 EventEmitter<MerkleCheckEvent> merkle_event_emitter;
163 MerkleCheck merkle_check(poseidon2, merkle_event_emitter);
164
165 NiceMock<MockRangeCheck> range_check;
166
167 DeduplicatingEventEmitter<FieldGreaterThanEvent> field_gt_event_emitter;
168 FieldGreaterThan field_gt(range_check, field_gt_event_emitter);
169
170 EventEmitter<NullifierTreeCheckEvent> nullifier_tree_check_event_emitter;
171 NullifierTreeCheck nullifier_tree_check_simulator(
172 poseidon2, merkle_check, field_gt, nullifier_tree_check_event_emitter);
173
174 TestTraceContainer trace({ { { C::precomputed_first_row, 1 } } });
175 Poseidon2TraceBuilder poseidon2_builder;
176 MerkleCheckTraceBuilder merkle_check_builder;
177 FieldGreaterThanTraceBuilder field_gt_builder;
178 NullifierTreeCheckTraceBuilder nullifier_tree_check_builder;
179
181 FF nullifier = 100;
183 FF low_nullifier = 40;
184 TestMemoryTree<Poseidon2HashPolicy> nullifier_tree(8, NULLIFIER_TREE_HEIGHT);
185
187 NullifierTreeLeafPreimage(NullifierLeafValue(low_nullifier), 10, siloed_nullifier + 1);
188 FF low_leaf_hash = RawPoseidon2::hash(low_leaf.get_hash_inputs());
189 uint64_t low_leaf_index = 0;
190 nullifier_tree.update_element(low_leaf_index, low_leaf_hash);
191
192 AppendOnlyTreeSnapshot prev_snapshot =
193 AppendOnlyTreeSnapshot{ .root = nullifier_tree.root(), .nextAvailableLeafIndex = 128 };
194 std::vector<FF> low_leaf_sibling_path = nullifier_tree.get_sibling_path(low_leaf_index);
195
196 NullifierTreeLeafPreimage updated_low_leaf = low_leaf;
197 updated_low_leaf.nextIndex = prev_snapshot.nextAvailableLeafIndex;
198 updated_low_leaf.nextKey = siloed_nullifier;
199 FF updated_low_leaf_hash = RawPoseidon2::hash(updated_low_leaf.get_hash_inputs());
200 nullifier_tree.update_element(low_leaf_index, updated_low_leaf_hash);
201
202 std::vector<FF> insertion_sibling_path = nullifier_tree.get_sibling_path(prev_snapshot.nextAvailableLeafIndex);
203
205 NullifierTreeLeafPreimage(NullifierLeafValue(siloed_nullifier), low_leaf.nextIndex, low_leaf.nextKey);
206 FF new_leaf_hash = RawPoseidon2::hash(new_leaf.get_hash_inputs());
207 nullifier_tree.update_element(prev_snapshot.nextAvailableLeafIndex, new_leaf_hash);
208
209 nullifier_tree_check_simulator.write(nullifier,
211 0,
212 low_leaf,
213 low_leaf_index,
214 low_leaf_sibling_path,
215 prev_snapshot,
216 insertion_sibling_path);
217
219 merkle_check_builder.process(merkle_event_emitter.dump_events(), trace);
221 nullifier_tree_check_builder.process(nullifier_tree_check_event_emitter.dump_events(), trace);
222
223 // Not checking all interactions due to the public inputs interaction, which needs to be checked in an e2e test
224 check_interaction<NullifierTreeCheckTraceBuilder,
233}
234
235} // namespace
236} // namespace bb::avm2::tracegen
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 NULLIFIER_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
void process(const simulation::EventEmitterInterface< simulation::FieldGreaterThanEvent >::Container &events, TraceContainer &trace)
void process_hash(const simulation::EventEmitterInterface< simulation::Poseidon2HashEvent >::Container &hash_events, TraceContainer &trace)
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...
FieldGreaterThanTraceBuilder field_gt_builder
Definition alu.test.cpp:121
ExecutionIdManager execution_id_manager
RangeCheck range_check
TestTraceContainer trace
NullifierTreeLeafPreimage low_leaf
void check_interaction(tracegen::TestTraceContainer &trace)
crypto::merkle_tree::IndexedLeaf< crypto::merkle_tree::NullifierLeafValue > NullifierTreeLeafPreimage
Definition db_types.hpp:9
::bb::crypto::merkle_tree::NullifierLeafValue NullifierLeafValue
Definition db.hpp:30
FF unconstrained_root_from_path(const FF &leaf_value, const uint64_t leaf_index, std::span< const FF > path)
Definition merkle.cpp:12
std::variant< NullifierTreeReadWriteEvent, CheckPointEventType > NullifierTreeCheckEvent
FF unconstrained_silo_nullifier(const AztecAddress &contract_address, const FF &nullifier)
Definition merkle.cpp:31
crypto::Poseidon2< crypto::Poseidon2Bn254ScalarFieldParams > Poseidon2
lookup_settings< lookup_nullifier_check_updated_low_leaf_poseidon2_settings_ > lookup_nullifier_check_updated_low_leaf_poseidon2_settings
lookup_settings< lookup_nullifier_check_low_leaf_poseidon2_settings_ > lookup_nullifier_check_low_leaf_poseidon2_settings
lookup_settings< lookup_nullifier_check_low_leaf_nullifier_validation_settings_ > lookup_nullifier_check_low_leaf_nullifier_validation_settings
lookup_settings< lookup_nullifier_check_low_leaf_merkle_check_settings_ > lookup_nullifier_check_low_leaf_merkle_check_settings
lookup_settings< lookup_nullifier_check_low_leaf_next_nullifier_validation_settings_ > lookup_nullifier_check_low_leaf_next_nullifier_validation_settings
lookup_settings< lookup_nullifier_check_silo_poseidon2_settings_ > lookup_nullifier_check_silo_poseidon2_settings
lookup_settings< lookup_nullifier_check_new_leaf_merkle_check_settings_ > lookup_nullifier_check_new_leaf_merkle_check_settings
lookup_settings< lookup_nullifier_check_new_leaf_poseidon2_settings_ > lookup_nullifier_check_new_leaf_poseidon2_settings
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:188
typename Flavor::FF FF
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
FieldGreaterThan field_gt
NoopEventEmitter< FieldGreaterThanEvent > field_gt_event_emitter