Skip to content

Commit f8f8953

Browse files
committed
feat!: update address derivation
1 parent 30d8c61 commit f8f8953

61 files changed

Lines changed: 3545 additions & 3416 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

barretenberg/cpp/pil/vm2/bytecode/address_derivation.pil

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ include "../scalar_mul.pil";
99
* during contract instance retrieval (contract_instance_retrieval.pil) in our execution flow.
1010
* The address is defined by the following flow, where the hash function H() is Poseidon2, and G1
1111
* is the Grumpkin curve's generator point:
12-
* 1. salted_init_hash = H(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr)
12+
* 1. salted_init_hash = H(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr, immutables_hash)
1313
* 2. partial_address = H(DOM_SEP__PARTIAL_ADDRESS, class_id, salted_init_hash)
1414
* 3. public_keys_hash = H(DOM_SEP__PUBLIC_KEYS_HASH,
1515
* nullifier_key_x, nullifier_key_y, nullifier_key_is_infinity,
1616
* incoming_viewing_key_x, incoming_viewing_key_y, incoming_viewing_key_is_infinity,
1717
* outgoing_viewing_key_x, outgoing_viewing_key_y, outgoing_viewing_key_is_infinity,
1818
* tagging_key_x, tagging_key_y, tagging_key_is_infinity)
19-
* 4. preaddress = H(DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address)
19+
* 4. preaddress = H(DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address)
2020
* 5. preaddress_public_key = preaddress * G1
2121
* 6. address = (preaddress_public_key + incoming_viewing_key).x
2222
*
@@ -101,6 +101,7 @@ namespace address_derivation;
101101
pol commit deployer_addr;
102102
pol commit class_id; // = original_contract_class_id
103103
pol commit init_hash;
104+
pol commit immutables_hash;
104105
// Public keys, all Grumpkin curve points (see PublicKeys in barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp).
105106
pol commit nullifier_key_x;
106107
pol commit nullifier_key_y;
@@ -117,14 +118,14 @@ namespace address_derivation;
117118
///////////////////////////////
118119
//
119120
// This trace constrains the result of four Poseidon2 hashes:
120-
// 1. salted_init_hash = H(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr)
121+
// 1. salted_init_hash = H(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr, immutables_hash)
121122
// 2. partial_address = H(DOM_SEP__PARTIAL_ADDRESS, class_id, salted_init_hash)
122123
// 3. public_keys_hash = H(DOM_SEP__PUBLIC_KEYS_HASH,
123124
// nullifier_key_x, nullifier_key_y, 0,
124125
// incoming_viewing_key_x, incoming_viewing_key_y, 0,
125126
// outgoing_viewing_key_x, outgoing_viewing_key_y, 0,
126127
// tagging_key_x, tagging_key_y, 0)
127-
// 4. preaddress = H(DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address)
128+
// 4. preaddress = H(DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address)
128129
//
129130

130131
// Lookup constant support: Can be removed when we support constants in lookups.
@@ -134,6 +135,8 @@ namespace address_derivation;
134135
sel * (const_three - 3) = 0;
135136
pol commit const_four;
136137
sel * (const_four - 4) = 0;
138+
pol commit const_five; // Used for the salted initialization hash
139+
sel * (const_five - 5) = 0;
137140
pol commit const_thirteen;
138141
sel * (const_thirteen - 13) = 0;
139142
pol commit salted_init_hash_domain_separator;
@@ -143,25 +146,25 @@ namespace address_derivation;
143146
pol commit public_keys_hash_domain_separator;
144147
sel * (public_keys_hash_domain_separator - constants.DOM_SEP__PUBLIC_KEYS_HASH) = 0;
145148
pol commit preaddress_domain_separator;
146-
sel * (preaddress_domain_separator - constants.DOM_SEP__CONTRACT_ADDRESS_V1) = 0;
149+
sel * (preaddress_domain_separator - constants.DOM_SEP__CONTRACT_ADDRESS_V2) = 0;
147150

148151
// 1. Computation of salted initialization hash
149152
pol commit salted_init_hash;
150153

