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
5#include "barretenberg/aztec/aztec_constants.hpp"
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,
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,
68 incoming_viewing_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.
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
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