Skip to content

Commit

Permalink
chore: add back Pedersen blackbox functions (revert PR 5221) (#5318)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

This PR adds (back) the blackbox functions for Pedersen hash/commitment,
until we get a similar circuit (in term of number of gates) with the
Noir implementation.

## Summary\*
The Noir version is kept and assert to ouput the same value in a test.


## Additional Context
This PR reverts the PR #5221


## Documentation\*

Check one:
- [X] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: Tom French <tom@tomfren.ch>
Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com>
  • Loading branch information
3 people authored Jun 24, 2024
1 parent b859ef9 commit f2f8ecc
Show file tree
Hide file tree
Showing 17 changed files with 309 additions and 39 deletions.
12 changes: 6 additions & 6 deletions acvm-repo/acir/src/circuit/black_box_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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",
}
}

Expand Down Expand Up @@ -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,
}
}
Expand Down
12 changes: 6 additions & 6 deletions acvm-repo/acir/src/circuit/opcodes/black_box_function_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ pub enum BlackBoxFuncCall {
message: Vec<FunctionInput>,
output: Witness,
},
/// Deprecated. To be removed with a sync from aztec-packages
/// Will be deprecated
PedersenCommitment {
inputs: Vec<FunctionInput>,
domain_separator: u32,
outputs: (Witness, Witness),
},
/// Deprecated. To be removed with a sync from aztec-packages
/// Will be deprecated
PedersenHash {
inputs: Vec<FunctionInput>,
domain_separator: u32,
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -318,8 +320,6 @@ impl BlackBoxFuncCall {
inputs.push(*key_hash);
inputs
}
BlackBoxFuncCall::PedersenCommitment { .. } => todo!(),
BlackBoxFuncCall::PedersenHash { .. } => todo!(),
}
}

Expand All @@ -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]
Expand All @@ -356,8 +358,6 @@ impl BlackBoxFuncCall {
vec![]
}
BlackBoxFuncCall::BigIntToLeBytes { outputs, .. } => outputs.to_vec(),
BlackBoxFuncCall::PedersenCommitment { .. } => todo!(),
BlackBoxFuncCall::PedersenHash { .. } => todo!(),
}
}
}
Expand Down
10 changes: 8 additions & 2 deletions acvm-repo/acvm/src/pwg/blackbox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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},
Expand Down Expand Up @@ -125,6 +127,12 @@ pub(crate) fn solve<F: AcirField>(
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,
Expand Down Expand Up @@ -179,7 +187,5 @@ pub(crate) fn solve<F: AcirField>(
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"),
}
}
47 changes: 47 additions & 0 deletions acvm-repo/acvm/src/pwg/blackbox/pedersen.rs
Original file line number Diff line number Diff line change
@@ -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<F: AcirField>(
backend: &impl BlackBoxFunctionSolver<F>,
initial_witness: &mut WitnessMap<F>,
inputs: &[FunctionInput],
domain_separator: u32,
outputs: (Witness, Witness),
) -> Result<(), OpcodeResolutionError<F>> {
let scalars: Result<Vec<_>, _> =
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<F: AcirField>(
backend: &impl BlackBoxFunctionSolver<F>,
initial_witness: &mut WitnessMap<F>,
inputs: &[FunctionInput],
domain_separator: u32,
output: Witness,
) -> Result<(), OpcodeResolutionError<F>> {
let scalars: Result<Vec<_>, _> =
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(())
}
25 changes: 25 additions & 0 deletions acvm-repo/blackbox_solver/src/curve_specific_solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ pub trait BlackBoxFunctionSolver<F> {
signature: &[u8; 64],
message: &[u8],
) -> Result<bool, BlackBoxResolutionError>;
fn pedersen_commitment(
&self,
inputs: &[F],
domain_separator: u32,
) -> Result<(F, F), BlackBoxResolutionError>;
fn pedersen_hash(
&self,
inputs: &[F],
domain_separator: u32,
) -> Result<F, BlackBoxResolutionError>;
fn multi_scalar_mul(
&self,
points: &[F],
Expand Down Expand Up @@ -57,6 +67,21 @@ impl<F> BlackBoxFunctionSolver<F> for StubbedBlackBoxSolver {
) -> Result<bool, BlackBoxResolutionError> {
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<F, BlackBoxResolutionError> {
Err(Self::fail(BlackBoxFunc::PedersenHash))
}

fn multi_scalar_mul(
&self,
_points: &[F],
Expand Down
28 changes: 28 additions & 0 deletions acvm-repo/bn254_blackbox_solver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -40,6 +41,33 @@ impl BlackBoxFunctionSolver<FieldElement> for Bn254BlackBoxSolver {
))
}

fn pedersen_commitment(
&self,
inputs: &[FieldElement],
domain_separator: u32,
) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> {
let inputs: Vec<grumpkin::Fq> = 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<FieldElement, BlackBoxResolutionError> {
let inputs: Vec<grumpkin::Fq> = 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],
Expand Down
4 changes: 2 additions & 2 deletions acvm-repo/brillig/src/black_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
37 changes: 35 additions & 2 deletions acvm-repo/brillig_vm/src/black_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,41 @@ pub(crate) fn evaluate_black_box<F: AcirField, Solver: BlackBoxFunctionSolver<F>
);
Ok(())
}
BlackBoxOp::PedersenCommitment { inputs, domain_separator, output } => {
let inputs: Vec<F> = 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 separator 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<F> = 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 separator 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();
Expand Down Expand Up @@ -343,8 +378,6 @@ pub(crate) fn evaluate_black_box<F: AcirField, Solver: BlackBoxFunctionSolver<F>

Ok(())
}
BlackBoxOp::PedersenCommitment { .. } => todo!("Deprecated Blackbox"),
BlackBoxOp::PedersenHash { .. } => todo!("Deprecated Blackbox"),
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,39 @@ pub(crate) fn convert_black_box_call<F: AcirField + DebugToString>(
)
}
}

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],
Expand Down Expand Up @@ -391,8 +424,6 @@ pub(crate) fn convert_black_box_call<F: AcirField + DebugToString>(
unreachable!("ICE: AES128Encrypt expects three array arguments, one array result")
}
}
BlackBoxFunc::PedersenCommitment => todo!("Deprecated Blackbox"),
BlackBoxFunc::PedersenHash => todo!("Deprecated Blackbox"),
}
}

Expand Down
15 changes: 14 additions & 1 deletion compiler/noirc_evaluator/src/brillig/brillig_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,20 @@ pub(crate) mod tests {
) -> Result<bool, BlackBoxResolutionError> {
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<FieldElement, BlackBoxResolutionError> {
Ok(6_u128.into())
}
fn multi_scalar_mul(
&self,
_points: &[FieldElement],
Expand Down
Loading

0 comments on commit f2f8ecc

Please sign in to comment.