From ca3c2fe8d3390843f8f40660b75779d115d12a33 Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 24 Jun 2024 16:56:11 +0000 Subject: [PATCH 1/9] Revert PR5221 (partially) --- .../acir/src/circuit/black_box_functions.rs | 12 ++--- .../opcodes/black_box_function_call.rs | 12 ++--- acvm-repo/acvm/src/pwg/blackbox/mod.rs | 10 +++- acvm-repo/acvm/src/pwg/blackbox/pedersen.rs | 47 +++++++++++++++++++ .../src/curve_specific_solver.rs | 25 ++++++++++ acvm-repo/bn254_blackbox_solver/src/lib.rs | 28 +++++++++++ acvm-repo/brillig/src/black_box.rs | 4 +- acvm-repo/brillig_vm/src/black_box.rs | 37 ++++++++++++++- .../brillig/brillig_gen/brillig_black_box.rs | 35 +++++++++++++- .../noirc_evaluator/src/brillig/brillig_ir.rs | 15 +++++- .../src/brillig/brillig_ir/debug_show.rs | 20 +++++++- .../src/ssa/acir_gen/acir_ir/acir_variable.rs | 25 ++++++++++ .../ssa/acir_gen/acir_ir/generated_acir.rs | 26 +++++++--- .../src/ssa/ir/instruction/call.rs | 6 +-- noir_stdlib/src/hash.nr | 23 ++++++++- tooling/lsp/src/solver.rs | 16 +++++++ 16 files changed, 306 insertions(+), 35 deletions(-) create mode 100644 acvm-repo/acvm/src/pwg/blackbox/pedersen.rs diff --git a/acvm-repo/acir/src/circuit/black_box_functions.rs b/acvm-repo/acir/src/circuit/black_box_functions.rs index aadee59f507..fb7d9eb584c 100644 --- a/acvm-repo/acir/src/circuit/black_box_functions.rs +++ b/acvm-repo/acir/src/circuit/black_box_functions.rs @@ -82,9 +82,9 @@ pub enum BlackBoxFunc { /// /// [grumpkin]: https://hackmd.io/@aztec-network/ByzgNxBfd#2-Grumpkin---A-curve-on-top-of-BN-254-for-SNARK-efficient-group-operations SchnorrVerify, - /// Deprecated. To be removed with a sync from aztec-packages + /// Will be deprecated PedersenCommitment, - /// Deprecated. To be removed with a sync from aztec-packages + /// Will be deprecated PedersenHash, /// Verifies a ECDSA signature over the secp256k1 curve. /// - inputs: @@ -227,8 +227,8 @@ impl BlackBoxFunc { BlackBoxFunc::BigIntToLeBytes => "bigint_to_le_bytes", BlackBoxFunc::Poseidon2Permutation => "poseidon2_permutation", BlackBoxFunc::Sha256Compression => "sha256_compression", - BlackBoxFunc::PedersenCommitment => "deprecated pedersen commitment", - BlackBoxFunc::PedersenHash => "deprecated pedersen hash", + BlackBoxFunc::PedersenCommitment => "pedersen_commitment", + BlackBoxFunc::PedersenHash => "pedersen_hash", } } @@ -257,8 +257,8 @@ impl BlackBoxFunc { "bigint_to_le_bytes" => Some(BlackBoxFunc::BigIntToLeBytes), "poseidon2_permutation" => Some(BlackBoxFunc::Poseidon2Permutation), "sha256_compression" => Some(BlackBoxFunc::Sha256Compression), - "deprecated pedersen commitment" => Some(BlackBoxFunc::PedersenCommitment), - "deprecated pedersen hash" => Some(BlackBoxFunc::PedersenHash), + "pedersen_commitment" => Some(BlackBoxFunc::PedersenCommitment), + "pedersen_hash" => Some(BlackBoxFunc::PedersenHash), _ => None, } } diff --git a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs index 09b39964813..b8be81fcdef 100644 --- a/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs +++ b/acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs @@ -54,13 +54,13 @@ pub enum BlackBoxFuncCall { message: Vec, output: Witness, }, - /// Deprecated. To be removed with a sync from aztec-packages + /// Will be deprecated PedersenCommitment { inputs: Vec, domain_separator: u32, outputs: (Witness, Witness), }, - /// Deprecated. To be removed with a sync from aztec-packages + /// Will be deprecated PedersenHash { inputs: Vec, domain_separator: u32, @@ -222,6 +222,8 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::Blake2s { inputs, .. } | BlackBoxFuncCall::Blake3 { inputs, .. } | BlackBoxFuncCall::BigIntFromLeBytes { inputs, .. } + | BlackBoxFuncCall::PedersenCommitment { inputs, .. } + | BlackBoxFuncCall::PedersenHash { inputs, .. } | BlackBoxFuncCall::Poseidon2Permutation { inputs, .. } => inputs.to_vec(), BlackBoxFuncCall::Keccakf1600 { inputs, .. } => inputs.to_vec(), @@ -318,8 +320,6 @@ impl BlackBoxFuncCall { inputs.push(*key_hash); inputs } - BlackBoxFuncCall::PedersenCommitment { .. } => todo!(), - BlackBoxFuncCall::PedersenHash { .. } => todo!(), } } @@ -341,7 +341,9 @@ impl BlackBoxFuncCall { | BlackBoxFuncCall::XOR { output, .. } | BlackBoxFuncCall::SchnorrVerify { output, .. } | BlackBoxFuncCall::EcdsaSecp256k1 { output, .. } + | BlackBoxFuncCall::PedersenHash { output, .. } | BlackBoxFuncCall::EcdsaSecp256r1 { output, .. } => vec![*output], + BlackBoxFuncCall::PedersenCommitment { outputs, .. } => vec![outputs.0, outputs.1], BlackBoxFuncCall::MultiScalarMul { outputs, .. } | BlackBoxFuncCall::EmbeddedCurveAdd { outputs, .. } => { vec![outputs.0, outputs.1, outputs.2] @@ -356,8 +358,6 @@ impl BlackBoxFuncCall { vec![] } BlackBoxFuncCall::BigIntToLeBytes { outputs, .. } => outputs.to_vec(), - BlackBoxFuncCall::PedersenCommitment { .. } => todo!(), - BlackBoxFuncCall::PedersenHash { .. } => todo!(), } } } diff --git a/acvm-repo/acvm/src/pwg/blackbox/mod.rs b/acvm-repo/acvm/src/pwg/blackbox/mod.rs index b3064c47d82..0c65759ebcd 100644 --- a/acvm-repo/acvm/src/pwg/blackbox/mod.rs +++ b/acvm-repo/acvm/src/pwg/blackbox/mod.rs @@ -18,6 +18,7 @@ pub(crate) mod bigint; mod embedded_curve_ops; mod hash; mod logic; +mod pedersen; mod range; mod signature; pub(crate) mod utils; @@ -26,6 +27,7 @@ use embedded_curve_ops::{embedded_curve_add, multi_scalar_mul}; // Hash functions should eventually be exposed for external consumers. use hash::{solve_generic_256_hash_opcode, solve_sha_256_permutation_opcode}; use logic::{and, xor}; +use pedersen::{pedersen, pedersen_hash}; pub(crate) use range::solve_range_opcode; use signature::{ ecdsa::{secp256k1_prehashed, secp256r1_prehashed}, @@ -125,6 +127,12 @@ pub(crate) fn solve( message, *output, ), + BlackBoxFuncCall::PedersenCommitment { inputs, domain_separator, outputs } => { + pedersen(backend, initial_witness, inputs, *domain_separator, *outputs) + } + BlackBoxFuncCall::PedersenHash { inputs, domain_separator, output } => { + pedersen_hash(backend, initial_witness, inputs, *domain_separator, *output) + } BlackBoxFuncCall::EcdsaSecp256k1 { public_key_x, public_key_y, @@ -179,7 +187,5 @@ pub(crate) fn solve( BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs, len } => { solve_poseidon2_permutation_opcode(backend, initial_witness, inputs, outputs, *len) } - BlackBoxFuncCall::PedersenCommitment { .. } => todo!("Deprecated BlackBox"), - BlackBoxFuncCall::PedersenHash { .. } => todo!("Deprecated BlackBox"), } } diff --git a/acvm-repo/acvm/src/pwg/blackbox/pedersen.rs b/acvm-repo/acvm/src/pwg/blackbox/pedersen.rs new file mode 100644 index 00000000000..f64a3a79465 --- /dev/null +++ b/acvm-repo/acvm/src/pwg/blackbox/pedersen.rs @@ -0,0 +1,47 @@ +use acir::{ + circuit::opcodes::FunctionInput, + native_types::{Witness, WitnessMap}, + AcirField, +}; + +use crate::{ + pwg::{insert_value, witness_to_value, OpcodeResolutionError}, + BlackBoxFunctionSolver, +}; + +pub(super) fn pedersen( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, + inputs: &[FunctionInput], + domain_separator: u32, + outputs: (Witness, Witness), +) -> Result<(), OpcodeResolutionError> { + let scalars: Result, _> = + inputs.iter().map(|input| witness_to_value(initial_witness, input.witness)).collect(); + let scalars: Vec<_> = scalars?.into_iter().cloned().collect(); + + let (res_x, res_y) = backend.pedersen_commitment(&scalars, domain_separator)?; + + insert_value(&outputs.0, res_x, initial_witness)?; + insert_value(&outputs.1, res_y, initial_witness)?; + + Ok(()) +} + +pub(super) fn pedersen_hash( + backend: &impl BlackBoxFunctionSolver, + initial_witness: &mut WitnessMap, + inputs: &[FunctionInput], + domain_separator: u32, + output: Witness, +) -> Result<(), OpcodeResolutionError> { + let scalars: Result, _> = + inputs.iter().map(|input| witness_to_value(initial_witness, input.witness)).collect(); + let scalars: Vec<_> = scalars?.into_iter().cloned().collect(); + + let res = backend.pedersen_hash(&scalars, domain_separator)?; + + insert_value(&output, res, initial_witness)?; + + Ok(()) +} diff --git a/acvm-repo/blackbox_solver/src/curve_specific_solver.rs b/acvm-repo/blackbox_solver/src/curve_specific_solver.rs index 869017f52ee..f729a5033fb 100644 --- a/acvm-repo/blackbox_solver/src/curve_specific_solver.rs +++ b/acvm-repo/blackbox_solver/src/curve_specific_solver.rs @@ -14,6 +14,16 @@ pub trait BlackBoxFunctionSolver { signature: &[u8; 64], message: &[u8], ) -> Result; + fn pedersen_commitment( + &self, + inputs: &[F], + domain_separator: u32, + ) -> Result<(F, F), BlackBoxResolutionError>; + fn pedersen_hash( + &self, + inputs: &[F], + domain_separator: u32, + ) -> Result; fn multi_scalar_mul( &self, points: &[F], @@ -57,6 +67,21 @@ impl BlackBoxFunctionSolver for StubbedBlackBoxSolver { ) -> Result { Err(Self::fail(BlackBoxFunc::SchnorrVerify)) } + fn pedersen_commitment( + &self, + _inputs: &[F], + _domain_separator: u32, + ) -> Result<(F, F), BlackBoxResolutionError> { + Err(Self::fail(BlackBoxFunc::PedersenCommitment)) + } + fn pedersen_hash( + &self, + _inputs: &[F], + _domain_separator: u32, + ) -> Result { + Err(Self::fail(BlackBoxFunc::PedersenHash)) + } + fn multi_scalar_mul( &self, _points: &[F], diff --git a/acvm-repo/bn254_blackbox_solver/src/lib.rs b/acvm-repo/bn254_blackbox_solver/src/lib.rs index ec69c3797f6..6897116e90e 100644 --- a/acvm-repo/bn254_blackbox_solver/src/lib.rs +++ b/acvm-repo/bn254_blackbox_solver/src/lib.rs @@ -10,6 +10,7 @@ mod pedersen; mod poseidon2; mod schnorr; +use ark_ec::AffineRepr; pub use embedded_curve_ops::{embedded_curve_add, multi_scalar_mul}; pub use generator::generators::derive_generators; pub use poseidon2::poseidon2_permutation; @@ -40,6 +41,33 @@ impl BlackBoxFunctionSolver for Bn254BlackBoxSolver { )) } + fn pedersen_commitment( + &self, + inputs: &[FieldElement], + domain_separator: u32, + ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + let inputs: Vec = inputs.iter().map(|input| input.into_repr()).collect(); + let result = pedersen::commitment::commit_native_with_index(&inputs, domain_separator); + let result = if let Some((x, y)) = result.xy() { + (FieldElement::from_repr(*x), FieldElement::from_repr(*y)) + } else { + (FieldElement::from(0_u128), FieldElement::from(0_u128)) + }; + + Ok(result) + } + + fn pedersen_hash( + &self, + inputs: &[FieldElement], + domain_separator: u32, + ) -> Result { + let inputs: Vec = inputs.iter().map(|input| input.into_repr()).collect(); + let result = pedersen::hash::hash_with_index(&inputs, domain_separator); + let result = FieldElement::from_repr(result); + Ok(result) + } + fn multi_scalar_mul( &self, points: &[FieldElement], diff --git a/acvm-repo/brillig/src/black_box.rs b/acvm-repo/brillig/src/black_box.rs index 2b39e279aa8..60e4af11ea2 100644 --- a/acvm-repo/brillig/src/black_box.rs +++ b/acvm-repo/brillig/src/black_box.rs @@ -61,13 +61,13 @@ pub enum BlackBoxOp { signature: HeapVector, result: MemoryAddress, }, - /// Deprecated. To be removed with a sync from aztec-packages + /// Will be deprecated PedersenCommitment { inputs: HeapVector, domain_separator: MemoryAddress, output: HeapArray, }, - /// Deprecated. To be removed with a sync from aztec-packages + /// Will be deprecated PedersenHash { inputs: HeapVector, domain_separator: MemoryAddress, diff --git a/acvm-repo/brillig_vm/src/black_box.rs b/acvm-repo/brillig_vm/src/black_box.rs index 544963b00db..4e8bd8e3a16 100644 --- a/acvm-repo/brillig_vm/src/black_box.rs +++ b/acvm-repo/brillig_vm/src/black_box.rs @@ -232,6 +232,41 @@ pub(crate) fn evaluate_black_box ); Ok(()) } + BlackBoxOp::PedersenCommitment { inputs, domain_separator, output } => { + let inputs: Vec = read_heap_vector(memory, inputs) + .iter() + .map(|x| *x.extract_field().unwrap()) + .collect(); + let domain_separator: u32 = + memory.read(*domain_separator).try_into().map_err(|_| { + BlackBoxResolutionError::Failed( + BlackBoxFunc::PedersenCommitment, + "Invalid signature length".to_string(), + ) + })?; + let (x, y) = solver.pedersen_commitment(&inputs, domain_separator)?; + memory.write_slice( + memory.read_ref(output.pointer), + &[MemoryValue::new_field(x), MemoryValue::new_field(y)], + ); + Ok(()) + } + BlackBoxOp::PedersenHash { inputs, domain_separator, output } => { + let inputs: Vec = read_heap_vector(memory, inputs) + .iter() + .map(|x| *x.extract_field().unwrap()) + .collect(); + let domain_separator: u32 = + memory.read(*domain_separator).try_into().map_err(|_| { + BlackBoxResolutionError::Failed( + BlackBoxFunc::PedersenCommitment, + "Invalid signature length".to_string(), + ) + })?; + let hash = solver.pedersen_hash(&inputs, domain_separator)?; + memory.write(*output, MemoryValue::new_field(hash)); + Ok(()) + } BlackBoxOp::BigIntAdd { lhs, rhs, output } => { let lhs = memory.read(*lhs).try_into().unwrap(); let rhs = memory.read(*rhs).try_into().unwrap(); @@ -343,8 +378,6 @@ pub(crate) fn evaluate_black_box Ok(()) } - BlackBoxOp::PedersenCommitment { .. } => todo!("Deprecated Blackbox"), - BlackBoxOp::PedersenHash { .. } => todo!("Deprecated Blackbox"), } } 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 c62365162ba..367cdbe4973 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 @@ -137,6 +137,39 @@ pub(crate) fn convert_black_box_call( ) } } + + BlackBoxFunc::PedersenCommitment => { + if let ( + [message, BrilligVariable::SingleAddr(domain_separator)], + [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::PedersenCommitment { + inputs: message_vector.to_heap_vector(), + domain_separator: domain_separator.address, + output: result_array.to_heap_array(), + }); + } else { + unreachable!("ICE: Pedersen expects one array argument, a register for the domain separator, and one array result") + } + } + BlackBoxFunc::PedersenHash => { + if let ( + [message, BrilligVariable::SingleAddr(domain_separator)], + [BrilligVariable::SingleAddr(result)], + ) = (function_arguments, function_results) + { + let message_vector = convert_array_or_vector(brillig_context, message, bb_func); + brillig_context.black_box_op_instruction(BlackBoxOp::PedersenHash { + inputs: message_vector.to_heap_vector(), + domain_separator: domain_separator.address, + output: result.address, + }); + } else { + unreachable!("ICE: Pedersen hash expects one array argument, a register for the domain separator, and one register result") + } + } BlackBoxFunc::SchnorrVerify => { if let ( [BrilligVariable::SingleAddr(public_key_x), BrilligVariable::SingleAddr(public_key_y), BrilligVariable::BrilligArray(signature), message], @@ -391,8 +424,6 @@ pub(crate) fn convert_black_box_call( unreachable!("ICE: AES128Encrypt expects three array arguments, one array result") } } - BlackBoxFunc::PedersenCommitment => todo!("Deprecated Blackbox"), - BlackBoxFunc::PedersenHash => todo!("Deprecated Blackbox"), } } diff --git a/compiler/noirc_evaluator/src/brillig/brillig_ir.rs b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs index a0bf89fff0d..9785e073be9 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir.rs @@ -158,7 +158,20 @@ pub(crate) mod tests { ) -> Result { Ok(true) } - + fn pedersen_commitment( + &self, + _inputs: &[FieldElement], + _domain_separator: u32, + ) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> { + Ok((2_u128.into(), 3_u128.into())) + } + fn pedersen_hash( + &self, + _inputs: &[FieldElement], + _domain_separator: u32, + ) -> Result { + Ok(6_u128.into()) + } fn multi_scalar_mul( &self, _points: &[FieldElement], 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 a595584b376..b258905d657 100644 --- a/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs +++ b/compiler/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs @@ -347,6 +347,24 @@ impl DebugShow { result ); } + BlackBoxOp::PedersenCommitment { inputs, domain_separator, output } => { + debug_println!( + self.enable_debug_trace, + " PEDERSEN {} {} -> {}", + inputs, + domain_separator, + output + ); + } + BlackBoxOp::PedersenHash { inputs, domain_separator, output } => { + debug_println!( + self.enable_debug_trace, + " PEDERSEN_HASH {} {} -> {}", + inputs, + domain_separator, + output + ); + } BlackBoxOp::SchnorrVerify { public_key_x, public_key_y, @@ -444,8 +462,6 @@ impl DebugShow { output ); } - BlackBoxOp::PedersenCommitment { .. } => todo!("Deprecated Blackbox"), - BlackBoxOp::PedersenHash { .. } => todo!("Deprecated Blackbox"), } } diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs index e09f95508de..56b869fbf6b 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs @@ -1215,6 +1215,31 @@ impl AcirContext { ) -> Result, RuntimeError> { // Separate out any arguments that should be constants let (constant_inputs, constant_outputs) = match name { + BlackBoxFunc::PedersenCommitment | BlackBoxFunc::PedersenHash => { + // The last argument of pedersen is the domain separator, which must be a constant + let domain_var = match inputs.pop() { + Some(domain_var) => domain_var.into_var()?, + None => { + return Err(RuntimeError::InternalError(InternalError::MissingArg { + name: "pedersen call".to_string(), + arg: "domain separator".to_string(), + call_stack: self.get_call_stack(), + })) + } + }; + + let domain_constant = match self.vars[&domain_var].as_constant() { + Some(domain_constant) => domain_constant, + None => { + return Err(RuntimeError::InternalError(InternalError::NotAConstant { + name: "domain separator".to_string(), + call_stack: self.get_call_stack(), + })) + } + }; + + (vec![*domain_constant], Vec::new()) + } BlackBoxFunc::Poseidon2Permutation => { // The last argument is the state length, which must be a constant let state_len = match inputs.pop() { diff --git a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs index 6a1118de059..179958f305f 100644 --- a/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs +++ b/compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/generated_acir.rs @@ -224,6 +224,16 @@ impl GeneratedAcir { output: outputs[0], } } + BlackBoxFunc::PedersenCommitment => BlackBoxFuncCall::PedersenCommitment { + inputs: inputs[0].clone(), + outputs: (outputs[0], outputs[1]), + domain_separator: constant_inputs[0].to_u128() as u32, + }, + BlackBoxFunc::PedersenHash => BlackBoxFuncCall::PedersenHash { + inputs: inputs[0].clone(), + output: outputs[0], + domain_separator: constant_inputs[0].to_u128() as u32, + }, BlackBoxFunc::EcdsaSecp256k1 => { BlackBoxFuncCall::EcdsaSecp256k1 { // 32 bytes for each public key co-ordinate @@ -361,8 +371,6 @@ impl GeneratedAcir { .expect("Compiler should generate correct size inputs"), outputs: outputs.try_into().expect("Compiler should generate correct size outputs"), }, - BlackBoxFunc::PedersenCommitment => todo!("Deprecated Blackbox"), - BlackBoxFunc::PedersenHash => todo!("Deprecated Blackbox"), }; self.push_opcode(AcirOpcode::BlackBoxFuncCall(black_box_func_call)); @@ -641,7 +649,9 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { | BlackBoxFunc::Keccak256 | BlackBoxFunc::SHA256 | BlackBoxFunc::Blake2s - | BlackBoxFunc::Blake3 => None, + | BlackBoxFunc::Blake3 + | BlackBoxFunc::PedersenCommitment + | BlackBoxFunc::PedersenHash => None, BlackBoxFunc::Keccakf1600 => Some(25), // The permutation takes a fixed number of inputs, but the inputs length depends on the proving system implementation. @@ -677,8 +687,6 @@ fn black_box_func_expected_input_size(name: BlackBoxFunc) -> Option { // FromLeBytes takes a variable array of bytes as input BlackBoxFunc::BigIntFromLeBytes => None, - BlackBoxFunc::PedersenCommitment => todo!(), - BlackBoxFunc::PedersenHash => todo!(), } } @@ -702,6 +710,12 @@ fn black_box_expected_output_size(name: BlackBoxFunc) -> Option { BlackBoxFunc::Sha256Compression => Some(8), + // Pedersen commitment returns a point + BlackBoxFunc::PedersenCommitment => Some(2), + + // Pedersen hash returns a field + BlackBoxFunc::PedersenHash => Some(1), + // Can only apply a range constraint to one // witness at a time. BlackBoxFunc::RANGE => Some(0), @@ -730,8 +744,6 @@ fn black_box_expected_output_size(name: BlackBoxFunc) -> Option { // AES encryption returns a variable number of outputs BlackBoxFunc::AES128Encrypt => None, - BlackBoxFunc::PedersenCommitment => todo!(), - BlackBoxFunc::PedersenHash => todo!(), } } diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index a9e3570ba0f..e4635c0f974 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -446,7 +446,9 @@ fn simplify_black_box_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 => SimplifyResult::None, //TODO(Guillaume) + BlackBoxFunc::PedersenCommitment + | BlackBoxFunc::PedersenHash + | BlackBoxFunc::Keccakf1600 => SimplifyResult::None, //TODO(Guillaume) BlackBoxFunc::Keccak256 => { match (dfg.get_array_constant(arguments[0]), dfg.get_numeric_constant(arguments[1])) { (Some((input, _)), Some(num_bytes)) if array_is_constant(dfg, &input) => { @@ -501,8 +503,6 @@ fn simplify_black_box_func( } BlackBoxFunc::Sha256Compression => SimplifyResult::None, //TODO(Guillaume) BlackBoxFunc::AES128Encrypt => SimplifyResult::None, - BlackBoxFunc::PedersenCommitment => todo!("Deprecated Blackbox"), - BlackBoxFunc::PedersenHash => todo!("Deprecated Blackbox"), } } diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index b72c1ecba8f..86c0fed3c42 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -36,7 +36,7 @@ pub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint { } } -pub fn pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> EmbeddedCurvePoint { +pub fn pedersen_commitment_with_separator_noir(input: [Field; N], separator: u32) -> EmbeddedCurvePoint { let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N]; for i in 0..N { points[i] = EmbeddedCurveScalar::from_field(input[i]); @@ -46,6 +46,11 @@ pub fn pedersen_commitment_with_separator(input: [Field; N], separator: u32) EmbeddedCurvePoint { x: values[0], y: values[1], is_infinite: values[2] as bool } } +pub fn pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> EmbeddedCurvePoint { + let values = __pedersen_commitment_with_separator(input, separator); + EmbeddedCurvePoint { x: values[0], y: values[1], is_infinite: false } +} + // docs:start:pedersen_hash pub fn pedersen_hash(input: [Field; N]) -> Field // docs:end:pedersen_hash @@ -64,7 +69,7 @@ fn derive_generators(domain_separator_bytes: [u8; M], starting_index: u32) #[field(bn254)] fn __derive_generators(domain_separator_bytes: [u8; M], starting_index: u32) -> [EmbeddedCurvePoint; N] {} -pub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field { +pub fn pedersen_hash_with_separator_noir(input: [Field; N], separator: u32) -> Field { let v1 = pedersen_commitment(input); let length_generator :[EmbeddedCurvePoint;1] = derive_generators("pedersen_hash_length".as_bytes(), separator); multi_scalar_mul( @@ -73,6 +78,12 @@ pub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Fie )[0] } +#[foreign(pedersen_hash)] +pub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {} + +#[foreign(pedersen_commitment)] +pub fn __pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> [Field; 2] {} + pub fn hash_to_field(inputs: [Field]) -> Field { let mut sum = 0; @@ -246,3 +257,11 @@ impl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: self.4.hash(state); } } + +#[test] +fn assert_pedersen_noir() { + assert_eq(pedersen_hash_with_separator([1, 2, 3], 4), pedersen_hash_with_separator_noir([1, 2, 3], 4)); + assert_eq( + pedersen_commitment_with_separator([1, 2, 3], 4), pedersen_commitment_with_separator_noir([1, 2, 3], 4) + ); +} diff --git a/tooling/lsp/src/solver.rs b/tooling/lsp/src/solver.rs index 3c2d7499880..9d1185e3a79 100644 --- a/tooling/lsp/src/solver.rs +++ b/tooling/lsp/src/solver.rs @@ -16,6 +16,22 @@ impl BlackBoxFunctionSolver for WrapperSolver { self.0.schnorr_verify(public_key_x, public_key_y, signature, message) } + fn pedersen_commitment( + &self, + inputs: &[acvm::FieldElement], + domain_separator: u32, + ) -> Result<(acvm::FieldElement, acvm::FieldElement), acvm::BlackBoxResolutionError> { + self.0.pedersen_commitment(inputs, domain_separator) + } + + fn pedersen_hash( + &self, + inputs: &[acvm::FieldElement], + domain_separator: u32, + ) -> Result { + self.0.pedersen_hash(inputs, domain_separator) + } + fn multi_scalar_mul( &self, points: &[acvm::FieldElement], From 7867faa469ba222524b449e69446ff0999989d3a Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 24 Jun 2024 17:16:32 +0000 Subject: [PATCH 2/9] de-activate failing test --- noir_stdlib/src/hash.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index 86c0fed3c42..defe694e295 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -260,7 +260,7 @@ impl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: #[test] fn assert_pedersen_noir() { - assert_eq(pedersen_hash_with_separator([1, 2, 3], 4), pedersen_hash_with_separator_noir([1, 2, 3], 4)); + //TODO: assert_eq(pedersen_hash_with_separator([1, 2, 3], 4), pedersen_hash_with_separator_noir([1, 2, 3], 4)); assert_eq( pedersen_commitment_with_separator([1, 2, 3], 4), pedersen_commitment_with_separator_noir([1, 2, 3], 4) ); From 7b6e37d66b9ee28fa6853537270f3c82de72cfd6 Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 24 Jun 2024 17:28:23 +0000 Subject: [PATCH 3/9] Code review --- noir_stdlib/src/hash.nr | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index defe694e295..e08562c443e 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -36,7 +36,7 @@ pub fn pedersen_commitment(input: [Field; N]) -> EmbeddedCurvePoint { } } -pub fn pedersen_commitment_with_separator_noir(input: [Field; N], separator: u32) -> EmbeddedCurvePoint { +fn pedersen_commitment_with_separator_noir(input: [Field; N], separator: u32) -> EmbeddedCurvePoint { let mut points = [EmbeddedCurveScalar { lo: 0, hi: 0 }; N]; for i in 0..N { points[i] = EmbeddedCurveScalar::from_field(input[i]); @@ -69,9 +69,9 @@ fn derive_generators(domain_separator_bytes: [u8; M], starting_index: u32) #[field(bn254)] fn __derive_generators(domain_separator_bytes: [u8; M], starting_index: u32) -> [EmbeddedCurvePoint; N] {} -pub fn pedersen_hash_with_separator_noir(input: [Field; N], separator: u32) -> Field { - let v1 = pedersen_commitment(input); - let length_generator :[EmbeddedCurvePoint;1] = derive_generators("pedersen_hash_length".as_bytes(), separator); +fn pedersen_hash_with_separator_noir(input: [Field; N], separator: u32) -> Field { + let v1 = pedersen_commitment_with_separator(input, separator); + let length_generator : [EmbeddedCurvePoint; 1] = derive_generators("pedersen_hash_length".as_bytes(), 0); multi_scalar_mul( [length_generator[0], v1], [EmbeddedCurveScalar { lo: N as Field, hi: 0 }, EmbeddedCurveScalar { lo: 1, hi: 0 }] @@ -260,7 +260,7 @@ impl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: #[test] fn assert_pedersen_noir() { - //TODO: assert_eq(pedersen_hash_with_separator([1, 2, 3], 4), pedersen_hash_with_separator_noir([1, 2, 3], 4)); + assert_eq(pedersen_hash_with_separator([1, 2, 3], 4), pedersen_hash_with_separator_noir([1, 2, 3], 4)); assert_eq( pedersen_commitment_with_separator([1, 2, 3], 4), pedersen_commitment_with_separator_noir([1, 2, 3], 4) ); From e8ab0518c0c6f5d3f4fde0a962d1964f5f22c532 Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 24 Jun 2024 17:38:26 +0000 Subject: [PATCH 4/9] test for the fuzzer --- noir_stdlib/src/hash.nr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index e08562c443e..315ce5614ec 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -259,9 +259,9 @@ impl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: } #[test] -fn assert_pedersen_noir() { - assert_eq(pedersen_hash_with_separator([1, 2, 3], 4), pedersen_hash_with_separator_noir([1, 2, 3], 4)); +fn assert_pedersen_noir(input: [Field; 10], separator: u32) { + assert_eq(pedersen_hash_with_separator(input, separator), pedersen_hash_with_separator_noir(input, separator)); assert_eq( - pedersen_commitment_with_separator([1, 2, 3], 4), pedersen_commitment_with_separator_noir([1, 2, 3], 4) + pedersen_commitment_with_separator(input, separator), pedersen_commitment_with_separator_noir(input, separator) ); } From da28ac7502bd2028b6a85467e8da035be9570fac Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 24 Jun 2024 17:43:21 +0000 Subject: [PATCH 5/9] code review --- acvm-repo/brillig_vm/src/black_box.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acvm-repo/brillig_vm/src/black_box.rs b/acvm-repo/brillig_vm/src/black_box.rs index 4e8bd8e3a16..36d045efabf 100644 --- a/acvm-repo/brillig_vm/src/black_box.rs +++ b/acvm-repo/brillig_vm/src/black_box.rs @@ -241,7 +241,7 @@ pub(crate) fn evaluate_black_box memory.read(*domain_separator).try_into().map_err(|_| { BlackBoxResolutionError::Failed( BlackBoxFunc::PedersenCommitment, - "Invalid signature length".to_string(), + "Invalid separator length".to_string(), ) })?; let (x, y) = solver.pedersen_commitment(&inputs, domain_separator)?; @@ -260,7 +260,7 @@ pub(crate) fn evaluate_black_box memory.read(*domain_separator).try_into().map_err(|_| { BlackBoxResolutionError::Failed( BlackBoxFunc::PedersenCommitment, - "Invalid signature length".to_string(), + "Invalid separator length".to_string(), ) })?; let hash = solver.pedersen_hash(&inputs, domain_separator)?; From 458195bf92a61f46dc84db49d542558b093f589e Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 24 Jun 2024 17:54:54 +0000 Subject: [PATCH 6/9] use constant for separator --- noir_stdlib/src/hash.nr | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index 315ce5614ec..6caaa22d248 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -259,9 +259,9 @@ impl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: } #[test] -fn assert_pedersen_noir(input: [Field; 10], separator: u32) { - assert_eq(pedersen_hash_with_separator(input, separator), pedersen_hash_with_separator_noir(input, separator)); +fn assert_pedersen_noir(input: [Field; 10]) { + assert_eq(pedersen_hash_with_separator(input, 4), pedersen_hash_with_separator_noir(input, 4)); assert_eq( - pedersen_commitment_with_separator(input, separator), pedersen_commitment_with_separator_noir(input, separator) + pedersen_commitment_with_separator(input, 4), pedersen_commitment_with_separator_noir(input, 4) ); } From 614be5e6baae37df5d2ed0a99f0dab810f2ec8b6 Mon Sep 17 00:00:00 2001 From: guipublic Date: Mon, 24 Jun 2024 18:01:16 +0000 Subject: [PATCH 7/9] format --- noir_stdlib/src/hash.nr | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index 6caaa22d248..4a9e240331a 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -261,7 +261,5 @@ impl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: #[test] fn assert_pedersen_noir(input: [Field; 10]) { assert_eq(pedersen_hash_with_separator(input, 4), pedersen_hash_with_separator_noir(input, 4)); - assert_eq( - pedersen_commitment_with_separator(input, 4), pedersen_commitment_with_separator_noir(input, 4) - ); + assert_eq(pedersen_commitment_with_separator(input, 4), pedersen_commitment_with_separator_noir(input, 4)); } From 6fac1577fddb69919c6755d8433707a6fb60c96a Mon Sep 17 00:00:00 2001 From: Tom French Date: Mon, 24 Jun 2024 19:15:38 +0100 Subject: [PATCH 8/9] chore: fix stdlib test --- noir_stdlib/src/hash.nr | 4 +++- tooling/nargo_cli/tests/stdlib-tests.rs | 3 +-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index 4a9e240331a..6bff2fb4619 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -259,7 +259,9 @@ impl Hash for (A, B, C, D, E) where A: Hash, B: Hash, C: Hash, D: } #[test] -fn assert_pedersen_noir(input: [Field; 10]) { +fn assert_pedersen_noir() { + // TODO: make this a fuzzer test once fuzzer supports curve-specific blackbox functions. + let input = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; assert_eq(pedersen_hash_with_separator(input, 4), pedersen_hash_with_separator_noir(input, 4)); assert_eq(pedersen_commitment_with_separator(input, 4), pedersen_commitment_with_separator_noir(input, 4)); } diff --git a/tooling/nargo_cli/tests/stdlib-tests.rs b/tooling/nargo_cli/tests/stdlib-tests.rs index 5badd76605a..7fd396d6961 100644 --- a/tooling/nargo_cli/tests/stdlib-tests.rs +++ b/tooling/nargo_cli/tests/stdlib-tests.rs @@ -1,7 +1,6 @@ use std::io::Write; use std::{collections::BTreeMap, path::PathBuf}; -use acvm::blackbox_solver::StubbedBlackBoxSolver; use fm::FileManager; use noirc_driver::{check_crate, compile_no_check, file_manager_with_stdlib, CompileOptions}; use noirc_frontend::hir::FunctionNameMatch; @@ -56,7 +55,7 @@ fn run_stdlib_tests() { let status = if test_function_has_no_arguments { run_test( - &StubbedBlackBoxSolver, + &bn254_blackbox_solver::Bn254BlackBoxSolver, &mut context, &test_function, false, From 1bc521432830510dfe6cb6c9e51b255fd9b4be09 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 24 Jun 2024 19:29:17 +0100 Subject: [PATCH 9/9] Update noir_stdlib/src/hash.nr --- noir_stdlib/src/hash.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/noir_stdlib/src/hash.nr b/noir_stdlib/src/hash.nr index 6bff2fb4619..62b47b67241 100644 --- a/noir_stdlib/src/hash.nr +++ b/noir_stdlib/src/hash.nr @@ -82,7 +82,7 @@ fn pedersen_hash_with_separator_noir(input: [Field; N], separator: u32) -> Fi pub fn pedersen_hash_with_separator(input: [Field; N], separator: u32) -> Field {} #[foreign(pedersen_commitment)] -pub fn __pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> [Field; 2] {} +fn __pedersen_commitment_with_separator(input: [Field; N], separator: u32) -> [Field; 2] {} pub fn hash_to_field(inputs: [Field]) -> Field { let mut sum = 0;