From dc51329829af288cc7cc3b457045561c724bad90 Mon Sep 17 00:00:00 2001 From: fcarreiro Date: Wed, 27 Mar 2024 12:21:53 +0000 Subject: [PATCH] wip --- avm-transpiler/src/transpile.rs | 8 ++++++-- .../contracts/avm_test_contract/src/main.nr | 5 +++++ .../simulator/src/avm/avm_simulator.test.ts | 1 + .../simulator/src/avm/opcodes/hashing.test.ts | 14 +++++++++++--- yarn-project/simulator/src/avm/opcodes/hashing.ts | 9 ++++++--- 5 files changed, 29 insertions(+), 8 deletions(-) diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index c7c57603caf..6883265c401 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -880,18 +880,22 @@ fn handle_black_box_function(avm_instrs: &mut Vec, operation: &B match operation { BlackBoxOp::PedersenHash { inputs, - domain_separator: _, + domain_separator, output, } => { let message_offset = inputs.pointer.0; let message_size_offset = inputs.size.0; + let index_offset = domain_separator.0; let dest_offset = output.0; avm_instrs.push(AvmInstruction { opcode: AvmOpcode::PEDERSEN, - indirect: Some(FIRST_OPERAND_INDIRECT), + indirect: Some(SECOND_OPERAND_INDIRECT), operands: vec![ + AvmOperand::U32 { + value: index_offset as u32, + }, AvmOperand::U32 { value: dest_offset as u32, }, diff --git a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr index eff362ec1d6..f09e441aa99 100644 --- a/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -176,6 +176,11 @@ contract AvmTest { dep::std::hash::pedersen_hash(data) } + #[aztec(public-vm)] + fn pedersen_hash_with_index(data: [Field; 3]) -> pub Field { + dep::std::hash::pedersen_hash_with_separator(data, 20) + } + /************************************************************************ * AvmContext functions ************************************************************************/ diff --git a/yarn-project/simulator/src/avm/avm_simulator.test.ts b/yarn-project/simulator/src/avm/avm_simulator.test.ts index 287ad4c8acd..21402c71d4f 100644 --- a/yarn-project/simulator/src/avm/avm_simulator.test.ts +++ b/yarn-project/simulator/src/avm/avm_simulator.test.ts @@ -130,6 +130,7 @@ describe('AVM simulator: transpiled Noir contracts', () => { describe.each([ ['poseidon_hash', poseidonHash], ['pedersen_hash', pedersenHash], + ['pedersen_hash_with_index', (m: Buffer[]) => pedersenHash(m, 20)], ])('Hashes with field returned in noir contracts', (name: string, hashFunction: (data: Buffer[]) => Fr) => { it(`Should execute contract function that performs ${name} hash`, async () => { const calldata = [new Fr(1), new Fr(2), new Fr(3)]; diff --git a/yarn-project/simulator/src/avm/opcodes/hashing.test.ts b/yarn-project/simulator/src/avm/opcodes/hashing.test.ts index b2c4dc44cf9..b8df94ef432 100644 --- a/yarn-project/simulator/src/avm/opcodes/hashing.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/hashing.test.ts @@ -205,12 +205,14 @@ describe('Hashing Opcodes', () => { const buf = Buffer.from([ Pedersen.opcode, // opcode 1, // indirect + ...Buffer.from('02345678', 'hex'), // dstOffset ...Buffer.from('12345678', 'hex'), // dstOffset ...Buffer.from('23456789', 'hex'), // messageOffset ...Buffer.from('3456789a', 'hex'), // hashSize ]); const inst = new Pedersen( /*indirect=*/ 1, + /*genIndexOffset=*/ 0x02345678, /*dstOffset=*/ 0x12345678, /*messageOffset=*/ 0x23456789, /*hashSizeOffset=*/ 0x3456789a, @@ -224,15 +226,18 @@ describe('Hashing Opcodes', () => { const args = [new Field(1n), new Field(2n), new Field(3n)]; const messageOffset = 0; const sizeOffset = 10; + const genIndexOffset = 20; const indirect = 0; + const genIndex = 20; context.machineState.memory.setSlice(messageOffset, args); context.machineState.memory.set(sizeOffset, new Uint32(args.length)); + context.machineState.memory.set(genIndexOffset, new Uint32(genIndex)); const dstOffset = 3; - const expectedHash = pedersenHash(args); - await new Pedersen(indirect, dstOffset, messageOffset, sizeOffset).execute(context); + const expectedHash = pedersenHash(args, genIndex); + await new Pedersen(indirect, genIndexOffset, dstOffset, messageOffset, sizeOffset).execute(context); const result = context.machineState.memory.get(dstOffset); expect(result).toEqual(new Field(expectedHash)); @@ -241,6 +246,7 @@ describe('Hashing Opcodes', () => { it('Should hash correctly - indirect', async () => { const args = [new Field(1n), new Field(2n), new Field(3n)]; const indirect = new Addressing([ + /*genIndexOffset=*/ AddressingMode.DIRECT, /*dstOffset=*/ AddressingMode.DIRECT, /*messageOffset*/ AddressingMode.INDIRECT, /*messageSizeOffset*/ AddressingMode.INDIRECT, @@ -249,16 +255,18 @@ describe('Hashing Opcodes', () => { const sizeOffset = 10; const realLocation = 4; const realSizeLocation = 20; + const genIndexOffset = 50; context.machineState.memory.set(messageOffset, new Uint32(realLocation)); context.machineState.memory.set(sizeOffset, new Uint32(realSizeLocation)); context.machineState.memory.setSlice(realLocation, args); context.machineState.memory.set(realSizeLocation, new Uint32(args.length)); + context.machineState.memory.set(genIndexOffset, new Uint32(0)); const dstOffset = 300; const expectedHash = pedersenHash(args); - await new Pedersen(indirect, dstOffset, messageOffset, sizeOffset).execute(context); + await new Pedersen(indirect, genIndexOffset, dstOffset, messageOffset, sizeOffset).execute(context); const result = context.machineState.memory.get(dstOffset); expect(result).toEqual(new Field(expectedHash)); diff --git a/yarn-project/simulator/src/avm/opcodes/hashing.ts b/yarn-project/simulator/src/avm/opcodes/hashing.ts index 9a60e47a6c8..194a1114f6d 100644 --- a/yarn-project/simulator/src/avm/opcodes/hashing.ts +++ b/yarn-project/simulator/src/avm/opcodes/hashing.ts @@ -147,10 +147,12 @@ export class Pedersen extends Instruction { OperandType.UINT32, OperandType.UINT32, OperandType.UINT32, + OperandType.UINT32, ]; constructor( private indirect: number, + private genIndexOffset: number, private dstOffset: number, private messageOffset: number, private messageSizeOffset: number, @@ -159,17 +161,18 @@ export class Pedersen extends Instruction { } async execute(context: AvmContext): Promise { - const [dstOffset, messageOffset, messageSizeOffset] = Addressing.fromWire(this.indirect).resolve( - [this.dstOffset, this.messageOffset, this.messageSizeOffset], + const [genIndexOffset, dstOffset, messageOffset, messageSizeOffset] = Addressing.fromWire(this.indirect).resolve( + [this.genIndexOffset, this.dstOffset, this.messageOffset, this.messageSizeOffset], context.machineState.memory, ); // We hash a set of field elements + const genIndex = Number(context.machineState.memory.get(genIndexOffset).toBigInt()); const messageSize = Number(context.machineState.memory.get(messageSizeOffset).toBigInt()); const hashData = context.machineState.memory.getSlice(messageOffset, messageSize); // No domain sep for now - const hash = pedersenHash(hashData); + const hash = pedersenHash(hashData, genIndex); context.machineState.memory.set(dstOffset, new Field(hash)); context.machineState.incrementPc();