151-
// Since Poseidon2 processes inputs in chunks of 3, we need 2 permutation rounds to cover our 4 inputs:
152-
// salted_init_hash = H(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr)
153-
// Round 1 (start, input_len=4): (DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash)
154-
// Round 2 (end): (deployer_addr, 0, 0)
154+
// Since Poseidon2 processes inputs in chunks of 3, we need 2 permutation rounds to cover our 5 inputs:
155+
// salted_init_hash = H(DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash, deployer_addr, immutables_hash)
156+
// Round 1 (start, input_len=5): (DOM_SEP__SALTED_INITIALIZATION_HASH, salt, init_hash)
157+
// Round 2 (end): (deployer_addr, immutables_hash, 0)
155158

156-
// Enforces the first round of salted_init_hash. Note that we must lookup poseidon2_hash.input_len == 4
159+
// Enforces the first round of salted_init_hash. Note that we must lookup poseidon2_hash.input_len == 5
157160
// here since it is constrained in the poseidon trace on the start row.
158161
#[SALTED_INITIALIZATION_HASH_POSEIDON2_0]
159-
sel { salted_init_hash_domain_separator, salt, init_hash, salted_init_hash, const_four }
162+
sel { salted_init_hash_domain_separator, salt, init_hash, salted_init_hash, const_five }
160163
in poseidon2_hash.start { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output, poseidon2_hash.input_len };
161164

162165
// Enforces the second and final round of salted_init_hash. Note that we must enforce the padded values are zero here.
163166
#[SALTED_INITIALIZATION_HASH_POSEIDON2_1]
164-
sel { deployer_addr, precomputed.zero, precomputed.zero, salted_init_hash }
167+
sel { deployer_addr, immutables_hash, precomputed.zero, salted_init_hash }
165168
in poseidon2_hash.end { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output };
166169

167170
// 2. Computation of partial address
@@ -234,8 +237,8 @@ namespace address_derivation;
234237
pol commit preaddress;
235238

236239
// We have 3 inputs, hence a single Poseidon2 round:
237-
// preaddress = H(DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address)
238-
// Round 1 (start, input_len=3): (DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address)
240+
// preaddress = H(DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address)
241+
// Round 1 (start, input_len=3): (DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address)
239242

240243
// Enforces the single round of preaddress. Since input_len=3 fills exactly one permutation,
241244
// this start lookup is also the final round and no separate end lookup is needed (the poseidon trace

barretenberg/cpp/pil/vm2/bytecode/contract_instance_retrieval.pil

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ namespace contract_instance_retrieval;
256256
deployer_addr,
257257
original_class_id,
258258
init_hash,
259+
immutables_hash,
259260
nullifier_key_x,
260261
nullifier_key_y,
261262
incoming_viewing_key_x,
@@ -270,6 +271,7 @@ namespace contract_instance_retrieval;
270271
address_derivation.deployer_addr,
271272
address_derivation.class_id,
272273
address_derivation.init_hash,
274+
address_derivation.immutables_hash,
273275
address_derivation.nullifier_key_x,
274276
address_derivation.nullifier_key_y,
275277
address_derivation.incoming_viewing_key_x,

barretenberg/cpp/pil/vm2/constants_gen.pil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,6 @@ namespace constants;
181181
pol DOM_SEP__SALTED_INITIALIZATION_HASH = 2763052992;
182182
pol DOM_SEP__PUBLIC_KEYS_HASH = 777457226;
183183
pol DOM_SEP__PARTIAL_ADDRESS = 2103633018;
184-
pol DOM_SEP__CONTRACT_ADDRESS_V1 = 1788365517;
184+
pol DOM_SEP__CONTRACT_ADDRESS_V2 = 4099338721;
185185
pol DOM_SEP__PUBLIC_CALLDATA = 2760353947;
186186

barretenberg/cpp/src/barretenberg/aztec/aztec_constants.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,6 @@
273273
#define DOM_SEP__SALTED_INITIALIZATION_HASH 2763052992UL
274274
#define DOM_SEP__PUBLIC_KEYS_HASH 777457226UL
275275
#define DOM_SEP__PARTIAL_ADDRESS 2103633018UL
276-
#define DOM_SEP__CONTRACT_ADDRESS_V1 1788365517UL
276+
#define DOM_SEP__CONTRACT_ADDRESS_V2 4099338721UL
277277
#define DOM_SEP__BLOCK_HEADER_HASH 4195546849UL
278278
#define DOM_SEP__PUBLIC_CALLDATA 2760353947UL

