diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index a1240378368..311fa5a87d1 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -1012,9 +1012,9 @@ fn handle_black_box_function(avm_instrs: &mut Vec, operation: &B ..Default::default() }); } - BlackBoxOp::Keccakf1600 { message, output } => { - let message_offset = message.pointer.to_usize(); - let message_size_offset = message.size.to_usize(); + BlackBoxOp::Keccakf1600 { input, output } => { + let input_offset = input.pointer.to_usize(); + assert_eq!(input.size, 25, "Keccakf1600 input size must be 25!"); let dest_offset = output.pointer.to_usize(); assert_eq!(output.size, 25, "Keccakf1600 output size must be 25!"); @@ -1023,14 +1023,12 @@ fn handle_black_box_function(avm_instrs: &mut Vec, operation: &B indirect: Some( AddressingModeBuilder::default() .indirect_operand(&output.pointer) - .indirect_operand(&message.pointer) - .direct_operand(&message.size) + .indirect_operand(&input.pointer) .build(), ), operands: vec![ AvmOperand::U16 { value: dest_offset as u16 }, - AvmOperand::U16 { value: message_offset as u16 }, - AvmOperand::U16 { value: message_size_offset as u16 }, + AvmOperand::U16 { value: input_offset as u16 }, ], ..Default::default() }); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp index 7fc66d2af01..5abc053e40d 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -286,7 +286,7 @@ struct BlackBoxOp { }; struct Keccakf1600 { - Program::HeapVector message; + Program::HeapArray input; Program::HeapArray output; friend bool operator==(const Keccakf1600&, const Keccakf1600&); @@ -424,8 +424,8 @@ struct BlackBoxOp { }; struct Sha256Compression { - Program::HeapVector input; - Program::HeapVector hash_values; + Program::HeapArray input; + Program::HeapArray hash_values; Program::HeapArray output; friend bool operator==(const Sha256Compression&, const Sha256Compression&); @@ -4061,7 +4061,7 @@ namespace Program { inline bool operator==(const BlackBoxOp::Keccakf1600& lhs, const BlackBoxOp::Keccakf1600& rhs) { - if (!(lhs.message == rhs.message)) { + if (!(lhs.input == rhs.input)) { return false; } if (!(lhs.output == rhs.output)) { @@ -4094,7 +4094,7 @@ template void serde::Serializable::serialize(const Program::BlackBoxOp::Keccakf1600& obj, Serializer& serializer) { - serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.input, serializer); serde::Serializable::serialize(obj.output, serializer); } @@ -4104,7 +4104,7 @@ Program::BlackBoxOp::Keccakf1600 serde::Deserializable::deserialize(deserializer); + obj.input = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp index efe26926f36..03cce00a6a8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp @@ -1000,7 +1000,7 @@ TEST_F(AvmExecutionTests, keccakf1600OpCode) std::string bytecode_preamble; // Set operations for keccak state - for (uint8_t i = 0; i < 25; i++) { + for (uint8_t i = 0; i < KECCAKF1600_INPUT_SIZE; i++) { bytecode_preamble += to_hex(OpCode::SET_64) + // opcode SET "00" // Indirect flag + to_hex(AvmMemoryTag::U64) + to_hex(state[i]) + // val i @@ -1012,13 +1012,8 @@ TEST_F(AvmExecutionTests, keccakf1600OpCode) to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) "00" // Indirect flag + to_hex(AvmMemoryTag::U32) + - "01" // value 1 (i.e. where the src will be read from) - "24" // input_offset 36 - + to_hex(OpCode::SET_8) + // - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "19" // value 25 (i.e. where the length parameter is stored) - "25" // input_offset 37 + "01" // value 1 (i.e. where the src will be read from) + "24" // input_offset 36 + to_hex(OpCode::SET_16) + // opcode SET for indirect dst (output) "00" // Indirect flag + to_hex(AvmMemoryTag::U32) + @@ -1028,7 +1023,6 @@ TEST_F(AvmExecutionTests, keccakf1600OpCode) "03" // Indirect flag (first 2 operands indirect) "0023" // output offset (indirect 35) "0024" // input offset (indirect 36) - "0025" // length offset 37 + to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag "0100" // ret offset 256 diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp index e14c44399bf..88be6bca8df 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp @@ -162,7 +162,7 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = { OpCode::POSEIDON2PERM, { OperandType::INDIRECT8, OperandType::UINT16, OperandType::UINT16 } }, { OpCode::SHA256COMPRESSION, { OperandType::INDIRECT8, OperandType::UINT16, OperandType::UINT16, OperandType::UINT16 } }, - { OpCode::KECCAKF1600, { OperandType::INDIRECT8, OperandType::UINT16, OperandType::UINT16, OperandType::UINT16 } }, + { OpCode::KECCAKF1600, { OperandType::INDIRECT8, OperandType::UINT16, OperandType::UINT16 } }, // TEMP ECADD without relative memory { OpCode::ECADD, { OperandType::INDIRECT16, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp index e7560783e95..0c276efe07d 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp @@ -710,8 +710,7 @@ std::vector Execution::gen_trace(std::vector const& instructio case OpCode::KECCAKF1600: trace_builder.op_keccakf1600(std::get(inst.operands.at(0)), std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3))); + std::get(inst.operands.at(2))); break; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/keccak.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/keccak.cpp index d7f90159e63..462b1767e94 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/keccak.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/keccak.cpp @@ -18,17 +18,18 @@ void AvmKeccakTraceBuilder::reset() keccak_trace.shrink_to_fit(); // Reclaim memory. } -std::array AvmKeccakTraceBuilder::keccakf1600(uint32_t clk, std::array input) +std::array AvmKeccakTraceBuilder::keccakf1600( + uint32_t clk, std::array input) { // BB's Eth hash function uses C-style arrays, while we like to use std::array // We do a few conversions for here but maybe we will update later. - uint64_t state[25] = {}; + uint64_t state[KECCAKF1600_INPUT_SIZE] = {}; std::copy(input.begin(), input.end(), state); std::vector input_vector(input.begin(), input.end()); // This function mutates state ethash_keccakf1600(state); - std::array output = {}; - for (size_t i = 0; i < 25; i++) { + std::array output = {}; + for (size_t i = 0; i < KECCAKF1600_INPUT_SIZE; i++) { output[i] = state[i]; } std::vector output_vector(output.begin(), output.end()); @@ -36,8 +37,8 @@ std::array AvmKeccakTraceBuilder::keccakf1600(uint32_t clk, std::a .clk = clk, .input = input_vector, .output = output_vector, - .input_size = 25, - .output_size = 25, + .input_size = KECCAKF1600_INPUT_SIZE, + .output_size = KECCAKF1600_INPUT_SIZE, }); return output; } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/keccak.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/keccak.hpp index 621b8985f94..7616d912d0a 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/keccak.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/gadgets/keccak.hpp @@ -8,6 +8,8 @@ namespace bb::avm_trace { +constexpr uint32_t KECCAKF1600_INPUT_SIZE = 25; + class AvmKeccakTraceBuilder { public: struct KeccakTraceEntry { @@ -23,7 +25,8 @@ class AvmKeccakTraceBuilder { // Finalize the trace std::vector finalize(); - std::array keccakf1600(uint32_t clk, std::array input); + std::array keccakf1600(uint32_t clk, + std::array input); private: std::vector keccak_trace; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index b1ccbb0f664..e7133c81dbb 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -26,6 +26,7 @@ #include "barretenberg/vm/avm/trace/fixed_gas.hpp" #include "barretenberg/vm/avm/trace/fixed_powers.hpp" #include "barretenberg/vm/avm/trace/gadgets/cmp.hpp" +#include "barretenberg/vm/avm/trace/gadgets/keccak.hpp" #include "barretenberg/vm/avm/trace/gadgets/slice_trace.hpp" #include "barretenberg/vm/avm/trace/helper.hpp" #include "barretenberg/vm/avm/trace/opcode.hpp" @@ -2950,27 +2951,17 @@ void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, /** * @brief Keccakf1600 with direct or indirect memory access. - * This function temporarily has the same interface as the kecccak opcode for compatibility, when the keccak - * migration is complete (to keccakf1600) We will update this function call as we will not likely need - * input_size_offset * @param indirect byte encoding information about indirect/direct memory access. * @param output_offset An index in memory pointing to where the first u64 value of the output array should be * stored. * @param input_offset An index in memory pointing to the first u64 value of the input array to be used in the next - * instance of poseidon2 permutation. - * @param input_size offset An index in memory pointing to the size of the input array. Temporary while we maintain - * the same interface as keccak (this is fixed to 25) + * instance of keccakf1600. */ -void AvmTraceBuilder::op_keccakf1600(uint8_t indirect, - uint32_t output_offset, - uint32_t input_offset, - [[maybe_unused]] uint32_t input_size_offset) +void AvmTraceBuilder::op_keccakf1600(uint8_t indirect, uint32_t output_offset, uint32_t input_offset) { - // What happens if the input_size_offset is > 25 when the state is more that that? auto clk = static_cast(main_trace.size()) + 1; - auto [resolved_output_offset, resolved_input_offset, _] = - Addressing<3>::fromWire(indirect, call_ptr) - .resolve({ output_offset, input_offset, input_size_offset }, mem_trace_builder); + auto [resolved_output_offset, resolved_input_offset] = + Addressing<2>::fromWire(indirect, call_ptr).resolve({ output_offset, input_offset }, mem_trace_builder); auto input_read = constrained_read_from_memory( call_ptr, clk, resolved_input_offset, AvmMemoryTag::U64, AvmMemoryTag::FF, IntermRegister::IA); auto output_read = constrained_read_from_memory( @@ -3002,13 +2993,13 @@ void AvmTraceBuilder::op_keccakf1600(uint8_t indirect, // Array input is fixed to 1600 bits std::vector input_vec; // Read results are written to input array - read_slice_from_memory(resolved_input_offset, 25, input_vec); - std::array input = vec_to_arr(input_vec); + read_slice_from_memory(resolved_input_offset, KECCAKF1600_INPUT_SIZE, input_vec); + std::array input = vec_to_arr(input_vec); // Now that we have read all the values, we can perform the operation to get the resulting witness. // Note: We use the keccak_op_clk to ensure that the keccakf1600 operation is performed at the same clock cycle // as the main trace that has the selector - std::array result = keccak_trace_builder.keccakf1600(clk, input); + std::array result = keccak_trace_builder.keccakf1600(clk, input); // Write the result to memory after write_slice_to_memory(resolved_output_offset, AvmMemoryTag::U64, result); } diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp index 66cc8767930..9380c36846e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp @@ -142,7 +142,6 @@ class AvmTraceBuilder { std::vector op_revert(uint8_t indirect, uint32_t ret_offset, uint32_t ret_size); // Gadgets - void op_keccak(uint8_t indirect, uint32_t output_offset, uint32_t input_offset, uint32_t input_size_offset); void op_poseidon2_permutation(uint8_t indirect, uint32_t input_offset, uint32_t output_offset); void op_ec_add(uint16_t indirect, uint32_t lhs_x_offset, @@ -167,7 +166,7 @@ class AvmTraceBuilder { // Future Gadgets -- pending changes in noir void op_sha256_compression(uint8_t indirect, uint32_t output_offset, uint32_t state_offset, uint32_t inputs_offset); - void op_keccakf1600(uint8_t indirect, uint32_t output_offset, uint32_t input_offset, uint32_t input_size_offset); + void op_keccakf1600(uint8_t indirect, uint32_t output_offset, uint32_t input_offset); std::vector finalize(); void reset(); diff --git a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp index 637ac2ce201..1bb8931c642 100644 --- a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp +++ b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp @@ -286,7 +286,7 @@ namespace Program { }; struct Keccakf1600 { - Program::HeapVector message; + Program::HeapArray input; Program::HeapArray output; friend bool operator==(const Keccakf1600&, const Keccakf1600&); @@ -424,8 +424,8 @@ namespace Program { }; struct Sha256Compression { - Program::HeapVector input; - Program::HeapVector hash_values; + Program::HeapArray input; + Program::HeapArray hash_values; Program::HeapArray output; friend bool operator==(const Sha256Compression&, const Sha256Compression&); @@ -3498,7 +3498,7 @@ Program::BlackBoxOp::Blake3 serde::Deserializable:: namespace Program { inline bool operator==(const BlackBoxOp::Keccakf1600 &lhs, const BlackBoxOp::Keccakf1600 &rhs) { - if (!(lhs.message == rhs.message)) { return false; } + if (!(lhs.input == rhs.input)) { return false; } if (!(lhs.output == rhs.output)) { return false; } return true; } @@ -3523,7 +3523,7 @@ namespace Program { template <> template void serde::Serializable::serialize(const Program::BlackBoxOp::Keccakf1600 &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.message, serializer); + serde::Serializable::serialize(obj.input, serializer); serde::Serializable::serialize(obj.output, serializer); } @@ -3531,7 +3531,7 @@ template <> template Program::BlackBoxOp::Keccakf1600 serde::Deserializable::deserialize(Deserializer &deserializer) { Program::BlackBoxOp::Keccakf1600 obj; - obj.message = serde::Deserializable::deserialize(deserializer); + obj.input = serde::Deserializable::deserialize(deserializer); obj.output = serde::Deserializable::deserialize(deserializer); return obj; } diff --git a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs index b61c2272587..3264388c8ef 100644 --- a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs @@ -24,7 +24,7 @@ pub enum BlackBoxOp { }, /// Keccak Permutation function of 1600 width Keccakf1600 { - message: HeapVector, + input: HeapArray, output: HeapArray, }, /// Verifies a ECDSA signature over the secp256k1 curve. @@ -102,8 +102,8 @@ pub enum BlackBoxOp { len: MemoryAddress, }, Sha256Compression { - input: HeapVector, - hash_values: HeapVector, + input: HeapArray, + hash_values: HeapArray, output: HeapArray, }, ToRadix { diff --git a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs index 4201d2ddba2..04dd85d9324 100644 --- a/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig_vm/src/black_box.rs @@ -77,8 +77,8 @@ pub(crate) fn evaluate_black_box memory.write_slice(memory.read_ref(output.pointer), &to_value_vec(&bytes)); Ok(()) } - BlackBoxOp::Keccakf1600 { message, output } => { - let state_vec: Vec = read_heap_vector(memory, message) + BlackBoxOp::Keccakf1600 { input, output } => { + let state_vec: Vec = read_heap_array(memory, input) .iter() .map(|&memory_value| memory_value.try_into().unwrap()) .collect(); @@ -292,7 +292,7 @@ pub(crate) fn evaluate_black_box } BlackBoxOp::Sha256Compression { input, hash_values, output } => { let mut message = [0; 16]; - let inputs = read_heap_vector(memory, input); + let inputs = read_heap_array(memory, input); if inputs.len() != 16 { return Err(BlackBoxResolutionError::Failed( BlackBoxFunc::Sha256Compression, @@ -303,7 +303,7 @@ pub(crate) fn evaluate_black_box message[i] = input.try_into().unwrap(); } let mut state = [0; 8]; - let values = read_heap_vector(memory, hash_values); + let values = read_heap_array(memory, hash_values); if values.len() != 8 { return Err(BlackBoxResolutionError::Failed( BlackBoxFunc::Sha256Compression, diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index 10c0e8b8e8c..55f89dcb30f 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -60,19 +60,22 @@ pub(crate) fn convert_black_box_call { - if let ([message], [BrilligVariable::BrilligArray(result_array)]) = - (function_arguments, function_results) + if let ( + [BrilligVariable::BrilligArray(input_array)], + [BrilligVariable::BrilligArray(result_array)], + ) = (function_arguments, function_results) { - let message_vector = convert_array_or_vector(brillig_context, *message, bb_func); + let input_heap_array = + brillig_context.codegen_brillig_array_to_heap_array(*input_array); let output_heap_array = brillig_context.codegen_brillig_array_to_heap_array(*result_array); brillig_context.black_box_op_instruction(BlackBoxOp::Keccakf1600 { - message: message_vector, + input: input_heap_array, output: output_heap_array, }); - brillig_context.deallocate_heap_vector(message_vector); + brillig_context.deallocate_heap_array(input_heap_array); brillig_context.deallocate_heap_array(output_heap_array); } else { unreachable!("ICE: Keccakf1600 expects one array argument and one array result") @@ -348,21 +351,23 @@ pub(crate) fn convert_black_box_call { - if let ([message, hash_values], [BrilligVariable::BrilligArray(result_array)]) = - (function_arguments, function_results) + if let ( + [BrilligVariable::BrilligArray(input_array), BrilligVariable::BrilligArray(hash_values)], + [BrilligVariable::BrilligArray(result_array)], + ) = (function_arguments, function_results) { - let message_vector = convert_array_or_vector(brillig_context, *message, bb_func); - let hash_values = convert_array_or_vector(brillig_context, *hash_values, bb_func); + let input = brillig_context.codegen_brillig_array_to_heap_array(*input_array); + let hash_values = brillig_context.codegen_brillig_array_to_heap_array(*hash_values); let output = brillig_context.codegen_brillig_array_to_heap_array(*result_array); brillig_context.black_box_op_instruction(BlackBoxOp::Sha256Compression { - input: message_vector, + input, hash_values, output, }); - brillig_context.deallocate_heap_vector(message_vector); - brillig_context.deallocate_heap_vector(hash_values); + brillig_context.deallocate_heap_array(input); + brillig_context.deallocate_heap_array(hash_values); brillig_context.deallocate_heap_array(output); } else { unreachable!("ICE: Sha256Compression expects two array argument, one array result") diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index 7597da2be05..2a46a04cc91 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -270,8 +270,8 @@ impl DebugShow { outputs ); } - BlackBoxOp::Keccakf1600 { message, output } => { - debug_println!(self.enable_debug_trace, " KECCAKF1600 {} -> {}", message, output); + BlackBoxOp::Keccakf1600 { input, output } => { + debug_println!(self.enable_debug_trace, " KECCAKF1600 {} -> {}", input, output); } BlackBoxOp::Blake2s { message, output } => { debug_println!(self.enable_debug_trace, " BLAKE2S {} -> {}", message, output); diff --git a/yarn-project/simulator/src/avm/opcodes/hashing.test.ts b/yarn-project/simulator/src/avm/opcodes/hashing.test.ts index 26020a6e0c7..ca89cbee50f 100644 --- a/yarn-project/simulator/src/avm/opcodes/hashing.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/hashing.test.ts @@ -73,15 +73,9 @@ describe('Hashing Opcodes', () => { KeccakF1600.opcode, // opcode 1, // indirect ...Buffer.from('1234', 'hex'), // dstOffset - ...Buffer.from('2345', 'hex'), // messageOffset - ...Buffer.from('3456', 'hex'), // messageSizeOffset + ...Buffer.from('2345', 'hex'), // inputOffset ]); - const inst = new KeccakF1600( - /*indirect=*/ 1, - /*dstOffset=*/ 0x1234, - /*messageOffset=*/ 0x2345, - /*messageSizeOffset=*/ 0x3456, - ); + const inst = new KeccakF1600(/*indirect=*/ 1, /*dstOffset=*/ 0x1234, /*inputOffset=*/ 0x2345); expect(KeccakF1600.deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); @@ -92,12 +86,10 @@ describe('Hashing Opcodes', () => { const args = rawArgs.map(a => new Uint64(a)); const indirect = 0; const messageOffset = 0; - const messageSizeOffset = 50; const dstOffset = 100; - context.machineState.memory.set(messageSizeOffset, new Uint32(args.length)); context.machineState.memory.setSlice(messageOffset, args); - await new KeccakF1600(indirect, dstOffset, messageOffset, messageSizeOffset).execute(context); + await new KeccakF1600(indirect, dstOffset, messageOffset).execute(context); const result = context.machineState.memory.getSliceAs(dstOffset, 25); expect(result).toEqual(keccakf1600(rawArgs).map(a => new Uint64(a))); diff --git a/yarn-project/simulator/src/avm/opcodes/hashing.ts b/yarn-project/simulator/src/avm/opcodes/hashing.ts index 92e7bfb2a71..84344e1f10e 100644 --- a/yarn-project/simulator/src/avm/opcodes/hashing.ts +++ b/yarn-project/simulator/src/avm/opcodes/hashing.ts @@ -1,7 +1,5 @@ import { keccakf1600, poseidon2Permutation, sha256Compression } from '@aztec/foundation/crypto'; -import { strict as assert } from 'assert'; - import { type AvmContext } from '../avm_context.js'; import { Field, TypeTag, Uint32, Uint64 } from '../avm_memory_types.js'; import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; @@ -56,39 +54,30 @@ export class KeccakF1600 extends Instruction { OperandType.UINT8, OperandType.UINT16, OperandType.UINT16, - OperandType.UINT16, ]; - constructor( - private indirect: number, - private dstOffset: number, - private stateOffset: number, - // This is here for compatibility with the CPP side. Should be removed in both. - private stateSizeOffset: number, - ) { + constructor(private indirect: number, private dstOffset: number, private inputOffset: number) { super(); } // pub fn keccakf1600(input: [u64; 25]) -> [u64; 25] public async execute(context: AvmContext): Promise { + const inputSize = 25; const memory = context.machineState.memory.track(this.type); - const operands = [this.dstOffset, this.stateOffset, this.stateSizeOffset]; + const operands = [this.dstOffset, this.inputOffset]; const addressing = Addressing.fromWire(this.indirect, operands.length); - const [dstOffset, stateOffset, stateSizeOffset] = addressing.resolve(operands, memory); - memory.checkTag(TypeTag.UINT32, stateSizeOffset); - const stateSize = memory.get(stateSizeOffset).toNumber(); - assert(stateSize === 25, 'Invalid state size for keccakf1600'); + const [dstOffset, inputOffset] = addressing.resolve(operands, memory); context.machineState.consumeGas(this.gasCost()); - memory.checkTagsRange(TypeTag.UINT64, stateOffset, stateSize); + memory.checkTagsRange(TypeTag.UINT64, inputOffset, inputSize); - const stateData = memory.getSlice(stateOffset, stateSize).map(word => word.toBigInt()); + const stateData = memory.getSlice(inputOffset, inputSize).map(word => word.toBigInt()); const updatedState = keccakf1600(stateData); const res = updatedState.map(word => new Uint64(word)); memory.setSlice(dstOffset, res); - memory.assert({ reads: stateSize + 1, writes: 25, addressing }); + memory.assert({ reads: inputSize, writes: inputSize, addressing }); context.machineState.incrementPc(); } }