diff --git a/avm-transpiler/src/instructions.rs b/avm-transpiler/src/instructions.rs index 4b3df88e102..0f0a75495b9 100644 --- a/avm-transpiler/src/instructions.rs +++ b/avm-transpiler/src/instructions.rs @@ -10,6 +10,7 @@ pub const ALL_DIRECT: u8 = 0b00000000; pub const ZEROTH_OPERAND_INDIRECT: u8 = 0b00000001; pub const FIRST_OPERAND_INDIRECT: u8 = 0b00000010; pub const SECOND_OPERAND_INDIRECT: u8 = 0b00000100; +pub const THIRD_OPERAND_INDIRECT: u8 = 0b00001000; /// A simple representation of an AVM instruction for the purpose /// of generating an AVM bytecode from Brillig. diff --git a/avm-transpiler/src/opcodes.rs b/avm-transpiler/src/opcodes.rs index 93d1a3ba7ea..80defd4a393 100644 --- a/avm-transpiler/src/opcodes.rs +++ b/avm-transpiler/src/opcodes.rs @@ -88,16 +88,14 @@ pub enum AvmOpcode { // Gadgets KECCAK, POSEIDON2, - SHA256, // temp - may be removed, but alot of contracts rely on it + SHA256COMPRESSION, + KECCAKF1600, PEDERSEN, // temp - may be removed, but alot of contracts rely on it ECADD, MSM, PEDERSENCOMMITMENT, // temp // Conversions TORADIXLE, - // Other - SHA256COMPRESSION, - KECCAKF1600, } impl AvmOpcode { @@ -202,17 +200,15 @@ impl AvmOpcode { // Gadgets AvmOpcode::KECCAK => "KECCAK", + AvmOpcode::KECCAKF1600 => "KECCAKF1600", AvmOpcode::POSEIDON2 => "POSEIDON2", - AvmOpcode::SHA256 => "SHA256 ", + AvmOpcode::SHA256COMPRESSION => "SHA256COMPRESSION", AvmOpcode::PEDERSEN => "PEDERSEN", AvmOpcode::ECADD => "ECADD", AvmOpcode::MSM => "MSM", AvmOpcode::PEDERSENCOMMITMENT => "PEDERSENCOMMITMENT", // Conversions AvmOpcode::TORADIXLE => "TORADIXLE", - // Other - AvmOpcode::SHA256COMPRESSION => "SHA256COMPRESSION", - AvmOpcode::KECCAKF1600 => "KECCAKF1600", } } } diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs index b3fc61c1240..0b0fff16bae 100644 --- a/avm-transpiler/src/transpile.rs +++ b/avm-transpiler/src/transpile.rs @@ -12,7 +12,7 @@ use noirc_errors::debug_info::DebugInfo; use crate::bit_traits::bits_needed_for; use crate::instructions::{ AvmInstruction, AvmOperand, AvmTypeTag, ALL_DIRECT, FIRST_OPERAND_INDIRECT, - SECOND_OPERAND_INDIRECT, ZEROTH_OPERAND_INDIRECT, + SECOND_OPERAND_INDIRECT, THIRD_OPERAND_INDIRECT, ZEROTH_OPERAND_INDIRECT, }; use crate::opcodes::AvmOpcode; use crate::utils::{dbg_print_avm_program, dbg_print_brillig_program, make_operand}; @@ -865,19 +865,24 @@ fn generate_mov_instruction(indirect: Option, source: u32, dest: u32) -> Avm /// (array goes in -> field element comes out) fn handle_black_box_function(avm_instrs: &mut Vec, operation: &BlackBoxOp) { match operation { - BlackBoxOp::Sha256 { message, output } => { - let message_offset = message.pointer.0; - let message_size_offset = message.size.0; - let dest_offset = output.pointer.0; - assert_eq!(output.size, 32, "SHA256 output size must be 32!"); + BlackBoxOp::Sha256Compression { input, hash_values, output } => { + let inputs_offset = input.pointer.0; + let inputs_size_offset = input.size.0; + let state_offset = hash_values.pointer.0; + let state_size_offset = hash_values.size.0; + let output_offset = output.pointer.0; avm_instrs.push(AvmInstruction { - opcode: AvmOpcode::SHA256, - indirect: Some(ZEROTH_OPERAND_INDIRECT | FIRST_OPERAND_INDIRECT), + opcode: AvmOpcode::SHA256COMPRESSION, + indirect: Some( + ZEROTH_OPERAND_INDIRECT | FIRST_OPERAND_INDIRECT | THIRD_OPERAND_INDIRECT, + ), operands: vec![ - AvmOperand::U32 { value: dest_offset as u32 }, - AvmOperand::U32 { value: message_offset as u32 }, - AvmOperand::U32 { value: message_size_offset as u32 }, + AvmOperand::U32 { value: output_offset as u32 }, + AvmOperand::U32 { value: state_offset as u32 }, + AvmOperand::U32 { value: state_size_offset as u32 }, + AvmOperand::U32 { value: inputs_offset as u32 }, + AvmOperand::U32 { value: inputs_size_offset as u32 }, ], ..Default::default() }); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp index 5ca7ebe2068..30b9fca700f 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp @@ -74,13 +74,6 @@ void build_constraints(Builder& builder, } // Add sha256 constraints - for (size_t i = 0; i < constraint_system.sha256_constraints.size(); ++i) { - const auto& constraint = constraint_system.sha256_constraints.at(i); - create_sha256_constraints(builder, constraint); - gate_counter.track_diff(constraint_system.gates_per_opcode, - constraint_system.original_opcode_indices.sha256_constraints.at(i)); - } - for (size_t i = 0; i < constraint_system.sha256_compression.size(); ++i) { const auto& constraint = constraint_system.sha256_compression[i]; create_sha256_compression_constraints(builder, constraint); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp index fd9439cdfce..02de8ac8b9e 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.hpp @@ -41,7 +41,6 @@ struct AcirFormatOriginalOpcodeIndices { std::vector logic_constraints; std::vector range_constraints; std::vector aes128_constraints; - std::vector sha256_constraints; std::vector sha256_compression; std::vector schnorr_constraints; std::vector ecdsa_k1_constraints; @@ -90,7 +89,6 @@ struct AcirFormat { std::vector logic_constraints; std::vector range_constraints; std::vector aes128_constraints; - std::vector sha256_constraints; std::vector sha256_compression; std::vector schnorr_constraints; std::vector ecdsa_k1_constraints; @@ -137,7 +135,6 @@ struct AcirFormat { logic_constraints, range_constraints, aes128_constraints, - sha256_constraints, sha256_compression, schnorr_constraints, ecdsa_k1_constraints, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp index 64a7fea8a5e..f894d12eed4 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp @@ -45,7 +45,6 @@ TEST_F(AcirFormatTests, TestASingleConstraintNoPubInputs) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -169,7 +168,6 @@ TEST_F(AcirFormatTests, TestLogicGateFromNoirCircuit) .logic_constraints = { logic_constraint }, .range_constraints = { range_a, range_b }, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -243,6 +241,7 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass) .result = 76, .signature = signature, }; + AcirFormat constraint_system{ .varnum = 81, .recursive = false, @@ -251,7 +250,6 @@ TEST_F(AcirFormatTests, TestSchnorrVerifyPass) .logic_constraints = {}, .range_constraints = range_constraints, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = { schnorr_constraint }, .ecdsa_k1_constraints = {}, @@ -360,7 +358,6 @@ TEST_F(AcirFormatTests, TestSchnorrVerifySmallRange) .logic_constraints = {}, .range_constraints = range_constraints, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = { schnorr_constraint }, .ecdsa_k1_constraints = {}, @@ -482,7 +479,6 @@ TEST_F(AcirFormatTests, TestVarKeccak) .logic_constraints = {}, .range_constraints = { range_a, range_b, range_c, range_d }, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -564,7 +560,6 @@ TEST_F(AcirFormatTests, TestKeccakPermutation) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -598,11 +593,9 @@ TEST_F(AcirFormatTests, TestKeccakPermutation) 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50 }; auto builder = create_circuit(constraint_system, /*size_hint=*/0, witness); - auto composer = Composer(); auto prover = composer.create_ultra_with_keccak_prover(builder); auto proof = prover.construct_proof(); - auto verifier = composer.create_ultra_with_keccak_verifier(builder); EXPECT_EQ(verifier.verify_proof(proof), true); @@ -643,7 +636,6 @@ TEST_F(AcirFormatTests, TestCollectsGateCounts) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -676,4 +668,4 @@ TEST_F(AcirFormatTests, TestCollectsGateCounts) create_circuit(constraint_system, /*size_hint*/ 0, witness, false, std::make_shared(), true); EXPECT_EQ(constraint_system.gates_per_opcode, std::vector({ 2, 1 })); -} \ No newline at end of file +} diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format_mocks.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format_mocks.cpp index e1240d85e82..2173285becf 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format_mocks.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format_mocks.cpp @@ -6,7 +6,6 @@ acir_format::AcirFormatOriginalOpcodeIndices create_empty_original_opcode_indice .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -46,9 +45,6 @@ void mock_opcode_indices(acir_format::AcirFormat& constraint_system) for (size_t i = 0; i < constraint_system.aes128_constraints.size(); i++) { constraint_system.original_opcode_indices.aes128_constraints.push_back(current_opcode++); } - for (size_t i = 0; i < constraint_system.sha256_constraints.size(); i++) { - constraint_system.original_opcode_indices.sha256_constraints.push_back(current_opcode++); - } for (size_t i = 0; i < constraint_system.sha256_compression.size(); i++) { constraint_system.original_opcode_indices.sha256_compression.push_back(current_opcode++); } @@ -127,4 +123,4 @@ void mock_opcode_indices(acir_format::AcirFormat& constraint_system) } constraint_system.num_acir_opcodes = static_cast(current_opcode); -} \ No newline at end of file +} diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp index 245509e6b5c..91ed35c0b7f 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_to_constraint_buf.cpp @@ -354,21 +354,6 @@ void handle_blackbox_func_call(Program::Opcode::BlackBoxFuncCall const& arg, af.constrained_witness.insert(output); } af.original_opcode_indices.aes128_constraints.push_back(opcode_index); - - } else if constexpr (std::is_same_v) { - af.sha256_constraints.push_back(Sha256Constraint{ - .inputs = map(arg.inputs, - [](auto& e) { - auto input_witness = get_witness_from_function_input(e); - return Sha256Input{ - .witness = input_witness, - .num_bits = e.num_bits, - }; - }), - .result = map(arg.outputs, [](auto& e) { return e.value; }), - }); - af.original_opcode_indices.sha256_constraints.push_back(opcode_index); - } else if constexpr (std::is_same_v) { af.sha256_compression.push_back(Sha256Compression{ .inputs = map(arg.inputs, [](auto& e) { return parse_input(e); }), @@ -823,4 +808,4 @@ AcirProgramStack get_acir_program_stack(std::string const& bytecode_path, return { constraint_systems, witness_stack }; } #endif -} // namespace acir_format \ No newline at end of file +} // namespace acir_format diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp index a2dec9cce39..541dbcab37a 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/bigint_constraint.test.cpp @@ -178,7 +178,6 @@ TEST_F(BigIntTests, TestBigIntConstraintMultiple) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -254,7 +253,6 @@ TEST_F(BigIntTests, TestBigIntConstraintSimple) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -314,7 +312,6 @@ TEST_F(BigIntTests, TestBigIntConstraintReuse) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -379,7 +376,6 @@ TEST_F(BigIntTests, TestBigIntConstraintReuse2) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -465,7 +461,6 @@ TEST_F(BigIntTests, TestBigIntDIV) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp index 03ddf8035dc..45dece532ee 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/block_constraint.test.cpp @@ -146,7 +146,6 @@ TEST_F(UltraPlonkRAM, TestBlockConstraint) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -200,7 +199,6 @@ TEST_F(MegaHonk, Databus) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -309,7 +307,6 @@ TEST_F(MegaHonk, DatabusReturn) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp index ac86757bb0d..f12c39e8f8f 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ec_operations.test.cpp @@ -68,7 +68,6 @@ TEST_F(EcOperations, TestECOperations) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -207,7 +206,6 @@ TEST_F(EcOperations, TestECMultiScalarMul) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp index d8bc40c5308..24864b52f6d 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp @@ -100,7 +100,6 @@ TEST_F(ECDSASecp256k1, TestECDSAConstraintSucceed) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = { ecdsa_k1_constraint }, @@ -157,7 +156,6 @@ TEST_F(ECDSASecp256k1, TestECDSACompilesForVerifier) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = { ecdsa_k1_constraint }, @@ -209,7 +207,6 @@ TEST_F(ECDSASecp256k1, TestECDSAConstraintFail) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = { ecdsa_k1_constraint }, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp index 869c896ea6f..657eaa2d316 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256r1.test.cpp @@ -134,7 +134,6 @@ TEST(ECDSASecp256r1, test_hardcoded) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -193,7 +192,6 @@ TEST(ECDSASecp256r1, TestECDSAConstraintSucceed) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -250,7 +248,6 @@ TEST(ECDSASecp256r1, TestECDSACompilesForVerifier) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -303,7 +300,6 @@ TEST(ECDSASecp256r1, TestECDSAConstraintFail) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.test.cpp index abf9be04f69..5c3f1ab11ff 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/honk_recursion_constraint.test.cpp @@ -96,7 +96,6 @@ class AcirHonkRecursionConstraint : public ::testing::Test { .logic_constraints = { logic_constraint }, .range_constraints = { range_a, range_b }, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp index 47bd777cfce..a0adc6331e0 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/multi_scalar_mul.test.cpp @@ -68,7 +68,6 @@ TEST_F(MSMTests, TestMSM) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp index c3dc81fd9bc..ec2793c3aca 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/poseidon2_constraint.test.cpp @@ -48,7 +48,6 @@ TEST_F(Poseidon2Tests, TestPoseidon2Permutation) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp index 1811b8d7fee..ec22ec71fdb 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/recursion_constraint.test.cpp @@ -93,7 +93,6 @@ Builder create_inner_circuit() .logic_constraints = { logic_constraint }, .range_constraints = { range_a, range_b }, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, @@ -257,7 +256,6 @@ Builder create_outer_circuit(std::vector& inner_circuits) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = {}, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, 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 e2053834631..5905b337856 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/serde/acir.hpp @@ -256,15 +256,6 @@ struct BlackBoxOp { static AES128Encrypt bincodeDeserialize(std::vector); }; - struct Sha256 { - Program::HeapVector message; - Program::HeapArray output; - - friend bool operator==(const Sha256&, const Sha256&); - std::vector bincodeSerialize() const; - static Sha256 bincodeDeserialize(std::vector); - }; - struct Blake2s { Program::HeapVector message; Program::HeapArray output; @@ -472,7 +463,6 @@ struct BlackBoxOp { }; std::variant); }; - struct SHA256 { - std::vector inputs; - std::array outputs; - - friend bool operator==(const SHA256&, const SHA256&); - std::vector bincodeSerialize() const; - static SHA256 bincodeDeserialize(std::vector); - }; - struct Blake2s { std::vector inputs; std::array outputs; @@ -1086,7 +1067,6 @@ struct BlackBoxFuncCall { AND, XOR, RANGE, - SHA256, Blake2s, Blake3, SchnorrVerify, @@ -2922,58 +2902,6 @@ Program::BlackBoxFuncCall::RANGE serde::Deserializable BlackBoxFuncCall::SHA256::bincodeSerialize() const -{ - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); -} - -inline BlackBoxFuncCall::SHA256 BlackBoxFuncCall::SHA256::bincodeDeserialize(std::vector input) -{ - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw_or_abort("Some input bytes were not read"); - } - return value; -} - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::BlackBoxFuncCall::SHA256& obj, - Serializer& serializer) -{ - serde::Serializable::serialize(obj.inputs, serializer); - serde::Serializable::serialize(obj.outputs, serializer); -} - -template <> -template -Program::BlackBoxFuncCall::SHA256 serde::Deserializable::deserialize( - Deserializer& deserializer) -{ - Program::BlackBoxFuncCall::SHA256 obj; - obj.inputs = serde::Deserializable::deserialize(deserializer); - obj.outputs = serde::Deserializable::deserialize(deserializer); - return obj; -} - -namespace Program { - inline bool operator==(const BlackBoxFuncCall::Blake2s& lhs, const BlackBoxFuncCall::Blake2s& rhs) { if (!(lhs.inputs == rhs.inputs)) { @@ -4254,57 +4182,6 @@ Program::BlackBoxOp::AES128Encrypt serde::Deserializable BlackBoxOp::Sha256::bincodeSerialize() const -{ - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); -} - -inline BlackBoxOp::Sha256 BlackBoxOp::Sha256::bincodeDeserialize(std::vector input) -{ - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw_or_abort("Some input bytes were not read"); - } - return value; -} - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::BlackBoxOp::Sha256& obj, - Serializer& serializer) -{ - serde::Serializable::serialize(obj.message, serializer); - serde::Serializable::serialize(obj.output, serializer); -} - -template <> -template -Program::BlackBoxOp::Sha256 serde::Deserializable::deserialize(Deserializer& deserializer) -{ - Program::BlackBoxOp::Sha256 obj; - obj.message = serde::Deserializable::deserialize(deserializer); - obj.output = serde::Deserializable::deserialize(deserializer); - return obj; -} - -namespace Program { - inline bool operator==(const BlackBoxOp::Blake2s& lhs, const BlackBoxOp::Blake2s& rhs) { if (!(lhs.message == rhs.message)) { diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp index cafec218b11..80fd8a18867 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.cpp @@ -6,53 +6,10 @@ namespace acir_format { -using namespace bb; - -// This function does not work (properly) because the stdlib:sha256 function is not working correctly for 512 bits -// pair -template void create_sha256_constraints(Builder& builder, const Sha256Constraint& constraint) -{ - using byte_array_ct = stdlib::byte_array; - using field_ct = stdlib::field_t; - - // Create byte array struct - byte_array_ct arr(&builder); - - // Get the witness assignment for each witness index - // Write the witness assignment to the byte_array - for (const auto& witness_index_num_bits : constraint.inputs) { - auto witness_index = witness_index_num_bits.witness; - auto num_bits = witness_index_num_bits.num_bits; - - // XXX: The implementation requires us to truncate the element to the nearest byte and not bit - auto num_bytes = round_to_nearest_byte(num_bits); - - field_ct element = field_ct::from_witness_index(&builder, witness_index); - byte_array_ct element_bytes(element, num_bytes); - - arr.write(element_bytes); - } - - // Compute sha256 - byte_array_ct output_bytes = stdlib::sha256(arr); - - // Convert byte array to vector of field_t - auto bytes = output_bytes.bytes(); - - for (size_t i = 0; i < bytes.size(); ++i) { - auto normalised = bytes[i].normalize(); - if (normalised.is_constant()) { - builder.fix_witness(constraint.result[i], normalised.get_value()); - } else { - builder.assert_equal(bytes[i].normalize().witness_index, constraint.result[i]); - } - } -} - template void create_sha256_compression_constraints(Builder& builder, const Sha256Compression& constraint) { - using field_ct = stdlib::field_t; + using field_ct = bb::stdlib::field_t; std::array inputs; std::array hash_inputs; @@ -72,14 +29,14 @@ void create_sha256_compression_constraints(Builder& builder, const Sha256Compres } // Compute sha256 compression - auto output_bytes = stdlib::sha256_plookup::sha256_block(hash_inputs, inputs); + auto output_bytes = bb::stdlib::sha256_plookup::sha256_block(hash_inputs, inputs); for (size_t i = 0; i < 8; ++i) { auto normalised_output = output_bytes[i].normalize(); if (normalised_output.is_constant()) { builder.fix_witness(constraint.result[i], normalised_output.get_value()); } else { - poly_triple assert_equal{ + bb::poly_triple assert_equal{ .a = normalised_output.witness_index, .b = constraint.result[i], .c = 0, @@ -94,14 +51,9 @@ void create_sha256_compression_constraints(Builder& builder, const Sha256Compres } } -template void create_sha256_constraints(UltraCircuitBuilder& builder, - const Sha256Constraint& constraint); -template void create_sha256_constraints(MegaCircuitBuilder& builder, - const Sha256Constraint& constraint); - -template void create_sha256_compression_constraints(UltraCircuitBuilder& builder, - const Sha256Compression& constraint); -template void create_sha256_compression_constraints(MegaCircuitBuilder& builder, - const Sha256Compression& constraint); +template void create_sha256_compression_constraints(bb::UltraCircuitBuilder& builder, + const Sha256Compression& constraint); +template void create_sha256_compression_constraints(bb::MegaCircuitBuilder& builder, + const Sha256Compression& constraint); } // namespace acir_format diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp index 4b243b5b6ab..cb5e95f3328 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.hpp @@ -16,15 +16,6 @@ struct Sha256Input { MSGPACK_FIELDS(witness, num_bits); }; -struct Sha256Constraint { - std::vector inputs; - std::array result; - - friend bool operator==(Sha256Constraint const& lhs, Sha256Constraint const& rhs) = default; - // for serialization, update with any new fields - MSGPACK_FIELDS(inputs, result); -}; - struct Sha256Compression { std::array, 16> inputs; std::array, 8> hash_values; @@ -35,10 +26,6 @@ struct Sha256Compression { MSGPACK_FIELDS(inputs, hash_values, result); }; -// This function does not work (properly) because the stdlib:sha256 function is not working correctly for 512 bits -// pair -template void create_sha256_constraints(Builder& builder, const Sha256Constraint& constraint); - template void create_sha256_compression_constraints(Builder& builder, const Sha256Compression& constraint); diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp index 3f27b41c584..063ad4f62c8 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_format/sha256_constraint.test.cpp @@ -43,7 +43,6 @@ TEST_F(Sha256Tests, TestSha256Compression) .logic_constraints = {}, .range_constraints = {}, .aes128_constraints = {}, - .sha256_constraints = {}, .sha256_compression = { sha256_compression }, .schnorr_constraints = {}, .ecdsa_k1_constraints = {}, 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 e9d7fabaa67..f0e04c1feaf 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/tests/execution.test.cpp @@ -944,10 +944,12 @@ TEST_F(AvmExecutionTests, sha256CompressionOpcode) "09" // value 9 (i.e. where the input will be read from) "23" // dst_offset 35 + to_hex(OpCode::SHA256COMPRESSION) + // opcode SHA256COMPRESSION - "07" // Indirect flag (first 3 operands indirect) - "00000024" // output offset (indirect 36) - "00000022" // state offset (indirect 34) - "00000023" // input offset (indirect 35) + "00" // Indirect flag + "00000100" // output offset + "00000001" // state offset + "0000000F" // state size + "00000009" // input offset + "00000008" // input size + to_hex(OpCode::RETURN) + // opcode RETURN "00" // Indirect flag "00000100" // ret offset 256 @@ -971,74 +973,6 @@ TEST_F(AvmExecutionTests, sha256CompressionOpcode) validate_trace(std::move(trace), public_inputs, calldata, returndata); } -// Positive test with SHA256 -TEST_F(AvmExecutionTests, sha256Opcode) -{ - - // Test vectors taken from noir black_box_solver - // Uint8Array.from([0x61, 0x62, 0x63]), - // Uint8Array.from([ - // 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, - // 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad, - // ]), - std::vector expected_output = { - FF(0xba), FF(0x78), FF(0x16), FF(0xbf), FF(0x8f), FF(0x01), FF(0xcf), FF(0xea), FF(0x41), FF(0x41), FF(0x40), - FF(0xde), FF(0x5d), FF(0xae), FF(0x22), FF(0x23), FF(0xb0), FF(0x03), FF(0x61), FF(0xa3), FF(0x96), FF(0x17), - FF(0x7a), FF(0x9c), FF(0xb4), FF(0x10), FF(0xff), FF(0x61), FF(0xf2), FF(0x00), FF(0x15), FF(0xad), - }; - std::string bytecode_hex = to_hex(OpCode::SET_8) + // Initial SET operations to store state and input - "00" // Indirect Flag - + to_hex(AvmMemoryTag::U8) + - "61" // val 97 - "01" // dst_offset 1 - + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) - "00" // Indirect flag - + to_hex(AvmMemoryTag::U8) + - "62" // value 98 (i.e. where the src will be read from)A - "02" // input_offset 2 - + to_hex(OpCode::SET_8) + // opcode SET for indirect src (input) - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "63" // value 99 (i.e. where the src will be read from) - "03" // input_offset 36 - + 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::U8) + - "03" // value 3 (i.e. where the length parameter is stored) - "25" // input_offset 37 - + to_hex(OpCode::SET_16) + // opcode SET for indirect dst (output) - "00" // Indirect flag - + to_hex(AvmMemoryTag::U32) + - "0100" // value 256 (i.e. where the ouput will be written to) - "0023" // dst_offset 35 - + to_hex(OpCode::SHA256) + // opcode SHA256 - "03" // Indirect flag (first 2 operands indirect) - "00000023" // output offset (indirect 35) - "00000024" // input offset (indirect 36) - "00000025" // length offset 37 - + to_hex(OpCode::RETURN) + // opcode RETURN - "00" // Indirect flag - "00000100" // ret offset 256 - "00000020"; // ret size 32 - - auto bytecode = hex_to_bytes(bytecode_hex); - auto instructions = Deserialization::parse(bytecode); - - // Assign a vector that we will mutate internally in gen_trace to store the return values; - std::vector returndata = std::vector(); - std::vector calldata = std::vector(); - auto trace = Execution::gen_trace(instructions, returndata, calldata, public_inputs_vec); - - EXPECT_EQ(returndata, expected_output); - - validate_trace(std::move(trace), public_inputs, calldata, returndata); -} - // Positive test with POSEIDON2_PERM. TEST_F(AvmExecutionTests, poseidon2PermutationOpCode) { diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp index 4a10416435e..bede0c625a8 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/deserialization.cpp @@ -174,7 +174,14 @@ const std::unordered_map> OPCODE_WIRE_FORMAT = // Gadgets - Hashing { OpCode::KECCAK, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, { OpCode::POSEIDON2, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32 } }, - { OpCode::SHA256, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, + { OpCode::SHA256COMPRESSION, + { OperandType::INDIRECT, + OperandType::UINT32, + OperandType::UINT32, + OperandType::UINT32, + OperandType::UINT32, + OperandType::UINT32 } }, + { OpCode::KECCAKF1600, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, { OpCode::PEDERSEN, { OperandType::INDIRECT, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32, OperandType::UINT32 } }, // TEMP ECADD without relative memory diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp index 6f56786ebee..5ded033326c 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/execution.cpp @@ -931,12 +931,6 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(2))); break; - case OpCode::SHA256: - trace_builder.op_sha256(std::get(inst.operands.at(0)), - std::get(inst.operands.at(1)), - std::get(inst.operands.at(2)), - std::get(inst.operands.at(3))); - break; case OpCode::PEDERSEN: trace_builder.op_pedersen_hash(std::get(inst.operands.at(0)), std::get(inst.operands.at(1)), @@ -972,12 +966,13 @@ std::vector Execution::gen_trace(std::vector const& instructio std::get(inst.operands.at(5))); break; - // Future Gadgets -- pending changes in noir case OpCode::SHA256COMPRESSION: trace_builder.op_sha256_compression(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(3)), + std::get(inst.operands.at(4)), + std::get(inst.operands.at(5))); break; case OpCode::KECCAKF1600: diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp index cf34e1d4691..e2c949b1031 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/fixed_gas.cpp @@ -96,15 +96,14 @@ const std::unordered_map GAS_COST_TABLE = { { OpCode::DEBUGLOG, make_cost(AVM_DEBUGLOG_BASE_L2_GAS, 0, AVM_DEBUGLOG_DYN_L2_GAS, 0) }, { OpCode::KECCAK, make_cost(AVM_KECCAK_BASE_L2_GAS, 0, AVM_KECCAK_DYN_L2_GAS, 0) }, { OpCode::POSEIDON2, make_cost(AVM_POSEIDON2_BASE_L2_GAS, 0, AVM_POSEIDON2_DYN_L2_GAS, 0) }, - { OpCode::SHA256, make_cost(AVM_SHA256_BASE_L2_GAS, 0, AVM_SHA256_DYN_L2_GAS, 0) }, + { OpCode::SHA256COMPRESSION, make_cost(AVM_SHA256COMPRESSION_BASE_L2_GAS, 0, AVM_SHA256COMPRESSION_DYN_L2_GAS, 0) }, + { OpCode::KECCAKF1600, make_cost(AVM_KECCAKF1600_BASE_L2_GAS, 0, AVM_KECCAKF1600_DYN_L2_GAS, 0) }, { OpCode::PEDERSEN, make_cost(AVM_PEDERSEN_BASE_L2_GAS, 0, AVM_PEDERSEN_DYN_L2_GAS, 0) }, { OpCode::ECADD, make_cost(AVM_ECADD_BASE_L2_GAS, 0, AVM_ECADD_DYN_L2_GAS, 0) }, { OpCode::MSM, make_cost(AVM_MSM_BASE_L2_GAS, 0, AVM_MSM_DYN_L2_GAS, 0) }, { OpCode::PEDERSENCOMMITMENT, make_cost(AVM_PEDERSENCOMMITMENT_BASE_L2_GAS, 0, AVM_PEDERSENCOMMITMENT_DYN_L2_GAS, 0) }, { OpCode::TORADIXLE, make_cost(AVM_TORADIXLE_BASE_L2_GAS, 0, AVM_TORADIXLE_DYN_L2_GAS, 0) }, - { OpCode::SHA256COMPRESSION, make_cost(AVM_SHA256COMPRESSION_BASE_L2_GAS, 0, AVM_SHA256COMPRESSION_DYN_L2_GAS, 0) }, - { OpCode::KECCAKF1600, make_cost(AVM_KECCAKF1600_BASE_L2_GAS, 0, AVM_KECCAKF1600_DYN_L2_GAS, 0) }, }; } // namespace diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp index b1cdfbb5710..56d67fa90f9 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.cpp @@ -191,8 +191,10 @@ std::string to_string(OpCode opcode) return "KECCAK"; case OpCode::POSEIDON2: return "POSEIDON2"; - case OpCode::SHA256: - return "SHA256"; + case OpCode::SHA256COMPRESSION: + return "SHA256COMPRESSION"; + case OpCode::KECCAKF1600: + return "KECCAKF1600"; case OpCode::PEDERSEN: return "PEDERSEN"; case OpCode::ECADD: @@ -202,11 +204,6 @@ std::string to_string(OpCode opcode) // Conversions case OpCode::TORADIXLE: return "TORADIXLE"; - // Future Gadgets -- pending changes in noir - case OpCode::SHA256COMPRESSION: - return "SHA256COMPRESSION"; - case OpCode::KECCAKF1600: - return "KECCAKF1600"; // Sentinel case OpCode::LAST_OPCODE_SENTINEL: return "LAST_OPCODE_SENTINEL"; diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp index 1c789c4e9cc..36ffca9234d 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/opcode.hpp @@ -116,16 +116,14 @@ enum class OpCode : uint8_t { // Gadgets KECCAK, POSEIDON2, - SHA256, + SHA256COMPRESSION, + KECCAKF1600, PEDERSEN, ECADD, MSM, PEDERSENCOMMITMENT, // Conversions TORADIXLE, - // Future Gadgets -- pending changes in noir - SHA256COMPRESSION, - KECCAKF1600, // Here for when we eventually support this // Sentinel LAST_OPCODE_SENTINEL, diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp index 8d493b33e82..3d2f928aa79 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.cpp @@ -2980,61 +2980,6 @@ void AvmTraceBuilder::op_poseidon2_permutation(uint8_t indirect, uint32_t input_ AvmMemTraceBuilder::POSEIDON2); } -/** - * @brief SHA256 Hash with direct or indirect memory access. - * This function is temporary until we have transitioned to sha256Compression - * @param indirect byte encoding information about indirect/direct memory access. - * @param output_offset An index in memory pointing to where the first U32 value of the output array should be - * stored. - * @param input_offset An index in memory pointing to the first U8 value of the state array to be used in the next - * instance of sha256. - * @param input_size_offset An index in memory pointing to the U32 value of the input size. - */ -void AvmTraceBuilder::op_sha256(uint8_t indirect, - uint32_t output_offset, - uint32_t input_offset, - uint32_t input_size_offset) -{ - auto clk = static_cast(main_trace.size()) + 1; - auto [resolved_output_offset, resolved_input_offset, resolved_input_size_offset] = - unpack_indirects<3>(indirect, { output_offset, input_offset, input_size_offset }); - - gas_trace_builder.constrain_gas(clk, OpCode::SHA256); - - auto input_length_read = constrained_read_from_memory( - call_ptr, clk, resolved_input_size_offset, AvmMemoryTag::U32, AvmMemoryTag::U0, IntermRegister::IB); - - // Store the clock time that we will use to line up the gadget later - auto sha256_op_clk = clk; - main_trace.push_back(Row{ - .main_clk = clk, - .main_ib = input_length_read.val, // Message Length - .main_ind_addr_b = FF(input_length_read.indirect_address), - .main_internal_return_ptr = FF(internal_return_ptr), - .main_mem_addr_b = FF(input_length_read.direct_address), - .main_pc = FF(pc++), - .main_r_in_tag = FF(static_cast(AvmMemoryTag::U32)), - .main_sel_mem_op_b = FF(1), - .main_sel_op_sha256 = FF(1), - .main_sel_resolve_ind_addr_b = FF(static_cast(input_length_read.is_indirect)), - .main_tag_err = FF(static_cast(!input_length_read.tag_match)), - }); - clk++; - - std::vector input; - input.reserve(uint32_t(input_length_read.val)); - read_slice_from_memory(resolved_input_offset, uint32_t(input_length_read.val), input); - - std::array result = sha256_trace_builder.sha256(input, sha256_op_clk); - - std::vector ff_result; - for (uint32_t i = 0; i < 32; i++) { - ff_result.emplace_back(result[i]); - } - // Write the result to memory after - write_slice_to_memory(resolved_output_offset, AvmMemoryTag::U8, ff_result); -} - /** * @brief Pedersen Hash with direct or indirect memory access. * @param indirect byte encoding information about indirect/direct memory access. @@ -3369,7 +3314,7 @@ void AvmTraceBuilder::op_to_radix_le(uint8_t indirect, * @brief SHA256 Compression with direct or indirect memory access. * * @param indirect byte encoding information about indirect/direct memory access. - * @param h_init_offset An index in memory pointing to the first U32 value of the state array to be used in the next + * @param state_offset An index in memory pointing to the first U32 value of the state array to be used in the next * instance of sha256 compression. * @param input_offset An index in memory pointing to the first U32 value of the input array to be used in the next * instance of sha256 compression. @@ -3378,21 +3323,28 @@ void AvmTraceBuilder::op_to_radix_le(uint8_t indirect, */ void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, uint32_t output_offset, - uint32_t h_init_offset, - uint32_t input_offset) + uint32_t state_offset, + uint32_t state_size_offset, + uint32_t inputs_offset, + uint32_t inputs_size_offset) { // The clk plays a crucial role in this function as we attempt to write across multiple lines in the main trace. auto clk = static_cast(main_trace.size()) + 1; // Resolve the indirect flags, the results of this function are used to determine the memory offsets // that point to the starting memory addresses for the input and output values. - auto [resolved_h_init_offset, resolved_input_offset, resolved_output_offset] = - unpack_indirects<3>(indirect, { h_init_offset, input_offset, output_offset }); + auto [resolved_output_offset, + resolved_state_offset, + resolved_state_size_offset, + resolved_inputs_offset, + resolved_inputs_size_offset] = + unpack_indirects<5>(indirect, + { output_offset, state_offset, state_size_offset, inputs_offset, inputs_size_offset }); auto read_a = constrained_read_from_memory( - call_ptr, clk, resolved_h_init_offset, AvmMemoryTag::U32, AvmMemoryTag::U0, IntermRegister::IA); + call_ptr, clk, resolved_state_offset, AvmMemoryTag::U32, AvmMemoryTag::U0, IntermRegister::IA); auto read_b = constrained_read_from_memory( - call_ptr, clk, resolved_input_offset, AvmMemoryTag::U32, AvmMemoryTag::U0, IntermRegister::IB); + call_ptr, clk, resolved_inputs_offset, AvmMemoryTag::U32, AvmMemoryTag::U0, IntermRegister::IB); bool tag_match = read_a.tag_match && read_b.tag_match; // Constrain gas cost @@ -3434,9 +3386,9 @@ void AvmTraceBuilder::op_sha256_compression(uint8_t indirect, // Input for hash is expanded to 512 bits std::vector input_vec; // Read results are written to h_init array. - read_slice_from_memory(resolved_h_init_offset, 8, h_init_vec); + read_slice_from_memory(resolved_state_offset, 8, h_init_vec); // Read results are written to input array - read_slice_from_memory(resolved_input_offset, 16, input_vec); + read_slice_from_memory(resolved_inputs_offset, 16, input_vec); // Now that we have read all the values, we can perform the operation to get the resulting witness. // Note: We use the sha_op_clk to ensure that the sha256 operation is performed at the same clock cycle as the diff --git a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp index bd8f84bbcb7..6390d6a1aba 100644 --- a/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp +++ b/barretenberg/cpp/src/barretenberg/vm/avm/trace/trace.hpp @@ -162,7 +162,6 @@ class AvmTraceBuilder { // 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_sha256(uint8_t indirect, uint32_t output_offset, uint32_t input_offset, uint32_t input_size_offset); void op_pedersen_hash(uint8_t indirect, uint32_t gen_ctx_offset, uint32_t output_offset, @@ -195,7 +194,12 @@ class AvmTraceBuilder { uint8_t output_bits); // Future Gadgets -- pending changes in noir - void op_sha256_compression(uint8_t indirect, uint32_t output_offset, uint32_t h_init_offset, uint32_t input_offset); + void op_sha256_compression(uint8_t indirect, + uint32_t output_offset, + uint32_t state_offset, + uint32_t state_size_offset, + uint32_t inputs_offset, + uint32_t inputs_size_offset); void op_keccakf1600(uint8_t indirect, uint32_t output_offset, uint32_t input_offset, uint32_t input_size_offset); std::vector finalize(); diff --git a/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr b/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr index 312805f1802..3ee2ebfd294 100644 --- a/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/ecdsa_k_account_contract/src/main.nr @@ -70,3 +70,4 @@ contract EcdsaKAccount { std::ecdsa_secp256k1::verify_signature(public_key.x, public_key.y, signature, hashed_message) } } + diff --git a/noir/noir-repo/.github/scripts/playwright-install.sh b/noir/noir-repo/.github/scripts/playwright-install.sh index 4072e996264..7e65021166c 100755 --- a/noir/noir-repo/.github/scripts/playwright-install.sh +++ b/noir/noir-repo/.github/scripts/playwright-install.sh @@ -1,4 +1,4 @@ #!/bin/bash set -eu -npx playwright install && npx playwright install-deps +npx -y playwright@1.42 install --with-deps diff --git a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp index 875f076a911..70ad596a93a 100644 --- a/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp +++ b/noir/noir-repo/acvm-repo/acir/codegen/acir.cpp @@ -256,15 +256,6 @@ namespace Program { static AES128Encrypt bincodeDeserialize(std::vector); }; - struct Sha256 { - Program::HeapVector message; - Program::HeapArray output; - - friend bool operator==(const Sha256&, const Sha256&); - std::vector bincodeSerialize() const; - static Sha256 bincodeDeserialize(std::vector); - }; - struct Blake2s { Program::HeapVector message; Program::HeapArray output; @@ -471,7 +462,7 @@ namespace Program { static ToRadix bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; friend bool operator==(const BlackBoxOp&, const BlackBoxOp&); std::vector bincodeSerialize() const; @@ -827,15 +818,6 @@ namespace Program { static RANGE bincodeDeserialize(std::vector); }; - struct SHA256 { - std::vector inputs; - std::array outputs; - - friend bool operator==(const SHA256&, const SHA256&); - std::vector bincodeSerialize() const; - static SHA256 bincodeDeserialize(std::vector); - }; - struct Blake2s { std::vector inputs; std::array outputs; @@ -1040,7 +1022,7 @@ namespace Program { static Sha256Compression bincodeDeserialize(std::vector); }; - std::variant value; + std::variant value; friend bool operator==(const BlackBoxFuncCall&, const BlackBoxFuncCall&); std::vector bincodeSerialize() const; @@ -2630,47 +2612,6 @@ Program::BlackBoxFuncCall::RANGE serde::Deserializable BlackBoxFuncCall::SHA256::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline BlackBoxFuncCall::SHA256 BlackBoxFuncCall::SHA256::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::BlackBoxFuncCall::SHA256 &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.inputs, serializer); - serde::Serializable::serialize(obj.outputs, serializer); -} - -template <> -template -Program::BlackBoxFuncCall::SHA256 serde::Deserializable::deserialize(Deserializer &deserializer) { - Program::BlackBoxFuncCall::SHA256 obj; - obj.inputs = serde::Deserializable::deserialize(deserializer); - obj.outputs = serde::Deserializable::deserialize(deserializer); - return obj; -} - namespace Program { inline bool operator==(const BlackBoxFuncCall::Blake2s &lhs, const BlackBoxFuncCall::Blake2s &rhs) { @@ -3652,47 +3593,6 @@ Program::BlackBoxOp::AES128Encrypt serde::Deserializable BlackBoxOp::Sha256::bincodeSerialize() const { - auto serializer = serde::BincodeSerializer(); - serde::Serializable::serialize(*this, serializer); - return std::move(serializer).bytes(); - } - - inline BlackBoxOp::Sha256 BlackBoxOp::Sha256::bincodeDeserialize(std::vector input) { - auto deserializer = serde::BincodeDeserializer(input); - auto value = serde::Deserializable::deserialize(deserializer); - if (deserializer.get_buffer_offset() < input.size()) { - throw serde::deserialization_error("Some input bytes were not read"); - } - return value; - } - -} // end of namespace Program - -template <> -template -void serde::Serializable::serialize(const Program::BlackBoxOp::Sha256 &obj, Serializer &serializer) { - serde::Serializable::serialize(obj.message, serializer); - serde::Serializable::serialize(obj.output, serializer); -} - -template <> -template -Program::BlackBoxOp::Sha256 serde::Deserializable::deserialize(Deserializer &deserializer) { - Program::BlackBoxOp::Sha256 obj; - obj.message = serde::Deserializable::deserialize(deserializer); - obj.output = serde::Deserializable::deserialize(deserializer); - return obj; -} - namespace Program { inline bool operator==(const BlackBoxOp::Blake2s &lhs, const BlackBoxOp::Blake2s &rhs) { diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/black_box_functions.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/black_box_functions.rs index fb7d9eb584c..02978fc2298 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/black_box_functions.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/black_box_functions.rs @@ -40,12 +40,6 @@ pub enum BlackBoxFunc { /// - input: (witness, bit_size) RANGE, - /// Computes SHA256 of the inputs - /// - inputs are a byte array, i.e a vector of (witness, 8) - /// - output is a byte array of len 32, i.e an array of 32 (witness, 8), - /// constrained to be the sha256 of the inputs. - SHA256, - /// Computes the Blake2s hash of the inputs, as specified in /// https://tools.ietf.org/html/rfc7693 /// - inputs are a byte array, i.e a vector of (witness, 8) @@ -205,7 +199,6 @@ impl BlackBoxFunc { pub fn name(&self) -> &'static str { match self { BlackBoxFunc::AES128Encrypt => "aes128_encrypt", - BlackBoxFunc::SHA256 => "sha256", BlackBoxFunc::SchnorrVerify => "schnorr_verify", BlackBoxFunc::Blake2s => "blake2s", BlackBoxFunc::Blake3 => "blake3", @@ -235,7 +228,6 @@ impl BlackBoxFunc { pub fn lookup(op_name: &str) -> Option { match op_name { "aes128_encrypt" => Some(BlackBoxFunc::AES128Encrypt), - "sha256" => Some(BlackBoxFunc::SHA256), "schnorr_verify" => Some(BlackBoxFunc::SchnorrVerify), "blake2s" => Some(BlackBoxFunc::Blake2s), "blake3" => Some(BlackBoxFunc::Blake3), diff --git a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index f527522cceb..fbe179d7c04 100644 --- a/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/noir/noir-repo/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -94,10 +94,6 @@ pub enum BlackBoxFuncCall { RANGE { input: FunctionInput, }, - SHA256 { - inputs: Vec>, - outputs: Box<[Witness; 32]>, - }, Blake2s { inputs: Vec>, outputs: Box<[Witness; 32]>, @@ -251,7 +247,6 @@ impl BlackBoxFuncCall { BlackBoxFuncCall::AND { .. } => BlackBoxFunc::AND, BlackBoxFuncCall::XOR { .. } => BlackBoxFunc::XOR, BlackBoxFuncCall::RANGE { .. } => BlackBoxFunc::RANGE, - BlackBoxFuncCall::SHA256 { .. } => BlackBoxFunc::SHA256, BlackBoxFuncCall::Blake2s { .. } => BlackBoxFunc::Blake2s, BlackBoxFuncCall::Blake3 { .. } => BlackBoxFunc::Blake3, BlackBoxFuncCall::SchnorrVerify { .. } => BlackBoxFunc::SchnorrVerify, @@ -282,7 +277,6 @@ impl BlackBoxFuncCall { pub fn get_inputs_vec(&self) -> Vec> { match self { BlackBoxFuncCall::AES128Encrypt { inputs, .. } - | BlackBoxFuncCall::SHA256 { inputs, .. } | BlackBoxFuncCall::Blake2s { inputs, .. } | BlackBoxFuncCall::Blake3 { inputs, .. } | BlackBoxFuncCall::BigIntFromLeBytes { inputs, .. } @@ -391,8 +385,7 @@ impl BlackBoxFuncCall { pub fn get_outputs_vec(&self) -> Vec { match self { - BlackBoxFuncCall::SHA256 { outputs, .. } - | BlackBoxFuncCall::Blake2s { outputs, .. } + BlackBoxFuncCall::Blake2s { outputs, .. } | BlackBoxFuncCall::Blake3 { outputs, .. } | BlackBoxFuncCall::Keccak256 { outputs, .. } => outputs.to_vec(), diff --git a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs index 2b6ea83fafa..6bf5afe52d9 100644 --- a/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs +++ b/noir/noir-repo/acvm-repo/acir/tests/test_program_serialization.rs @@ -91,10 +91,10 @@ fn multi_scalar_mul_circuit() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 11, 10, 0, 32, 8, 67, 43, 181, 15, 116, 255, - 227, 70, 74, 11, 86, 194, 195, 169, 83, 115, 58, 49, 156, 12, 29, 121, 58, 66, 117, 176, - 144, 11, 105, 161, 222, 245, 42, 205, 13, 186, 58, 205, 233, 240, 25, 249, 11, 238, 40, - 245, 19, 253, 255, 119, 159, 216, 103, 157, 249, 169, 193, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 11, 10, 0, 32, 8, 67, 43, 181, 15, 221, 255, + 186, 145, 210, 130, 149, 240, 112, 234, 212, 156, 78, 12, 39, 67, 71, 158, 142, 80, 29, 44, + 228, 66, 90, 168, 119, 189, 74, 115, 131, 174, 78, 115, 58, 124, 70, 254, 130, 59, 74, 253, + 68, 255, 255, 221, 39, 54, 29, 134, 27, 102, 193, 0, 0, 0, ]; assert_eq!(bytes, expected_serialization) @@ -134,24 +134,24 @@ fn schnorr_verify_circuit() { let bytes = Program::serialize_program(&program); let expected_serialization: Vec = vec![ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 85, 211, 103, 78, 2, 81, 24, 70, 225, 193, 6, 216, 123, - 47, 216, 123, 239, 136, 136, 136, 136, 136, 187, 96, 255, 75, 32, 112, 194, 55, 201, 129, - 100, 50, 79, 244, 7, 228, 222, 243, 102, 146, 254, 167, 221, 123, 50, 97, 222, 217, 120, - 243, 116, 226, 61, 36, 15, 247, 158, 92, 120, 68, 30, 149, 199, 228, 172, 156, 147, 243, - 242, 184, 60, 33, 79, 202, 83, 242, 180, 60, 35, 207, 202, 115, 242, 188, 188, 32, 47, 202, - 75, 242, 178, 188, 34, 175, 202, 107, 242, 186, 188, 33, 111, 202, 91, 242, 182, 188, 35, - 23, 228, 93, 121, 79, 222, 151, 15, 228, 67, 249, 72, 62, 150, 79, 228, 83, 249, 76, 62, - 151, 47, 228, 75, 249, 74, 190, 150, 111, 228, 91, 249, 78, 190, 151, 31, 228, 71, 249, 73, - 126, 150, 95, 228, 87, 185, 40, 191, 201, 37, 249, 93, 46, 203, 31, 114, 69, 254, 148, 171, - 97, 58, 77, 226, 111, 95, 250, 127, 77, 254, 150, 235, 242, 143, 220, 144, 127, 229, 166, - 252, 39, 183, 194, 255, 241, 253, 45, 253, 14, 182, 201, 38, 217, 34, 27, 100, 123, 233, - 230, 242, 241, 155, 217, 20, 91, 98, 67, 108, 135, 205, 176, 21, 54, 194, 54, 216, 4, 91, - 96, 3, 180, 79, 243, 180, 78, 227, 180, 77, 211, 180, 76, 195, 180, 75, 179, 133, 164, 223, - 40, 109, 210, 36, 45, 210, 32, 237, 209, 28, 173, 209, 24, 109, 209, 20, 45, 209, 16, 237, - 208, 12, 173, 208, 8, 109, 208, 4, 45, 208, 0, 119, 207, 157, 115, 215, 220, 113, 49, 238, - 180, 20, 119, 88, 142, 59, 171, 196, 29, 85, 227, 46, 106, 113, 246, 245, 56, 235, 70, 156, - 109, 51, 206, 50, 61, 179, 244, 220, 18, 157, 231, 192, 167, 11, 75, 28, 99, 152, 25, 5, 0, - 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 85, 211, 103, 78, 2, 81, 24, 70, 225, 193, 130, 96, 239, + 189, 96, 239, 189, 35, 34, 34, 34, 34, 238, 130, 253, 47, 129, 192, 9, 223, 36, 7, 146, + 201, 60, 209, 31, 144, 123, 207, 155, 73, 250, 159, 118, 239, 201, 132, 121, 103, 227, 205, + 211, 137, 247, 144, 60, 220, 123, 114, 225, 17, 121, 84, 206, 202, 99, 114, 78, 206, 203, + 227, 242, 132, 60, 41, 79, 201, 211, 242, 140, 60, 43, 207, 201, 243, 242, 130, 188, 40, + 47, 201, 203, 242, 138, 188, 42, 175, 201, 235, 242, 134, 188, 41, 111, 201, 219, 242, 142, + 92, 144, 119, 229, 61, 121, 95, 62, 144, 15, 229, 35, 249, 88, 62, 145, 79, 229, 51, 249, + 92, 190, 144, 47, 229, 43, 249, 90, 190, 145, 111, 229, 59, 249, 94, 126, 144, 31, 229, 39, + 249, 89, 126, 145, 95, 229, 162, 252, 38, 151, 228, 119, 185, 44, 127, 200, 21, 249, 83, + 174, 134, 233, 52, 137, 191, 125, 233, 255, 53, 249, 91, 174, 203, 63, 114, 67, 254, 149, + 155, 242, 159, 220, 10, 255, 199, 247, 183, 244, 59, 216, 38, 155, 100, 139, 108, 144, 237, + 165, 155, 203, 199, 111, 102, 83, 108, 137, 13, 177, 29, 54, 195, 86, 216, 8, 219, 96, 19, + 108, 129, 13, 208, 62, 205, 211, 58, 141, 211, 54, 77, 211, 50, 13, 211, 46, 205, 22, 146, + 126, 163, 180, 73, 147, 180, 72, 131, 180, 71, 115, 180, 70, 99, 180, 69, 83, 180, 68, 67, + 180, 67, 51, 180, 66, 35, 180, 65, 19, 180, 64, 3, 220, 61, 119, 206, 93, 115, 199, 197, + 184, 211, 82, 220, 97, 57, 238, 172, 18, 119, 84, 141, 187, 168, 197, 217, 215, 227, 172, + 27, 113, 182, 205, 56, 203, 244, 204, 210, 115, 75, 116, 158, 3, 159, 46, 43, 32, 188, 53, + 25, 5, 0, 0, ]; assert_eq!(bytes, expected_serialization) diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/hash.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/hash.rs index 234ab6162ca..f177cd071d0 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/hash.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/hash.rs @@ -3,7 +3,7 @@ use acir::{ native_types::{Witness, WitnessMap}, AcirField, }; -use acvm_blackbox_solver::{sha256compression, BlackBoxFunctionSolver, BlackBoxResolutionError}; +use acvm_blackbox_solver::{sha256_compression, BlackBoxFunctionSolver, BlackBoxResolutionError}; use crate::pwg::{input_to_value, insert_value}; use crate::OpcodeResolutionError; @@ -94,7 +94,7 @@ pub(crate) fn solve_sha_256_permutation_opcode( let message = to_u32_array(initial_witness, inputs)?; let mut state = to_u32_array(initial_witness, hash_values)?; - sha256compression(&mut state, &message); + sha256_compression(&mut state, &message); for (output_witness, value) in outputs.iter().zip(state.into_iter()) { insert_value(output_witness, F::from(value as u128), initial_witness)?; diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs index 8b8bfc5cfc5..1cca14cc680 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -3,7 +3,7 @@ use acir::{ native_types::{Witness, WitnessMap}, AcirField, }; -use acvm_blackbox_solver::{blake2s, blake3, keccak256, keccakf1600, sha256}; +use acvm_blackbox_solver::{blake2s, blake3, keccak256, keccakf1600}; use self::{ aes128::solve_aes128_encryption_opcode, bigint::AcvmBigIntSolver, @@ -84,9 +84,6 @@ pub(crate) fn solve( BlackBoxFuncCall::AND { lhs, rhs, output } => and(initial_witness, lhs, rhs, output), BlackBoxFuncCall::XOR { lhs, rhs, output } => xor(initial_witness, lhs, rhs, output), BlackBoxFuncCall::RANGE { input } => solve_range_opcode(initial_witness, input), - BlackBoxFuncCall::SHA256 { inputs, outputs } => { - solve_generic_256_hash_opcode(initial_witness, inputs, None, outputs, sha256) - } BlackBoxFuncCall::Blake2s { inputs, outputs } => { solve_generic_256_hash_opcode(initial_witness, inputs, None, outputs, blake2s) } diff --git a/noir/noir-repo/acvm-repo/acvm/tests/solver.rs b/noir/noir-repo/acvm-repo/acvm/tests/solver.rs index 766d374c43c..6ad52999820 100644 --- a/noir/noir-repo/acvm-repo/acvm/tests/solver.rs +++ b/noir/noir-repo/acvm-repo/acvm/tests/solver.rs @@ -1075,18 +1075,6 @@ fn solve_blackbox_func_call( Ok(witness_map[&Witness(3)]) } -// N inputs -// 32 outputs -fn sha256_op( - function_inputs_and_outputs: (Vec>, Vec), -) -> Result, OpcodeResolutionError> { - let (function_inputs, outputs) = function_inputs_and_outputs; - Ok(BlackBoxFuncCall::SHA256 { - inputs: function_inputs, - outputs: outputs.try_into().expect("SHA256 returns 32 outputs"), - }) -} - // N inputs // 32 outputs fn blake2s_op( @@ -1457,19 +1445,6 @@ fn poseidon2_permutation_zeroes() { assert_eq!(results, expected_results); } -#[test] -fn sha256_zeros() { - let results = solve_array_input_blackbox_call(vec![], 32, None, sha256_op); - let expected_results: Vec<_> = vec![ - 227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65, - 228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85, - ] - .into_iter() - .map(|x: u128| FieldElement::from(x)) - .collect(); - assert_eq!(results, Ok(expected_results)); -} - #[test] fn sha256_compression_zeros() { let results = solve_array_input_blackbox_call( @@ -1643,12 +1618,6 @@ proptest! { prop_assert_eq!(result, expected_result) } - #[test] - fn sha256_injective(inputs_distinct_inputs in any_distinct_inputs(None, 0, 32)) { - let (inputs, distinct_inputs) = inputs_distinct_inputs; - let (result, message) = prop_assert_injective(inputs, distinct_inputs, 32, None, sha256_op); - prop_assert!(result, "{}", message); - } #[test] fn sha256_compression_injective(inputs_distinct_inputs in any_distinct_inputs(None, 24, 24)) { diff --git a/noir/noir-repo/acvm-repo/acvm_js/package.json b/noir/noir-repo/acvm-repo/acvm_js/package.json index 54261a78dbc..95b8a46456f 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/package.json +++ b/noir/noir-repo/acvm-repo/acvm_js/package.json @@ -40,7 +40,7 @@ "@esm-bundle/chai": "^4.3.4-fix.0", "@web/dev-server-esbuild": "^0.3.6", "@web/test-runner": "^0.18.1", - "@web/test-runner-playwright": "^0.10.0", + "@web/test-runner-playwright": "^0.11.0", "chai": "^4.4.1", "eslint": "^8.57.0", "eslint-plugin-prettier": "^5.1.3", diff --git a/noir/noir-repo/acvm-repo/acvm_js/src/black_box_solvers.rs b/noir/noir-repo/acvm-repo/acvm_js/src/black_box_solvers.rs index 4cd85a5ed87..6046d52943c 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/src/black_box_solvers.rs +++ b/noir/noir-repo/acvm-repo/acvm_js/src/black_box_solvers.rs @@ -22,10 +22,13 @@ pub fn xor(lhs: JsString, rhs: JsString) -> JsString { field_element_to_js_string(&result) } -/// Calculates the SHA256 hash of the input bytes +/// Sha256 compression function #[wasm_bindgen] -pub fn sha256(inputs: &[u8]) -> Vec { - acvm::blackbox_solver::sha256(inputs).unwrap().into() +pub fn sha256_compression(inputs: &[u32], state: &[u32]) -> Vec { + let mut state: [u32; 8] = state.try_into().unwrap(); + let inputs: [u32; 16] = inputs.try_into().unwrap(); + acvm::blackbox_solver::sha256_compression(&mut state, &inputs); + state.to_vec() } /// Calculates the Blake2s256 hash of the input bytes diff --git a/noir/noir-repo/acvm-repo/acvm_js/src/lib.rs b/noir/noir-repo/acvm-repo/acvm_js/src/lib.rs index fdb8d5ffe08..8fe64afbba9 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/src/lib.rs +++ b/noir/noir-repo/acvm-repo/acvm_js/src/lib.rs @@ -17,7 +17,8 @@ mod logging; mod public_witness; pub use black_box_solvers::{ - and, blake2s256, ecdsa_secp256k1_verify, ecdsa_secp256r1_verify, keccak256, sha256, xor, + and, blake2s256, ecdsa_secp256k1_verify, ecdsa_secp256r1_verify, keccak256, sha256_compression, + xor, }; pub use build_info::build_info; pub use compression::{ diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/browser/black_box_solvers.test.ts b/noir/noir-repo/acvm-repo/acvm_js/test/browser/black_box_solvers.test.ts index 695f6b89afc..9dc5be2c682 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/browser/black_box_solvers.test.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/browser/black_box_solvers.test.ts @@ -5,7 +5,7 @@ import initACVM, { ecdsa_secp256k1_verify, ecdsa_secp256r1_verify, keccak256, - sha256, + sha256_compression, xor, } from '@noir-lang/acvm_js'; @@ -32,11 +32,11 @@ it('successfully calculates the bitwise XOR of two fields', async () => { }); it('successfully calculates the sha256 hash', async () => { - const { sha256_test_cases } = await import('../shared/black_box_solvers'); + const { sha256_compression_test_cases } = await import('../shared/black_box_solvers'); - for (const testCase of sha256_test_cases) { - const [preimage, expectedResult] = testCase; - const hash = sha256(preimage); + for (const testCase of sha256_compression_test_cases) { + const [message, state, expectedResult] = testCase; + const hash = sha256_compression(message, state); hash.forEach((value, index) => expect(value).to.be.eq(expectedResult.at(index))); } }); diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/node/black_box_solvers.test.ts b/noir/noir-repo/acvm-repo/acvm_js/test/node/black_box_solvers.test.ts index cedadba2c1a..fc998ced5a5 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/node/black_box_solvers.test.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/node/black_box_solvers.test.ts @@ -5,7 +5,7 @@ import { ecdsa_secp256k1_verify, ecdsa_secp256r1_verify, keccak256, - sha256, + sha256_compression, xor, } from '@noir-lang/acvm_js'; @@ -28,11 +28,11 @@ it('successfully calculates the bitwise XOR of two fields', async () => { }); it('successfully calculates the sha256 hash', async () => { - const { sha256_test_cases } = await import('../shared/black_box_solvers'); + const { sha256_compression_test_cases } = await import('../shared/black_box_solvers'); - for (const testCase of sha256_test_cases) { - const [preimage, expectedResult] = testCase; - const hash = sha256(preimage); + for (const testCase of sha256_compression_test_cases) { + const [message, state, expectedResult] = testCase; + const hash = sha256_compression(message, state); hash.forEach((value, index) => expect(value).to.be.eq(expectedResult.at(index))); } }); diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/black_box_solvers.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/black_box_solvers.ts index 0ab3fc12b72..22783a028ea 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/black_box_solvers.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/black_box_solvers.ts @@ -32,15 +32,11 @@ export const xor_test_cases: [[string, string], string][] = [ ], ]; -// https://www.di-mgt.com.au/sha_testvectors.html -export const sha256_test_cases: [Uint8Array, Uint8Array][] = [ +export const sha256_compression_test_cases: [Uint32Array, Uint32Array, Uint32Array][] = [ [ - // "abc" - Uint8Array.from([0x61, 0x62, 0x63]), - Uint8Array.from([ - 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, - 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad, - ]), + Uint32Array.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]), + Uint32Array.from([1, 2, 3, 4, 5, 6, 7, 8]), + Uint32Array.from([1862536192, 526086805, 2067405084, 593147560, 726610467, 813867028, 4091010797, 3974542186]), ], ]; diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/multi_scalar_mul.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/multi_scalar_mul.ts index ffb9952b136..f23847a75fc 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/multi_scalar_mul.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/multi_scalar_mul.ts @@ -1,8 +1,8 @@ // See `multi_scalar_mul_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 11, 10, 0, 32, 8, 67, 43, 181, 15, 116, 255, 227, 70, 74, 11, 86, 194, - 195, 169, 83, 115, 58, 49, 156, 12, 29, 121, 58, 66, 117, 176, 144, 11, 105, 161, 222, 245, 42, 205, 13, 186, 58, 205, - 233, 240, 25, 249, 11, 238, 40, 245, 19, 253, 255, 119, 159, 216, 103, 157, 249, 169, 193, 0, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 93, 141, 11, 10, 0, 32, 8, 67, 43, 181, 15, 221, 255, 186, 145, 210, 130, 149, 240, + 112, 234, 212, 156, 78, 12, 39, 67, 71, 158, 142, 80, 29, 44, 228, 66, 90, 168, 119, 189, 74, 115, 131, 174, 78, 115, + 58, 124, 70, 254, 130, 59, 74, 253, 68, 255, 255, 221, 39, 54, 29, 134, 27, 102, 193, 0, 0, 0, ]); export const initialWitnessMap = new Map([ [1, '0x0000000000000000000000000000000000000000000000000000000000000001'], diff --git a/noir/noir-repo/acvm-repo/acvm_js/test/shared/schnorr_verify.ts b/noir/noir-repo/acvm-repo/acvm_js/test/shared/schnorr_verify.ts index c071c86f61f..830ca1026d6 100644 --- a/noir/noir-repo/acvm-repo/acvm_js/test/shared/schnorr_verify.ts +++ b/noir/noir-repo/acvm-repo/acvm_js/test/shared/schnorr_verify.ts @@ -1,19 +1,19 @@ // See `schnorr_verify_circuit` integration test in `acir/tests/test_program_serialization.rs`. export const bytecode = Uint8Array.from([ - 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 85, 211, 103, 78, 2, 81, 24, 70, 225, 193, 6, 216, 123, 47, 216, 123, 239, 136, - 136, 136, 136, 136, 187, 96, 255, 75, 32, 112, 194, 55, 201, 129, 100, 50, 79, 244, 7, 228, 222, 243, 102, 146, 254, - 167, 221, 123, 50, 97, 222, 217, 120, 243, 116, 226, 61, 36, 15, 247, 158, 92, 120, 68, 30, 149, 199, 228, 172, 156, - 147, 243, 242, 184, 60, 33, 79, 202, 83, 242, 180, 60, 35, 207, 202, 115, 242, 188, 188, 32, 47, 202, 75, 242, 178, - 188, 34, 175, 202, 107, 242, 186, 188, 33, 111, 202, 91, 242, 182, 188, 35, 23, 228, 93, 121, 79, 222, 151, 15, 228, - 67, 249, 72, 62, 150, 79, 228, 83, 249, 76, 62, 151, 47, 228, 75, 249, 74, 190, 150, 111, 228, 91, 249, 78, 190, 151, - 31, 228, 71, 249, 73, 126, 150, 95, 228, 87, 185, 40, 191, 201, 37, 249, 93, 46, 203, 31, 114, 69, 254, 148, 171, 97, - 58, 77, 226, 111, 95, 250, 127, 77, 254, 150, 235, 242, 143, 220, 144, 127, 229, 166, 252, 39, 183, 194, 255, 241, - 253, 45, 253, 14, 182, 201, 38, 217, 34, 27, 100, 123, 233, 230, 242, 241, 155, 217, 20, 91, 98, 67, 108, 135, 205, - 176, 21, 54, 194, 54, 216, 4, 91, 96, 3, 180, 79, 243, 180, 78, 227, 180, 77, 211, 180, 76, 195, 180, 75, 179, 133, - 164, 223, 40, 109, 210, 36, 45, 210, 32, 237, 209, 28, 173, 209, 24, 109, 209, 20, 45, 209, 16, 237, 208, 12, 173, - 208, 8, 109, 208, 4, 45, 208, 0, 119, 207, 157, 115, 215, 220, 113, 49, 238, 180, 20, 119, 88, 142, 59, 171, 196, 29, - 85, 227, 46, 106, 113, 246, 245, 56, 235, 70, 156, 109, 51, 206, 50, 61, 179, 244, 220, 18, 157, 231, 192, 167, 11, - 75, 28, 99, 152, 25, 5, 0, 0, + 31, 139, 8, 0, 0, 0, 0, 0, 0, 255, 85, 211, 103, 78, 2, 81, 24, 70, 225, 193, 130, 96, 239, 189, 96, 239, 189, 35, 34, + 34, 34, 34, 238, 130, 253, 47, 129, 192, 9, 223, 36, 7, 146, 201, 60, 209, 31, 144, 123, 207, 155, 73, 250, 159, 118, + 239, 201, 132, 121, 103, 227, 205, 211, 137, 247, 144, 60, 220, 123, 114, 225, 17, 121, 84, 206, 202, 99, 114, 78, + 206, 203, 227, 242, 132, 60, 41, 79, 201, 211, 242, 140, 60, 43, 207, 201, 243, 242, 130, 188, 40, 47, 201, 203, 242, + 138, 188, 42, 175, 201, 235, 242, 134, 188, 41, 111, 201, 219, 242, 142, 92, 144, 119, 229, 61, 121, 95, 62, 144, 15, + 229, 35, 249, 88, 62, 145, 79, 229, 51, 249, 92, 190, 144, 47, 229, 43, 249, 90, 190, 145, 111, 229, 59, 249, 94, 126, + 144, 31, 229, 39, 249, 89, 126, 145, 95, 229, 162, 252, 38, 151, 228, 119, 185, 44, 127, 200, 21, 249, 83, 174, 134, + 233, 52, 137, 191, 125, 233, 255, 53, 249, 91, 174, 203, 63, 114, 67, 254, 149, 155, 242, 159, 220, 10, 255, 199, 247, + 183, 244, 59, 216, 38, 155, 100, 139, 108, 144, 237, 165, 155, 203, 199, 111, 102, 83, 108, 137, 13, 177, 29, 54, 195, + 86, 216, 8, 219, 96, 19, 108, 129, 13, 208, 62, 205, 211, 58, 141, 211, 54, 77, 211, 50, 13, 211, 46, 205, 22, 146, + 126, 163, 180, 73, 147, 180, 72, 131, 180, 71, 115, 180, 70, 99, 180, 69, 83, 180, 68, 67, 180, 67, 51, 180, 66, 35, + 180, 65, 19, 180, 64, 3, 220, 61, 119, 206, 93, 115, 199, 197, 184, 211, 82, 220, 97, 57, 238, 172, 18, 119, 84, 141, + 187, 168, 197, 217, 215, 227, 172, 27, 113, 182, 205, 56, 203, 244, 204, 210, 115, 75, 116, 158, 3, 159, 46, 43, 32, + 188, 53, 25, 5, 0, 0, ]); export const initialWitnessMap = new Map([ diff --git a/noir/noir-repo/acvm-repo/blackbox_solver/src/hash.rs b/noir/noir-repo/acvm-repo/blackbox_solver/src/hash.rs index ac56029b436..af503117466 100644 --- a/noir/noir-repo/acvm-repo/blackbox_solver/src/hash.rs +++ b/noir/noir-repo/acvm-repo/blackbox_solver/src/hash.rs @@ -1,7 +1,6 @@ use acir::BlackBoxFunc; use blake2::digest::generic_array::GenericArray; use blake2::{Blake2s256, Digest}; -use sha2::Sha256; use sha3::Keccak256; use crate::BlackBoxResolutionError; @@ -14,11 +13,6 @@ fn generic_hash_256(message: &[u8]) -> Result<[u8; 32], String> { Ok(output_bytes) } -pub fn sha256(inputs: &[u8]) -> Result<[u8; 32], BlackBoxResolutionError> { - generic_hash_256::(inputs) - .map_err(|err| BlackBoxResolutionError::Failed(BlackBoxFunc::SHA256, err)) -} - pub fn blake2s(inputs: &[u8]) -> Result<[u8; 32], BlackBoxResolutionError> { generic_hash_256::(inputs) .map_err(|err| BlackBoxResolutionError::Failed(BlackBoxFunc::Blake2s, err)) @@ -33,7 +27,7 @@ pub fn keccak256(inputs: &[u8]) -> Result<[u8; 32], BlackBoxResolutionError> { .map_err(|err| BlackBoxResolutionError::Failed(BlackBoxFunc::Keccak256, err)) } -pub fn sha256compression(state: &mut [u32; 8], msg_blocks: &[u32; 16]) { +pub fn sha256_compression(state: &mut [u32; 8], msg_blocks: &[u32; 16]) { let mut blocks = [0_u8; 64]; for (i, block) in msg_blocks.iter().enumerate() { let bytes = block.to_be_bytes(); diff --git a/noir/noir-repo/acvm-repo/blackbox_solver/src/lib.rs b/noir/noir-repo/acvm-repo/blackbox_solver/src/lib.rs index c39deb64138..87ca539f435 100644 --- a/noir/noir-repo/acvm-repo/blackbox_solver/src/lib.rs +++ b/noir/noir-repo/acvm-repo/blackbox_solver/src/lib.rs @@ -21,7 +21,7 @@ pub use aes128::aes128_encrypt; pub use bigint::BigIntSolver; pub use curve_specific_solver::{BlackBoxFunctionSolver, StubbedBlackBoxSolver}; pub use ecdsa::{ecdsa_secp256k1_verify, ecdsa_secp256r1_verify}; -pub use hash::{blake2s, blake3, keccak256, keccakf1600, sha256, sha256compression}; +pub use hash::{blake2s, blake3, keccak256, keccakf1600, sha256_compression}; pub use logic::{bit_and, bit_xor}; #[derive(Clone, PartialEq, Eq, Debug, Error)] 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 7dccfbf677f..534ef7d318e 100644 --- a/noir/noir-repo/acvm-repo/brillig/src/black_box.rs +++ b/noir/noir-repo/acvm-repo/brillig/src/black_box.rs @@ -12,11 +12,6 @@ pub enum BlackBoxOp { key: HeapArray, outputs: HeapVector, }, - /// Calculates the SHA256 hash of the inputs. - Sha256 { - message: HeapVector, - output: HeapArray, - }, /// Calculates the Blake2s hash of the inputs. Blake2s { message: HeapVector, 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 8d1bf3ec2ea..56f715c13a9 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 @@ -3,7 +3,7 @@ use acir::{AcirField, BlackBoxFunc}; use acvm_blackbox_solver::BigIntSolver; use acvm_blackbox_solver::{ aes128_encrypt, blake2s, blake3, ecdsa_secp256k1_verify, ecdsa_secp256r1_verify, keccak256, - keccakf1600, sha256, sha256compression, BlackBoxFunctionSolver, BlackBoxResolutionError, + keccakf1600, sha256_compression, BlackBoxFunctionSolver, BlackBoxResolutionError, }; use num_bigint::BigUint; use num_traits::Zero; @@ -65,12 +65,6 @@ pub(crate) fn evaluate_black_box Ok(()) } - BlackBoxOp::Sha256 { message, output } => { - let message = to_u8_vec(read_heap_vector(memory, message)); - let bytes = sha256(message.as_slice())?; - memory.write_slice(memory.read_ref(output.pointer), &to_value_vec(&bytes)); - Ok(()) - } BlackBoxOp::Blake2s { message, output } => { let message = to_u8_vec(read_heap_vector(memory, message)); let bytes = blake2s(message.as_slice())?; @@ -361,7 +355,7 @@ pub(crate) fn evaluate_black_box state[i] = value.try_into().unwrap(); } - sha256compression(&mut state, &message); + sha256_compression(&mut state, &message); let state = state.map(|x| x.into()); memory.write_slice(memory.read_ref(output.pointer), &state); @@ -451,7 +445,6 @@ impl BrilligBigintSolver { fn black_box_function_from_op(op: &BlackBoxOp) -> BlackBoxFunc { match op { BlackBoxOp::AES128Encrypt { .. } => BlackBoxFunc::AES128Encrypt, - BlackBoxOp::Sha256 { .. } => BlackBoxFunc::SHA256, BlackBoxOp::Blake2s { .. } => BlackBoxFunc::Blake2s, BlackBoxOp::Blake3 { .. } => BlackBoxFunc::Blake3, BlackBoxOp::Keccak256 { .. } => BlackBoxFunc::Keccak256, @@ -474,54 +467,3 @@ fn black_box_function_from_op(op: &BlackBoxOp) -> BlackBoxFunc { BlackBoxOp::PedersenHash { .. } => BlackBoxFunc::PedersenHash, } } - -#[cfg(test)] -mod test { - use acir::{ - brillig::{BlackBoxOp, MemoryAddress}, - FieldElement, - }; - use acvm_blackbox_solver::StubbedBlackBoxSolver; - - use crate::{ - black_box::{evaluate_black_box, to_u8_vec, to_value_vec, BrilligBigintSolver}, - HeapArray, HeapVector, Memory, - }; - - #[test] - fn sha256() { - let message: Vec = b"hello world".to_vec(); - let message_length = message.len(); - - let mut memory: Memory = Memory::default(); - let message_pointer = 3; - let result_pointer = message_pointer + message_length; - memory.write(MemoryAddress(0), message_pointer.into()); - memory.write(MemoryAddress(1), message_length.into()); - memory.write(MemoryAddress(2), result_pointer.into()); - memory.write_slice(MemoryAddress(message_pointer), to_value_vec(&message).as_slice()); - - let op = BlackBoxOp::Sha256 { - message: HeapVector { pointer: 0.into(), size: 1.into() }, - output: HeapArray { pointer: 2.into(), size: 32 }, - }; - - evaluate_black_box( - &op, - &StubbedBlackBoxSolver, - &mut memory, - &mut BrilligBigintSolver::default(), - ) - .unwrap(); - - let result = memory.read_slice(MemoryAddress(result_pointer), 32); - - assert_eq!( - to_u8_vec(result), - vec![ - 185, 77, 39, 185, 147, 77, 62, 8, 165, 46, 82, 215, 218, 125, 171, 250, 196, 132, - 239, 227, 122, 83, 128, 238, 144, 136, 247, 172, 226, 239, 205, 233 - ] - ); - } -} diff --git a/noir/noir-repo/compiler/integration-tests/package.json b/noir/noir-repo/compiler/integration-tests/package.json index a88e55b2321..64a638539d5 100644 --- a/noir/noir-repo/compiler/integration-tests/package.json +++ b/noir/noir-repo/compiler/integration-tests/package.json @@ -21,7 +21,7 @@ "@web/dev-server-esbuild": "^0.3.6", "@web/dev-server-import-maps": "^0.2.0", "@web/test-runner": "^0.18.1", - "@web/test-runner-playwright": "^0.10.0", + "@web/test-runner-playwright": "^0.11.0", "eslint": "^8.57.0", "eslint-plugin-prettier": "^5.1.3", "ethers": "^6.7.1", 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 2dde5d2ca49..889af07fbef 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 @@ -23,25 +23,6 @@ pub(crate) fn convert_black_box_call { - if let ([message], [BrilligVariable::BrilligArray(result_array)]) = - (function_arguments, function_results) - { - let message_vector = convert_array_or_vector(brillig_context, *message, bb_func); - let output_heap_array = - brillig_context.codegen_brillig_array_to_heap_array(*result_array); - - brillig_context.black_box_op_instruction(BlackBoxOp::Sha256 { - message: message_vector, - output: output_heap_array, - }); - - brillig_context.deallocate_heap_vector(message_vector); - brillig_context.deallocate_heap_array(output_heap_array); - } else { - unreachable!("ICE: SHA256 expects one array argument and one array result") - } - } BlackBoxFunc::Blake2s => { if let ([message], [BrilligVariable::BrilligArray(result_array)]) = (function_arguments, function_results) 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 7c2fb541006..08e6c18182b 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 @@ -285,9 +285,6 @@ impl DebugShow { outputs ); } - BlackBoxOp::Sha256 { message, output } => { - debug_println!(self.enable_debug_trace, " SHA256 {} -> {}", message, output); - } BlackBoxOp::Keccak256 { message, output } => { debug_println!(self.enable_debug_trace, " KECCAK256 {} -> {}", message, output); } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index 0cad7b9c978..21d4dfb60b8 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -204,10 +204,6 @@ impl GeneratedAcir { BlackBoxFuncCall::XOR { lhs: inputs[0][0], rhs: inputs[1][0], output: outputs[0] } } BlackBoxFunc::RANGE => BlackBoxFuncCall::RANGE { input: inputs[0][0] }, - BlackBoxFunc::SHA256 => BlackBoxFuncCall::SHA256 { - inputs: inputs[0].clone(), - outputs: outputs.try_into().expect("Compiler should generate correct size outputs"), - }, BlackBoxFunc::Blake2s => BlackBoxFuncCall::Blake2s { inputs: inputs[0].clone(), outputs: outputs.try_into().expect("Compiler should generate correct size outputs"), @@ -649,7 +645,6 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { // variable number of inputs. BlackBoxFunc::AES128Encrypt | BlackBoxFunc::Keccak256 - | BlackBoxFunc::SHA256 | BlackBoxFunc::Blake2s | BlackBoxFunc::Blake3 | BlackBoxFunc::PedersenCommitment @@ -701,10 +696,7 @@ fn black_box_expected_output_size(name: BlackBoxFunc) -> Option { BlackBoxFunc::AND | BlackBoxFunc::XOR => Some(1), // 32 byte hash algorithms - BlackBoxFunc::Keccak256 - | BlackBoxFunc::SHA256 - | BlackBoxFunc::Blake2s - | BlackBoxFunc::Blake3 => Some(32), + BlackBoxFunc::Keccak256 | BlackBoxFunc::Blake2s | BlackBoxFunc::Blake3 => Some(32), BlackBoxFunc::Keccakf1600 => Some(25), // The permutation returns a fixed number of outputs, equals to the inputs length which depends on the proving system implementation. diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index d3e5acb467b..3068f2b5c37 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -488,7 +488,6 @@ fn simplify_black_box_func( } }; match bb_func { - BlackBoxFunc::SHA256 => simplify_hash(dfg, arguments, acvm::blackbox_solver::sha256), BlackBoxFunc::Blake2s => simplify_hash(dfg, arguments, acvm::blackbox_solver::blake2s), BlackBoxFunc::Blake3 => simplify_hash(dfg, arguments, acvm::blackbox_solver::blake3), BlackBoxFunc::Keccakf1600 => { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs index 467514114e4..cb455507985 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs @@ -925,7 +925,7 @@ mod test { ir::{ dfg::DataFlowGraph, function::Function, - instruction::{BinaryOp, Instruction, Intrinsic, TerminatorInstruction}, + instruction::{BinaryOp, Instruction, TerminatorInstruction}, map::Id, types::Type, value::{Value, ValueId}, @@ -1487,8 +1487,7 @@ mod test { // Tests that it does not simplify a true constraint an always-false constraint // acir(inline) fn main f1 { // b0(v0: [u8; 2]): - // v4 = call sha256(v0, u8 2) - // v5 = array_get v4, index u8 0 + // v5 = array_get v0, index u8 0 // v6 = cast v5 as u32 // v8 = truncate v6 to 1 bits, max_bit_size: 32 // v9 = cast v8 as u1 @@ -1520,13 +1519,8 @@ mod test { let array = builder.add_parameter(array_type); let zero = builder.numeric_constant(0_u128, Type::unsigned(8)); - let two = builder.numeric_constant(2_u128, Type::unsigned(8)); - let keccak = - builder.import_intrinsic_id(Intrinsic::BlackBox(acvm::acir::BlackBoxFunc::SHA256)); - let v4 = - builder.insert_call(keccak, vec![array, two], vec![Type::Array(element_type, 32)])[0]; - let v5 = builder.insert_array_get(v4, zero, Type::unsigned(8)); + let v5 = builder.insert_array_get(array, zero, Type::unsigned(8)); let v6 = builder.insert_cast(v5, Type::unsigned(32)); let i_two = builder.numeric_constant(2_u128, Type::unsigned(32)); let v8 = builder.insert_binary(v6, BinaryOp::Mod, i_two); diff --git a/noir/noir-repo/noir_stdlib/src/hash/mod.nr b/noir/noir-repo/noir_stdlib/src/hash/mod.nr index 9aa7d220593..93bce3c20e1 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/mod.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/mod.nr @@ -135,7 +135,7 @@ pub fn keccak256(input: [u8; N], message_size: u32) -> [u8; 32] #[foreign(poseidon2_permutation)] pub fn poseidon2_permutation(_input: [Field; N], _state_length: u32) -> [Field; N] {} -// Generic hashing support. +// Generic hashing support. // Partially ported and impacted by rust. // Hash trait shall be implemented per type. @@ -157,7 +157,7 @@ comptime fn derive_hash(s: StructDefinition) -> Quoted { // TODO: consider making the types generic here ([u8], [Field], etc.) pub trait Hasher { fn finish(self) -> Field; - + fn write(&mut self, input: Field); } @@ -169,7 +169,7 @@ pub trait BuildHasher where H: Hasher { pub struct BuildHasherDefault; impl BuildHasher for BuildHasherDefault -where +where H: Hasher + Default { fn build_hasher(_self: Self) -> H { H::default() @@ -177,7 +177,7 @@ where } impl Default for BuildHasherDefault -where +where H: Hasher + Default { fn default() -> Self { BuildHasherDefault {} diff --git a/noir/noir-repo/noir_stdlib/src/hash/sha256.nr b/noir/noir-repo/noir_stdlib/src/hash/sha256.nr index 7f255fe5586..e99c7678176 100644 --- a/noir/noir-repo/noir_stdlib/src/hash/sha256.nr +++ b/noir/noir-repo/noir_stdlib/src/hash/sha256.nr @@ -4,11 +4,12 @@ use crate::runtime::is_unconstrained; // 32 bytes. // Deprecated in favour of `sha256_var` -#[foreign(sha256)] // docs:start:sha256 pub fn sha256(input: [u8; N]) -> [u8; 32] // docs:end:sha256 -{} +{ + crate::sha256::digest(input) +} #[foreign(sha256_compression)] pub fn sha256_compression(_input: [u32; 16], _state: [u32; 8]) -> [u32; 8] {} @@ -104,7 +105,7 @@ pub fn sha256_var(msg: [u8; N], message_size: u64) -> [u8; 32] { msg_byte_ptr = new_msg_byte_ptr; } - // If the block is filled, compress it. + // If the block is filled, compress it. // An un-filled block is handled after this loop. if msg_byte_ptr == 64 { h = sha256_compression(msg_u8_to_u32(msg_block), h); @@ -113,8 +114,8 @@ pub fn sha256_var(msg: [u8; N], message_size: u64) -> [u8; 32] { let modulo = N % BLOCK_SIZE; // Handle setup of the final msg block. - // This case is only hit if the msg is less than the block size, - // or our message cannot be evenly split into blocks. + // This case is only hit if the msg is less than the block size, + // or our message cannot be evenly split into blocks. if modulo != 0 { let msg_start = BLOCK_SIZE * num_blocks; let (new_msg_block, new_msg_byte_ptr) = unsafe { @@ -145,7 +146,7 @@ pub fn sha256_var(msg: [u8; N], message_size: u64) -> [u8; 32] { let zero = msg_block[0] - msg_block[0]; // Pad the rest such that we have a [u32; 2] block at the end representing the length - // of the message, and a block of 1 0 ... 0 following the message (i.e. [1 << 7, 0, ..., 0]). + // of the message, and a block of 1 0 ... 0 following the message (i.e. [1 << 7, 0, ..., 0]). msg_block[msg_byte_ptr] = 1 << 7; let last_block = msg_block; msg_byte_ptr = msg_byte_ptr + 1; diff --git a/noir/noir-repo/tooling/noir_js/src/index.ts b/noir/noir-repo/tooling/noir_js/src/index.ts index 1feca8fa275..653c51a2292 100644 --- a/noir/noir-repo/tooling/noir_js/src/index.ts +++ b/noir/noir-repo/tooling/noir_js/src/index.ts @@ -7,7 +7,6 @@ export { ecdsa_secp256k1_verify, keccak256, blake2s256, - sha256, xor, and, } from '@noir-lang/acvm_js'; diff --git a/noir/noir-repo/tooling/noirc_abi_wasm/package.json b/noir/noir-repo/tooling/noirc_abi_wasm/package.json index b8d0e74617d..021e80017aa 100644 --- a/noir/noir-repo/tooling/noirc_abi_wasm/package.json +++ b/noir/noir-repo/tooling/noirc_abi_wasm/package.json @@ -42,7 +42,7 @@ "@esm-bundle/chai": "^4.3.4-fix.0", "@web/dev-server-esbuild": "^0.3.6", "@web/test-runner": "^0.18.1", - "@web/test-runner-playwright": "^0.10.0", + "@web/test-runner-playwright": "^0.11.0", "eslint": "^8.57.0", "mocha": "^10.2.0" } diff --git a/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs b/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs index fa72793e406..f367360b189 100644 --- a/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs +++ b/noir/noir-repo/tooling/profiler/src/opcode_formatter.rs @@ -14,7 +14,6 @@ fn format_blackbox_function(call: &BlackBoxFuncCall) -> String { BlackBoxFuncCall::AND { .. } => "and".to_string(), BlackBoxFuncCall::XOR { .. } => "xor".to_string(), BlackBoxFuncCall::RANGE { .. } => "range".to_string(), - BlackBoxFuncCall::SHA256 { .. } => "sha256".to_string(), BlackBoxFuncCall::Blake2s { .. } => "blake2s".to_string(), BlackBoxFuncCall::Blake3 { .. } => "blake3".to_string(), BlackBoxFuncCall::SchnorrVerify { .. } => "schnorr_verify".to_string(), @@ -41,7 +40,6 @@ fn format_blackbox_function(call: &BlackBoxFuncCall) -> String { fn format_blackbox_op(call: &BlackBoxOp) -> String { match call { BlackBoxOp::AES128Encrypt { .. } => "aes128_encrypt".to_string(), - BlackBoxOp::Sha256 { .. } => "sha256".to_string(), BlackBoxOp::Blake2s { .. } => "blake2s".to_string(), BlackBoxOp::Blake3 { .. } => "blake3".to_string(), BlackBoxOp::SchnorrVerify { .. } => "schnorr_verify".to_string(), diff --git a/noir/noir-repo/yarn.lock b/noir/noir-repo/yarn.lock index f77e9f7e72e..77708cc9b21 100644 --- a/noir/noir-repo/yarn.lock +++ b/noir/noir-repo/yarn.lock @@ -4145,7 +4145,7 @@ __metadata: "@esm-bundle/chai": ^4.3.4-fix.0 "@web/dev-server-esbuild": ^0.3.6 "@web/test-runner": ^0.18.1 - "@web/test-runner-playwright": ^0.10.0 + "@web/test-runner-playwright": ^0.11.0 chai: ^4.4.1 eslint: ^8.57.0 eslint-plugin-prettier: ^5.1.3 @@ -4277,7 +4277,7 @@ __metadata: "@noir-lang/types": "workspace:*" "@web/dev-server-esbuild": ^0.3.6 "@web/test-runner": ^0.18.1 - "@web/test-runner-playwright": ^0.10.0 + "@web/test-runner-playwright": ^0.11.0 eslint: ^8.57.0 mocha: ^10.2.0 languageName: unknown @@ -6172,15 +6172,6 @@ __metadata: languageName: node linkType: hard -"@web/browser-logs@npm:^0.3.4": - version: 0.3.4 - resolution: "@web/browser-logs@npm:0.3.4" - dependencies: - errorstacks: ^2.2.0 - checksum: fe212c91c26deada3458b6562a8d7d2ae98b7b51c7099e1cdb972e9f799c63f6cd170776b2eadbe43c47531cb6d9b06f48282113a5944f4394270a0076f8565e - languageName: node - linkType: hard - "@web/browser-logs@npm:^0.4.0": version: 0.4.0 resolution: "@web/browser-logs@npm:0.4.0" @@ -6223,32 +6214,6 @@ __metadata: languageName: node linkType: hard -"@web/dev-server-core@npm:^0.6.2": - version: 0.6.3 - resolution: "@web/dev-server-core@npm:0.6.3" - dependencies: - "@types/koa": ^2.11.6 - "@types/ws": ^7.4.0 - "@web/parse5-utils": ^2.0.2 - chokidar: ^3.4.3 - clone: ^2.1.2 - es-module-lexer: ^1.0.0 - get-stream: ^6.0.0 - is-stream: ^2.0.0 - isbinaryfile: ^5.0.0 - koa: ^2.13.0 - koa-etag: ^4.0.0 - koa-send: ^5.0.1 - koa-static: ^5.0.0 - lru-cache: ^8.0.4 - mime-types: ^2.1.27 - parse5: ^6.0.1 - picomatch: ^2.2.2 - ws: ^7.4.2 - checksum: 98ba42df5eb865828c223bd1de098d013efd8e89983efff28e26ecd9d08c8b35fd29b4c1256ed08b05ecb365abe1aa80d2854e1953bdebbbe230a7e2a597dd8f - languageName: node - linkType: hard - "@web/dev-server-core@npm:^0.7.0": version: 0.7.0 resolution: "@web/dev-server-core@npm:0.7.0" @@ -6351,7 +6316,7 @@ __metadata: languageName: node linkType: hard -"@web/parse5-utils@npm:^2.0.2, @web/parse5-utils@npm:^2.1.0": +"@web/parse5-utils@npm:^2.1.0": version: 2.1.0 resolution: "@web/parse5-utils@npm:2.1.0" dependencies: @@ -6384,40 +6349,6 @@ __metadata: languageName: node linkType: hard -"@web/test-runner-core@npm:^0.12.0": - version: 0.12.0 - resolution: "@web/test-runner-core@npm:0.12.0" - dependencies: - "@babel/code-frame": ^7.12.11 - "@types/babel__code-frame": ^7.0.2 - "@types/co-body": ^6.1.0 - "@types/convert-source-map": ^2.0.0 - "@types/debounce": ^1.2.0 - "@types/istanbul-lib-coverage": ^2.0.3 - "@types/istanbul-reports": ^3.0.0 - "@web/browser-logs": ^0.3.4 - "@web/dev-server-core": ^0.6.2 - chokidar: ^3.4.3 - cli-cursor: ^3.1.0 - co-body: ^6.1.0 - convert-source-map: ^2.0.0 - debounce: ^1.2.0 - dependency-graph: ^0.11.0 - globby: ^11.0.1 - ip: ^1.1.5 - istanbul-lib-coverage: ^3.0.0 - istanbul-lib-report: ^3.0.1 - istanbul-reports: ^3.0.2 - log-update: ^4.0.0 - nanocolors: ^0.2.1 - nanoid: ^3.1.25 - open: ^8.0.2 - picomatch: ^2.2.2 - source-map: ^0.7.3 - checksum: e71afa227f9dc2ea4ec67838b1bc4c8af2c61d3e6002b78e37724e3dc09be466e7f7aa5e6795d5431dca1a0b13b94765a880103f98c5497c97943c2f708327eb - languageName: node - linkType: hard - "@web/test-runner-core@npm:^0.13.0": version: 0.13.0 resolution: "@web/test-runner-core@npm:0.13.0" @@ -6452,19 +6383,6 @@ __metadata: languageName: node linkType: hard -"@web/test-runner-coverage-v8@npm:^0.7.3": - version: 0.7.3 - resolution: "@web/test-runner-coverage-v8@npm:0.7.3" - dependencies: - "@web/test-runner-core": ^0.12.0 - istanbul-lib-coverage: ^3.0.0 - lru-cache: ^8.0.4 - picomatch: ^2.2.2 - v8-to-istanbul: ^9.0.1 - checksum: 05d7a9a4df8ca30991307a8d69ac9388a6572a9c6585887a925e7bdb158a0430f213c81cb356b8dcb7bf9cd3423d0071030b481c29358562bd344da8ea814daa - languageName: node - linkType: hard - "@web/test-runner-coverage-v8@npm:^0.8.0": version: 0.8.0 resolution: "@web/test-runner-coverage-v8@npm:0.8.0" @@ -6487,17 +6405,6 @@ __metadata: languageName: node linkType: hard -"@web/test-runner-playwright@npm:^0.10.0": - version: 0.10.3 - resolution: "@web/test-runner-playwright@npm:0.10.3" - dependencies: - "@web/test-runner-core": ^0.12.0 - "@web/test-runner-coverage-v8": ^0.7.3 - playwright: ^1.22.2 - checksum: 7c765d34482f2e299742c3ffe80790229d0825569016ccfccbb1a0c915f89551a3cc14a1454ed7c6895aaa03605ea444f7c1846eeab82bf02702e87a60628b3c - languageName: node - linkType: hard - "@web/test-runner-playwright@npm:^0.11.0": version: 0.11.0 resolution: "@web/test-runner-playwright@npm:0.11.0" @@ -12671,7 +12578,7 @@ __metadata: "@web/dev-server-esbuild": ^0.3.6 "@web/dev-server-import-maps": ^0.2.0 "@web/test-runner": ^0.18.1 - "@web/test-runner-playwright": ^0.10.0 + "@web/test-runner-playwright": ^0.11.0 eslint: ^8.57.0 eslint-plugin-prettier: ^5.1.3 ethers: ^6.7.1 @@ -16391,27 +16298,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.40.1": - version: 1.40.1 - resolution: "playwright-core@npm:1.40.1" +"playwright-core@npm:1.42.1": + version: 1.42.1 + resolution: "playwright-core@npm:1.42.1" bin: playwright-core: cli.js - checksum: 84d92fb9b86e3c225b16b6886bf858eb5059b4e60fa1205ff23336e56a06dcb2eac62650992dede72f406c8e70a7b6a5303e511f9b4bc0b85022ede356a01ee0 + checksum: e7081ff0f43b4b9053255109eb1d82164b7c6b55c7d022e25fca935d0f4fc547cb2e02a7b64f0c2a9462729be7bb45edb082f8b038306415944f1061d00d9c90 languageName: node linkType: hard "playwright@npm:^1.22.2": - version: 1.40.1 - resolution: "playwright@npm:1.40.1" + version: 1.42.1 + resolution: "playwright@npm:1.42.1" dependencies: fsevents: 2.3.2 - playwright-core: 1.40.1 + playwright-core: 1.42.1 dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 9e36791c1b4a649c104aa365fdd9d049924eeb518c5967c0e921aa38b9b00994aa6ee54784d6c2af194b3b494b6f69772673081ef53c6c4a4b2065af9955c4ba + checksum: 06c16bcd07d03993126ee6c168bde28c59d3cab7f7d4721eaf57bd5c51e9c929e10a286758de062b5fc02874413ceae2684d14cbb7865c0a51fc8df6d9001ad1 languageName: node linkType: hard diff --git a/noir/scripts/test_js_packages.sh b/noir/scripts/test_js_packages.sh index 687ab802fee..f7fa23301e2 100755 --- a/noir/scripts/test_js_packages.sh +++ b/noir/scripts/test_js_packages.sh @@ -4,6 +4,7 @@ set -eu cd $(dirname "$0")/../noir-repo ./.github/scripts/wasm-bindgen-install.sh +./.github/scripts/playwright-install.sh # Set build data manually. export SOURCE_DATE_EPOCH=$(date +%s) @@ -15,6 +16,5 @@ export PATH="${PATH}:/usr/src/noir/noir-repo/target/release/" yarn --immutable yarn build -./.github/scripts/playwright-install.sh yarn test diff --git a/yarn-project/foundation/src/crypto/sha256/index.test.ts b/yarn-project/foundation/src/crypto/sha256/index.test.ts index 8b30661302a..f350bc035df 100644 --- a/yarn-project/foundation/src/crypto/sha256/index.test.ts +++ b/yarn-project/foundation/src/crypto/sha256/index.test.ts @@ -1,14 +1,46 @@ -import { createHash, randomBytes } from 'crypto'; +import { createHash, randomBytes, randomInt } from 'crypto'; -import { sha256 } from './index.js'; +import { sha256, sha256Compression } from './index.js'; describe('sha256', () => { - it('should correctly hash data using hash.js', () => { - const data = randomBytes(67); + describe('sha256 hash', () => { + it('should correctly hash data using hash.js', () => { + const data = randomBytes(67); - const expected = createHash('sha256').update(data).digest(); + const expected = createHash('sha256').update(data).digest(); - const result = sha256(data); - expect(result).toEqual(expected); + const result = sha256(data); + expect(result).toEqual(expected); + }); + }); + + describe('sha256 compression', () => { + it('sha256Compression works', () => { + const state = Uint32Array.from(Array.from({ length: 8 }, () => randomInt(2 ** 32))); + const inputs = Uint32Array.from(Array.from({ length: 16 }, () => randomInt(2 ** 32))); + + const output = sha256Compression(state, inputs); + expect(output.length).toEqual(8); + }); + it('sha256 compression does not work on state.length < 8', () => { + const state = Uint32Array.from(Array.from({ length: 7 }, () => randomInt(2 ** 32))); + const inputs = Uint32Array.from(Array.from({ length: 16 }, () => randomInt(2 ** 32))); + expect(() => sha256Compression(state, inputs)).toThrowError(); + }); + it('sha256 compression does not work on state.length > 8', () => { + const state = Uint32Array.from(Array.from({ length: 9 }, () => randomInt(2 ** 32))); + const inputs = Uint32Array.from(Array.from({ length: 16 }, () => randomInt(2 ** 32))); + expect(() => sha256Compression(state, inputs)).toThrowError(); + }); + it('sha256 compression does not work on inputs.length < 16', () => { + const state = Uint32Array.from(Array.from({ length: 8 }, () => randomInt(2 ** 32))); + const inputs = Uint32Array.from(Array.from({ length: 15 }, () => randomInt(2 ** 32))); + expect(() => sha256Compression(state, inputs)).toThrowError(); + }); + it('sha256 compression does not work on inputs.length > 16', () => { + const state = Uint32Array.from(Array.from({ length: 8 }, () => randomInt(2 ** 32))); + const inputs = Uint32Array.from(Array.from({ length: 17 }, () => randomInt(2 ** 32))); + expect(() => sha256Compression(state, inputs)).toThrowError(); + }); }); }); diff --git a/yarn-project/foundation/src/crypto/sha256/index.ts b/yarn-project/foundation/src/crypto/sha256/index.ts index 1ff89efda47..528adf850f1 100644 --- a/yarn-project/foundation/src/crypto/sha256/index.ts +++ b/yarn-project/foundation/src/crypto/sha256/index.ts @@ -1,14 +1,147 @@ +/* eslint-disable camelcase */ import { default as hash } from 'hash.js'; import { Fr } from '../../fields/fields.js'; import { truncateAndPad } from '../../serialize/free_funcs.js'; import { type Bufferable, serializeToBuffer } from '../../serialize/serialize.js'; -export const sha256 = (data: Buffer) => Buffer.from(hash.sha256().update(data).digest()); +export function sha256(data: Buffer) { + return Buffer.from(hash.sha256().update(data).digest()); +} -export const sha256Trunc = (data: Buffer) => truncateAndPad(sha256(data)); +export function sha256Trunc(data: Buffer) { + return truncateAndPad(sha256(data)); +} -export const sha256ToField = (data: Bufferable[]) => { +export function sha256ToField(data: Bufferable[]) { const buffer = serializeToBuffer(data); return Fr.fromBuffer(sha256Trunc(buffer)); -}; +} + +/** + * The "SHA256 Compression" operation (component operation of SHA256 "Hash"). + * WARNING: modifies `state` in place (and also returns it) + * + * This algorithm is extracted from the hash.js package + * and modified to take in an initial state to operate on. + * + * @param state - The initial state to operate on (modified in-place). 8 u32s. + * @param inputs - The inputs to compress into the state. 16 u32s. + * @returns The modified state. 8 u32s. + */ +export function sha256Compression(state: Uint32Array, inputs: Uint32Array): Uint32Array { + if (state.length !== 8) { + throw new Error('`state` argument to SHA256 compression must be of length 8'); + } + if (inputs.length !== 16) { + throw new Error('`inputs` argument to SHA256 compression must be of length 16'); + } + + const W = new Array(64); + const k = [ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, + 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, + 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, + 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, + 0xc67178f2, + ]; + let i = 0; + for (i = 0; i < 16; i++) { + W[i] = inputs[i]; + } + for (i = 16; i < W.length; i++) { + W[i] = sum32_4( + W[i - 16], + W[i - 7], + g0_256(W[i - 15]), // Rot17, Rot18, Sh3 + g1_256(W[i - 2]), //ROt17, Rot19, Sh10 + ); + } + + let a = state[0]; + let b = state[1]; + let c = state[2]; + let d = state[3]; + let e = state[4]; + let f = state[5]; + let g = state[6]; + let h = state[7]; + + for (let i = 0; i < 64; i++) { + const T1 = sum32_5( + h, + s1_256(e), // Rot6, Rot11, Rot25 + ch32(e, f, g), + k[i], + W[i], + ); + + const T2 = sum32( + s0_256(a), // Rot2, Rot13, Rot22 + maj32(a, b, c), + ); + h = g; + g = f; + f = e; + e = sum32(d, T1); + d = c; + c = b; + b = a; + a = sum32(T1, T2); + } + + state[0] = sum32(state[0], a); + state[1] = sum32(state[1], b); + state[2] = sum32(state[2], c); + state[3] = sum32(state[3], d); + state[4] = sum32(state[4], e); + state[5] = sum32(state[5], f); + state[6] = sum32(state[6], g); + state[7] = sum32(state[7], h); + return state; +} + +// SHA256 HELPER FUNCTIONS (from hash.js package) + +function rotr32(w: number, b: number) { + return (w >>> b) | (w << (32 - b)); +} + +function sum32(a: number, b: number) { + return (a + b) >>> 0; +} + +function sum32_4(a: number, b: number, c: number, d: number) { + return (a + b + c + d) >>> 0; +} + +function sum32_5(a: number, b: number, c: number, d: number, e: number) { + return (a + b + c + d + e) >>> 0; +} + +function ch32(x: number, y: number, z: number) { + return (x & y) ^ (~x & z); +} + +function maj32(x: number, y: number, z: number) { + return (x & y) ^ (x & z) ^ (y & z); +} + +function s0_256(x: number) { + return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22); +} + +function s1_256(x: number) { + return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25); +} + +function g0_256(x: number) { + return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3); +} + +function g1_256(x: number) { + return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10); +} diff --git a/yarn-project/simulator/src/avm/avm_gas.ts b/yarn-project/simulator/src/avm/avm_gas.ts index b0c3c79e3c8..7a4eb8e3db2 100644 --- a/yarn-project/simulator/src/avm/avm_gas.ts +++ b/yarn-project/simulator/src/avm/avm_gas.ts @@ -133,7 +133,6 @@ const BaseGasCosts: Record = { [Opcode.DEBUGLOG]: makeCost(c.AVM_DEBUGLOG_BASE_L2_GAS, 0), [Opcode.KECCAK]: makeCost(c.AVM_KECCAK_BASE_L2_GAS, 0), [Opcode.POSEIDON2]: makeCost(c.AVM_POSEIDON2_BASE_L2_GAS, 0), - [Opcode.SHA256]: makeCost(c.AVM_SHA256_BASE_L2_GAS, 0), [Opcode.PEDERSEN]: makeCost(c.AVM_PEDERSEN_BASE_L2_GAS, 0), [Opcode.ECADD]: makeCost(c.AVM_ECADD_BASE_L2_GAS, 0), [Opcode.MSM]: makeCost(c.AVM_MSM_BASE_L2_GAS, 0), @@ -220,7 +219,6 @@ const DynamicGasCosts: Record = { [Opcode.DEBUGLOG]: makeCost(c.AVM_DEBUGLOG_DYN_L2_GAS, 0), [Opcode.KECCAK]: makeCost(c.AVM_KECCAK_DYN_L2_GAS, 0), [Opcode.POSEIDON2]: makeCost(c.AVM_POSEIDON2_DYN_L2_GAS, 0), - [Opcode.SHA256]: makeCost(c.AVM_SHA256_DYN_L2_GAS, 0), [Opcode.PEDERSEN]: makeCost(c.AVM_PEDERSEN_DYN_L2_GAS, 0), [Opcode.ECADD]: makeCost(c.AVM_ECADD_DYN_L2_GAS, 0), [Opcode.MSM]: makeCost(c.AVM_MSM_DYN_L2_GAS, 0), diff --git a/yarn-project/simulator/src/avm/fixtures/index.ts b/yarn-project/simulator/src/avm/fixtures/index.ts index 28092122612..ebbe4bb56e7 100644 --- a/yarn-project/simulator/src/avm/fixtures/index.ts +++ b/yarn-project/simulator/src/avm/fixtures/index.ts @@ -15,7 +15,7 @@ import { type PublicSideEffectTraceInterface } from '../../public/side_effect_tr import { AvmContext } from '../avm_context.js'; import { AvmContextInputs, AvmExecutionEnvironment } from '../avm_execution_environment.js'; import { AvmMachineState } from '../avm_machine_state.js'; -import { Field, Uint8, Uint64 } from '../avm_memory_types.js'; +import { Field, Uint8, Uint32, Uint64 } from '../avm_memory_types.js'; import { type AvmRevertReason } from '../errors.js'; import { AvmPersistableStateManager } from '../journal/journal.js'; import { NullifierManager } from '../journal/nullifiers.js'; @@ -124,6 +124,10 @@ export function randomMemoryBytes(length: number): Uint8[] { return [...Array(length)].map(_ => new Uint8(Math.floor(Math.random() * 255))); } +export function randomMemoryUint32s(length: number): Uint32[] { + return [...Array(length)].map(_ => new Uint32(Math.floor(Math.random() * 255))); +} + export function randomMemoryUint64s(length: number): Uint64[] { return [...Array(length)].map(_ => new Uint64(Math.floor(Math.random() * 255))); } diff --git a/yarn-project/simulator/src/avm/opcodes/hashing.test.ts b/yarn-project/simulator/src/avm/opcodes/hashing.test.ts index ae350b94250..3d17a0d9d2a 100644 --- a/yarn-project/simulator/src/avm/opcodes/hashing.test.ts +++ b/yarn-project/simulator/src/avm/opcodes/hashing.test.ts @@ -1,10 +1,10 @@ -import { keccak256, keccakf1600, pedersenHash, sha256 } from '@aztec/foundation/crypto'; +import { keccak256, keccakf1600, pedersenHash, sha256Compression } from '@aztec/foundation/crypto'; import { type AvmContext } from '../avm_context.js'; import { Field, type Uint8, Uint32, Uint64 } from '../avm_memory_types.js'; -import { initContext, randomMemoryBytes, randomMemoryFields } from '../fixtures/index.js'; +import { initContext, randomMemoryBytes, randomMemoryFields, randomMemoryUint32s } from '../fixtures/index.js'; import { Addressing, AddressingMode } from './addressing_mode.js'; -import { Keccak, KeccakF1600, Pedersen, Poseidon2, Sha256 } from './hashing.js'; +import { Keccak, KeccakF1600, Pedersen, Poseidon2, Sha256Compression } from './hashing.js'; describe('Hashing Opcodes', () => { let context: AvmContext; @@ -173,72 +173,108 @@ describe('Hashing Opcodes', () => { }); }); - describe('Sha256', () => { + describe('Sha256Compression', () => { it('Should (de)serialize correctly', () => { const buf = Buffer.from([ - Sha256.opcode, // opcode + Sha256Compression.opcode, // opcode 1, // indirect ...Buffer.from('12345678', 'hex'), // dstOffset - ...Buffer.from('23456789', 'hex'), // messageOffset - ...Buffer.from('3456789a', 'hex'), // messageSizeOffset + ...Buffer.from('23456789', 'hex'), // stateOffset + ...Buffer.from('3456789a', 'hex'), // stateSizeOffset + ...Buffer.from('456789ab', 'hex'), // inputsOffset + ...Buffer.from('56789abc', 'hex'), // inputsSizeOffset ]); - const inst = new Sha256( + const inst = new Sha256Compression( /*indirect=*/ 1, /*dstOffset=*/ 0x12345678, - /*messageOffset=*/ 0x23456789, - /*messageSizeOffset=*/ 0x3456789a, + /*stateOffset=*/ 0x23456789, + /*stateSizeOffset=*/ 0x3456789a, + /*inputsOffset=*/ 0x456789ab, + /*inputsSizeOffset=*/ 0x56789abc, ); - expect(Sha256.deserialize(buf)).toEqual(inst); + expect(Sha256Compression.deserialize(buf)).toEqual(inst); expect(inst.serialize()).toEqual(buf); }); it('Should hash correctly - direct', async () => { - const args = randomMemoryBytes(10); + const state = randomMemoryUint32s(8); + const stateArray = Uint32Array.from(state.map(byte => byte.toNumber())); + const inputs = randomMemoryUint32s(16); + const inputsArray = Uint32Array.from(inputs.map(byte => byte.toNumber())); const indirect = 0; - const messageOffset = 0; - const messageSizeOffset = 15; - const dstOffset = 20; - context.machineState.memory.set(messageSizeOffset, new Uint32(args.length)); - context.machineState.memory.setSlice(messageOffset, args); - - await new Sha256(indirect, dstOffset, messageOffset, messageSizeOffset).execute(context); - - const resultBuffer = Buffer.concat( - context.machineState.memory.getSliceAs(dstOffset, 32).map(byte => byte.toBuffer()), - ); - const inputBuffer = Buffer.concat(args.map(byte => byte.toBuffer())); - const expectedHash = sha256(inputBuffer); - expect(resultBuffer).toEqual(expectedHash); + const stateOffset = 0; + const stateSizeOffset = 100; + const inputsOffset = 200; + const inputsSizeOffset = 300; + const outputOffset = 300; + context.machineState.memory.set(stateSizeOffset, new Uint32(state.length)); + context.machineState.memory.setSlice(stateOffset, state); + context.machineState.memory.set(inputsSizeOffset, new Uint32(inputs.length)); + context.machineState.memory.setSlice(inputsOffset, inputs); + + await new Sha256Compression( + indirect, + outputOffset, + stateOffset, + stateSizeOffset, + inputsOffset, + inputsSizeOffset, + ).execute(context); + + const output = context.machineState.memory.getSliceAs(outputOffset, 8); + const outputArray = Uint32Array.from(output.map(word => word.toNumber())); + + const expectedOutput = sha256Compression(stateArray, inputsArray); + expect(outputArray).toEqual(expectedOutput); }); it('Should hash correctly - indirect', async () => { - const args = randomMemoryBytes(10); + const state = randomMemoryUint32s(8); + const stateArray = Uint32Array.from(state.map(byte => byte.toNumber())); + const inputs = randomMemoryUint32s(16); + const inputsArray = Uint32Array.from(inputs.map(byte => byte.toNumber())); const indirect = new Addressing([ /*dstOffset=*/ AddressingMode.INDIRECT, - /*messageOffset*/ AddressingMode.INDIRECT, - /*messageSizeOffset*/ AddressingMode.INDIRECT, + /*stateOffset*/ AddressingMode.INDIRECT, + /*stateSizeOffset*/ AddressingMode.INDIRECT, + /*inputsOffset*/ AddressingMode.INDIRECT, + /*inputsSizeOffset*/ AddressingMode.INDIRECT, ]).toWire(); - const messageOffset = 0; - const messageOffsetReal = 10; - const messageSizeOffset = 1; - const messageSizeOffsetReal = 100; - const dstOffset = 2; - const dstOffsetReal = 30; - context.machineState.memory.set(messageOffset, new Uint32(messageOffsetReal)); - context.machineState.memory.set(dstOffset, new Uint32(dstOffsetReal)); - context.machineState.memory.set(messageSizeOffset, new Uint32(messageSizeOffsetReal)); - context.machineState.memory.set(messageSizeOffsetReal, new Uint32(args.length)); - context.machineState.memory.setSlice(messageOffsetReal, args); - - await new Sha256(indirect, dstOffset, messageOffset, messageSizeOffset).execute(context); - - const resultBuffer = Buffer.concat( - context.machineState.memory.getSliceAs(dstOffsetReal, 32).map(byte => byte.toBuffer()), - ); - const inputBuffer = Buffer.concat(args.map(byte => byte.toBuffer())); - const expectedHash = sha256(inputBuffer); - expect(resultBuffer).toEqual(expectedHash); + const stateOffset = 0; + const stateOffsetReal = 10; + const stateSizeOffset = 1; + const stateSizeOffsetReal = 100; + const inputsOffset = 2; + const inputsOffsetReal = 200; + const inputsSizeOffset = 3; + const inputsSizeOffsetReal = 300; + const outputOffset = 4; + const outputOffsetReal = 400; + context.machineState.memory.set(stateSizeOffset, new Uint32(stateSizeOffsetReal)); + context.machineState.memory.set(stateSizeOffsetReal, new Uint32(state.length)); + context.machineState.memory.set(stateOffset, new Uint32(stateOffsetReal)); + context.machineState.memory.setSlice(stateOffsetReal, state); + context.machineState.memory.set(inputsSizeOffset, new Uint32(inputsSizeOffsetReal)); + context.machineState.memory.set(inputsSizeOffsetReal, new Uint32(inputs.length)); + context.machineState.memory.set(inputsOffset, new Uint32(inputsOffsetReal)); + context.machineState.memory.setSlice(inputsOffsetReal, inputs); + context.machineState.memory.set(outputOffset, new Uint32(outputOffsetReal)); + + await new Sha256Compression( + indirect, + outputOffset, + stateOffset, + stateSizeOffset, + inputsOffset, + inputsSizeOffset, + ).execute(context); + + const output = context.machineState.memory.getSliceAs(outputOffsetReal, 8); + const outputArray = Uint32Array.from(output.map(word => word.toNumber())); + + const expectedOutput = sha256Compression(stateArray, inputsArray); + expect(outputArray).toEqual(expectedOutput); }); }); diff --git a/yarn-project/simulator/src/avm/opcodes/hashing.ts b/yarn-project/simulator/src/avm/opcodes/hashing.ts index 6a70b7e6a6b..6b8dd16f774 100644 --- a/yarn-project/simulator/src/avm/opcodes/hashing.ts +++ b/yarn-project/simulator/src/avm/opcodes/hashing.ts @@ -1,9 +1,16 @@ -import { keccak256, keccakf1600, pedersenHash, poseidon2Permutation, sha256 } from '@aztec/foundation/crypto'; +import { + keccak256, + keccakf1600, + pedersenHash, + poseidon2Permutation, + sha256Compression, +} from '@aztec/foundation/crypto'; import { strict as assert } from 'assert'; import { type AvmContext } from '../avm_context.js'; -import { Field, TypeTag, Uint8, Uint64 } from '../avm_memory_types.js'; +import { Field, TypeTag, Uint8, Uint32, Uint64 } from '../avm_memory_types.js'; +import { InstructionExecutionError } from '../errors.js'; import { Opcode, OperandType } from '../serialization/instruction_serialization.js'; import { Addressing } from './addressing_mode.js'; import { Instruction } from './instruction.js'; @@ -145,9 +152,9 @@ export class KeccakF1600 extends Instruction { } } -export class Sha256 extends Instruction { - static type: string = 'SHA256'; - static readonly opcode: Opcode = Opcode.SHA256; +export class Sha256Compression extends Instruction { + static type: string = 'SHA256COMPRESSION'; + static readonly opcode: Opcode = Opcode.SHA256COMPRESSION; // Informs (de)serialization. See Instruction.deserialize. static readonly wireFormat: OperandType[] = [ @@ -156,36 +163,54 @@ export class Sha256 extends Instruction { OperandType.UINT32, OperandType.UINT32, OperandType.UINT32, + OperandType.UINT32, + OperandType.UINT32, ]; constructor( private indirect: number, - private dstOffset: number, - private messageOffset: number, - private messageSizeOffset: number, + private outputOffset: number, + private stateOffset: number, + private stateSizeOffset: number, + private inputsOffset: number, + private inputsSizeOffset: number, ) { super(); } - // pub fn sha256_slice(input: [u8]) -> [u8; 32] public async execute(context: AvmContext): Promise { + const STATE_SIZE = 8; + const INPUTS_SIZE = 16; + const memory = context.machineState.memory.track(this.type); - const [dstOffset, messageOffset, messageSizeOffset] = Addressing.fromWire(this.indirect).resolve( - [this.dstOffset, this.messageOffset, this.messageSizeOffset], + const [outputOffset, stateOffset, stateSizeOffset, inputsOffset, inputsSizeOffset] = Addressing.fromWire( + this.indirect, + ).resolve( + [this.outputOffset, this.stateOffset, this.stateSizeOffset, this.inputsOffset, this.inputsSizeOffset], memory, ); - memory.checkTag(TypeTag.UINT32, messageSizeOffset); - const messageSize = memory.get(messageSizeOffset).toNumber(); - const memoryOperations = { reads: messageSize + 1, writes: 32, indirect: this.indirect }; + const stateSize = memory.get(stateSizeOffset).toNumber(); + const inputsSize = memory.get(inputsSizeOffset).toNumber(); + if (stateSize !== STATE_SIZE) { + throw new InstructionExecutionError('`state` argument to SHA256 compression must be of length 8'); + } + if (inputsSize !== INPUTS_SIZE) { + throw new InstructionExecutionError('`inputs` argument to SHA256 compression must be of length 16'); + } + // +2 to account for both size offsets (stateSizeOffset and inputsSizeOffset) + // Note: size of output is same as size of state + const memoryOperations = { reads: stateSize + inputsSize + 2, writes: stateSize, indirect: this.indirect }; context.machineState.consumeGas(this.gasCost(memoryOperations)); - memory.checkTagsRange(TypeTag.UINT8, messageOffset, messageSize); + memory.checkTagsRange(TypeTag.UINT32, inputsOffset, inputsSize); + memory.checkTagsRange(TypeTag.UINT32, stateOffset, stateSize); - const messageData = Buffer.concat(memory.getSlice(messageOffset, messageSize).map(word => word.toBuffer())); - const hashBuffer = sha256(messageData); + const state = Uint32Array.from(memory.getSlice(stateOffset, stateSize).map(word => word.toNumber())); + const inputs = Uint32Array.from(memory.getSlice(inputsOffset, inputsSize).map(word => word.toNumber())); + const output = sha256Compression(state, inputs); - // We need to convert the hashBuffer because map doesn't work as expected on an Uint8Array (Buffer). - const res = [...hashBuffer].map(byte => new Uint8(byte)); - memory.setSlice(dstOffset, res); + // Conversion required from Uint32Array to Uint32[] (can't map directly, need `...`) + const res = [...output].map(word => new Uint32(word)); + memory.setSlice(outputOffset, res); memory.assert(memoryOperations); context.machineState.incrementPc(); diff --git a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts index da4ded88423..6f5fae94394 100644 --- a/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/bytecode_serialization.ts @@ -1,7 +1,7 @@ import { PedersenCommitment } from '../opcodes/commitment.js'; import { DAGasLeft, L2GasLeft } from '../opcodes/context_getters.js'; import { EcAdd } from '../opcodes/ec_add.js'; -import { Keccak, KeccakF1600, Pedersen, Poseidon2, Sha256 } from '../opcodes/hashing.js'; +import { Keccak, KeccakF1600, Pedersen, Poseidon2, Sha256Compression } from '../opcodes/hashing.js'; import { Add, Address, @@ -167,7 +167,7 @@ const INSTRUCTION_SET = () => [EcAdd.opcode, Instruction.deserialize.bind(EcAdd)], [Keccak.opcode, Instruction.deserialize.bind(Keccak)], [Poseidon2.opcode, Instruction.deserialize.bind(Poseidon2)], - [Sha256.opcode, Instruction.deserialize.bind(Sha256)], + [Sha256Compression.opcode, Instruction.deserialize.bind(Sha256Compression)], [Pedersen.opcode, Instruction.deserialize.bind(Pedersen)], [MultiScalarMul.opcode, Instruction.deserialize.bind(MultiScalarMul)], [PedersenCommitment.opcode, Instruction.deserialize.bind(PedersenCommitment)], diff --git a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts index 8dc7047d3c6..9a458b2dfcf 100644 --- a/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts +++ b/yarn-project/simulator/src/avm/serialization/instruction_serialization.ts @@ -92,16 +92,14 @@ export enum Opcode { // Gadgets KECCAK, POSEIDON2, - SHA256, // temp - may be removed, but alot of contracts rely on it + SHA256COMPRESSION, + KECCAKF1600, PEDERSEN, // temp - may be removed, but alot of contracts rely on it ECADD, MSM, PEDERSENCOMMITMENT, // Conversion TORADIXLE, - // Future Gadgets -- pending changes in noir - SHA256COMPRESSION, - KECCAKF1600, // Here for when we eventually support this } // Possible types for an instruction's operand in its wire format. (Keep in sync with CPP code. diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index 123ba02da59..677a033c70b 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -3380,12 +3380,12 @@ __metadata: "@noir-lang/noir_js@file:../noir/packages/noir_js::locator=%40aztec%2Faztec3-packages%40workspace%3A.": version: 0.34.0 - resolution: "@noir-lang/noir_js@file:../noir/packages/noir_js#../noir/packages/noir_js::hash=0a6cc4&locator=%40aztec%2Faztec3-packages%40workspace%3A." + resolution: "@noir-lang/noir_js@file:../noir/packages/noir_js#../noir/packages/noir_js::hash=999f32&locator=%40aztec%2Faztec3-packages%40workspace%3A." dependencies: "@noir-lang/acvm_js": 0.50.0 "@noir-lang/noirc_abi": 0.34.0 "@noir-lang/types": 0.34.0 - checksum: 432f14d70d911c94aacab42012e7813b5823d9a8971d1d9a543b82ab3b2e38739bf1e065788c08e8f44bebd75fb3ab0f8dba3151b74bbb3aa2ec5c105f4bca61 + checksum: 72009b3553a8c2652270b86b02bf5215456adb3c66ebb08a3b66185d20b708e86cf3300c3f57641d2e9e9f10d340bbf5e2f9fb1f89507900ccdd9b0e42c4349a languageName: node linkType: hard