Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
contract_crypto.cpp
Go to the documentation of this file.
2
6
7namespace bb::avm2::simulation {
8
10
12{
13 size_t bytecode_len = bytecode.size();
14
15 auto bytecode_field_at = [&](size_t i) -> FF {
16 // We need to read uint256_ts because reading FFs messes up the order of the bytes.
17 uint256_t as_int = 0;
18 if (bytecode_len - i >= 32) {
19 as_int = from_buffer<uint256_t>(bytecode, i);
20 } else {
21 std::vector<uint8_t> tail(bytecode.begin() + static_cast<ssize_t>(i), bytecode.end());
22 tail.resize(32, 0);
23 as_int = from_buffer<uint256_t>(tail, 0);
24 }
25 return as_int >> 8;
26 };
27
28 std::vector<FF> contract_bytecode_fields;
29 auto number_of_fields = (bytecode_len + 30) / 31;
30 contract_bytecode_fields.reserve(number_of_fields);
31
32 for (uint32_t i = 0; i < bytecode_len; i += 31) {
33 FF bytecode_field = bytecode_field_at(i);
34 contract_bytecode_fields.push_back(bytecode_field);
35 }
36
37 return contract_bytecode_fields;
38}
39
40// Takes the size of the bytecode in bytes and computes the field prepended to the public bytecode
41// commitment hash.
43{
44 // Note: Shifting by 32 (4 bytes). This value was chosen to keep the value of the first field small, avoiding having
45 // to change types further down the stack. The maximum first field is currently:
46 // Fr<0x00000000000000000000000000000000000000000000000000016b480f8411f1> From: max fields in bytes = 3000 * 31 =
47 // 16b48, Dom sep = f8411f1
48 static_assert(DOM_SEP__PUBLIC_BYTECODE <= UINT32_MAX, "Public bytecode domain separator must fit in 32 bits");
49 return uint256_t(DOM_SEP__PUBLIC_BYTECODE) + uint256_t(bytecode_size << 32);
50}
51
53{
54 std::vector<FF> inputs = { compute_public_bytecode_first_field(bytecode.size()) };
55 auto bytecode_as_fields = encode_bytecode(bytecode);
56 inputs.insert(inputs.end(), bytecode_as_fields.begin(), bytecode_as_fields.end());
57 return poseidon2::hash(inputs);
58}
59
60FF compute_contract_class_id(const FF& artifact_hash, const FF& private_fn_root, const FF& public_bytecode_commitment)
61{
62 return poseidon2::hash({ DOM_SEP__CONTRACT_CLASS_ID, artifact_hash, private_fn_root, public_bytecode_commitment });
63}
64
65FF hash_public_keys(const PublicKeys& public_keys)
66{
67 std::vector<FF> public_keys_hash_fields = public_keys.to_fields();
68
69 std::vector<FF> public_key_hash_vec{ DOM_SEP__PUBLIC_KEYS_HASH };
70 for (size_t i = 0; i < public_keys_hash_fields.size(); i += 2) {
71 public_key_hash_vec.push_back(public_keys_hash_fields[i]);
72 public_key_hash_vec.push_back(public_keys_hash_fields[i + 1]);
73 // is_infinity will be removed from address preimage, asumming false.
74 public_key_hash_vec.push_back(FF::zero());
75 }
76 return poseidon2::hash({ public_key_hash_vec });
77}
78
80{
81 FF salted_initialization_hash = poseidon2::hash({ DOM_SEP__PARTIAL_ADDRESS,
82 contract_instance.salt,
83 contract_instance.initialization_hash,
84 contract_instance.deployer });
85 FF partial_address = poseidon2::hash(
86 { DOM_SEP__PARTIAL_ADDRESS, contract_instance.original_contract_class_id, salted_initialization_hash });
87
88 FF public_keys_hash = hash_public_keys(contract_instance.public_keys);
89 FF h = poseidon2::hash({ DOM_SEP__CONTRACT_ADDRESS_V1, public_keys_hash, partial_address });
90 // This is safe since BN254_Fr < GRUMPKIN_Fr so we know there is no modulo reduction
91 grumpkin::fr h_fq = grumpkin::fr(h);
93 "Incoming viewing key is not on the curve when computing contract address");
94 return (grumpkin::g1::affine_one * h_fq + contract_instance.public_keys.incoming_viewing_key).x;
95}
96
98{
99 std::vector<FF> calldata_with_sep = { DOM_SEP__PUBLIC_CALLDATA };
100 for (const auto& value : calldata) {
101 // Note: Using `insert` breaks GCC.
102 calldata_with_sep.push_back(value);
103 }
104 return poseidon2::hash(calldata_with_sep);
105}
106
107} // namespace bb::avm2::simulation
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
std::shared_ptr< Napi::ThreadSafeFunction > bytecode
#define DOM_SEP__PARTIAL_ADDRESS
#define DOM_SEP__PUBLIC_BYTECODE
#define DOM_SEP__PUBLIC_CALLDATA
#define DOM_SEP__PUBLIC_KEYS_HASH
#define DOM_SEP__CONTRACT_ADDRESS_V1
#define DOM_SEP__CONTRACT_CLASS_ID
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
constexpr bool on_curve() const noexcept
static constexpr affine_element affine_one
Definition group.hpp:48
AvmProvingInputs inputs
AVM range check gadget for witness generation.
FF compute_public_bytecode_commitment(std::span< const uint8_t > bytecode)
FF hash_public_keys(const PublicKeys &public_keys)
std::vector< FF > encode_bytecode(std::span< const uint8_t > bytecode)
FF compute_contract_class_id(const FF &artifact_hash, const FF &private_fn_root, const FF &public_bytecode_commitment)
FF compute_public_bytecode_first_field(size_t bytecode_size)
FF compute_calldata_hash(std::span< const FF > calldata)
FF compute_contract_address(const ContractInstance &contract_instance)
AvmFlavorSettings::FF FF
Definition field.hpp:10
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
ContractClassId original_contract_class_id
AffinePoint incoming_viewing_key
std::vector< FF > to_fields() const