Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
address_derivation.cpp
Go to the documentation of this file.
2
3#include <cassert>
4
8
9namespace bb::avm2::simulation {
10
33{
34 // Check if we've already derived this address.
35 if (cached_derivations.contains(address)) {
36 // Note: it is likely safe to skip this recalculation, but if we do, then a mismatch will throw in the
37 // non-cache case and return in the cache case for the same input. No events are emitted either way, so
38 // circuit and tracegen behave the same. The below exists just to unify simulation behaviour (#21374).
39 BB_ASSERT_EQ(address, simulation::compute_contract_address(instance), "Address derivation mismatch");
40 // Already processed this address - cache hit, don't emit event.
41 return;
42 }
43
44 // First time seeing this address - do the actual derivation.
45 // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[SALTED_INITIALIZATION_HASH_POSEIDON2_i] in
46 // address_derivation.pil.
47 FF salted_initialization_hash = poseidon2.hash(
49 // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PARTIAL_ADDRESS_POSEIDON2] in
50 // address_derivation.pil.
51 FF partial_address =
52 poseidon2.hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash });
53
54 std::vector<FF> public_keys_hash_fields = instance.public_keys.to_fields();
55 std::vector<FF> public_key_hash_vec{ DOM_SEP__PUBLIC_KEYS_HASH };
56 for (size_t i = 0; i < public_keys_hash_fields.size(); i += 2) {
57 // Public key x coordinate.
58 public_key_hash_vec.push_back(public_keys_hash_fields[i]);
59 // Public key y coordinate.
60 public_key_hash_vec.push_back(public_keys_hash_fields[i + 1]);
61 // TODO(#7529): Public key is_infinity will be removed from address preimage, assuming false.
62 public_key_hash_vec.push_back(FF::zero());
63 }
64 // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PUBLIC_KEYS_HASH_POSEIDON2_i] in
65 // address_derivation.pil.
66 FF public_keys_hash = poseidon2.hash(public_key_hash_vec);
67 // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PREADDRESS_POSEIDON2] in address_derivation.pil.
68 FF preaddress = poseidon2.hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address });
69
70 // Note: the below ecc calls assume points are on the curve. We know preaddress_public_key is (by definition),
71 // but it may be possible that incoming_viewing_key is not.
72 // The circuit enforces that the point is on the curve to meet ecc's precondition and we replicate this here.
74 "Incoming viewing key is not on the curve when asserting contract address derivation");
75
76 // Emits ScalarMulEvent and EccAddEvents, see #[PREADDRESS_SCALAR_MUL] in address_derivation.pil.
77 EmbeddedCurvePoint preaddress_public_key = ecc.scalar_mul(EmbeddedCurvePoint::one(), preaddress);
78 // Emits EccAddEvent, see #[ADDRESS_ECADD] in address_derivation.pil.
79 EmbeddedCurvePoint address_point = ecc.add(preaddress_public_key, instance.public_keys.incoming_viewing_key);
80
81 // This will throw an unexpected exception if it fails. If we have reached this point,
82 // the contract instance retrieval should have enforced this.
83 BB_ASSERT_EQ(address, address_point.x(), "Address derivation mismatch");
84
85 // Cache this derivation so we don't repeat it
87
88 // Emits AddressDerivationEvent.
89 events.emit({
90 .address = address,
91 .instance = instance,
92 .salted_initialization_hash = salted_initialization_hash,
93 .partial_address = partial_address,
94 .public_keys_hash = public_keys_hash,
95 .preaddress = preaddress,
96 .preaddress_public_key = preaddress_public_key,
97 .address_point = address_point,
98 });
99}
100
101} // namespace bb::avm2::simulation
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
#define DOM_SEP__SALTED_INITIALIZATION_HASH
#define DOM_SEP__PARTIAL_ADDRESS
#define DOM_SEP__PUBLIC_KEYS_HASH
#define DOM_SEP__CONTRACT_ADDRESS_V1
constexpr const BaseField & x() const noexcept
unordered_flat_set< AztecAddress > cached_derivations
void assert_derivation(const AztecAddress &address, const ContractInstance &instance) override
Verifies a contract instance's address derivation and emits an AddressDerivationEvent....
EventEmitterInterface< AddressDerivationEvent > & events
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
constexpr bool on_curve() const noexcept
AVM range check gadget for witness generation.
FF compute_contract_address(const ContractInstance &contract_instance)
AvmFlavorSettings::FF FF
Definition field.hpp:10
ContractClassId original_contract_class_id
AffinePoint incoming_viewing_key
std::vector< FF > to_fields() const