From 0e0748cacac5b0e04e76b7241a07be372daaf32d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Tue, 26 Mar 2024 15:46:35 +0100 Subject: [PATCH] refactor: leveraging `Bufferable` in `pedersenHash(...)` and `sha256ToField(...)` (#5444) We had a ton of manual conversions to buffer when computing hashes. A few PRs ago I sneaked in a modification and pedersenHash(...) now accepts `Bufferable[]` instead of `Buffer[]`. In this PR I leverage this and remove the unnecessary conversions and do the same for `sha256ToField(...)`. --- yarn-project/aztec.js/src/utils/authwit.ts | 10 +- .../aztec.js/src/utils/cheat_codes.ts | 2 +- yarn-project/circuit-types/src/l2_block.ts | 6 +- .../src/messaging/l1_to_l2_message.ts | 2 +- .../src/contract/contract_address.ts | 18 +- .../src/contract/contract_class_id.ts | 2 +- .../src/contract/private_function.ts | 5 +- yarn-project/circuits.js/src/hash/hash.ts | 29 +- yarn-project/circuits.js/src/keys/index.ts | 2 +- .../circuits.js/src/structs/function_data.ts | 5 +- .../circuits.js/src/structs/header.ts | 5 +- .../src/structs/private_call_stack_item.ts | 5 +- .../structs/private_circuit_public_inputs.ts | 5 +- .../src/structs/public_call_stack_item.ts | 2 +- .../structs/public_circuit_public_inputs.ts | 5 +- .../circuits.js/src/structs/tx_context.ts | 5 +- .../circuits.js/src/structs/tx_request.ts | 5 +- .../end-to-end/src/e2e_block_building.test.ts | 4 +- .../src/e2e_cross_chain_messaging.test.ts | 23 +- .../end-to-end/src/e2e_outbox.test.ts | 16 +- .../e2e_public_cross_chain_messaging.test.ts | 39 +- .../src/shared/cross_chain_test_harness.ts | 30 +- .../end-to-end/src/shared/uniswap_l1_l2.ts | 332 ++++++++---------- .../src/simulators/lending_simulator.ts | 2 +- .../entrypoints/src/entrypoint_payload.ts | 7 +- .../foundation/src/crypto/sha256/index.ts | 6 +- yarn-project/foundation/src/fields/point.ts | 4 +- .../foundation/src/serialize/serialize.ts | 2 +- .../pxe/src/database/deferred_note_dao.ts | 12 +- yarn-project/pxe/src/database/note_dao.ts | 24 +- .../src/note_processor/note_processor.test.ts | 7 +- .../src/sequencer/tx_validator.test.ts | 8 +- .../src/sequencer/tx_validator.ts | 2 +- .../src/avm/avm_execution_environment.ts | 5 +- .../simulator/src/avm/avm_simulator.test.ts | 2 +- .../simulator/src/avm/opcodes/hashing.test.ts | 6 +- .../simulator/src/avm/opcodes/hashing.ts | 2 +- .../src/client/private_execution.test.ts | 12 +- .../simulator/src/client/simulator.test.ts | 8 +- .../simulator/src/public/index.test.ts | 10 +- yarn-project/simulator/src/test/utils.ts | 3 +- yarn-project/simulator/src/utils.ts | 2 +- 42 files changed, 288 insertions(+), 393 deletions(-) diff --git a/yarn-project/aztec.js/src/utils/authwit.ts b/yarn-project/aztec.js/src/utils/authwit.ts index b7fd074d300..0979524b9dd 100644 --- a/yarn-project/aztec.js/src/utils/authwit.ts +++ b/yarn-project/aztec.js/src/utils/authwit.ts @@ -40,10 +40,7 @@ export const computeAuthWitMessageHash = (caller: AztecAddress, chainId: Fr, ver * @returns The inner hash for the witness */ export const computeInnerAuthWitHash = (args: Fr[]) => { - return pedersenHash( - args.map(fr => fr.toBuffer()), - GeneratorIndex.AUTHWIT_INNER, - ); + return pedersenHash(args, GeneratorIndex.AUTHWIT_INNER); }; /** @@ -61,8 +58,5 @@ export const computeInnerAuthWitHash = (args: Fr[]) => { * @returns The outer hash for the witness */ export const computeOuterAuthWitHash = (consumer: AztecAddress, chainId: Fr, version: Fr, innerHash: Fr) => { - return pedersenHash( - [consumer.toField(), chainId, version, innerHash].map(fr => fr.toBuffer()), - GeneratorIndex.AUTHWIT_OUTER, - ); + return pedersenHash([consumer.toField(), chainId, version, innerHash], GeneratorIndex.AUTHWIT_OUTER); }; diff --git a/yarn-project/aztec.js/src/utils/cheat_codes.ts b/yarn-project/aztec.js/src/utils/cheat_codes.ts index b22aa828bee..49f91a3247a 100644 --- a/yarn-project/aztec.js/src/utils/cheat_codes.ts +++ b/yarn-project/aztec.js/src/utils/cheat_codes.ts @@ -246,7 +246,7 @@ export class AztecCheatCodes { public computeSlotInMap(baseSlot: Fr | bigint, key: Fr | bigint | AztecAddress): Fr { // Based on `at` function in // aztec3-packages/aztec-nr/aztec/src/state_vars/map.nr - return pedersenHash([new Fr(baseSlot), new Fr(key)].map(f => f.toBuffer())); + return pedersenHash([new Fr(baseSlot), new Fr(key)]); } /** diff --git a/yarn-project/circuit-types/src/l2_block.ts b/yarn-project/circuit-types/src/l2_block.ts index db167a6640e..c62b4e8c9db 100644 --- a/yarn-project/circuit-types/src/l2_block.ts +++ b/yarn-project/circuit-types/src/l2_block.ts @@ -145,7 +145,7 @@ export class L2Block { */ // TODO(#4844) getPublicInputsHash(): Fr { - const buf = serializeToBuffer( + const preimage = [ this.header.globalVariables, AppendOnlyTreeSnapshot.zero(), // this.startNoteHashTreeSnapshot / commitments, AppendOnlyTreeSnapshot.zero(), // this.startNullifierTreeSnapshot, @@ -158,9 +158,9 @@ export class L2Block { this.header.state.l1ToL2MessageTree, this.archive, this.body.getTxsEffectsHash(), - ); + ]; - return sha256ToField(buf); + return sha256ToField(preimage); } /** diff --git a/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts b/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts index 07666712eee..79980b07da4 100644 --- a/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts +++ b/yarn-project/circuit-types/src/messaging/l1_to_l2_message.ts @@ -41,7 +41,7 @@ export class L1ToL2Message { } hash(): Fr { - return sha256ToField(serializeToBuffer(...this.toFields())); + return sha256ToField(this.toFields()); } static fromBuffer(buffer: Buffer | BufferReader): L1ToL2Message { diff --git a/yarn-project/circuits.js/src/contract/contract_address.ts b/yarn-project/circuits.js/src/contract/contract_address.ts index 2f5e684ac1d..68802e622cf 100644 --- a/yarn-project/circuits.js/src/contract/contract_address.ts +++ b/yarn-project/circuits.js/src/contract/contract_address.ts @@ -43,10 +43,7 @@ export function computePartialAddress( ? instance.saltedInitializationHash : computeSaltedInitializationHash(instance); - return pedersenHash( - [instance.contractClassId, saltedInitializationHash].map(x => x.toBuffer()), - GeneratorIndex.PARTIAL_ADDRESS, - ); + return pedersenHash([instance.contractClassId, saltedInitializationHash], GeneratorIndex.PARTIAL_ADDRESS); } /** @@ -57,9 +54,7 @@ export function computeSaltedInitializationHash( instance: Pick, ): Fr { return pedersenHash( - [instance.salt, instance.initializationHash, instance.deployer, instance.portalContractAddress].map(x => - x.toBuffer(), - ), + [instance.salt, instance.initializationHash, instance.deployer, instance.portalContractAddress], GeneratorIndex.PARTIAL_ADDRESS, ); } @@ -73,10 +68,7 @@ export function computeContractAddressFromPartial( args: ({ publicKeyHash: Fr } | { publicKey: PublicKey }) & { partialAddress: Fr }, ): AztecAddress { const publicKeyHash = 'publicKey' in args ? computePublicKeysHash(args.publicKey) : args.publicKeyHash; - const result = pedersenHash( - [publicKeyHash.toBuffer(), args.partialAddress.toBuffer()], - GeneratorIndex.CONTRACT_ADDRESS, - ); + const result = pedersenHash([publicKeyHash, args.partialAddress], GeneratorIndex.CONTRACT_ADDRESS); return AztecAddress.fromField(result); } @@ -89,7 +81,7 @@ export function computePublicKeysHash(publicKey: PublicKey | undefined): Fr { if (!publicKey) { return Fr.ZERO; } - return pedersenHash([publicKey.x.toBuffer(), publicKey.y.toBuffer()], GeneratorIndex.PARTIAL_ADDRESS); + return pedersenHash([publicKey.x, publicKey.y], GeneratorIndex.PARTIAL_ADDRESS); } /** @@ -115,5 +107,5 @@ export function computeInitializationHash(initFn: FunctionAbi | undefined, args: */ export function computeInitializationHashFromEncodedArgs(initFn: FunctionSelector, encodedArgs: Fr[]): Fr { const argsHash = computeVarArgsHash(encodedArgs); - return pedersenHash([initFn.toBuffer(), argsHash.toBuffer()], GeneratorIndex.CONSTRUCTOR); + return pedersenHash([initFn, argsHash], GeneratorIndex.CONSTRUCTOR); } diff --git a/yarn-project/circuits.js/src/contract/contract_class_id.ts b/yarn-project/circuits.js/src/contract/contract_class_id.ts index d2e218f3fe8..b82aac66f21 100644 --- a/yarn-project/circuits.js/src/contract/contract_class_id.ts +++ b/yarn-project/circuits.js/src/contract/contract_class_id.ts @@ -36,7 +36,7 @@ export function computeContractClassIdWithPreimage( ? contractClass.publicBytecodeCommitment : computePublicBytecodeCommitment(contractClass.packedBytecode); const id = pedersenHash( - [artifactHash.toBuffer(), privateFunctionsRoot.toBuffer(), publicBytecodeCommitment.toBuffer()], + [artifactHash, privateFunctionsRoot, publicBytecodeCommitment], GeneratorIndex.CONTRACT_LEAF, // TODO(@spalladino): Review all generator indices in this file ); return { id, artifactHash, privateFunctionsRoot, publicBytecodeCommitment }; diff --git a/yarn-project/circuits.js/src/contract/private_function.ts b/yarn-project/circuits.js/src/contract/private_function.ts index ffc5a90b5f9..a6670b03c51 100644 --- a/yarn-project/circuits.js/src/contract/private_function.ts +++ b/yarn-project/circuits.js/src/contract/private_function.ts @@ -27,10 +27,7 @@ function computePrivateFunctionLeaves(fns: PrivateFunction[]): Buffer[] { /** Returns the leaf for a given private function. */ export function computePrivateFunctionLeaf(fn: PrivateFunction): Buffer { - return pedersenHash( - [fn.selector, fn.vkHash].map(x => x.toBuffer()), - GeneratorIndex.FUNCTION_LEAF, - ).toBuffer(); + return pedersenHash([fn.selector, fn.vkHash], GeneratorIndex.FUNCTION_LEAF).toBuffer(); } function getPrivateFunctionTreeCalculator(): MerkleTreeCalculator { diff --git a/yarn-project/circuits.js/src/hash/hash.ts b/yarn-project/circuits.js/src/hash/hash.ts index 21cad66ffe4..60440f4205e 100644 --- a/yarn-project/circuits.js/src/hash/hash.ts +++ b/yarn-project/circuits.js/src/hash/hash.ts @@ -61,7 +61,7 @@ export function hashVK(vkBuf: Buffer) { * @returns A commitment nonce. */ export function computeCommitmentNonce(nullifierZero: Fr, commitmentIndex: number): Fr { - return pedersenHash([nullifierZero.toBuffer(), numToUInt32BE(commitmentIndex, 32)], GeneratorIndex.NOTE_HASH_NONCE); + return pedersenHash([nullifierZero, numToUInt32BE(commitmentIndex, 32)], GeneratorIndex.NOTE_HASH_NONCE); } /** @@ -72,7 +72,7 @@ export function computeCommitmentNonce(nullifierZero: Fr, commitmentIndex: numbe * @returns A siloed commitment. */ export function siloNoteHash(contract: AztecAddress, innerNoteHash: Fr): Fr { - return pedersenHash([contract.toBuffer(), innerNoteHash.toBuffer()], GeneratorIndex.SILOED_NOTE_HASH); + return pedersenHash([contract, innerNoteHash], GeneratorIndex.SILOED_NOTE_HASH); } /** @@ -82,7 +82,7 @@ export function siloNoteHash(contract: AztecAddress, innerNoteHash: Fr): Fr { * @returns A unique commitment. */ export function computeUniqueCommitment(nonce: Fr, siloedCommitment: Fr): Fr { - return pedersenHash([nonce.toBuffer(), siloedCommitment.toBuffer()], GeneratorIndex.UNIQUE_NOTE_HASH); + return pedersenHash([nonce, siloedCommitment], GeneratorIndex.UNIQUE_NOTE_HASH); } /** @@ -93,7 +93,7 @@ export function computeUniqueCommitment(nonce: Fr, siloedCommitment: Fr): Fr { * @returns A siloed nullifier. */ export function siloNullifier(contract: AztecAddress, innerNullifier: Fr): Fr { - return pedersenHash([contract.toBuffer(), innerNullifier.toBuffer()], GeneratorIndex.OUTER_NULLIFIER); + return pedersenHash([contract, innerNullifier], GeneratorIndex.OUTER_NULLIFIER); } /** @@ -114,7 +114,7 @@ export function computePublicDataTreeValue(value: Fr): Fr { */ export function computePublicDataTreeLeafSlot(contractAddress: AztecAddress, storageSlot: Fr): Fr { - return pedersenHash([contractAddress.toBuffer(), storageSlot.toBuffer()], GeneratorIndex.PUBLIC_LEAF_INDEX); + return pedersenHash([contractAddress, storageSlot], GeneratorIndex.PUBLIC_LEAF_INDEX); } /** @@ -138,31 +138,22 @@ export function computeVarArgsHash(args: Fr[]) { if (c.length < ARGS_HASH_CHUNK_LENGTH) { c = padArrayEnd(c, Fr.ZERO, ARGS_HASH_CHUNK_LENGTH); } - return pedersenHash( - c.map(a => a.toBuffer()), - GeneratorIndex.FUNCTION_ARGS, - ); + return pedersenHash(c, GeneratorIndex.FUNCTION_ARGS); }); if (chunksHashes.length < ARGS_HASH_CHUNK_COUNT) { chunksHashes = padArrayEnd(chunksHashes, Fr.ZERO, ARGS_HASH_CHUNK_COUNT); } - return pedersenHash( - chunksHashes.map(a => a.toBuffer()), - GeneratorIndex.FUNCTION_ARGS, - ); + return pedersenHash(chunksHashes, GeneratorIndex.FUNCTION_ARGS); } export function computeCommitmentsHash(input: SideEffect) { - return pedersenHash([input.value.toBuffer(), input.counter.toBuffer()], GeneratorIndex.SIDE_EFFECT); + return pedersenHash([input.value, input.counter], GeneratorIndex.SIDE_EFFECT); } export function computeNullifierHash(input: SideEffectLinkedToNoteHash) { - return pedersenHash( - [input.value.toBuffer(), input.noteHash.toBuffer(), input.counter.toBuffer()], - GeneratorIndex.SIDE_EFFECT, - ); + return pedersenHash([input.value, input.noteHash, input.counter], GeneratorIndex.SIDE_EFFECT); } /** @@ -171,7 +162,7 @@ export function computeNullifierHash(input: SideEffectLinkedToNoteHash) { * @returns the hash */ export function computeMessageSecretHash(secretMessage: Fr) { - return pedersenHash([secretMessage.toBuffer()], GeneratorIndex.L1_TO_L2_MESSAGE_SECRET); + return pedersenHash([secretMessage], GeneratorIndex.L1_TO_L2_MESSAGE_SECRET); } export function computeL1ToL2MessageNullifier( diff --git a/yarn-project/circuits.js/src/keys/index.ts b/yarn-project/circuits.js/src/keys/index.ts index 17f63615870..3f4969cf0cb 100644 --- a/yarn-project/circuits.js/src/keys/index.ts +++ b/yarn-project/circuits.js/src/keys/index.ts @@ -19,7 +19,7 @@ export function derivePublicKey(secretKey: GrumpkinPrivateKey) { function deriveSecretKey(secretKey: GrumpkinPrivateKey, index: Fr): GrumpkinPrivateKey { // TODO: Temporary hack. Should replace it with a secure way to derive the secret key. // Match the way keys are derived in noir-protocol-circuits/crates/private_kernel_lib/src/common.nr - const hash = pedersenHash([secretKey.high, secretKey.low, index].map(v => v.toBuffer())); + const hash = pedersenHash([secretKey.high, secretKey.low, index]); return new GrumpkinScalar(hash.toBuffer()); } diff --git a/yarn-project/circuits.js/src/structs/function_data.ts b/yarn-project/circuits.js/src/structs/function_data.ts index 9d1cdc1f283..08c803270b5 100644 --- a/yarn-project/circuits.js/src/structs/function_data.ts +++ b/yarn-project/circuits.js/src/structs/function_data.ts @@ -87,9 +87,6 @@ export class FunctionData { } hash(): Fr { - return pedersenHash( - this.toFields().map(field => field.toBuffer()), - GeneratorIndex.FUNCTION_DATA, - ); + return pedersenHash(this.toFields(), GeneratorIndex.FUNCTION_DATA); } } diff --git a/yarn-project/circuits.js/src/structs/header.ts b/yarn-project/circuits.js/src/structs/header.ts index 0194ec5f97e..782486a1fb6 100644 --- a/yarn-project/circuits.js/src/structs/header.ts +++ b/yarn-project/circuits.js/src/structs/header.ts @@ -94,9 +94,6 @@ export class Header { } hash(): Fr { - return pedersenHash( - this.toFields().map(f => f.toBuffer()), - GeneratorIndex.BLOCK_HASH, - ); + return pedersenHash(this.toFields(), GeneratorIndex.BLOCK_HASH); } } diff --git a/yarn-project/circuits.js/src/structs/private_call_stack_item.ts b/yarn-project/circuits.js/src/structs/private_call_stack_item.ts index d92883b57d8..700cd968d17 100644 --- a/yarn-project/circuits.js/src/structs/private_call_stack_item.ts +++ b/yarn-project/circuits.js/src/structs/private_call_stack_item.ts @@ -91,10 +91,7 @@ export class PrivateCallStackItem { * @returns Hash. */ public hash(): Fr { - return pedersenHash( - this.toFields().map(field => field.toBuffer()), - GeneratorIndex.CALL_STACK_ITEM, - ); + return pedersenHash(this.toFields(), GeneratorIndex.CALL_STACK_ITEM); } /** diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index 53e58221257..67e9347eba0 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -317,9 +317,6 @@ export class PrivateCircuitPublicInputs { } hash(): Fr { - return pedersenHash( - this.toFields().map(field => field.toBuffer()), - GeneratorIndex.PRIVATE_CIRCUIT_PUBLIC_INPUTS, - ); + return pedersenHash(this.toFields(), GeneratorIndex.PRIVATE_CIRCUIT_PUBLIC_INPUTS); } } diff --git a/yarn-project/circuits.js/src/structs/public_call_stack_item.ts b/yarn-project/circuits.js/src/structs/public_call_stack_item.ts index 5f9f98d2cae..454b695de62 100644 --- a/yarn-project/circuits.js/src/structs/public_call_stack_item.ts +++ b/yarn-project/circuits.js/src/structs/public_call_stack_item.ts @@ -97,7 +97,7 @@ export class PublicCallStackItem { } return pedersenHash( - [this.contractAddress, this.functionData.hash(), this.publicInputs.hash()].map(f => f.toBuffer()), + [this.contractAddress, this.functionData.hash(), this.publicInputs.hash()], GeneratorIndex.CALL_STACK_ITEM, ); } diff --git a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts index f9b3488558e..8ba49eb659a 100644 --- a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts @@ -280,9 +280,6 @@ export class PublicCircuitPublicInputs { } hash(): Fr { - return pedersenHash( - this.toFields().map(field => field.toBuffer()), - GeneratorIndex.PUBLIC_CIRCUIT_PUBLIC_INPUTS, - ); + return pedersenHash(this.toFields(), GeneratorIndex.PUBLIC_CIRCUIT_PUBLIC_INPUTS); } } diff --git a/yarn-project/circuits.js/src/structs/tx_context.ts b/yarn-project/circuits.js/src/structs/tx_context.ts index 577d4da75d1..0eae14c831d 100644 --- a/yarn-project/circuits.js/src/structs/tx_context.ts +++ b/yarn-project/circuits.js/src/structs/tx_context.ts @@ -90,9 +90,6 @@ export class TxContext { } hash(): Fr { - return pedersenHash( - this.toFields().map(f => f.toBuffer()), - GeneratorIndex.TX_CONTEXT, - ); + return pedersenHash(this.toFields(), GeneratorIndex.TX_CONTEXT); } } diff --git a/yarn-project/circuits.js/src/structs/tx_request.ts b/yarn-project/circuits.js/src/structs/tx_request.ts index f2d169fc827..6113bbb279a 100644 --- a/yarn-project/circuits.js/src/structs/tx_request.ts +++ b/yarn-project/circuits.js/src/structs/tx_request.ts @@ -71,10 +71,7 @@ export class TxRequest { } hash() { - return pedersenHash( - this.toFields().map(field => field.toBuffer()), - GeneratorIndex.TX_REQUEST, - ); + return pedersenHash(this.toFields(), GeneratorIndex.TX_REQUEST); } static empty() { diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index d20554df81b..36c99191177 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -154,7 +154,7 @@ describe('e2e_block_building', () => { it('drops tx with private nullifier already emitted from public on the same block', async () => { const secret = Fr.random(); // See yarn-project/simulator/src/public/index.test.ts 'Should be able to create a nullifier from the public context' - const emittedPublicNullifier = pedersenHash([new Fr(140), secret].map(a => a.toBuffer())); + const emittedPublicNullifier = pedersenHash([new Fr(140), secret]); const calls = [ contract.methods.create_nullifier_public(140n, secret), @@ -172,7 +172,7 @@ describe('e2e_block_building', () => { describe('across blocks', () => { it('drops a tx that tries to spend a nullifier already emitted on a previous block', async () => { const secret = Fr.random(); - const emittedPublicNullifier = pedersenHash([new Fr(140), secret].map(a => a.toBuffer())); + const emittedPublicNullifier = pedersenHash([new Fr(140), secret]); await expect(contract.methods.create_nullifier_public(140n, secret).send().wait()).resolves.toEqual( expect.objectContaining({ diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts index fe46f29a2b3..52bfa8b5b06 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging.test.ts @@ -11,7 +11,6 @@ import { computeAuthWitMessageHash, } from '@aztec/aztec.js'; import { sha256ToField } from '@aztec/foundation/crypto'; -import { serializeToBuffer } from '@aztec/foundation/serialize'; import { TokenBridgeContract, TokenContract } from '@aztec/noir-contracts.js'; import { toFunctionSelector } from 'viem/utils'; @@ -157,12 +156,11 @@ describe('e2e_cross_chain_messaging', () => { await crossChainTestHarness.makeMessageConsumable(msgHash); // 3. Consume L1 -> L2 message and mint private tokens on L2 - const content = sha256ToField( - Buffer.concat([ - Buffer.from(toFunctionSelector('mint_private(bytes32,uint256)').substring(2), 'hex'), - serializeToBuffer(...[secretHashForL2MessageConsumption, new Fr(bridgeAmount)]), - ]), - ); + const content = sha256ToField([ + Buffer.from(toFunctionSelector('mint_private(bytes32,uint256)').substring(2), 'hex'), + secretHashForL2MessageConsumption, + new Fr(bridgeAmount), + ]); const wrongMessage = new L1ToL2Message( new L1Actor(crossChainTestHarness.tokenPortalAddress, crossChainTestHarness.publicClient.chain.id), new L2Actor(l2Bridge.address, 1), @@ -235,12 +233,11 @@ describe('e2e_cross_chain_messaging', () => { // Wait for the message to be available for consumption await crossChainTestHarness.makeMessageConsumable(msgHash); - const content = sha256ToField( - Buffer.concat([ - Buffer.from(toFunctionSelector('mint_public(bytes32,uint256)').substring(2), 'hex'), - serializeToBuffer(...[ownerAddress, new Fr(bridgeAmount)]), - ]), - ); + const content = sha256ToField([ + Buffer.from(toFunctionSelector('mint_public(bytes32,uint256)').substring(2), 'hex'), + ownerAddress, + new Fr(bridgeAmount), + ]); const wrongMessage = new L1ToL2Message( new L1Actor(crossChainTestHarness.tokenPortalAddress, crossChainTestHarness.publicClient.chain.id), new L2Actor(l2Bridge.address, 1), diff --git a/yarn-project/end-to-end/src/e2e_outbox.test.ts b/yarn-project/end-to-end/src/e2e_outbox.test.ts index 5f7e84ca507..e94ecec0cd5 100644 --- a/yarn-project/end-to-end/src/e2e_outbox.test.ts +++ b/yarn-project/end-to-end/src/e2e_outbox.test.ts @@ -103,15 +103,13 @@ describe('E2E Outbox Tests', () => { } function makeL2ToL1Message(recipient: EthAddress, content: Fr = Fr.ZERO): Fr { - const leaf = sha256ToField( - Buffer.concat([ - contract.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - recipient.toBuffer32(), - new Fr(deployL1ContractsValues.publicClient.chain.id).toBuffer(), // chain id - content.toBuffer(), - ]), - ); + const leaf = sha256ToField([ + contract.address, + new Fr(1), // aztec version + recipient.toBuffer32(), + new Fr(deployL1ContractsValues.publicClient.chain.id), // chain id + content, + ]); return leaf; } diff --git a/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts b/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts index 713c29eefaa..740fb2a5c99 100644 --- a/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts +++ b/yarn-project/end-to-end/src/e2e_public_cross_chain_messaging.test.ts @@ -15,7 +15,6 @@ import { computeMessageSecretHash, } from '@aztec/aztec.js'; import { sha256ToField } from '@aztec/foundation/crypto'; -import { serializeToBuffer } from '@aztec/foundation/serialize'; import { InboxAbi, OutboxAbi } from '@aztec/l1-artifacts'; import { TestContract } from '@aztec/noir-contracts.js'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; @@ -152,12 +151,11 @@ describe('e2e_public_cross_chain_messaging', () => { await crossChainTestHarness.makeMessageConsumable(msgHash); - const content = sha256ToField( - Buffer.concat([ - Buffer.from(toFunctionSelector('mint_public(bytes32,uint256)').substring(2), 'hex'), - serializeToBuffer(...[user2Wallet.getAddress(), new Fr(bridgeAmount)]), - ]), - ); + const content = sha256ToField([ + Buffer.from(toFunctionSelector('mint_public(bytes32,uint256)').substring(2), 'hex'), + user2Wallet.getAddress(), + new Fr(bridgeAmount), + ]); const wrongMessage = new L1ToL2Message( new L1Actor(crossChainTestHarness.tokenPortalAddress, crossChainTestHarness.publicClient.chain.id), new L2Actor(l2Bridge.address, 1), @@ -204,12 +202,11 @@ describe('e2e_public_cross_chain_messaging', () => { await crossChainTestHarness.makeMessageConsumable(msgHash); // Wrong message hash - const content = sha256ToField( - Buffer.concat([ - Buffer.from(toFunctionSelector('mint_private(bytes32,uint256)').substring(2), 'hex'), - serializeToBuffer(...[secretHash, new Fr(bridgeAmount)]), - ]), - ); + const content = sha256ToField([ + Buffer.from(toFunctionSelector('mint_private(bytes32,uint256)').substring(2), 'hex'), + secretHash, + new Fr(bridgeAmount), + ]); const wrongMessage = new L1ToL2Message( new L1Actor(crossChainTestHarness.tokenPortalAddress, crossChainTestHarness.publicClient.chain.id), new L2Actor(l2Bridge.address, 1), @@ -256,15 +253,13 @@ describe('e2e_public_cross_chain_messaging', () => { content: content.toString() as Hex, }; - const leaf = sha256ToField( - Buffer.concat([ - testContract.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - recipient.toBuffer32(), - new Fr(crossChainTestHarness.publicClient.chain.id).toBuffer(), // chain id - content.toBuffer(), - ]), - ); + const leaf = sha256ToField([ + testContract.address, + new Fr(1), // aztec version + recipient.toBuffer32(), + new Fr(crossChainTestHarness.publicClient.chain.id), // chain id + content, + ]); const [l2MessageIndex, siblingPath] = await aztecNode.getL2ToL1MessageMembershipWitness( l2TxReceipt.blockNumber!, diff --git a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts index 47b49a52d86..89f8778ae5f 100644 --- a/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts +++ b/yarn-project/end-to-end/src/shared/cross_chain_test_harness.ts @@ -363,23 +363,19 @@ export class CrossChainTestHarness { } getL2ToL1MessageLeaf(withdrawAmount: bigint, callerOnL1: EthAddress = EthAddress.ZERO): Fr { - const content = sha256ToField( - Buffer.concat([ - Buffer.from(toFunctionSelector('withdraw(address,uint256,address)').substring(2), 'hex'), - this.ethAccount.toBuffer32(), - new Fr(withdrawAmount).toBuffer(), - callerOnL1.toBuffer32(), - ]), - ); - const leaf = sha256ToField( - Buffer.concat([ - this.l2Bridge.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - this.tokenPortalAddress.toBuffer32() ?? Buffer.alloc(32, 0), - new Fr(this.publicClient.chain.id).toBuffer(), // chain id - content.toBuffer(), - ]), - ); + const content = sha256ToField([ + Buffer.from(toFunctionSelector('withdraw(address,uint256,address)').substring(2), 'hex'), + this.ethAccount.toBuffer32(), + new Fr(withdrawAmount).toBuffer(), + callerOnL1.toBuffer32(), + ]); + const leaf = sha256ToField([ + this.l2Bridge.address.toBuffer(), + new Fr(1).toBuffer(), // aztec version + this.tokenPortalAddress.toBuffer32() ?? Buffer.alloc(32, 0), + new Fr(this.publicClient.chain.id).toBuffer(), // chain id + content.toBuffer(), + ]); return leaf; } diff --git a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts index cfc3b3de554..865b0cb9cd4 100644 --- a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts +++ b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts @@ -246,53 +246,45 @@ export const uniswapL1L2TestSuite = ( .send() .wait(); - const swapPrivateContent = sha256ToField( - Buffer.concat([ - Buffer.from( - toFunctionSelector( - 'swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)', - ).substring(2), - 'hex', + const swapPrivateContent = sha256ToField([ + Buffer.from( + toFunctionSelector('swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)').substring( + 2, ), - wethCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(wethAmountToBridge).toBuffer(), - new Fr(uniswapFeeTier).toBuffer(), - daiCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(minimumOutputAmount).toBuffer(), - secretHashForRedeemingDai.toBuffer(), - secretHashForDepositingSwappedDai.toBuffer(), - ownerEthAddress.toBuffer32(), - ]), - ); - - const swapPrivateLeaf = sha256ToField( - Buffer.concat([ - uniswapL2Contract.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - EthAddress.fromString(uniswapPortal.address).toBuffer32(), - new Fr(publicClient.chain.id).toBuffer(), // chain id - swapPrivateContent.toBuffer(), - ]), - ); - - const withdrawContent = sha256ToField( - Buffer.concat([ - Buffer.from(toFunctionSelector('withdraw(address,uint256,address)').substring(2), 'hex'), - uniswapPortalAddress.toBuffer32(), - new Fr(wethAmountToBridge).toBuffer(), - uniswapPortalAddress.toBuffer32(), - ]), - ); + 'hex', + ), + wethCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(wethAmountToBridge), + new Fr(uniswapFeeTier), + daiCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(minimumOutputAmount), + secretHashForRedeemingDai, + secretHashForDepositingSwappedDai, + ownerEthAddress.toBuffer32(), + ]); - const withdrawLeaf = sha256ToField( - Buffer.concat([ - wethCrossChainHarness.l2Bridge.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - wethCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(publicClient.chain.id).toBuffer(), // chain id - withdrawContent.toBuffer(), - ]), - ); + const swapPrivateLeaf = sha256ToField([ + uniswapL2Contract.address, + new Fr(1), // aztec version + EthAddress.fromString(uniswapPortal.address).toBuffer32(), + new Fr(publicClient.chain.id), // chain id + swapPrivateContent, + ]); + + const withdrawContent = sha256ToField([ + Buffer.from(toFunctionSelector('withdraw(address,uint256,address)').substring(2), 'hex'), + uniswapPortalAddress.toBuffer32(), + new Fr(wethAmountToBridge), + uniswapPortalAddress.toBuffer32(), + ]); + + const withdrawLeaf = sha256ToField([ + wethCrossChainHarness.l2Bridge.address, + new Fr(1), // aztec version + wethCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(publicClient.chain.id), // chain id + withdrawContent, + ]); // ensure that user's funds were burnt await wethCrossChainHarness.expectPrivateBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge); @@ -474,53 +466,45 @@ export const uniswapL1L2TestSuite = ( // 4.2 Call swap_public from user2 on behalf of owner const uniswapL2Interaction = await action.send().wait(); - const swapPublicContent = sha256ToField( - Buffer.concat([ - Buffer.from( - toFunctionSelector('swap_public(address,uint256,uint24,address,uint256,bytes32,bytes32,address)').substring( - 2, - ), - 'hex', + const swapPublicContent = sha256ToField([ + Buffer.from( + toFunctionSelector('swap_public(address,uint256,uint24,address,uint256,bytes32,bytes32,address)').substring( + 2, ), - wethCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(wethAmountToBridge).toBuffer(), - new Fr(uniswapFeeTier).toBuffer(), - daiCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(minimumOutputAmount).toBuffer(), - ownerAddress.toBuffer(), - secretHashForDepositingSwappedDai.toBuffer(), - ownerEthAddress.toBuffer32(), - ]), - ); - - const swapPublicLeaf = sha256ToField( - Buffer.concat([ - uniswapL2Contract.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - EthAddress.fromString(uniswapPortal.address).toBuffer32(), - new Fr(publicClient.chain.id).toBuffer(), // chain id - swapPublicContent.toBuffer(), - ]), - ); - - const withdrawContent = sha256ToField( - Buffer.concat([ - Buffer.from(toFunctionSelector('withdraw(address,uint256,address)').substring(2), 'hex'), - uniswapPortalAddress.toBuffer32(), - new Fr(wethAmountToBridge).toBuffer(), - uniswapPortalAddress.toBuffer32(), - ]), - ); - - const withdrawLeaf = sha256ToField( - Buffer.concat([ - wethCrossChainHarness.l2Bridge.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - wethCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(publicClient.chain.id).toBuffer(), // chain id - withdrawContent.toBuffer(), - ]), - ); + 'hex', + ), + wethCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(wethAmountToBridge), + new Fr(uniswapFeeTier), + daiCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(minimumOutputAmount), + ownerAddress, + secretHashForDepositingSwappedDai, + ownerEthAddress.toBuffer32(), + ]); + + const swapPublicLeaf = sha256ToField([ + uniswapL2Contract.address, + new Fr(1), // aztec version + EthAddress.fromString(uniswapPortal.address).toBuffer32(), + new Fr(publicClient.chain.id), // chain id + swapPublicContent, + ]); + + const withdrawContent = sha256ToField([ + Buffer.from(toFunctionSelector('withdraw(address,uint256,address)').substring(2), 'hex'), + uniswapPortalAddress.toBuffer32(), + new Fr(wethAmountToBridge), + uniswapPortalAddress.toBuffer32(), + ]); + + const withdrawLeaf = sha256ToField([ + wethCrossChainHarness.l2Bridge.address, + new Fr(1), // aztec version + wethCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(publicClient.chain.id), // chain id + withdrawContent, + ]); // check weth balance of owner on L2 (we first bridged `wethAmountToBridge` into L2 and now withdrew it!) await wethCrossChainHarness.expectPublicBalanceOnL2(ownerAddress, wethL2BalanceBeforeSwap - wethAmountToBridge); @@ -846,53 +830,45 @@ export const uniswapL1L2TestSuite = ( .send() .wait(); - const swapPrivateContent = sha256ToField( - Buffer.concat([ - Buffer.from( - toFunctionSelector( - 'swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)', - ).substring(2), - 'hex', + const swapPrivateContent = sha256ToField([ + Buffer.from( + toFunctionSelector('swap_private(address,uint256,uint24,address,uint256,bytes32,bytes32,address)').substring( + 2, ), - wethCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(wethAmountToBridge).toBuffer(), - new Fr(uniswapFeeTier).toBuffer(), - daiCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(minimumOutputAmount).toBuffer(), - secretHashForRedeemingDai.toBuffer(), - secretHashForDepositingSwappedDai.toBuffer(), - ownerEthAddress.toBuffer32(), - ]), - ); - - const swapPrivateLeaf = sha256ToField( - Buffer.concat([ - uniswapL2Contract.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - EthAddress.fromString(uniswapPortal.address).toBuffer32(), - new Fr(publicClient.chain.id).toBuffer(), // chain id - swapPrivateContent.toBuffer(), - ]), - ); - - const withdrawContent = sha256ToField( - Buffer.concat([ - Buffer.from(toFunctionSelector('withdraw(address,uint256,address)').substring(2), 'hex'), - uniswapPortalAddress.toBuffer32(), - new Fr(wethAmountToBridge).toBuffer(), - uniswapPortalAddress.toBuffer32(), - ]), - ); + 'hex', + ), + wethCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(wethAmountToBridge), + new Fr(uniswapFeeTier), + daiCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(minimumOutputAmount), + secretHashForRedeemingDai, + secretHashForDepositingSwappedDai, + ownerEthAddress.toBuffer32(), + ]); - const withdrawLeaf = sha256ToField( - Buffer.concat([ - wethCrossChainHarness.l2Bridge.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - wethCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(publicClient.chain.id).toBuffer(), // chain id - withdrawContent.toBuffer(), - ]), - ); + const swapPrivateLeaf = sha256ToField([ + uniswapL2Contract.address, + new Fr(1), // aztec version + EthAddress.fromString(uniswapPortal.address).toBuffer32(), + new Fr(publicClient.chain.id), // chain id + swapPrivateContent, + ]); + + const withdrawContent = sha256ToField([ + Buffer.from(toFunctionSelector('withdraw(address,uint256,address)').substring(2), 'hex'), + uniswapPortalAddress.toBuffer32(), + new Fr(wethAmountToBridge), + uniswapPortalAddress.toBuffer32(), + ]); + + const withdrawLeaf = sha256ToField([ + wethCrossChainHarness.l2Bridge.address, + new Fr(1), // aztec version + wethCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(publicClient.chain.id), // chain id + withdrawContent, + ]); const [swapPrivateL2MessageIndex, swapPrivateSiblingPath] = await aztecNode.getL2ToL1MessageMembershipWitness( withdrawReceipt.blockNumber!, @@ -977,53 +953,45 @@ export const uniswapL1L2TestSuite = ( .send() .wait(); - const swapPublicContent = sha256ToField( - Buffer.concat([ - Buffer.from( - toFunctionSelector('swap_public(address,uint256,uint24,address,uint256,bytes32,bytes32,address)').substring( - 2, - ), - 'hex', + const swapPublicContent = sha256ToField([ + Buffer.from( + toFunctionSelector('swap_public(address,uint256,uint24,address,uint256,bytes32,bytes32,address)').substring( + 2, ), - wethCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(wethAmountToBridge).toBuffer(), - new Fr(uniswapFeeTier).toBuffer(), - daiCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(minimumOutputAmount).toBuffer(), - ownerAddress.toBuffer(), - secretHashForDepositingSwappedDai.toBuffer(), - ownerEthAddress.toBuffer32(), - ]), - ); - - const swapPublicLeaf = sha256ToField( - Buffer.concat([ - uniswapL2Contract.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - EthAddress.fromString(uniswapPortal.address).toBuffer32(), - new Fr(publicClient.chain.id).toBuffer(), // chain id - swapPublicContent.toBuffer(), - ]), - ); - - const withdrawContent = sha256ToField( - Buffer.concat([ - Buffer.from(toFunctionSelector('withdraw(address,uint256,address)').substring(2), 'hex'), - uniswapPortalAddress.toBuffer32(), - new Fr(wethAmountToBridge).toBuffer(), - uniswapPortalAddress.toBuffer32(), - ]), - ); - - const withdrawLeaf = sha256ToField( - Buffer.concat([ - wethCrossChainHarness.l2Bridge.address.toBuffer(), - new Fr(1).toBuffer(), // aztec version - wethCrossChainHarness.tokenPortalAddress.toBuffer32(), - new Fr(publicClient.chain.id).toBuffer(), // chain id - withdrawContent.toBuffer(), - ]), - ); + 'hex', + ), + wethCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(wethAmountToBridge), + new Fr(uniswapFeeTier), + daiCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(minimumOutputAmount), + ownerAddress, + secretHashForDepositingSwappedDai, + ownerEthAddress.toBuffer32(), + ]); + + const swapPublicLeaf = sha256ToField([ + uniswapL2Contract.address, + new Fr(1), // aztec version + EthAddress.fromString(uniswapPortal.address).toBuffer32(), + new Fr(publicClient.chain.id), // chain id + swapPublicContent, + ]); + + const withdrawContent = sha256ToField([ + Buffer.from(toFunctionSelector('withdraw(address,uint256,address)').substring(2), 'hex'), + uniswapPortalAddress.toBuffer32(), + new Fr(wethAmountToBridge), + uniswapPortalAddress.toBuffer32(), + ]); + + const withdrawLeaf = sha256ToField([ + wethCrossChainHarness.l2Bridge.address, + new Fr(1), // aztec version + wethCrossChainHarness.tokenPortalAddress.toBuffer32(), + new Fr(publicClient.chain.id), // chain id + withdrawContent, + ]); const [swapPublicL2MessageIndex, swapPublicSiblingPath] = await aztecNode.getL2ToL1MessageMembershipWitness( withdrawReceipt.blockNumber!, diff --git a/yarn-project/end-to-end/src/simulators/lending_simulator.ts b/yarn-project/end-to-end/src/simulators/lending_simulator.ts index df9e9da0ec9..48bd93fcd15 100644 --- a/yarn-project/end-to-end/src/simulators/lending_simulator.ts +++ b/yarn-project/end-to-end/src/simulators/lending_simulator.ts @@ -24,7 +24,7 @@ export class LendingAccount { * @returns Key in public space */ public key() { - return pedersenHash([this.address, this.secret].map(f => f.toBuffer())); + return pedersenHash([this.address, this.secret]); } } diff --git a/yarn-project/entrypoints/src/entrypoint_payload.ts b/yarn-project/entrypoints/src/entrypoint_payload.ts index 644af140d89..c76d20e70db 100644 --- a/yarn-project/entrypoints/src/entrypoint_payload.ts +++ b/yarn-project/entrypoints/src/entrypoint_payload.ts @@ -99,15 +99,12 @@ export async function buildFeePayload(feeOpts?: FeeOptions): Promise fr.toBuffer()), - generatorIndex, - ); + return pedersenHash(flattenPayload(payload), generatorIndex); } /** Hash the payload for a dapp */ export function hashDappPayload(payload: EntrypointPayload, userAddress: AztecAddress, generatorIndex: number) { - return pedersenHash([...flattenPayload(payload).map(fr => fr.toBuffer()), userAddress.toBuffer()], generatorIndex); + return pedersenHash([...flattenPayload(payload), userAddress], generatorIndex); } /** Flattens an payload */ diff --git a/yarn-project/foundation/src/crypto/sha256/index.ts b/yarn-project/foundation/src/crypto/sha256/index.ts index 0f6fb259e85..6b9676f3913 100644 --- a/yarn-project/foundation/src/crypto/sha256/index.ts +++ b/yarn-project/foundation/src/crypto/sha256/index.ts @@ -2,9 +2,13 @@ import { default as hash } from 'hash.js'; import { Fr } from '../../fields/fields.js'; import { truncateAndPad } from '../../serialize/free_funcs.js'; +import { Bufferable, serializeToBuffer } from '../../serialize/serialize.js'; export const sha256 = (data: Buffer) => Buffer.from(hash.sha256().update(data).digest()); export const sha256Trunc = (data: Buffer) => truncateAndPad(sha256(data)); -export const sha256ToField = (data: Buffer) => Fr.fromBuffer(sha256Trunc(data)); +export const sha256ToField = (data: Bufferable[]) => { + const buffer = serializeToBuffer(data); + return Fr.fromBuffer(sha256Trunc(buffer)); +}; diff --git a/yarn-project/foundation/src/fields/point.ts b/yarn-project/foundation/src/fields/point.ts index b1135d6e6b5..dfb5065c03d 100644 --- a/yarn-project/foundation/src/fields/point.ts +++ b/yarn-project/foundation/src/fields/point.ts @@ -1,4 +1,4 @@ -import { BufferReader, FieldReader } from '../serialize/index.js'; +import { BufferReader, FieldReader, serializeToBuffer } from '../serialize/index.js'; import { Fr } from './fields.js'; /** @@ -88,7 +88,7 @@ export class Point { * @returns A Buffer representation of the Point instance. */ toBuffer() { - return Buffer.concat([this.x.toBuffer(), this.y.toBuffer()]); + return serializeToBuffer([this.x, this.y]); } /** diff --git a/yarn-project/foundation/src/serialize/serialize.ts b/yarn-project/foundation/src/serialize/serialize.ts index 758a466dcd5..c610b5fea64 100644 --- a/yarn-project/foundation/src/serialize/serialize.ts +++ b/yarn-project/foundation/src/serialize/serialize.ts @@ -152,7 +152,7 @@ export function serializeToBufferArray(...objs: Bufferable[]): Buffer[] { ret.push(boolToBuffer(obj)); } else if (typeof obj === 'bigint') { // Throw if bigint does not fit into 32 bytes - if (obj > BigInt('0xffffffffffffffffffffffffffffffff')) { + if (obj > BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')) { throw new Error(`BigInt ${obj} does not fit into 32 bytes`); } ret.push(serializeBigInt(obj)); diff --git a/yarn-project/pxe/src/database/deferred_note_dao.ts b/yarn-project/pxe/src/database/deferred_note_dao.ts index af0ee6a89b2..06354bb4074 100644 --- a/yarn-project/pxe/src/database/deferred_note_dao.ts +++ b/yarn-project/pxe/src/database/deferred_note_dao.ts @@ -29,12 +29,12 @@ export class DeferredNoteDao { toBuffer(): Buffer { return serializeToBuffer( - this.publicKey.toBuffer(), - this.note.toBuffer(), - this.contractAddress.toBuffer(), - this.storageSlot.toBuffer(), - this.noteTypeId.toBuffer(), - this.txHash.toBuffer(), + this.publicKey, + this.note, + this.contractAddress, + this.storageSlot, + this.noteTypeId, + this.txHash, new Vector(this.newNoteHashes), this.dataStartIndexForTx, ); diff --git a/yarn-project/pxe/src/database/note_dao.ts b/yarn-project/pxe/src/database/note_dao.ts index 2255420fc57..5ca51311182 100644 --- a/yarn-project/pxe/src/database/note_dao.ts +++ b/yarn-project/pxe/src/database/note_dao.ts @@ -1,7 +1,7 @@ import { Note, TxHash } from '@aztec/circuit-types'; import { AztecAddress, Fr, Point, PublicKey } from '@aztec/circuits.js'; -import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; -import { BufferReader } from '@aztec/foundation/serialize'; +import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; +import { BufferReader, serializeToBuffer } from '@aztec/foundation/serialize'; import { NoteData } from '@aztec/simulator'; /** @@ -35,17 +35,17 @@ export class NoteDao implements NoteData { ) {} toBuffer(): Buffer { - return Buffer.concat([ - this.note.toBuffer(), - this.contractAddress.toBuffer(), - this.storageSlot.toBuffer(), - this.noteTypeId.toBuffer(), + return serializeToBuffer([ + this.note, + this.contractAddress, + this.storageSlot, + this.noteTypeId, this.txHash.buffer, - this.nonce.toBuffer(), - this.innerNoteHash.toBuffer(), - this.siloedNullifier.toBuffer(), - toBufferBE(this.index, 32), - this.publicKey.toBuffer(), + this.nonce, + this.innerNoteHash, + this.siloedNullifier, + this.index, + this.publicKey, ]); } static fromBuffer(buffer: Buffer | BufferReader) { diff --git a/yarn-project/pxe/src/note_processor/note_processor.test.ts b/yarn-project/pxe/src/note_processor/note_processor.test.ts index e7de9c66bf8..ed30e119880 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.test.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.test.ts @@ -7,7 +7,6 @@ import { L2Block, L2BlockContext, L2BlockL2Logs, - Note, TaggedNote, TxL2Logs, } from '@aztec/circuit-types'; @@ -44,8 +43,6 @@ describe('Note Processor', () => { const firstBlockDataStartIndex = (firstBlockNum - 1) * numCommitmentsPerBlock; const firstBlockDataEndIndex = firstBlockNum * numCommitmentsPerBlock; - const computeMockNoteHash = (note: Note) => pedersenHash(note.items.map(i => i.toBuffer())); - // ownedData: [tx1, tx2, ...], the numbers in each tx represents the indices of the note hashes the account owns. const createEncryptedLogsAndOwnedL1NotePayloads = (ownedData: number[][], ownedNotes: TaggedNote[]) => { const newNotes: TaggedNote[] = []; @@ -109,7 +106,7 @@ describe('Note Processor', () => { ownedL1NotePayloads.push(...payloads); for (let i = 0; i < TXS_PER_BLOCK; i++) { block.body.txEffects[i].noteHashes = newNotes - .map(n => computeMockNoteHash(n.notePayload.note)) + .map(n => pedersenHash(n.notePayload.note.items)) .slice(i * MAX_NEW_NOTE_HASHES_PER_TX, (i + 1) * MAX_NEW_NOTE_HASHES_PER_TX) as Tuple< Fr, typeof MAX_NEW_NOTE_HASHES_PER_TX @@ -148,7 +145,7 @@ describe('Note Processor', () => { Promise.resolve({ innerNoteHash: Fr.random(), siloedNoteHash: Fr.random(), - uniqueSiloedNoteHash: computeMockNoteHash(args[4]), // args[4] is note + uniqueSiloedNoteHash: pedersenHash(args[4].items), // args[4] is note innerNullifier: Fr.random(), }), ); diff --git a/yarn-project/sequencer-client/src/sequencer/tx_validator.test.ts b/yarn-project/sequencer-client/src/sequencer/tx_validator.test.ts index f89d521c87c..08f73968242 100644 --- a/yarn-project/sequencer-client/src/sequencer/tx_validator.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/tx_validator.test.ts @@ -96,7 +96,7 @@ describe('TxValidator', () => { describe('inspects tx gas', () => { it('allows native fee paying txs', async () => { const sender = makeAztecAddress(); - const expectedBalanceSlot = pedersenHash([new Fr(1).toBuffer(), sender.toBuffer()]); + const expectedBalanceSlot = pedersenHash([new Fr(1), sender]); const tx = nativeFeePayingTx(sender); publicStateSource.storageRead.mockImplementation((address, slot) => { @@ -112,7 +112,7 @@ describe('TxValidator', () => { it('rejects native fee paying txs if out of balance', async () => { const sender = makeAztecAddress(); - const expectedBalanceSlot = pedersenHash([new Fr(1).toBuffer(), sender.toBuffer()]); + const expectedBalanceSlot = pedersenHash([new Fr(1), sender]); const tx = nativeFeePayingTx(sender); publicStateSource.storageRead.mockImplementation((address, slot) => { @@ -128,7 +128,7 @@ describe('TxValidator', () => { it('allows txs paying through a fee payment contract', async () => { const fpcAddress = makeAztecAddress(); - const expectedBalanceSlot = pedersenHash([new Fr(1).toBuffer(), fpcAddress.toBuffer()]); + const expectedBalanceSlot = pedersenHash([new Fr(1), fpcAddress]); const tx = fxFeePayingTx(fpcAddress); publicStateSource.storageRead.mockImplementation((address, slot) => { @@ -144,7 +144,7 @@ describe('TxValidator', () => { it('rejects txs paying through a fee payment contract out of balance', async () => { const fpcAddress = makeAztecAddress(); - const expectedBalanceSlot = pedersenHash([new Fr(1).toBuffer(), fpcAddress.toBuffer()]); + const expectedBalanceSlot = pedersenHash([new Fr(1), fpcAddress]); const tx = nativeFeePayingTx(fpcAddress); publicStateSource.storageRead.mockImplementation((address, slot) => { diff --git a/yarn-project/sequencer-client/src/sequencer/tx_validator.ts b/yarn-project/sequencer-client/src/sequencer/tx_validator.ts index 7444e3359b4..45146da70bf 100644 --- a/yarn-project/sequencer-client/src/sequencer/tx_validator.ts +++ b/yarn-project/sequencer-client/src/sequencer/tx_validator.ts @@ -171,7 +171,7 @@ export class TxValidator { } // TODO(#1204) if a generator index is used for the derived storage slot of a map, update it here as well - const slot = pedersenHash([GAS_TOKEN_BALANCES_SLOT.toBuffer(), teardownFn.callContext.msgSender.toBuffer()]); + const slot = pedersenHash([GAS_TOKEN_BALANCES_SLOT, teardownFn.callContext.msgSender]); const gasBalance = await this.#publicStateSource.storageRead( getCanonicalGasTokenAddress(this.#gasPortalAddress), slot, diff --git a/yarn-project/simulator/src/avm/avm_execution_environment.ts b/yarn-project/simulator/src/avm/avm_execution_environment.ts index d6ffd51d9ba..77233c5b56b 100644 --- a/yarn-project/simulator/src/avm/avm_execution_environment.ts +++ b/yarn-project/simulator/src/avm/avm_execution_environment.ts @@ -54,10 +54,7 @@ export class AvmExecutionEnvironment { ) { // We encode some extra inputs (AvmContextInputs) in calldata. // This will have to go once we move away from one proof per call. - const inputs = new AvmContextInputs( - temporaryFunctionSelector.toField(), - pedersenHash(calldata.map(word => word.toBuffer())), - ); + const inputs = new AvmContextInputs(temporaryFunctionSelector.toField(), pedersenHash(calldata)); this.calldata = [...inputs.toFields(), ...calldata]; } diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index 4f1aa990cd1..a16ae2474a3 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -246,7 +246,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { const results = await new AvmSimulator(context).executeBytecode(bytecode); expect(results.reverted).toBe(false); - expect(results.output).toEqual([pedersenHash(calldata.map(f => f.toBuffer()))]); + expect(results.output).toEqual([pedersenHash(calldata)]); }); }); diff --git a/yarn-project/simulator/src/avm/opcodes/hashing.test.ts b/yarn-project/simulator/src/avm/opcodes/hashing.test.ts index 1b261643950..957f62ca507 100644 --- a/yarn-project/simulator/src/avm/opcodes/hashing.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/hashing.test.ts @@ -231,8 +231,7 @@ describe('Hashing Opcodes', () => { const dstOffset = 3; - const inputBuffer = args.map(field => field.toBuffer()); - const expectedHash = pedersenHash(inputBuffer); + const expectedHash = pedersenHash(args); await new Pedersen(indirect, dstOffset, messageOffset, sizeOffset).execute(context); const result = context.machineState.memory.get(dstOffset); @@ -258,8 +257,7 @@ describe('Hashing Opcodes', () => { const dstOffset = 300; - const inputBuffer = args.map(field => field.toBuffer()); - const expectedHash = pedersenHash(inputBuffer); + const expectedHash = pedersenHash(args); await new Pedersen(indirect, dstOffset, messageOffset, sizeOffset).execute(context); const result = context.machineState.memory.get(dstOffset); diff --git a/yarn-project/simulator/src/avm/opcodes/hashing.ts b/yarn-project/simulator/src/avm/opcodes/hashing.ts index ca212dc2d19..a7e54e539e6 100644 --- a/yarn-project/simulator/src/avm/opcodes/hashing.ts +++ b/yarn-project/simulator/src/avm/opcodes/hashing.ts @@ -166,7 +166,7 @@ export class Pedersen extends Instruction { // We hash a set of field elements const messageSize = Number(context.machineState.memory.get(messageSizeOffset).toBigInt()); - const hashData = context.machineState.memory.getSlice(messageOffset, messageSize).map(word => word.toBuffer()); + const hashData = context.machineState.memory.getSlice(messageOffset, messageSize); // No domain sep for now const hash = pedersenHash(hashData); diff --git a/yarn-project/simulator/src/client/private_execution.test.ts b/yarn-project/simulator/src/client/private_execution.test.ts index 6a938252408..6495690acb1 100644 --- a/yarn-project/simulator/src/client/private_execution.test.ts +++ b/yarn-project/simulator/src/client/private_execution.test.ts @@ -162,8 +162,6 @@ describe('Private Execution test suite', () => { return trees[name]; }; - const hashFields = (data: Fr[]) => pedersenHash(data.map(f => f.toBuffer())); - beforeAll(() => { logger = createDebugLogger('aztec:test:private_execution'); @@ -248,7 +246,7 @@ describe('Private Execution test suite', () => { const noteHashIndex = randomInt(1); // mock index in TX's final newNoteHashes array const nonce = computeCommitmentNonce(mockFirstNullifier, noteHashIndex); const note = new Note([new Fr(amount), owner.toField(), Fr.random()]); - const innerNoteHash = hashFields(note.items); + const innerNoteHash = pedersenHash(note.items); return { contractAddress, storageSlot, @@ -449,7 +447,7 @@ describe('Private Execution test suite', () => { logger(`Parent deployed at ${parentAddress.toShortString()}`); logger(`Calling child function ${childSelector.toString()} at ${childAddress.toShortString()}`); - const args = [Fr.fromBuffer(childAddress.toBuffer()), Fr.fromBuffer(childSelector.toBuffer())]; + const args = [childAddress, childSelector]; const result = await runSimulator({ args, artifact: parentArtifact }); expect(result.callStackItem.publicInputs.returnValues[0]).toEqual(new Fr(privateIncrement)); @@ -784,7 +782,7 @@ describe('Private Execution test suite', () => { oracle.getPortalContractAddress.mockImplementation(() => Promise.resolve(childPortalContractAddress)); oracle.getFunctionArtifact.mockImplementation(() => Promise.resolve({ ...childContractArtifact, isInternal })); - const args = [Fr.fromBuffer(childAddress.toBuffer()), childSelector.toField(), 42n]; + const args = [childAddress, childSelector, 42n]; const result = await runSimulator({ msgSender: parentAddress, contractAddress: parentAddress, @@ -896,7 +894,7 @@ describe('Private Execution test suite', () => { ownerNullifierKeyPair.secretKey, contractAddress, ); - const expectedNullifier = hashFields([ + const expectedNullifier = pedersenHash([ innerNoteHash, siloedNullifierSecretKey.low, siloedNullifierSecretKey.high, @@ -972,7 +970,7 @@ describe('Private Execution test suite', () => { ownerNullifierKeyPair.secretKey, contractAddress, ); - const expectedNullifier = hashFields([ + const expectedNullifier = pedersenHash([ innerNoteHash, siloedNullifierSecretKey.low, siloedNullifierSecretKey.high, diff --git a/yarn-project/simulator/src/client/simulator.test.ts b/yarn-project/simulator/src/client/simulator.test.ts index fe7e32cfdff..636f3349fb5 100644 --- a/yarn-project/simulator/src/client/simulator.test.ts +++ b/yarn-project/simulator/src/client/simulator.test.ts @@ -23,8 +23,6 @@ describe('Simulator', () => { const ownerNullifierSecretKey = GrumpkinScalar.random(); const ownerNullifierPublicKey = Point.random(); - const hashFields = (data: Fr[]) => pedersenHash(data.map(f => f.toBuffer())); - beforeEach(() => { oracle = mock(); node = mock(); @@ -50,11 +48,11 @@ describe('Simulator', () => { oracle.getFunctionArtifactByName.mockResolvedValue(artifact); const note = createNote(); - const tokenNoteHash = hashFields(note.items); - const innerNoteHash = hashFields([storageSlot, tokenNoteHash]); + const tokenNoteHash = pedersenHash(note.items); + const innerNoteHash = pedersenHash([storageSlot, tokenNoteHash]); const siloedNoteHash = siloNoteHash(contractAddress, innerNoteHash); const uniqueSiloedNoteHash = computeUniqueCommitment(nonce, siloedNoteHash); - const innerNullifier = hashFields([ + const innerNullifier = pedersenHash([ uniqueSiloedNoteHash, ownerNullifierSecretKey.low, ownerNullifierSecretKey.high, diff --git a/yarn-project/simulator/src/public/index.test.ts b/yarn-project/simulator/src/public/index.test.ts index bde9242d755..03f6a631f9b 100644 --- a/yarn-project/simulator/src/public/index.test.ts +++ b/yarn-project/simulator/src/public/index.test.ts @@ -347,9 +347,9 @@ describe('ACIR public execution simulator', () => { // Assert the note hash was created expect(result.newNoteHashes.length).toEqual(1); - const expectedNoteHash = pedersenHash([amount.toBuffer(), secretHash.toBuffer()]); + const expectedNoteHash = pedersenHash([amount, secretHash]); const storageSlot = new Fr(5); // for pending_shields - const expectedInnerNoteHash = pedersenHash([storageSlot, expectedNoteHash].map(f => f.toBuffer())); + const expectedInnerNoteHash = pedersenHash([storageSlot, expectedNoteHash]); expect(result.newNoteHashes[0].value).toEqual(expectedInnerNoteHash); }); @@ -379,7 +379,7 @@ describe('ACIR public execution simulator', () => { // Assert the l2 to l1 message was created expect(result.newL2ToL1Messages.length).toEqual(1); - const expectedNewMessage = new L2ToL1Message(portalContractAddress, pedersenHash(params.map(a => a.toBuffer()))); + const expectedNewMessage = new L2ToL1Message(portalContractAddress, pedersenHash(params)); expect(result.newL2ToL1Messages[0]).toEqual(expectedNewMessage); }); @@ -409,7 +409,7 @@ describe('ACIR public execution simulator', () => { // Assert the l2 to l1 message was created expect(result.newNullifiers.length).toEqual(1); - const expectedNewMessageValue = pedersenHash(params.map(a => a.toBuffer())); + const expectedNewMessageValue = pedersenHash(params); expect(result.newNullifiers[0].value).toEqual(expectedNewMessageValue); }); @@ -479,7 +479,7 @@ describe('ACIR public execution simulator', () => { let root = preimage.hash(); for (const sibling of siblingPathBuffers) { - root = pedersenHash([root.toBuffer(), sibling]); + root = pedersenHash([root, sibling]); } commitmentsDb.getL1ToL2MembershipWitness.mockImplementation(() => { return Promise.resolve(new MessageLoadOracleInputs(0n, siblingPath)); diff --git a/yarn-project/simulator/src/test/utils.ts b/yarn-project/simulator/src/test/utils.ts index f8f5b6b4166..1e0118b9c97 100644 --- a/yarn-project/simulator/src/test/utils.ts +++ b/yarn-project/simulator/src/test/utils.ts @@ -20,8 +20,7 @@ export const buildL1ToL2Message = ( // Write the selector into a buffer. const selectorBuf = Buffer.from(selector, 'hex'); - const contentBuf = Buffer.concat([selectorBuf, ...contentPreimage.map(field => field.toBuffer())]); - const content = sha256ToField(contentBuf); + const content = sha256ToField([selectorBuf, ...contentPreimage]); const secretHash = computeMessageSecretHash(secret); // Eventually the kernel will need to prove the kernel portal pair exists within the contract tree, diff --git a/yarn-project/simulator/src/utils.ts b/yarn-project/simulator/src/utils.ts index ad65917f013..9dc93abe392 100644 --- a/yarn-project/simulator/src/utils.ts +++ b/yarn-project/simulator/src/utils.ts @@ -14,5 +14,5 @@ export function computeSlotForMapping( toField: () => Fr; }, ) { - return pedersenHash([mappingSlot, key.toField()].map(field => field.toBuffer())); + return pedersenHash([mappingSlot, key.toField()]); }