Skip to content

Commit cdabd85

Browse files
authored
fix: make bytecode part of artifact hash preimage again (#9771)
In this PR, we are simply trying to re-introduce the bytecode hash as a part of the preimage to the function artifact hash. I had tried to reproduce the weird noir non-deterministic bytecode bug that @spalladino documented [here](https://aztecprotocol.slack.com/archives/C053490AV6V/p1713480846092319?thread_ts=1713445232.979779&cid=C053490AV6V) referenced in #5860 but was unable to do so. I see only matched bytecode hashes on local and CI: <img width="807" alt="•noir-projects+build-contracts bar_far," src="https://github.com/user-attachments/assets/404ae02f-4f72-4ea4-a5e1-43b2d96d507b"> <img width="733" alt="Pasted Graphic 6" src="https://github.com/user-attachments/assets/1a7e15bf-6ca6-45ab-bfa7-4b97ea336e61"> If this has been already fixed by the noir team it may make sense that this should be merged in to simply re-add the security check.
1 parent 10df7c5 commit cdabd85

File tree

5 files changed

+9
-15
lines changed

5 files changed

+9
-15
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ describe('ArtifactHash', () => {
3030

3131
for (let i = 0; i < 1000; i++) {
3232
expect(computeArtifactHash(testArtifact).toString()).toMatchInlineSnapshot(
33-
`"0x237feccc8e34a39c0e5133c8653fc278b39275bfa3f7459e4aba07d53b752c19"`,
33+
`"0x21070d88558fdc3906322f267cf6f0f632caf3949295520fe1f71f156fbb0d0b"`,
3434
);
3535
}
3636
});
@@ -43,7 +43,7 @@ describe('ArtifactHash', () => {
4343
const testArtifact = loadContractArtifact(content);
4444

4545
expect(computeArtifactHash(testArtifact).toString()).toMatchInlineSnapshot(
46-
`"0x237feccc8e34a39c0e5133c8653fc278b39275bfa3f7459e4aba07d53b752c19"`,
46+
`"0x21070d88558fdc3906322f267cf6f0f632caf3949295520fe1f71f156fbb0d0b"`,
4747
);
4848
});
4949
});

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

+4-5
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,10 @@ export function computeFunctionArtifactHash(
9292
| (Pick<FunctionArtifact, 'bytecode'> & { functionMetadataHash: Fr; selector: FunctionSelector }),
9393
) {
9494
const selector = 'selector' in fn ? fn.selector : FunctionSelector.fromNameAndParameters(fn);
95-
// TODO(#5860): make bytecode part of artifact hash preimage again
96-
// const bytecodeHash = sha256Fr(fn.bytecode).toBuffer();
97-
// const metadataHash = 'functionMetadataHash' in fn ? fn.functionMetadataHash : computeFunctionMetadataHash(fn);
98-
// return sha256Fr(Buffer.concat([numToUInt8(VERSION), selector.toBuffer(), metadataHash.toBuffer(), bytecodeHash]));
99-
return sha256Fr(Buffer.concat([numToUInt8(VERSION), selector.toBuffer()]));
95+
96+
const bytecodeHash = sha256Fr(fn.bytecode).toBuffer();
97+
const metadataHash = 'functionMetadataHash' in fn ? fn.functionMetadataHash : computeFunctionMetadataHash(fn);
98+
return sha256Fr(Buffer.concat([numToUInt8(VERSION), selector.toBuffer(), metadataHash.toBuffer(), bytecodeHash]));
10099
}
101100

102101
export function computeFunctionMetadataHash(fn: FunctionArtifact) {

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ describe('private_function_membership_proof', () => {
3131
expect(isValidPrivateFunctionMembershipProof(fn, contractClass)).toBeTruthy();
3232
});
3333

34-
// TODO(#5860): Re-enable this test once noir non-determinism is addressed
35-
test.skip.each([
34+
test.each([
3635
'artifactTreeSiblingPath',
3736
'artifactMetadataHash',
3837
'functionMetadataHash',

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

+1-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ describe('unconstrained_function_membership_proof', () => {
5050
expect(isValidUnconstrainedFunctionMembershipProof(fn, contractClass)).toBeTruthy();
5151
});
5252

53-
// TODO(#5860): Re-enable this test once noir non-determinism is addressed
54-
test.skip.each(['artifactTreeSiblingPath', 'artifactMetadataHash', 'functionMetadataHash'] as const)(
53+
test.each(['artifactTreeSiblingPath', 'artifactMetadataHash', 'functionMetadataHash'] as const)(
5554
'fails proof if %s is mangled',
5655
field => {
5756
const proof = createUnconstrainedFunctionMembershipProof(selector, artifact);

yarn-project/pxe/src/pxe_service/pxe_service.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,7 @@ export class PXEService implements PXE {
250250
`Artifact does not match expected class id (computed ${contractClassId} but instance refers to ${instance.contractClassId})`,
251251
);
252252
}
253-
if (
254-
// Computed address from the instance does not match address inside instance
255-
!computeContractAddressFromInstance(instance).equals(instance.address)
256-
) {
253+
if (!computeContractAddressFromInstance(instance).equals(instance.address)) {
257254
throw new Error('Added a contract in which the address does not match the contract instance.');
258255
}
259256

0 commit comments

Comments
 (0)