Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
address_derivation.test.cpp
Go to the documentation of this file.
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3
25
26namespace bb::avm2::constraining {
27namespace {
28
29using ::testing::Return;
30using ::testing::StrictMock;
31
32using tracegen::AddressDerivationTraceBuilder;
33using tracegen::EccTraceBuilder;
34using tracegen::Poseidon2TraceBuilder;
35using tracegen::TestTraceContainer;
36
37using simulation::AddressDerivation;
38using simulation::AddressDerivationEvent;
40using simulation::Ecc;
41using simulation::EccAddEvent;
42using simulation::EccAddMemoryEvent;
43using simulation::EventEmitter;
45using simulation::MockExecutionIdManager;
46using simulation::MockGreaterThan;
47using simulation::NoopEventEmitter;
48using simulation::Poseidon2;
49using simulation::Poseidon2HashEvent;
50using simulation::Poseidon2PermutationEvent;
51using simulation::Poseidon2PermutationMemoryEvent;
52using simulation::PureToRadix;
53using simulation::ScalarMulEvent;
54
56using C = Column;
57using address_derivation_relation = bb::avm2::address_derivation<FF>;
58using poseidon2_relation = bb::avm2::poseidon2_hash<FF>;
59using ecadd_relation = bb::avm2::ecc<FF>;
60using scalar_mul_relation = bb::avm2::scalar_mul<FF>;
62
63TEST(AddressDerivationConstrainingTest, EmptyRow)
64{
65 check_relation<address_derivation_relation>(testing::empty_trace());
66}
67
68TEST(AddressDerivationConstrainingTest, Basic)
69{
70 TestTraceContainer trace;
71 AddressDerivationTraceBuilder builder;
72
74
75 FF salted_initialization_hash = poseidon2::hash(
76 { DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer });
77
78 FF partial_address =
79 poseidon2::hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash });
80
81 FF public_keys_hash = hash_public_keys(instance.public_keys);
82 FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address });
83
85 EmbeddedCurvePoint preaddress_public_key = g1 * Fq(preaddress);
86 EmbeddedCurvePoint address_point = preaddress_public_key + instance.public_keys.incoming_viewing_key;
87
88 builder.process({ { .address = address_point.x(),
90 .salted_initialization_hash = salted_initialization_hash,
91 .partial_address = partial_address,
92 .public_keys_hash = public_keys_hash,
93 .preaddress = preaddress,
94 .preaddress_public_key = preaddress_public_key,
95 .address_point = address_point } },
96 trace);
97
98 EXPECT_EQ(trace.get_num_rows(), 1);
99 check_relation<address_derivation_relation>(trace);
100}
101
102TEST(AddressDerivationConstrainingTest, WithInteractions)
103{
104 EventEmitter<EccAddEvent> ecadd_event_emitter;
105 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
106 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
107 EventEmitter<Poseidon2HashEvent> hash_event_emitter;
108 NoopEventEmitter<Poseidon2PermutationEvent> perm_event_emitter;
109 NoopEventEmitter<Poseidon2PermutationMemoryEvent> perm_mem_event_emitter;
110 EventEmitter<AddressDerivationEvent> address_derivation_event_emitter;
111
112 StrictMock<MockExecutionIdManager> mock_exec_id_manager;
113 EXPECT_CALL(mock_exec_id_manager, get_execution_id)
114 .WillRepeatedly(Return(0)); // Use a fixed execution ID for the test
115 StrictMock<MockGreaterThan> mock_gt;
116 Poseidon2 poseidon2_simulator(
118
119 PureToRadix to_radix_simulator;
120 Ecc ecc_simulator(mock_exec_id_manager,
121 mock_gt,
122 to_radix_simulator,
123 ecadd_event_emitter,
124 scalar_mul_event_emitter,
125 ecc_add_memory_event_emitter);
126
127 AddressDerivation address_derivation(poseidon2_simulator, ecc_simulator, address_derivation_event_emitter);
128
129 TestTraceContainer trace({
130 { { C::precomputed_first_row, 1 } },
131 });
132
133 AddressDerivationTraceBuilder builder;
134 Poseidon2TraceBuilder poseidon2_builder;
135 EccTraceBuilder ecc_builder;
136
137 ContractInstance instance = testing::random_contract_instance();
139 address_derivation.assert_derivation(address, instance);
140
141 builder.process(address_derivation_event_emitter.dump_events(), trace);
143 ecc_builder.process_add(ecadd_event_emitter.dump_events(), trace);
144 ecc_builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
145
146 check_all_interactions<AddressDerivationTraceBuilder>(trace);
147 check_relation<address_derivation_relation>(trace);
148}
149
150TEST(AddressDerivationConstrainingTest, NegativeWithInteractions)
151{
152 EventEmitter<EccAddEvent> ecadd_event_emitter;
153 EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
154 NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
155 EventEmitter<Poseidon2HashEvent> hash_event_emitter;
156 NoopEventEmitter<Poseidon2PermutationEvent> perm_event_emitter;
157 NoopEventEmitter<Poseidon2PermutationMemoryEvent> perm_mem_event_emitter;
158 EventEmitter<AddressDerivationEvent> address_derivation_event_emitter;
159
160 StrictMock<MockExecutionIdManager> mock_exec_id_manager;
161 EXPECT_CALL(mock_exec_id_manager, get_execution_id)
162 .WillRepeatedly(Return(0)); // Use a fixed execution ID for the test
163 StrictMock<MockGreaterThan> mock_gt;
164 Poseidon2 poseidon2_simulator(
166
167 PureToRadix to_radix_simulator;
168 Ecc ecc_simulator(mock_exec_id_manager,
169 mock_gt,
170 to_radix_simulator,
171 ecadd_event_emitter,
172 scalar_mul_event_emitter,
173 ecc_add_memory_event_emitter);
174
175 AddressDerivation address_derivation(poseidon2_simulator, ecc_simulator, address_derivation_event_emitter);
176
177 TestTraceContainer trace({
178 { { C::precomputed_first_row, 1 } },
179 });
180
181 AddressDerivationTraceBuilder builder;
182 Poseidon2TraceBuilder poseidon2_builder;
183 EccTraceBuilder ecc_builder;
184
185 ContractInstance instance = testing::random_contract_instance();
187 address_derivation.assert_derivation(address, instance);
188
189 builder.process(address_derivation_event_emitter.dump_events(), trace);
191 ecc_builder.process_add(ecadd_event_emitter.dump_events(), trace);
192 ecc_builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
193
194 check_all_interactions<AddressDerivationTraceBuilder>(trace);
195 check_relation<address_derivation_relation>(trace);
196
197 // Mutate the final address to the wrong value.
198 trace.set(C::address_derivation_address, 0, 1);
200 (check_interaction<AddressDerivationTraceBuilder, lookup_address_derivation_address_ecadd_settings>(trace)),
201 "Failed.*ADDRESS_ECADD. Could not find tuple in destination.");
202
203 // Reset.
204 trace.set(C::address_derivation_address, 0, address);
205 // Mutate the preaddress to the wrong value.
206 trace.set(C::address_derivation_preaddress, 0, 1);
207 // Both the derivation via hash and scalar mul of preaddress * G1 will fail.
209 (check_interaction<AddressDerivationTraceBuilder, lookup_address_derivation_preaddress_poseidon2_settings>(
210 trace)),
211 "Failed.*PREADDRESS_POSEIDON2. Could not find tuple in destination.");
213 (check_interaction<AddressDerivationTraceBuilder, lookup_address_derivation_preaddress_scalar_mul_settings>(
214 trace)),
215 "Failed.*PREADDRESS_SCALAR_MUL. Could not find tuple in destination.");
216}
217
218TEST(AddressDerivationConstrainingTest, NegativeIVKNotOnCurve)
219{
220 TestTraceContainer trace;
221 AddressDerivationTraceBuilder builder;
222
224
225 // Mutate ivk to a point not on the curve.
226 instance.public_keys.incoming_viewing_key = AffinePoint(1, 2);
227
228 FF salted_initialization_hash = poseidon2::hash(
229 { DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer });
230
231 FF partial_address =
232 poseidon2::hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash });
233
234 FF public_keys_hash = hash_public_keys(instance.public_keys);
235 FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address });
236
238 EmbeddedCurvePoint preaddress_public_key = g1 * Fq(preaddress);
239 EmbeddedCurvePoint address_point = preaddress_public_key + instance.public_keys.incoming_viewing_key;
240
241 builder.process({ { .address = address_point.x(),
243 .salted_initialization_hash = salted_initialization_hash,
244 .partial_address = partial_address,
245 .public_keys_hash = public_keys_hash,
246 .preaddress = preaddress,
247 .preaddress_public_key = preaddress_public_key,
248 .address_point = address_point } },
249 trace);
250
252 check_relation<address_derivation_relation>(trace, address_derivation_relation::SR_IVK_ON_CURVE_CHECK),
253 "IVK_ON_CURVE_CHECK");
254}
255
256} // namespace
257} // namespace bb::avm2::constraining
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
Definition assert.hpp:193
std::shared_ptr< Napi::ThreadSafeFunction > instance
#define DOM_SEP__SALTED_INITIALIZATION_HASH
#define DOM_SEP__PARTIAL_ADDRESS
#define DOM_SEP__CONTRACT_ADDRESS_V1
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::AluEvent >::Container &events, TraceContainer &trace)
Process the ALU events and populate the ALU 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...
void set(Column col, uint32_t row, const FF &value)
Native Poseidon2 hash function implementation.
Definition poseidon2.hpp:22
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
group class. Represents an elliptic curve group element. Group is parametrised by Fq and Fr
Definition group.hpp:38
AluTraceBuilder builder
Definition alu.test.cpp:124
TestTraceContainer trace
TEST(AvmFixedVKTests, FixedVKCommitments)
Test that the fixed VK commitments agree with the ones computed from precomputed columns.
FF hash_public_keys(const PublicKeys &public_keys)
FF compute_contract_address(const ContractInstance &contract_instance)
ContractInstance random_contract_instance()
Definition fixtures.cpp:159
TestTraceContainer empty_trace()
Definition fixtures.cpp:153
StandardAffinePoint< AvmFlavorSettings::EmbeddedCurve::AffineElement > EmbeddedCurvePoint
Definition field.hpp:12
AvmFlavorSettings::G1::Fq Fq
Definition field.hpp:11
grumpkin::g1::affine_element AffinePoint