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

chore: Bump arkworks to version 0.5.0 #6871

Merged
merged 6 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
395 changes: 110 additions & 285 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,16 @@ bb_abstraction_leaks = { path = "tooling/bb_abstraction_leaks" }
acvm_cli = { path = "tooling/acvm_cli" }

# Arkworks
ark-bn254 = { version = "^0.4.0", default-features = false, features = [
ark-bn254 = { version = "^0.5.0", default-features = false, features = [
"curve",
] }
ark-bls12-381 = { version = "^0.4.0", default-features = false, features = [
ark-bls12-381 = { version = "^0.5.0", default-features = false, features = [
"curve",
] }
grumpkin = { version = "0.1.0", package = "noir_grumpkin", features = ["std"] }
ark-ec = { version = "^0.4.0", default-features = false }
ark-ff = { version = "^0.4.0", default-features = false }
ark-std = { version = "^0.4.0", default-features = false }
ark-grumpkin = { version = "^0.5.0", default-features = false }
ark-ec = { version = "^0.5.0", default-features = false }
ark-ff = { version = "^0.5.0", default-features = false }
ark-std = { version = "^0.5.0", default-features = false }

# Misc utils crates
iter-extended = { path = "utils/iter-extended" }
Expand Down
4 changes: 2 additions & 2 deletions acvm-repo/acvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ bls12_381 = [
]

[dev-dependencies]
ark-bls12-381 = { version = "^0.4.0", default-features = false, features = [
ark-bls12-381 = { version = "^0.5.0", default-features = false, features = [
"curve",
] }
ark-ff.workspace = true
ark-bn254.workspace = true
bn254_blackbox_solver.workspace = true
proptest.workspace = true
zkhash = { version = "^0.2.0", default-features = false }
num-bigint.workspace = true
278 changes: 267 additions & 11 deletions acvm-repo/acvm/tests/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use proptest::arbitrary::any;
use proptest::prelude::*;
use proptest::result::maybe_ok;
use proptest::sample::select;
use zkhash::poseidon2::poseidon2_params::Poseidon2Params;

#[test]
fn bls12_381_circuit() {
Expand Down Expand Up @@ -1210,6 +1209,264 @@ where
fields.into_iter().map(|field| into_repr_vec(field)).collect()
}

// From https://docs.rs/crate/zkhash/0.2.0/source/ .
// The original code depends on `ark_ff` v0.4.0, but here we use v0.5.0.
mod zkhash {
TomAFrench marked this conversation as resolved.
Show resolved Hide resolved
use ark_ff::PrimeField;
use std::sync::Arc;

#[derive(Clone, Debug)]
pub struct Poseidon2Params<F: PrimeField> {
pub(crate) t: usize, // statesize
pub(crate) d: usize, // sbox degree
pub(crate) rounds_f_beginning: usize,
pub(crate) rounds_p: usize,
#[allow(dead_code)]
pub(crate) rounds_f_end: usize,
pub(crate) rounds: usize,
pub(crate) mat_internal_diag_m_1: Vec<F>,
pub(crate) _mat_internal: Vec<Vec<F>>,
pub(crate) round_constants: Vec<Vec<F>>,
}

impl<F: PrimeField> Poseidon2Params<F> {
#[allow(clippy::too_many_arguments)]
pub fn new(
t: usize,
d: usize,
rounds_f: usize,
rounds_p: usize,
mat_internal_diag_m_1: &[F],
mat_internal: &[Vec<F>],
round_constants: &[Vec<F>],
) -> Self {
assert!(d == 3 || d == 5 || d == 7 || d == 11);
assert_eq!(rounds_f % 2, 0);
let r = rounds_f / 2;
let rounds = rounds_f + rounds_p;

Poseidon2Params {
t,
d,
rounds_f_beginning: r,
rounds_p,
rounds_f_end: r,
rounds,
mat_internal_diag_m_1: mat_internal_diag_m_1.to_owned(),
_mat_internal: mat_internal.to_owned(),
round_constants: round_constants.to_owned(),
}
}
}

#[derive(Clone, Debug)]
pub struct Poseidon2<F: PrimeField> {
pub(crate) params: Arc<Poseidon2Params<F>>,
}

impl<F: PrimeField> Poseidon2<F> {
pub fn new(params: &Arc<Poseidon2Params<F>>) -> Self {
Poseidon2 { params: Arc::clone(params) }
}

pub fn permutation(&self, input: &[F]) -> Vec<F> {
let t = self.params.t;
assert_eq!(input.len(), t);

let mut current_state = input.to_owned();

// Linear layer at beginning
self.matmul_external(&mut current_state);

for r in 0..self.params.rounds_f_beginning {
current_state = self.add_rc(&current_state, &self.params.round_constants[r]);
current_state = self.sbox(&current_state);
self.matmul_external(&mut current_state);
}

let p_end = self.params.rounds_f_beginning + self.params.rounds_p;
for r in self.params.rounds_f_beginning..p_end {
current_state[0].add_assign(&self.params.round_constants[r][0]);
current_state[0] = self.sbox_p(&current_state[0]);
self.matmul_internal(&mut current_state, &self.params.mat_internal_diag_m_1);
}

for r in p_end..self.params.rounds {
current_state = self.add_rc(&current_state, &self.params.round_constants[r]);
current_state = self.sbox(&current_state);
self.matmul_external(&mut current_state);
}
current_state
}

fn sbox(&self, input: &[F]) -> Vec<F> {
input.iter().map(|el| self.sbox_p(el)).collect()
}

fn sbox_p(&self, input: &F) -> F {
let mut input2 = *input;
input2.square_in_place();

match self.params.d {
3 => {
let mut out = input2;
out.mul_assign(input);
out
}
5 => {
let mut out = input2;
out.square_in_place();
out.mul_assign(input);
out
}
7 => {
let mut out = input2;
out.square_in_place();
out.mul_assign(&input2);
out.mul_assign(input);
out
}
_ => {
panic!()
}
}
}

fn matmul_m4(&self, input: &mut [F]) {
let t = self.params.t;
let t4 = t / 4;
for i in 0..t4 {
let start_index = i * 4;
let mut t_0 = input[start_index];
t_0.add_assign(&input[start_index + 1]);
let mut t_1 = input[start_index + 2];
t_1.add_assign(&input[start_index + 3]);
let mut t_2 = input[start_index + 1];
t_2.double_in_place();
t_2.add_assign(&t_1);
let mut t_3 = input[start_index + 3];
t_3.double_in_place();
t_3.add_assign(&t_0);
let mut t_4 = t_1;
t_4.double_in_place();
t_4.double_in_place();
t_4.add_assign(&t_3);
let mut t_5 = t_0;
t_5.double_in_place();
t_5.double_in_place();
t_5.add_assign(&t_2);
let mut t_6 = t_3;
t_6.add_assign(&t_5);
let mut t_7 = t_2;
t_7.add_assign(&t_4);
input[start_index] = t_6;
input[start_index + 1] = t_5;
input[start_index + 2] = t_7;
input[start_index + 3] = t_4;
}
}

fn matmul_external(&self, input: &mut [F]) {
let t = self.params.t;
match t {
2 => {
// Matrix circ(2, 1)
let mut sum = input[0];
sum.add_assign(&input[1]);
input[0].add_assign(&sum);
input[1].add_assign(&sum);
}
3 => {
// Matrix circ(2, 1, 1)
let mut sum = input[0];
sum.add_assign(&input[1]);
sum.add_assign(&input[2]);
input[0].add_assign(&sum);
input[1].add_assign(&sum);
input[2].add_assign(&sum);
}
4 => {
// Applying cheap 4x4 MDS matrix to each 4-element part of the state
self.matmul_m4(input);
}
8 | 12 | 16 | 20 | 24 => {
// Applying cheap 4x4 MDS matrix to each 4-element part of the state
self.matmul_m4(input);

// Applying second cheap matrix for t > 4
let t4 = t / 4;
let mut stored = [F::zero(); 4];
for l in 0..4 {
stored[l] = input[l];
for j in 1..t4 {
stored[l].add_assign(&input[4 * j + l]);
}
}
for i in 0..input.len() {
input[i].add_assign(&stored[i % 4]);
}
}
_ => {
panic!()
}
}
}

fn matmul_internal(&self, input: &mut [F], mat_internal_diag_m_1: &[F]) {
let t = self.params.t;

match t {
2 => {
// [2, 1]
// [1, 3]
let mut sum = input[0];
sum.add_assign(&input[1]);
input[0].add_assign(&sum);
input[1].double_in_place();
input[1].add_assign(&sum);
}
3 => {
// [2, 1, 1]
// [1, 2, 1]
// [1, 1, 3]
let mut sum = input[0];
sum.add_assign(&input[1]);
sum.add_assign(&input[2]);
input[0].add_assign(&sum);
input[1].add_assign(&sum);
input[2].double_in_place();
input[2].add_assign(&sum);
}
4 | 8 | 12 | 16 | 20 | 24 => {
// Compute input sum
let mut sum = input[0];
input.iter().skip(1).take(t - 1).for_each(|el| sum.add_assign(el));
// Add sum + diag entry * element to each element
for i in 0..input.len() {
input[i].mul_assign(&mat_internal_diag_m_1[i]);
input[i].add_assign(&sum);
}
}
_ => {
panic!()
}
}
}

fn add_rc(&self, input: &[F], rc: &[F]) -> Vec<F> {
input
.iter()
.zip(rc.iter())
.map(|(a, b)| {
let mut r = *a;
r.add_assign(b);
r
})
.collect()
}
}
}

fn run_both_poseidon2_permutations(
inputs: Vec<ConstantOrWitness>,
) -> Result<(Vec<ark_bn254::Fr>, Vec<ark_bn254::Fr>), OpcodeResolutionError<FieldElement>> {
Expand All @@ -1228,16 +1485,15 @@ fn run_both_poseidon2_permutations(
let mat_internal = vec![];
let round_constants = into_repr_mat(POSEIDON2_CONFIG.round_constant);

let external_poseidon2 =
zkhash::poseidon2::poseidon2::Poseidon2::new(&Arc::new(Poseidon2Params::new(
poseidon2_t,
poseidon2_d,
rounds_f,
rounds_p,
&mat_internal_diag_m_1,
&mat_internal,
&round_constants,
)));
let external_poseidon2 = zkhash::Poseidon2::new(&Arc::new(zkhash::Poseidon2Params::new(
poseidon2_t,
poseidon2_d,
rounds_f,
rounds_p,
&mat_internal_diag_m_1,
&mat_internal,
&round_constants,
)));

let expected_result =
external_poseidon2.permutation(&into_repr_vec(drop_use_constant(&inputs)));
Expand Down
2 changes: 1 addition & 1 deletion acvm-repo/bn254_blackbox_solver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ hex.workspace = true
lazy_static.workspace = true

ark-bn254.workspace = true
grumpkin.workspace = true
ark-grumpkin.workspace = true
ark-ec.workspace = true
ark-ff.workspace = true
num-bigint.workspace = true
Expand Down
Loading
Loading