Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
nullifier_exists.test.cpp
Go to the documentation of this file.
1#include <gtest/gtest.h>
2
3#include <cstdint>
4
22
23namespace bb::avm2::constraining {
24namespace {
25
26using tracegen::ExecutionTraceBuilder;
27using tracegen::NullifierTreeCheckTraceBuilder;
28using tracegen::TestTraceContainer;
29
30using simulation::EventEmitter;
31using simulation::FieldGreaterThan;
32using simulation::FieldGreaterThanEvent;
33using simulation::MockMerkleCheck;
34using simulation::MockPoseidon2;
35using simulation::MockRangeCheck;
36using simulation::NullifierTreeCheck;
38
39using testing::NiceMock;
40
42using C = Column;
43using nullifier_exists = bb::avm2::nullifier_exists<FF>;
44
45TEST(NullifierExistsConstrainingTest, PositiveTest)
46{
47 TestTraceContainer trace({ { { C::execution_sel, 1 },
48 { C::execution_sel_execute_nullifier_exists, 1 },
49 { C::execution_register_0_, /*nullifier=*/FF(0x123456) },
50 { C::execution_register_1_, /*address=*/FF(0xdeadbeef) },
51 { C::execution_register_2_, /*exists=*/1 },
52 { C::execution_prev_nullifier_tree_root, FF(0xabc) },
53 { C::execution_mem_tag_reg_0_, static_cast<uint8_t>(MemoryTag::FF) },
54 { C::execution_mem_tag_reg_1_, static_cast<uint8_t>(MemoryTag::FF) },
55 { C::execution_mem_tag_reg_2_, static_cast<uint8_t>(MemoryTag::U1) },
56 { C::execution_sel_opcode_error, 0 },
57 { C::execution_subtrace_operation_id, AVM_EXEC_OP_ID_NULLIFIER_EXISTS } } });
58 check_relation<nullifier_exists>(trace);
59}
60
61TEST(NullifierExistsConstrainingTest, PositiveNullifierNotExists)
62{
63 TestTraceContainer trace({ { { C::execution_sel, 1 },
64 { C::execution_sel_execute_nullifier_exists, 1 },
65 { C::execution_register_0_, /*nullifier=*/FF(0x123456) },
66 { C::execution_register_1_, /*address=*/FF(0xdeadbeef) },
67 { C::execution_register_2_, /*exists=*/0 }, // nullifier does not exist!
68 { C::execution_prev_nullifier_tree_root, FF(0xabc) },
69 { C::execution_mem_tag_reg_0_, static_cast<uint8_t>(MemoryTag::FF) },
70 { C::execution_mem_tag_reg_1_, static_cast<uint8_t>(MemoryTag::FF) },
71 { C::execution_mem_tag_reg_2_, static_cast<uint8_t>(MemoryTag::U1) },
72 { C::execution_sel_opcode_error, 0 },
73 { C::execution_subtrace_operation_id, AVM_EXEC_OP_ID_NULLIFIER_EXISTS } } });
74 check_relation<nullifier_exists>(trace);
75}
76
77TEST(NullifierExistsConstrainingTest, NegativeInvalidOutputTag)
78{
79 TestTraceContainer trace({ { { C::execution_sel, 1 },
80 { C::execution_sel_execute_nullifier_exists, 1 },
81 { C::execution_register_0_, /*nullifier=*/FF(0x123456) },
82 { C::execution_register_1_, /*address=*/FF(0xdeadbeef) },
83 { C::execution_register_2_, /*exists=*/0 }, // nullifier does not exist!
84 { C::execution_prev_nullifier_tree_root, FF(0xabc) },
85 { C::execution_mem_tag_reg_0_, static_cast<uint8_t>(MemoryTag::FF) },
86 { C::execution_mem_tag_reg_1_, static_cast<uint8_t>(MemoryTag::FF) },
87 { C::execution_mem_tag_reg_2_, static_cast<uint8_t>(MemoryTag::U8) }, // WRONG!
88 { C::execution_sel_opcode_error, 0 },
89 { C::execution_subtrace_operation_id, AVM_EXEC_OP_ID_NULLIFIER_EXISTS } } });
91 check_relation<nullifier_exists>(trace, nullifier_exists::SR_NULLIFIER_EXISTS_U1_OUTPUT_TAG),
92 "NULLIFIER_EXISTS_U1_OUTPUT_TAG");
93}
94
95TEST(NullifierExistsConstrainingTest, NegativeNullifierExistsSuccess)
96{
97 TestTraceContainer trace({ {
98 { C::execution_sel_execute_nullifier_exists, 1 },
99 { C::execution_sel_opcode_error, 1 },
100 } });
101
103 "NULLIFIER_EXISTS_SUCCESS");
104}
105
106TEST(NullifierExistsConstrainingTest, Interactions)
107{
108 NiceMock<MockPoseidon2> poseidon2;
109 NiceMock<MockMerkleCheck> merkle_check;
110
111 NiceMock<MockRangeCheck> range_check;
112 EventEmitter<FieldGreaterThanEvent> event_emitter;
113 FieldGreaterThan field_gt(range_check, event_emitter);
114
115 EventEmitter<NullifierTreeCheckEvent> nullifier_tree_check_event_emitter;
116 NullifierTreeCheck nullifier_tree_check(poseidon2, merkle_check, field_gt, nullifier_tree_check_event_emitter);
117
118 FF nullifier = 42;
119 FF address = 43;
120
121 AppendOnlyTreeSnapshot nullifier_tree_snapshot = AppendOnlyTreeSnapshot{
122 .root = 42,
123 .nextAvailableLeafIndex = 128,
124 };
125
126 nullifier_tree_check.assert_read(nullifier, address, true, {}, 0, {}, nullifier_tree_snapshot);
127
128 TestTraceContainer trace({ {
129 { C::execution_sel_execute_nullifier_exists, 1 },
130 { C::execution_register_0_, nullifier },
131 { C::execution_register_1_, address },
132 { C::execution_register_2_, /*exists=*/1 },
133 { C::execution_mem_tag_reg_0_, static_cast<uint8_t>(MemoryTag::FF) },
134 { C::execution_mem_tag_reg_1_, static_cast<uint8_t>(MemoryTag::FF) },
135 { C::execution_mem_tag_reg_2_, static_cast<uint8_t>(MemoryTag::U1) },
136 { C::execution_prev_nullifier_tree_root, nullifier_tree_snapshot.root },
137 { C::execution_sel_opcode_error, 0 },
138 { C::execution_subtrace_operation_id, AVM_EXEC_OP_ID_NULLIFIER_EXISTS },
139 } });
140
141 NullifierTreeCheckTraceBuilder nullifier_tree_check_trace_builder;
142 nullifier_tree_check_trace_builder.process(nullifier_tree_check_event_emitter.dump_events(), trace);
143
144 check_relation<nullifier_exists>(trace);
145
146 check_interaction<ExecutionTraceBuilder, lookup_nullifier_exists_nullifier_exists_check_settings>(trace);
147}
148
149// TODO(dbanks12): interaction tests
150
151} // namespace
152} // namespace bb::avm2::constraining
#define AVM_EXEC_OP_ID_NULLIFIER_EXISTS
static constexpr size_t SR_NULLIFIER_EXISTS_U1_OUTPUT_TAG
static constexpr size_t SR_NULLIFIER_EXISTS_SUCCESS
EventEmitter< DataCopyEvent > event_emitter
RangeCheck range_check
TestTraceContainer trace
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
Definition macros.hpp:7
AvmFlavorSettings::FF FF
TEST(TxExecutionConstrainingTest, WriteTreeValue)
Definition tx.test.cpp:508
crypto::Poseidon2< crypto::Poseidon2Bn254ScalarFieldParams > poseidon2
std::variant< NullifierTreeReadWriteEvent, CheckPointEventType > NullifierTreeCheckEvent
typename Flavor::FF FF
NiceMock< MockFieldGreaterThan > field_gt