Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add poseidon2 opcode implementation for acvm/brillig, and Noir #4398

Merged
merged 6 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 35 additions & 1 deletion acvm-repo/acvm/src/pwg/blackbox/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use acir::{
native_types::{Witness, WitnessMap},
BlackBoxFunc, FieldElement,
};
use acvm_blackbox_solver::{sha256compression, BlackBoxResolutionError};
use acvm_blackbox_solver::{sha256compression, BlackBoxFunctionSolver, BlackBoxResolutionError};

use crate::pwg::{insert_value, witness_to_value};
use crate::OpcodeResolutionError;
Expand Down Expand Up @@ -131,3 +131,37 @@ pub(crate) fn solve_sha_256_permutation_opcode(

Ok(())
}

pub(crate) fn solve_poseidon2_permutation_opcode(
backend: &impl BlackBoxFunctionSolver,
initial_witness: &mut WitnessMap,
inputs: &[FunctionInput],
outputs: &[Witness],
len: u32,
) -> Result<(), OpcodeResolutionError> {
if len as usize != inputs.len() {
return Err(OpcodeResolutionError::BlackBoxFunctionFailed(
acir::BlackBoxFunc::Poseidon2Permutation,
format!(
"the number of inputs does not match specified length. {} > {}",
inputs.len(),
len
),
));
}

// Read witness assignments
let mut state = Vec::new();
for input in inputs.iter() {
let witness_assignment = witness_to_value(initial_witness, input.witness)?;
state.push(*witness_assignment);
}

let state = backend.poseidon2_permutation(&state, len)?;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will state.len() != outputs.len() ever be false?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It must be the same, because the inputs and outputs represent the same state (respectively before/after applying the permutation).
However this equality is not enforced, apart from the fact that Noir will always create a valid opcode.
I will add a check.

// Write witness assignments
for (output_witness, value) in outputs.iter().zip(state.into_iter()) {
insert_value(output_witness, value, initial_witness)?;
}
Ok(())
}
8 changes: 6 additions & 2 deletions acvm-repo/acvm/src/pwg/blackbox/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
};
use acvm_blackbox_solver::{blake2s, blake3, keccak256, keccakf1600, sha256};

use self::{bigint::BigIntSolver, pedersen::pedersen_hash};
use self::{
bigint::BigIntSolver, hash::solve_poseidon2_permutation_opcode, pedersen::pedersen_hash,
};

use super::{insert_value, OpcodeNotSolvable, OpcodeResolutionError};
use crate::{pwg::witness_to_value, BlackBoxFunctionSolver};
Expand All @@ -25,7 +27,7 @@
use pedersen::pedersen;
use range::solve_range_opcode;
use signature::{
ecdsa::{secp256k1_prehashed, secp256r1_prehashed},

Check warning on line 30 in acvm-repo/acvm/src/pwg/blackbox/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (prehashed)

Check warning on line 30 in acvm-repo/acvm/src/pwg/blackbox/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (prehashed)
schnorr::schnorr_verify,
};

Expand Down Expand Up @@ -154,7 +156,7 @@
signature,
hashed_message: message,
output,
} => secp256k1_prehashed(

Check warning on line 159 in acvm-repo/acvm/src/pwg/blackbox/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (prehashed)
initial_witness,
public_key_x,
public_key_y,
Expand All @@ -168,7 +170,7 @@
signature,
hashed_message: message,
output,
} => secp256r1_prehashed(

Check warning on line 173 in acvm-repo/acvm/src/pwg/blackbox/mod.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (prehashed)
initial_witness,
public_key_x,
public_key_y,
Expand Down Expand Up @@ -204,7 +206,6 @@
BlackBoxFuncCall::BigIntToLeBytes { input, outputs } => {
bigint_solver.bigint_to_bytes(*input, outputs, initial_witness)
}
BlackBoxFuncCall::Poseidon2Permutation { .. } => todo!(),
BlackBoxFuncCall::Sha256Compression { inputs, hash_values, outputs } => {
solve_sha_256_permutation_opcode(
initial_witness,
Expand All @@ -214,5 +215,8 @@
bb_func.get_black_box_func(),
)
}
BlackBoxFuncCall::Poseidon2Permutation { inputs, outputs, len } => {
solve_poseidon2_permutation_opcode(backend, initial_witness, inputs, outputs, *len)
}
}
}
12 changes: 12 additions & 0 deletions acvm-repo/blackbox_solver/src/curve_specific_solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ pub trait BlackBoxFunctionSolver {
input2_x: &FieldElement,
input2_y: &FieldElement,
) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError>;
fn poseidon2_permutation(
&self,
_inputs: &[FieldElement],
_len: u32,
) -> Result<Vec<FieldElement>, BlackBoxResolutionError>;
}

pub struct StubbedBlackBoxSolver;
Expand Down Expand Up @@ -89,4 +94,11 @@ impl BlackBoxFunctionSolver for StubbedBlackBoxSolver {
) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> {
Err(Self::fail(BlackBoxFunc::EmbeddedCurveAdd))
}
fn poseidon2_permutation(
&self,
_inputs: &[FieldElement],
_len: u32,
) -> Result<Vec<FieldElement>, BlackBoxResolutionError> {
Err(Self::fail(BlackBoxFunc::Poseidon2Permutation))
}
}
1 change: 1 addition & 0 deletions acvm-repo/bn254_blackbox_solver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ repository.workspace = true
acir.workspace = true
acvm_blackbox_solver.workspace = true
thiserror.workspace = true
num-traits.workspace = true

rust-embed = { version = "6.6.0", features = [
"debug-embed",
Expand Down
11 changes: 11 additions & 0 deletions acvm-repo/bn254_blackbox_solver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ use acir::{BlackBoxFunc, FieldElement};
use acvm_blackbox_solver::{BlackBoxFunctionSolver, BlackBoxResolutionError};

mod fixed_base_scalar_mul;
mod poseidon2;
mod wasm;

pub use fixed_base_scalar_mul::{embedded_curve_add, fixed_base_scalar_mul};
use poseidon2::Poseidon2;
use wasm::Barretenberg;

use self::wasm::{Pedersen, SchnorrSig};
Expand Down Expand Up @@ -97,4 +99,13 @@ impl BlackBoxFunctionSolver for Bn254BlackBoxSolver {
) -> Result<(FieldElement, FieldElement), BlackBoxResolutionError> {
embedded_curve_add(*input1_x, *input1_y, *input2_x, *input2_y)
}

fn poseidon2_permutation(
&self,
inputs: &[FieldElement],
len: u32,
) -> Result<Vec<FieldElement>, BlackBoxResolutionError> {
let poseidon = Poseidon2::new();
poseidon.permutation(inputs, len)
}
}
Loading
Loading