Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
zhenfeizhang committed Jun 13, 2024
1 parent f0650e9 commit d15058a
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 116 deletions.
33 changes: 22 additions & 11 deletions bi-kzg/src/bi_kzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use rand::Rng;
use rand::RngCore;

use crate::msm::best_multiexp;
use crate::structs::BivaraitePolynomial;
use crate::util::lagrange_coefficients;
use crate::poly::lagrange_coefficients;
use crate::structs::BivariatePolynomial;
use crate::util::parallelize;
use crate::{
pcs::PolynomialCommitmentScheme,
Expand All @@ -26,7 +26,7 @@ use crate::{
};

pub struct BiKZG<E: MultiMillerLoop> {
_MultiMillerLoop: PhantomData<E>,
_phantom: PhantomData<E>,
}

impl<E: MultiMillerLoop> PolynomialCommitmentScheme for BiKZG<E>
Expand All @@ -36,7 +36,7 @@ where
type SRS = BiKZGSRS<E>;
type ProverParam = BiKZGSRS<E>;
type VerifierParam = BiKZGVerifierParam<E>;
type Polynomial = BivaraitePolynomial<E::Fr>;
type Polynomial = BivariatePolynomial<E::Fr>;
type Commitment = BiKZGCommitment<E>;
type Proof = BiKZGProof<E>;
type Evaluation = E::Fr;
Expand Down Expand Up @@ -64,6 +64,9 @@ where
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]);

println!("omega 0: {:?}", omega_0);
println!("omega 1: {:?}", omega_1);

assert!(
omega_0.pow_vartime(&[supported_n as u64]) == E::Fr::ONE,
"omega_0 is not root of unity for supported_n"
Expand Down Expand Up @@ -101,18 +104,15 @@ where

let mut g_bases = vec![E::G1Affine::identity(); supported_n * supported_m];
parallelize(&mut g_bases, |g, starts| {
E::G1::batch_normalize(
&proj_bases[starts..(starts + g.len())],
g,
);
E::G1::batch_normalize(&proj_bases[starts..(starts + g.len())], g);
});
drop(proj_bases);
g_bases
};