barretenberg/cpp/src/barretenberg/vm2/constraining/relations/address_derivation.test.cpp

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,17 @@ TEST(AddressDerivationConstrainingTest, Basic)
7272

7373
auto instance = testing::random_contract_instance();
7474

75-
FF salted_initialization_hash = poseidon2::hash(
76-
{ DOM_SEP__SALTED_INITIALIZATION_HASH, instance.salt, instance.initialization_hash, instance.deployer });
75+
FF salted_initialization_hash = poseidon2::hash({ DOM_SEP__SALTED_INITIALIZATION_HASH,
76+
instance.salt,
77+
instance.initialization_hash,
78+
instance.deployer,
79+
instance.immutables_hash });
7780

7881
FF partial_address =
7982
poseidon2::hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash });
8083

8184
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 });
85+
FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address });
8386

8487
EmbeddedCurvePoint g1 = EmbeddedCurvePoint::one();
8588
EmbeddedCurvePoint preaddress_public_key = g1 * Fq(preaddress);
@@ -215,6 +218,62 @@ TEST(AddressDerivationConstrainingTest, NegativeWithInteractions)
215218
"Failed.*PREADDRESS_SCALAR_MUL. Could not find tuple in destination.");
216219
}
217220

221+
TEST(AddressDerivationConstrainingTest, NegativeMutateImmutablesHash)
222+
{
223+
EventEmitter<EccAddEvent> ecadd_event_emitter;
224+
EventEmitter<ScalarMulEvent> scalar_mul_event_emitter;
225+
NoopEventEmitter<EccAddMemoryEvent> ecc_add_memory_event_emitter;
226+
EventEmitter<Poseidon2HashEvent> hash_event_emitter;
227+
NoopEventEmitter<Poseidon2PermutationEvent> perm_event_emitter;
228+
NoopEventEmitter<Poseidon2PermutationMemoryEvent> perm_mem_event_emitter;
229+
EventEmitter<AddressDerivationEvent> address_derivation_event_emitter;
230+
231+
StrictMock<MockExecutionIdManager> mock_exec_id_manager;
232+
EXPECT_CALL(mock_exec_id_manager, get_execution_id).WillRepeatedly(Return(0));
233+
StrictMock<MockGreaterThan> mock_gt;
234+
Poseidon2 poseidon2_simulator(
235+
mock_exec_id_manager, mock_gt, hash_event_emitter, perm_event_emitter, perm_mem_event_emitter);
236+
237+
PureToRadix to_radix_simulator;
238+
Ecc ecc_simulator(mock_exec_id_manager,
239+
mock_gt,
240+
to_radix_simulator,
241+
ecadd_event_emitter,
242+
scalar_mul_event_emitter,
243+
ecc_add_memory_event_emitter);
244+
245+
AddressDerivation address_derivation(poseidon2_simulator, ecc_simulator, address_derivation_event_emitter);
246+
247+
TestTraceContainer trace({
248+
{ { C::precomputed_first_row, 1 } },
249+
});
250+
251+
AddressDerivationTraceBuilder builder;
252+
Poseidon2TraceBuilder poseidon2_builder;
253+
EccTraceBuilder ecc_builder;
254+
255+
ContractInstance instance = testing::random_contract_instance();
256+
AztecAddress address = compute_contract_address(instance);
257+
address_derivation.assert_derivation(address, instance);
258+
259+
builder.process(address_derivation_event_emitter.dump_events(), trace);
260+
poseidon2_builder.process_hash(hash_event_emitter.dump_events(), trace);
261+
ecc_builder.process_add(ecadd_event_emitter.dump_events(), trace);
262+
ecc_builder.process_scalar_mul(scalar_mul_event_emitter.dump_events(), trace);
263+
264+
check_all_interactions<AddressDerivationTraceBuilder>(trace);
265+
check_relation<address_derivation_relation>(trace);
266+
267+
// Mutate immutables_hash (the second input of the second poseidon2 round). The salted-init-hash
268+
// round-2 lookup into poseidon2 should now fail because (deployer, mutated_immutables_hash, 0,
269+
// salted_init_hash) no longer exists in the poseidon2 trace.
270+
trace.set(C::address_derivation_immutables_hash, 0, instance.immutables_hash + 1);
271+
EXPECT_THROW_WITH_MESSAGE(
272+
(check_interaction<AddressDerivationTraceBuilder,
273+
lookup_address_derivation_salted_initialization_hash_poseidon2_1_settings>(trace)),
274+
"Failed.*SALTED_INITIALIZATION_HASH_POSEIDON2_1. Could not find tuple in destination.");
275+
}
276+
218277
TEST(AddressDerivationConstrainingTest, NegativeIVKNotOnCurve)
219278
{
220279
TestTraceContainer trace;
@@ -232,7 +291,7 @@ TEST(AddressDerivationConstrainingTest, NegativeIVKNotOnCurve)
232291
poseidon2::hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash });
233292

