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
35{
36 // Check if we've already derived this address.
37 if (cached_derivations.contains(address)) {
38 // Note: it is likely safe to skip this recalculation, but if we do, then a mismatch will throw in the
39 // non-cache case and return in the cache case for the same input. No events are emitted either way, so
40 // circuit and tracegen behave the same. The below exists just to unify simulation behaviour (#21374).
41 BB_ASSERT_EQ(address, simulation::compute_contract_address(instance), "Address derivation mismatch");
42 // Already processed this address - cache hit, don't emit event.
43 return;
44 }
45
46 // First time seeing this address - do the actual derivation.
47 // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[SALTED_INITIALIZATION_HASH_POSEIDON2_i] in
48 // address_derivation.pil.
49 FF salted_initialization_hash = poseidon2.hash({ DOM_SEP__SALTED_INITIALIZATION_HASH,
50 instance.salt,
51 instance.initialization_hash,
52 instance.deployer,
53 instance.immutables_hash });
54
55 // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PARTIAL_ADDRESS_POSEIDON2] in
56 // address_derivation.pil.
57 FF partial_address =
58 poseidon2.hash({ DOM_SEP__PARTIAL_ADDRESS, instance.original_contract_class_id, salted_initialization_hash });
59
60 // incoming_viewing_key_hash is the only single-key hash computed in-circuit (see #[IVPK_M_HASH_POSEIDON2]).
61 FF incoming_viewing_key_hash = poseidon2.hash({ DOM_SEP__SINGLE_PUBLIC_KEY_HASH,
62 instance.public_keys.incoming_viewing_key.x,
63 instance.public_keys.incoming_viewing_key.y });
64
65 // public_keys_hash combines the six single-key hashes (see #[PUBLIC_KEYS_HASH_POSEIDON2_0..2]).
66 FF public_keys_hash = poseidon2.hash({ DOM_SEP__PUBLIC_KEYS_HASH,
67 instance.public_keys.nullifier_key_hash,
68 incoming_viewing_key_hash,
69 instance.public_keys.outgoing_viewing_key_hash,
70 instance.public_keys.tagging_key_hash,
71 instance.public_keys.message_signing_key_hash,
72 instance.public_keys.fallback_key_hash });
73
74 // Emits Poseidon2HashEvents and Poseidon2PermutationEvents, see #[PREADDRESS_POSEIDON2] in address_derivation.pil.
75 FF preaddress = poseidon2.hash({ DOM_SEP__CONTRACT_ADDRESS_V2, public_keys_hash, partial_address });
76
77 // Note: the below ecc calls assume points are on the curve. We know preaddress_public_key is (by definition),
78 // but it may be possible that incoming_viewing_key is not.
79 // The circuit enforces that the point is on the curve to meet ecc's precondition and we replicate this here.
80 BB_ASSERT(instance.public_keys.incoming_viewing_key.on_curve(),
81 "Incoming viewing key is not on the curve when asserting contract address derivation");
82
83 // Emits ScalarMulEvent and EccAddEvents, see #[PREADDRESS_SCALAR_MUL] in address_derivation.pil.
84 EmbeddedCurvePoint preaddress_public_key = ecc.scalar_mul(EmbeddedCurvePoint::one(), preaddress);
85 // Emits EccAddEvent, see #[ADDRESS_ECADD] in address_derivation.pil.
86 EmbeddedCurvePoint address_point = ecc.add(preaddress_public_key, instance.public_keys.incoming_viewing_key);
87
88 // This will throw an unexpected exception if it fails. If we have reached this point,
89 // the contract instance retrieval should have enforced this.
90 BB_ASSERT_EQ(address, address_point.x(), "Address derivation mismatch");
91
92 // Cache this derivation so we don't repeat it
94
95 // Emits AddressDerivationEvent.
96 events.emit({
97 .address = address,
98 .instance = instance,
99 .salted_initialization_hash = salted_initialization_hash,
100 .partial_address = partial_address,
101 .incoming_viewing_key_hash = incoming_viewing_key_hash,
102 .public_keys_hash = public_keys_hash,
103 .preaddress = preaddress,
104 .preaddress_public_key = preaddress_public_key,
105 .address_point = address_point,
106 });
107}
108
109} // namespace bb::avm2::simulation
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:83
std::shared_ptr< Napi::ThreadSafeFunction > instance
#define DOM_SEP__SALTED_INITIALIZATION_HASH
#define DOM_SEP__SINGLE_PUBLIC_KEY_HASH
#define DOM_SEP__CONTRACT_ADDRESS_V2
#define DOM_SEP__PARTIAL_ADDRESS
#define DOM_SEP__PUBLIC_KEYS_HASH
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.
AVM range check gadget for witness generation.
FF compute_contract_address(const ContractInstance &contract_instance)
AvmFlavorSettings::FF FF
Definition field.hpp:10