Skip to content

Commit

Permalink
clean up; fix clippy
Browse files Browse the repository at this point in the history
  • Loading branch information
zhenfeizhang committed Jun 19, 2024
1 parent 2702817 commit 37cb42f
Show file tree
Hide file tree
Showing 9 changed files with 341 additions and 488 deletions.
71 changes: 9 additions & 62 deletions bi-kzg/src/bi_fft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ fn deep_swap_chunks<F: Clone + Copy>(a: &mut [&mut [F]], rk: usize, k: usize) {
let x = a[k].as_mut_ptr();
let y = a[rk].as_mut_ptr();
unsafe {
// is there a
for i in 0..a[k].len() {
std::ptr::swap(x.add(i), y.add(i));
}
Expand Down Expand Up @@ -129,15 +130,14 @@ pub fn best_fft_vec_in_place<F: PrimeField>(a: &mut [F], omega: F, log_n: u32, l
twiddle_chunk /= 2;
}
} else {
recursive_butterfly_arithmetic(&mut a_vec_ptrs, m, n, 1, &twiddles)
recursive_butterfly_arithmetic(&mut a_vec_ptrs, m, 1, &twiddles)
}
}

/// This perform recursive butterfly arithmetic
fn recursive_butterfly_arithmetic<F: PrimeField>(
a: &mut [&mut [F]],
m: usize,
n: usize,
twiddle_chunk: usize,
twiddles: &[F],
) {
Expand All @@ -154,8 +154,8 @@ fn recursive_butterfly_arithmetic<F: PrimeField>(
} else {
let (left, right) = a.split_at_mut(m / 2);
rayon::join(
|| recursive_butterfly_arithmetic(left, m / 2, n, twiddle_chunk * 2, twiddles),
|| recursive_butterfly_arithmetic(right, m / 2, n, twiddle_chunk * 2, twiddles),
|| recursive_butterfly_arithmetic(left, m / 2, twiddle_chunk * 2, twiddles),
|| recursive_butterfly_arithmetic(right, m / 2, twiddle_chunk * 2, twiddles),
);

// case when twiddle factor is one
Expand Down Expand Up @@ -188,6 +188,7 @@ fn recursive_butterfly_arithmetic<F: PrimeField>(
}
}

/// Convert a polynomial in coefficient form to evaluation form using a two layer FFT
pub(crate) fn bi_fft_in_place<F: PrimeField>(coeffs: &mut [F], degree_n: usize, degree_m: usize) {
assert_eq!(coeffs.len(), degree_n * degree_m);
assert!(degree_n.is_power_of_two());
Expand All @@ -196,71 +197,17 @@ pub(crate) fn bi_fft_in_place<F: PrimeField>(coeffs: &mut [F], degree_n: usize,
// roots of unity for supported_n and supported_m
let (omega_0, omega_1) = {
let omega = F::ROOT_OF_UNITY;
let omega_0 = omega.pow_vartime(&[(1 << F::S) / degree_n as u64]);
let omega_1 = omega.pow_vartime(&[(1 << F::S) / degree_m as u64]);
let omega_0 = omega.pow_vartime([(1 << F::S) / degree_n as u64]);
let omega_1 = omega.pow_vartime([(1 << F::S) / degree_m as u64]);

(omega_0, omega_1)
};

// inner layer of FFT over variable x
coeffs
.chunks_exact_mut(degree_n)
.for_each(|chunk| best_fft(chunk, omega_0, log2(degree_n)));

// outer layer of FFT over variable y
best_fft_vec_in_place(coeffs, omega_1, log2(degree_n), log2(degree_m));
}

#[cfg(test)]
mod tests {
use ark_std::test_rng;
use halo2curves::bn256::Fr;

use crate::BivariatePolynomial;

use super::bi_fft_in_place;

#[test]
fn test_bi_fft() {
{
let n = 4;
let m = 4;
let poly = BivariatePolynomial::new(
vec![
Fr::from(1u64),
Fr::from(2u64),
Fr::from(4u64),
Fr::from(8u64),
Fr::from(16u64),
Fr::from(32u64),
Fr::from(64u64),
Fr::from(128u64),
Fr::from(256u64),
Fr::from(128u64),
Fr::from(64u64),
Fr::from(32u64),
Fr::from(16u64),
Fr::from(8u64),
Fr::from(4u64),
Fr::from(2u64),
],
n,
m,
);
let mut poly_lag2 = poly.coefficients.clone();
let poly_lag = poly.interpolate();
bi_fft_in_place(&mut poly_lag2, n, m);
assert_eq!(poly_lag, poly_lag2);
}

let mut rng = test_rng();

for m in [2, 4, 8, 16, 32, 64].iter() {
for n in [2, 4, 8, 16, 32, 64].iter() {
let poly = BivariatePolynomial::<Fr>::random(&mut rng, *n, *m);
let mut poly_lag2 = poly.coefficients.clone();
let poly_lag = poly.evaluate_at_roots();
bi_fft_in_place(&mut poly_lag2, *n, *m);
assert_eq!(poly_lag, poly_lag2);
}
}
}
}
49 changes: 9 additions & 40 deletions bi-kzg/src/coeff_form_bi_kzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,36 +47,30 @@ where
supported_n: usize,
supported_m: usize,
) -> Self::SRS {
// LagrangeFormBiKZG::<E>::gen_srs_for_testing(rng, supported_n, supported_m)

assert!(supported_n.is_power_of_two());
assert!(supported_m.is_power_of_two());

let tau_0 = E::Fr::random(&mut rng);
let tau_1 = E::Fr::random(&mut rng);
// let tau_0 = E::Fr::from(5);
// let tau_1 = E::Fr::from(7);

let g1 = E::G1Affine::generator();

// roots of unity for supported_n and supported_m
let (omega_0, omega_1) = {
let omega = E::Fr::ROOT_OF_UNITY;
let omega_0 = omega.pow_vartime(&[(1 << E::Fr::S) / supported_n as u64]);
let omega_1 = omega.pow_vartime(&[(1 << E::Fr::S) / supported_m as u64]);
let omega_0 = omega.pow_vartime([(1 << E::Fr::S) / supported_n as u64]);
let omega_1 = omega.pow_vartime([(1 << E::Fr::S) / supported_m as u64]);

assert!(
omega_0.pow_vartime(&[supported_n as u64]) == E::Fr::ONE,
omega_0.pow_vartime([supported_n as u64]) == E::Fr::ONE,
"omega_0 is not root of unity for supported_n"
);
assert!(
omega_1.pow_vartime(&[supported_m as u64]) == E::Fr::ONE,
omega_1.pow_vartime([supported_m as u64]) == E::Fr::ONE,
"omega_1 is not root of unity for supported_m"
);
(omega_0, omega_1)
};

// println!("start to compute the scalars");
// computes the vector of L_i^N(tau_0) * L_j^M(tau_1) for i in 0..supported_n and j in 0..supported_m
let (scalars, lagrange_scalars) = {
let powers_of_omega_0 = powers_of_field_elements(&omega_0, supported_n);
Expand All @@ -91,7 +85,6 @@ where
(scalars, lagrange_scalars)
};

// println!("start to compute the affine bases");
let g1_prog = g1.to_curve();
let coeff_bases = {
let mut proj_bases = vec![E::G1::identity(); supported_n * supported_m];
Expand All @@ -110,8 +103,6 @@ where
g_bases
};

// println!("start to compute the lagrange bases");

let lagrange_bases = {
let mut proj_bases = vec![E::G1::identity(); supported_n * supported_m];
parallelize(&mut proj_bases, |g, start| {
Expand All @@ -132,8 +123,6 @@ where
affine_bases
};

// assert_eq!(coeff_bases[..supported_n], f_x_b_scalars);

BiKZGSRS {
powers_of_g: coeff_bases,
powers_of_g_lagrange_over_both_roots: lagrange_bases,
Expand Down Expand Up @@ -189,7 +178,7 @@ where
let timer2 = start_timer!(|| "Computing the proof pi0");
let (pi_0, f_x_b) = {
// t = f(x, b) - f(a, b)
let f_x_b = polynomial.evaluate_y(&point.1);
let f_x_b = polynomial.evaluate_at_y(&point.1);
let mut t = f_x_b.clone();
t[0] -= u;
// q_0(x, b) = t(x) / (x - a)
Expand Down Expand Up @@ -274,14 +263,10 @@ where
where
E: MultiMillerLoop,
{
let timers = start_timer!(|| "Verifying the proof");
let pi0_a_pi1_b_g1_cmu = best_multiexp(
&[point.0, point.1, E::Fr::ONE, -*value],
&[
proof.pi0,
proof.pi1,
commitment.com.into(),
verifier_param.g.into(),
],
&[proof.pi0, proof.pi1, commitment.com, verifier_param.g],
);
let pi0_a_pi1_b_g1_cmu = (-pi0_a_pi1_b_g1_cmu).to_affine();
let res = E::multi_miller_loop(&[
Expand All @@ -290,25 +275,9 @@ where
(&pi0_a_pi1_b_g1_cmu, &verifier_param.h.into()),
]);
let res = res.final_exponentiation().is_identity().into();

end_timer!(timers);
res
}

fn multi_open(
_prover_param: impl Borrow<Self::ProverParam>,
_polynomials: &[Self::Polynomial],
_points: &[Self::Point],
_evals: &[Self::Evaluation],
) -> Self::BatchProof {
unimplemented!()
}

fn batch_verify(
_verifier_param: &Self::VerifierParam,
_commitments: &[Self::Commitment],
_points: &[Self::Point],
_batch_proof: &Self::BatchProof,
) -> bool {
unimplemented!()
}
// TODO: implement multi-opening and batch verification
}
21 changes: 4 additions & 17 deletions bi-kzg/src/lagrange_form_bi_kzg.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! We don't need this file for now. We will use the `CoeffFormBiKZG`.

use std::{borrow::Borrow, marker::PhantomData};

use ark_std::{end_timer, start_timer};
Expand Down Expand Up @@ -276,21 +278,6 @@ where
res
}

fn multi_open(
_prover_param: impl Borrow<Self::ProverParam>,
_polynomials: &[Self::Polynomial],
_points: &[Self::Point],
_evals: &[Self::Evaluation],
) -> Self::BatchProof {
unimplemented!()
}

fn batch_verify(
_verifier_param: &Self::VerifierParam,
_commitments: &[Self::Commitment],
_points: &[Self::Point],
_batch_proof: &Self::BatchProof,
) -> bool {
unimplemented!()
}

// TODO: implement multi-opening and batch verification
}
6 changes: 4 additions & 2 deletions bi-kzg/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
mod bi_fft;
mod coeff_form_bi_kzg;
// mod lagrange_form_bi_kzg;
mod pcs;
mod poly;
mod structs;
mod util;

// mod lagrange_form_bi_kzg;

#[cfg(test)]
mod tests;

pub use coeff_form_bi_kzg::CoeffFormBiKZG;
// pub use lagrange_form_bi_kzg::LagrangeFormBiKZG;
pub use pcs::PolynomialCommitmentScheme;
pub use structs::BivariatePolynomial;
pub use structs::{BiKZGCommitment, BiKZGProof, BiKZGSRS, BiKZGVerifierParam};

// pub use lagrange_form_bi_kzg::LagrangeFormBiKZG;
27 changes: 4 additions & 23 deletions bi-kzg/src/pcs.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{borrow::Borrow, fmt::Debug};

use halo2curves::{ff::Field, serde::SerdeObject};
use halo2curves::ff::Field;
use rand::RngCore;

/// This trait defines APIs for polynomial commitment schemes.
Expand All @@ -21,9 +21,9 @@ pub trait PolynomialCommitmentScheme {
/// Polynomial Evaluation
type Evaluation: Field;
/// Commitments
type Commitment: Clone + SerdeObject + Debug;
type Commitment: Clone + Debug;
/// Proofs
type Proof: Clone + SerdeObject + Debug;
type Proof: Clone + Debug;
/// Batch proofs
type BatchProof;

Expand All @@ -34,22 +34,6 @@ pub trait PolynomialCommitmentScheme {
/// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION.
fn gen_srs_for_testing(rng: impl RngCore, supported_n: usize, supported_m: usize) -> Self::SRS;

// /// Trim the universal parameters to specialize the public parameters.
// /// Input both `supported_degree` for univariate and
// /// `supported_num_vars` for multilinear.
// /// ## Note on function signature
// /// Usually, data structure like SRS and ProverParam are huge and users
// /// might wish to keep them in heap using different kinds of smart pointers
// /// (instead of only in stack) therefore our `impl Borrow<_>` interface
// /// allows for passing in any pointer type, e.g.: `trim(srs: &Self::SRS,
// /// ..)` or `trim(srs: Box<Self::SRS>, ..)` or `trim(srs: Arc<Self::SRS>,
// /// ..)` etc.
// fn trim(
// srs: impl Borrow<Self::SRS>,
// supported_degree: Option<usize>,
// supported_num_vars: Option<usize>,
// ) -> (Self::ProverParam, Self::VerifierParam);

/// Generate a commitment for a polynomial
/// ## Note on function signature
/// Usually, data structure like SRS and ProverParam are huge and users
Expand All @@ -72,14 +56,12 @@ pub trait PolynomialCommitmentScheme {
point: &Self::Point,
) -> (Self::Proof, Self::Evaluation);

/// Input a list of multilinear extensions, and a same number of points, and
/// a transcript, compute a multi-opening for all the polynomials.
/// Input a list of polynomials, and a same number of points, compute a multi-opening for all the polynomials.
fn multi_open(
_prover_param: impl Borrow<Self::ProverParam>,
_polynomials: &[Self::Polynomial],
_points: &[Self::Point],
_evals: &[Self::Evaluation],
// _transcript: &mut IOPTranscript<E::ScalarField>,
) -> Self::BatchProof {
// the reason we use unimplemented!() is to enable developers to implement the
// trait without always implementing the batching APIs.
Expand All @@ -103,7 +85,6 @@ pub trait PolynomialCommitmentScheme {
_commitments: &[Self::Commitment],
_points: &[Self::Point],
_batch_proof: &Self::BatchProof,
// _transcript: &mut IOPTranscript<E::ScalarField>,
) -> bool {
// the reason we use unimplemented!() is to enable developers to implement the
// trait without always implementing the batching APIs.
Expand Down
Loading

0 comments on commit 37cb42f

Please sign in to comment.