println!("start to compute the lagrange bases");
let largrange_bases = {
println!("lagrange scalars: {:?} ", lagrange_scalars);
let lagrange_bases = {
let mut proj_bases = vec![E::G1::identity(); supported_n * supported_m];
parallelize(&mut proj_bases, |g, start| {
for (idx, g) in g.iter_mut().enumerate() {
Expand All @@ -136,7 +136,7 @@ where
tau_0,
tau_1,
powers_of_g: coeff_bases,
powers_of_g_largrange: largrange_bases,
powers_of_g_lagrange: lagrange_bases,
h: E::G2Affine::generator(),
tau_0_h: (E::G2Affine::generator() * tau_0).into(),
tau_1_h: (E::G2Affine::generator() * tau_1).into(),
Expand Down Expand Up @@ -169,6 +169,17 @@ where
"commitment is not equal to evaluation"
);

let lag_coeff = poly.lagrange_coeffs();
let com_lag = best_multiexp(
&lag_coeff,
prover_param.borrow().powers_of_g_lagrange.as_slice(),
)
.into();
assert_eq!(
com, com_lag,
"commitment is not equal to lagrange commitment"
);

Self::Commitment { com }
}

Expand Down
3 changes: 2 additions & 1 deletion bi-kzg/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ mod structs;
mod tests;
mod util;

pub use structs::BivaraitePolynomial;
pub use pcs::PolynomialCommitmentScheme;
pub use structs::BivariatePolynomial;
pub use structs::{BiKZGCommitment, BiKZGProof, BiKZGSRS, BiKZGVerifierParam};
39 changes: 0 additions & 39 deletions bi-kzg/src/pcs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@ pub trait PolynomialCommitmentScheme {

/// Build SRS for testing.
///
/// - For univariate polynomials, `supported_size` is the maximum degree.
/// - For multilinear polynomials, `supported_size` is the number of
/// variables.
///
/// WARNING: THIS FUNCTION IS FOR TESTING PURPOSE ONLY.
/// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION.
Expand Down Expand Up @@ -113,39 +110,3 @@ pub trait PolynomialCommitmentScheme {
unimplemented!()
}
}

// /// API definitions for structured reference string
// ///
// /// Credit: https://github.com/EspressoSystems/hyperplonk/blob/8698369edfe82bd6617a9609602380f21cabd1da/subroutines/src/pcs/mod.rs#L135
// pub trait StructuredReferenceString<E: Engine>: Sized {
// /// Prover parameters
// type ProverParam;
// /// Verifier parameters
// type VerifierParam;

// /// Extract the prover parameters from the public parameters.
// fn extract_prover_param(&self, supported_size: usize) -> Self::ProverParam;
// /// Extract the verifier parameters from the public parameters.
// fn extract_verifier_param(&self, supported_size: usize) -> Self::VerifierParam;

// /// Trim the universal parameters to specialize the public parameters
// /// for polynomials to the given `supported_size`, and
// /// returns committer key and verifier key.
// ///
// /// - For univariate polynomials, `supported_size` is the maximum degree.
// /// - For multilinear polynomials, `supported_size` is 2 to the number of
// /// variables.
// ///
// /// `supported_log_size` should be in range `1..=params.log_size`
// fn trim(&self, supported_size: usize) -> (Self::ProverParam, Self::VerifierParam);

// /// Build SRS for testing.
// ///
// /// - For univariate polynomials, `supported_size` is the maximum degree.
// /// - For multilinear polynomials, `supported_size` is the number of
// /// variables.
// ///
// /// WARNING: THIS FUNCTION IS FOR TESTING PURPOSE ONLY.
// /// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION.
// fn gen_srs_for_testing<R: Rng>(rng: &mut R, supported_size: usize) -> Self;
// }
132 changes: 124 additions & 8 deletions bi-kzg/src/poly.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use halo2curves::ff::Field;
use halo2curves::ff::{Field, PrimeField};
use rand::RngCore;
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};

use crate::structs::BivaraitePolynomial;
use crate::structs::{BivariateLagrangePolynomial, BivariatePolynomial};
use crate::util::powers_of_field_elements;

impl<F: Field> BivaraitePolynomial<F> {
impl<F: PrimeField> BivariatePolynomial<F> {
#[inline]
pub fn new(coefficients: Vec<F>, degree_0: usize, degree_1: usize) -> Self {
assert_eq!(coefficients.len(), degree_0 * degree_1);
Expand Down Expand Up @@ -37,16 +38,105 @@ impl<F: Field> BivaraitePolynomial<F> {
* y_i
})
}

///
pub fn lagrange_coeffs(&self) -> Vec<F> {
// 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) / self.degree_0 as u64]);
let omega_1 = omega.pow_vartime(&[(1 << F::S) / self.degree_1 as u64]);

assert!(
omega_0.pow_vartime(&[self.degree_0 as u64]) == F::ONE,
"omega_0 is not root of unity for supported_n"
);
assert!(
omega_1.pow_vartime(&[self.degree_1 as u64]) == F::ONE,
"omega_1 is not root of unity for supported_m"
);
(omega_0, omega_1)
};
let powers_of_omega_0 = powers_of_field_elements(&omega_0, self.degree_0);
let powers_of_omega_1 = powers_of_field_elements(&omega_1, self.degree_1);
println!(
"omega len {} {}",
powers_of_omega_0.len(),
powers_of_omega_1.len()
);

// Todo! Optimize me. This is not efficient.
let mut res = vec![];
for omega_1_power in powers_of_omega_1.iter() {
for omega_0_power in powers_of_omega_0.iter() {
res.push(self.evaluate(omega_0_power, omega_1_power));
}
}

println!("res: {:?}", res);
res
}

// pub fn from_lagrange_coeffs(coeffs: Vec<F>, degree_0: usize, degree_1: usize) -> Self {
// assert_eq!(coeffs.len(), degree_0 * degree_1);
// todo!()
// }
}

/// For x in points, compute the Lagrange coefficients at x given the roots.
/// `L_{i}(x) = \prod_{j \neq i} \frac{x - r_j}{r_i - r_j}``
pub(crate) fn lagrange_coefficients<F: Field + Send + Sync>(roots: &[F], points: &[F]) -> Vec<F> {
roots
.par_iter()
.enumerate()
.map(|(i, _)| {
let mut numerator = F::ONE;
let mut denominator = F::ONE;
for j in 0..roots.len() {
if i == j {
continue;
}
numerator *= roots[j] - points[i];
denominator *= roots[j] - roots[i];
}
numerator * denominator.invert().unwrap()
})
.collect()
}

impl<F: Field> BivariateLagrangePolynomial<F> {
fn new(coeffs: Vec<F>, degree_0: usize, degree_1: usize) -> Self {
assert_eq!(coeffs.len(), degree_0 * degree_1);
Self {
coefficients: coeffs,
degree_0,
degree_1,
}
}
}

impl<F: PrimeField> From<BivariatePolynomial<F>> for BivariateLagrangePolynomial<F> {
fn from(poly: BivariatePolynomial<F>) -> Self {
let coeffs = poly.lagrange_coeffs();
BivariateLagrangePolynomial::new(coeffs, poly.degree_0, poly.degree_1)
}
}

impl<F: PrimeField> From<BivariateLagrangePolynomial<F>> for BivariatePolynomial<F> {
fn from(poly: BivariateLagrangePolynomial<F>) -> Self {
todo!()
}
}

#[cfg(test)]
mod tests {
use crate::structs::BivariatePolynomial;
use halo2curves::bn256::Fr;

#[test]
fn test_bivariate_poly_eval() {
use crate::structs::BivaraitePolynomial;
use halo2curves::bn256::Fr;
{
let poly = BivaraitePolynomial::new(
let poly = BivariatePolynomial::new(
vec![
Fr::from(1u64),
Fr::from(2u64),
Expand All @@ -66,7 +156,7 @@ mod tests {
}

{
let poly = BivaraitePolynomial::new(
let poly = BivariatePolynomial::new(
vec![
Fr::from(1u64),
Fr::from(2u64),
Expand All @@ -93,7 +183,7 @@ mod tests {
);
}

let poly = BivaraitePolynomial::new(
let poly = BivariatePolynomial::new(
vec![
Fr::from(1u64),
Fr::from(2u64),
Expand Down Expand Up @@ -123,4 +213,30 @@ mod tests {
* y
);
}

// #[test]
// fn test_lagrange_coeffs() {
// let poly = BivariatePolynomial::new(
// vec![
// Fr::from(1u64),
// Fr::from(2u64),
// Fr::from(3u64),
// Fr::from(4u64),
// Fr::from(5u64),
// Fr::from(10u64),
// Fr::from(15u64),
// Fr::from(20u64),
// ],
// 4,
// 2,
// );

// let lagrange_coeffs = poly.lagrange_coeffs();
// println!("lag: {:?}", lagrange_coeffs);
// assert_eq!(lagrange_coeffs.len(), 8);
// assert_eq!(lagrange_coeffs[0], Fr::from(1u64));
// assert_eq!(lagrange_coeffs[1], Fr::from(2u64));
// assert_eq!(lagrange_coeffs[2], Fr::from(3u64));
// assert_eq!(lagrange_coeffs[3], Fr::from(4u64));
// }
}
11 changes: 9 additions & 2 deletions bi-kzg/src/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@ use std::io::{self, Read, Write};
use halo2curves::{pairing::Engine, serde::SerdeObject};

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct BivaraitePolynomial<F> {
pub struct BivariatePolynomial<F> {
pub coefficients: Vec<F>,
pub degree_0: usize,
pub degree_1: usize,
}

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct BivariateLagrangePolynomial<F> {
pub coefficients: Vec<F>,
pub degree_0: usize,
pub degree_1: usize,
Expand All @@ -24,7 +31,7 @@ pub struct BiKZGSRS<E: Engine> {
/// )
pub powers_of_g: Vec<E::G1Affine>,
/// g in lagrange form
pub powers_of_g_largrange: Vec<E::G1Affine>,
pub powers_of_g_lagrange: Vec<E::G1Affine>,
/// The generator of G2.
pub h: E::G2Affine,
/// tau_0 times the above generator of G2.
Expand Down
Loading

0 comments on commit d15058a

Please sign in to comment.