diff --git a/acvm-repo/brillig/src/black_box.rs b/acvm-repo/brillig/src/black_box.rs index 41e54ab2705..538c907620c 100644 --- a/acvm-repo/brillig/src/black_box.rs +++ b/acvm-repo/brillig/src/black_box.rs @@ -9,6 +9,8 @@ pub enum BlackBoxOp { Sha256 { message: HeapVector, output: HeapArray }, /// Calculates the Blake2s hash of the inputs. Blake2s { message: HeapVector, output: HeapArray }, + /// Calculates the Blake3 hash of the inputs. + Blake3 { message: HeapVector, output: HeapArray }, /// Calculates the Keccak256 hash of the inputs. Keccak256 { message: HeapVector, output: HeapArray }, /// Verifies a ECDSA signature over the secp256k1 curve. diff --git a/acvm-repo/brillig_vm/src/black_box.rs b/acvm-repo/brillig_vm/src/black_box.rs index 94feb23e1a6..009441269f8 100644 --- a/acvm-repo/brillig_vm/src/black_box.rs +++ b/acvm-repo/brillig_vm/src/black_box.rs @@ -1,7 +1,7 @@ use acir::brillig::{BlackBoxOp, HeapArray, HeapVector, Value}; use acir::{BlackBoxFunc, FieldElement}; use acvm_blackbox_solver::{ - blake2s, ecdsa_secp256k1_verify, ecdsa_secp256r1_verify, keccak256, sha256, + blake2s, blake3, ecdsa_secp256k1_verify, ecdsa_secp256r1_verify, keccak256, sha256, BlackBoxFunctionSolver, BlackBoxResolutionError, }; @@ -58,6 +58,12 @@ pub(crate) fn evaluate_black_box( memory.write_slice(registers.get(output.pointer).to_usize(), &to_value_vec(&bytes)); Ok(()) } + BlackBoxOp::Blake3 { message, output } => { + let message = to_u8_vec(read_heap_vector(memory, registers, message)); + let bytes = blake3(message.as_slice())?; + memory.write_slice(registers.get(output.pointer).to_usize(), &to_value_vec(&bytes)); + Ok(()) + } BlackBoxOp::Keccak256 { message, output } => { let message = to_u8_vec(read_heap_vector(memory, registers, message)); let bytes = keccak256(message.as_slice())?; @@ -171,6 +177,7 @@ fn black_box_function_from_op(op: &BlackBoxOp) -> BlackBoxFunc { match op { BlackBoxOp::Sha256 { .. } => BlackBoxFunc::SHA256, BlackBoxOp::Blake2s { .. } => BlackBoxFunc::Blake2s, + BlackBoxOp::Blake3 { .. } => BlackBoxFunc::Blake3, BlackBoxOp::Keccak256 { .. } => BlackBoxFunc::Keccak256, BlackBoxOp::EcdsaSecp256k1 { .. } => BlackBoxFunc::EcdsaSecp256k1, BlackBoxOp::EcdsaSecp256r1 { .. } => BlackBoxFunc::EcdsaSecp256r1, diff --git a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs index a6d3220fa85..8a1ae5301d6 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_black_box.rs @@ -41,6 +41,19 @@ pub(crate) fn convert_black_box_call( unreachable!("ICE: Blake2s expects one array argument and one array result") } } + BlackBoxFunc::Blake3 => { + if let ([message], [BrilligVariable::BrilligArray(result_array)]) = + (function_arguments, function_results) + { + let message_vector = convert_array_or_vector(brillig_context, message, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::Blake3 { + message: message_vector.to_heap_vector(), + output: result_array.to_heap_array(), + }); + } else { + unreachable!("ICE: Blake3 expects one array argument and one array result") + } + } BlackBoxFunc::Keccak256 => { if let ( [message, BrilligVariable::Simple(array_size)], @@ -181,9 +194,7 @@ pub(crate) fn convert_black_box_call( BlackBoxFunc::RecursiveAggregation => unimplemented!( "ICE: `BlackBoxFunc::RecursiveAggregation` is not implemented by the Brillig VM" ), - BlackBoxFunc::Blake3 => { - unimplemented!("ICE: `BlackBoxFunc::Blake3` is not implemented by the Brillig VM") - } + BlackBoxFunc::Keccakf1600 => { unimplemented!("ICE: `BlackBoxFunc::Keccakf1600` is not implemented by the Brillig VM") } diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs index aae74849b8c..ff3123ade09 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -353,6 +353,9 @@ impl DebugShow { BlackBoxOp::Blake2s { message, output } => { debug_println!(self.enable_debug_trace, " BLAKE2S {} -> {}", message, output); } + BlackBoxOp::Blake3 { message, output } => { + debug_println!(self.enable_debug_trace, " BLAKE3 {} -> {}", message, output); + } BlackBoxOp::EcdsaSecp256k1 { hashed_msg, public_key_x, diff --git a/test_programs/execution_success/brillig_blake3/Nargo.toml b/test_programs/execution_success/brillig_blake3/Nargo.toml new file mode 100644 index 00000000000..879476dbdcf --- /dev/null +++ b/test_programs/execution_success/brillig_blake3/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "brillig_blake3" +type = "bin" +authors = [""] +compiler_version = ">=0.22.0" + +[dependencies] diff --git a/test_programs/execution_success/brillig_blake3/Prover.toml b/test_programs/execution_success/brillig_blake3/Prover.toml new file mode 100644 index 00000000000..c807701479b --- /dev/null +++ b/test_programs/execution_success/brillig_blake3/Prover.toml @@ -0,0 +1,37 @@ +# hello as bytes +# https://connor4312.github.io/blake3/index.html +x = [104, 101, 108, 108, 111] +result = [ + 0xea, + 0x8f, + 0x16, + 0x3d, + 0xb3, + 0x86, + 0x82, + 0x92, + 0x5e, + 0x44, + 0x91, + 0xc5, + 0xe5, + 0x8d, + 0x4b, + 0xb3, + 0x50, + 0x6e, + 0xf8, + 0xc1, + 0x4e, + 0xb7, + 0x8a, + 0x86, + 0xe9, + 0x08, + 0xc5, + 0x62, + 0x4a, + 0x67, + 0x20, + 0x0f, +] diff --git a/test_programs/execution_success/brillig_blake3/src/main.nr b/test_programs/execution_success/brillig_blake3/src/main.nr new file mode 100644 index 00000000000..05a5b31f936 --- /dev/null +++ b/test_programs/execution_success/brillig_blake3/src/main.nr @@ -0,0 +1,6 @@ +use dep::std; + +unconstrained fn main(x: [u8; 5], result: [u8; 32]) { + let digest = std::hash::blake3(x); + assert(digest == result); +}