234293
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 });
294+
FF preaddress = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address });
236295

237296
EmbeddedCurvePoint g1 = EmbeddedCurvePoint::one();
238297
EmbeddedCurvePoint preaddress_public_key = g1 * Fq(preaddress);

barretenberg/cpp/src/barretenberg/vm2/constraining/relations/contract_instance_retrieval.test.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenValidInstance
472472
{ C::address_derivation_deployer_addr, contract_instance_data.deployer },
473473
{ C::address_derivation_class_id, contract_instance_data.original_contract_class_id },
474474
{ C::address_derivation_init_hash, contract_instance_data.initialization_hash },
475+
{ C::address_derivation_immutables_hash, contract_instance_data.immutables_hash },
475476
{ C::address_derivation_nullifier_key_x, contract_instance_data.public_keys.nullifier_key.x },
476477
{ C::address_derivation_nullifier_key_y, contract_instance_data.public_keys.nullifier_key.y },
477478
{ C::address_derivation_incoming_viewing_key_x, contract_instance_data.public_keys.incoming_viewing_key.x },
@@ -547,10 +548,11 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenNonExistentIn
547548
// For address derivation lookup
548549
{ C::address_derivation_sel, 0 }, // Not selected since nullifier doesn't exist
549550
{ C::address_derivation_address, contract_address },
550-
{ C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist
551-
{ C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist
552-
{ C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist
553-
{ C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist
551+
{ C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist
552+
{ C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist
553+
{ C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist
554+
{ C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist
555+
{ C::address_derivation_immutables_hash, 0 }, // zero since nullifier doesn't exist
554556
{ C::address_derivation_nullifier_key_x, 0 },
555557
{ C::address_derivation_nullifier_key_y, 0 },
556558
{ C::address_derivation_incoming_viewing_key_x, 0 },
@@ -628,10 +630,11 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenAddressZero)
628630
// For address derivation lookup
629631
{ C::address_derivation_sel, 0 }, // Not selected since nullifier doesn't exist
630632
{ C::address_derivation_address, contract_address },
631-
{ C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist
632-
{ C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist
633-
{ C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist
634-
{ C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist
633+
{ C::address_derivation_salt, 0 }, // zero since nullifier doesn't exist
634+
{ C::address_derivation_deployer_addr, 0 }, // zero since nullifier doesn't exist
635+
{ C::address_derivation_class_id, 0 }, // zero since nullifier doesn't exist
636+
{ C::address_derivation_init_hash, 0 }, // zero since nullifier doesn't exist
637+
{ C::address_derivation_immutables_hash, 0 }, // zero since nullifier doesn't exist
635638
{ C::address_derivation_nullifier_key_x, 0 },
636639
{ C::address_derivation_nullifier_key_y, 0 },
637640
{ C::address_derivation_incoming_viewing_key_x, 0 },
@@ -722,6 +725,7 @@ TEST(ContractInstanceRetrievalConstrainingTest, IntegrationTracegenMultipleInsta
722725
{ C::address_derivation_deployer_addr, contract_instance_data.deployer },
723726
{ C::address_derivation_class_id, contract_instance_data.original_contract_class_id },
724727
{ C::address_derivation_init_hash, contract_instance_data.initialization_hash },
728+
{ C::address_derivation_immutables_hash, contract_instance_data.immutables_hash },
725729
{ C::address_derivation_nullifier_key_x, contract_instance_data.public_keys.nullifier_key.x },
726730
{ C::address_derivation_nullifier_key_y, contract_instance_data.public_keys.nullifier_key.y },
727731
{ C::address_derivation_incoming_viewing_key_x,

0 commit comments

Comments
 (0)