Skip to content

Commit ab2c860

Browse files
authored
feat(avm)!: include length in bytecode hash (#11425)
Looks like it's easier to constrain the length of bytecode in the avm if we just include it in the hash computation
1 parent 7b510fe commit ab2c860

File tree

8 files changed

+22
-18
lines changed

8 files changed

+22
-18
lines changed

barretenberg/cpp/src/barretenberg/crypto/poseidon2/c_bind.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ WASM_EXPORT void poseidon2_hash_accumulate(fr::vec_in_buf inputs_buffer, fr::out
5353
std::vector<fr> to_hash;
5454
read(inputs_buffer, to_hash);
5555
const size_t numHashes = to_hash.size();
56-
fr result = 0;
57-
size_t count = 0;
56+
fr result = to_hash[0];
57+
size_t count = 1;
5858
while (count < numHashes) {
5959
result = crypto::Poseidon2<crypto::Poseidon2Bn254ScalarFieldParams>::hash({ to_hash[count], result });
6060
++count;

barretenberg/cpp/src/barretenberg/vm/avm/trace/bytecode_trace.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,9 @@ std::vector<FF> AvmBytecodeTraceBuilder::encode_bytecode(const std::vector<uint8
8080
// Compute the public bytecode commitment from a given contract bytecode
8181
FF AvmBytecodeTraceBuilder::compute_public_bytecode_commitment(const std::vector<uint8_t>& contract_bytes)
8282
{
83+
FF bytecode_length_in_bytes = FF(static_cast<uint64_t>(contract_bytes.size()));
8384
std::vector<FF> contract_bytecode_fields = encode_bytecode(contract_bytes);
84-
FF running_hash = FF::zero();
85+
FF running_hash = bytecode_length_in_bytes;
8586
for (auto& contract_bytecode_field : contract_bytecode_fields) {
8687
running_hash = poseidon2::hash({ contract_bytecode_field, running_hash });
8788
}
@@ -114,7 +115,8 @@ void AvmBytecodeTraceBuilder::build_bytecode_hash_columns()
114115
if (contract_bytecode.bytecode.size() == 0) {
115116
vinfo("Excluding non-existent contract from bytecode hash columns...");
116117
} else {
117-
FF running_hash = FF::zero();
118+
auto bytecode_length_in_bytes = FF(static_cast<uint64_t>(contract_bytecode.bytecode.size()));
119+
FF running_hash = bytecode_length_in_bytes;
118120
auto field_encoded_bytecode = encode_bytecode(contract_bytecode.bytecode);
119121
// This size is already based on the number of fields
120122
for (size_t i = 0; i < field_encoded_bytecode.size(); ++i) {

barretenberg/cpp/src/barretenberg/vm2/simulation/lib/contract_crypto.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ FF compute_public_bytecode_commitment(std::span<const uint8_t> bytecode)
2727
return contract_bytecode_fields;
2828
};
2929

30+
FF bytecode_length_in_bytes = FF(static_cast<uint64_t>(bytecode.size()));
3031
std::vector<FF> contract_bytecode_fields = encode_bytecode(bytecode);
31-
FF running_hash = 0;
32+
FF running_hash = bytecode_length_in_bytes;
3233
for (const auto& contract_bytecode_field : contract_bytecode_fields) {
3334
running_hash = poseidon2::hash({ contract_bytecode_field, running_hash });
3435
}
@@ -66,4 +67,4 @@ FF compute_contract_address(const ContractInstance& contract_instance)
6667
return (grumpkin::g1::affine_one * h_fq + contract_instance.public_keys.incoming_viewing_key).x;
6768
}
6869

69-
} // namespace bb::avm2::simulation
70+
} // namespace bb::avm2::simulation

noir-projects/noir-contracts/contracts/contract_class_registerer_contract/src/main.nr

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ contract ContractClassRegisterer {
5656
(bytecode_length_in_bytes / 31) + (bytecode_length_in_bytes % 31 != 0) as u32;
5757
assert(bytecode_length_in_fields < MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS);
5858

59-
let mut computed_public_bytecode_commitment = 0;
59+
// The first value in the running hash is the bytecode length in bytes
60+
let mut computed_public_bytecode_commitment = packed_public_bytecode[0];
6061
// We can hash up to MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS - 1, since the first element is the length
6162
for i in 0..(MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS - 1) {
6263
// While we are forced to run the hash MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS times in the circuit,

yarn-project/circuits.js/src/contract/contract_class_id.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ describe('ContractClass', () => {
2525
};
2626

2727
expect(computeContractClassId(contractClass).toString()).toMatchInlineSnapshot(
28-
`"0x2d5c712c483891d42e5bca539e8516fc52b5b024568ac71e4fe47c0c0157f851"`,
28+
`"0x2c3a8b2ad29dd4000cb827e973737bcf57fc072aeaf93ceeef4b4b9eb086cf67"`,
2929
);
3030
});
3131
});

yarn-project/circuits.js/src/contract/contract_class_id.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,5 @@ export function computePublicBytecodeCommitment(packedBytecode: Buffer) {
6666
const bytecodeLength = Math.ceil(encodedBytecode[0].toNumber() / (Fr.SIZE_IN_BYTES - 1));
6767
assert(bytecodeLength < MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, 'Bytecode exceeds maximum deployable size');
6868

69-
return bytecodeLength == 0 ? new Fr(0) : poseidon2HashAccumulate(encodedBytecode.slice(1, bytecodeLength + 1));
69+
return bytecodeLength == 0 ? new Fr(0) : poseidon2HashAccumulate(encodedBytecode.slice(0, bytecodeLength + 1));
7070
}

yarn-project/noir-protocol-circuits-types/src/__snapshots__/noir_test_gen.test.ts.snap

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ exports[`Data generation for noir tests Computes contract info for defaultContra
44
"{
55
contract_address_salt: 0x000000000000000000000000000000000000000000000000000000000000ddd5,
66
artifact_hash: 0x0000000000000000000000000000000000000000000000000000000000003039,
7-
public_bytecode_commitment: 0x11fb08be2c55e530172e671f647b16dddf9b66acf42489d0236785d8f7bc8b48,
7+
public_bytecode_commitment: 0x2e018d154e7faf1ddf8400a4b3605574e69afc04425f3e662e054dc094fb0428,
88
private_functions_root: 0x25d76df45434ec75a83321daf941cfc667ff3a9027942e17105da4f50d1d13f9,
9-
address: AztecAddress { inner: 0x29bc2e90ff6ec5f4a7c7f502e368af01eb74131a2eec6320e0e45419cddc7b6d },
10-
partial_address: PartialAddress { inner: 0x1a68423cf4f04eaede2b0e93131916b8b7330dae6e8ee202679d12a4eb49cc0b },
11-
contract_class_id: ContractClassId { inner: 0x1195b865ef122d75c8c4d6102d536193b69bbb712c85bafcbf7694f52e2d8c36 },
9+
address: AztecAddress { inner: 0x0d4379385723a3f96a0d9d59be7dc869e042a9f5b832749039a993e5ee6b91b8 },
10+
partial_address: PartialAddress { inner: 0x0b419abfd8ca509592b671ed9808138dced1df38835cbf3b3b693ad71623c90d },
11+
contract_class_id: ContractClassId { inner: 0x23b90310794d8e4ee1f13c0b97b4f5d11ddfa1642ad60e46169c3d3b2c6e03a6 },
1212
public_keys: PublicKeys { inner: 0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f },
1313
salted_initialization_hash: SaltedInitializationHash { inner: 0x13a939daa511233e5446905ed2cadbee14948fa75df183b53b5c14b612bffe88 },
1414
deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 }
@@ -19,11 +19,11 @@ exports[`Data generation for noir tests Computes contract info for parentContrac
1919
"{
2020
contract_address_salt: 0x0000000000000000000000000000000000000000000000000000000000001618,
2121
artifact_hash: 0x00000000000000000000000000000000000000000000000000000000000004bc,
22-
public_bytecode_commitment: 0x1c5009dd5e8baedc8dfb2e801c9f97361b1ae152ff52f82104119c476b369bef,
22+
public_bytecode_commitment: 0x258ed5ce21c3a9c15a1c6108ef0e759bb0617f2b505b8d64e927027d30e71791,
2323
private_functions_root: 0x1228b39ba6702af03e595300e8484c6373f00790d0148cc3d4ff0fd1c778a83a,
24-
address: AztecAddress { inner: 0x2749b685f752f6dfe1d4e532fc036839004926b7c18abf1a4f69ddf97d62f40e },
25-
partial_address: PartialAddress { inner: 0x1c30ee02dcd41bcdfc5191dc36ccaae15cdc7e1fc6bd8a0cbe1baeaf1335a771 },
26-
contract_class_id: ContractClassId { inner: 0x24f1b8df215c10ee7edd213b439c8f8e99198a802a3e1e41597b6554b17049a3 },
24+
address: AztecAddress { inner: 0x0907b0edaac863b283132ee3a4781395ace64ff8cec244f1c5235e88c320cca1 },
25+
partial_address: PartialAddress { inner: 0x00906eed7cc361cc78056365c5ddbb94fd8fa05c5fed118bd4033585914cda92 },
26+
contract_class_id: ContractClassId { inner: 0x1ffddcc4c6d113ae695384e3bae42cb0c4c6d8ba7edbb80c8c23848b55cd37f3 },
2727
public_keys: PublicKeys { inner: 0x01498945581e0eb9f8427ad6021184c700ef091d570892c437d12c7d90364bbd170ae506787c5c43d6ca9255d571c10fa9ffa9d141666e290c347c5c9ab7e34400c044b05b6ca83b9c2dbae79cc1135155956a64e136819136e9947fe5e5866c1c1f0ca244c7cd46b682552bff8ae77dea40b966a71de076ec3b7678f2bdb1511b00316144359e9a3ec8e49c1cdb7eeb0cedd190dfd9dc90eea5115aa779e287080ffc74d7a8b0bccb88ac11f45874172f3847eb8b92654aaa58a3d2b8dc7833019c111f36ad3fc1d9b7a7a14344314d2864b94f030594cd67f753ef774a1efb2039907fe37f08d10739255141bb066c506a12f7d1e8dfec21abc58494705b6f },
2828
salted_initialization_hash: SaltedInitializationHash { inner: 0x24bd6ac7a182e2cf25e437c72f53544ef81dfd97d9afee23abb07a638e7be749 },
2929
deployer: AztecAddress { inner: 0x0000000000000000000000000000000000000000000000000000000000000000 }

yarn-project/protocol-contracts/src/class-registerer/contract_class_registered_event.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe('ContractClassRegisteredEvent', () => {
1515
expect(event.artifactHash.toString()).toEqual('0x072dce903b1a299d6820eeed695480fe9ec46658b1101885816aed6dd86037f0');
1616
expect(event.packedPublicBytecode.length).toEqual(27090);
1717
expect(computePublicBytecodeCommitment(event.packedPublicBytecode).toString()).toEqual(
18-
'0x0378491b34825cd67d1e13e140bbc80f2cd3a9b52171ea577f8f11620d4198ba',
18+
'0x1d7d509f736d09975b88d01b5779a6f52e70905ba9294776d4881e811e6c1e9f',
1919
);
2020
});
2121
});

0 commit comments

Comments
 (0)