Browse Source

Merge pull request #105 from EspressoSystems/arcpariter-new

Parallelization optimizations
main
Benedikt Bünz 1 year ago
committed by GitHub
parent
commit
77bc9f5e4a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 166 additions and 186 deletions
  1. +18
    -32
      arithmetic/src/multilinear_polynomial.rs
  2. +14
    -20
      arithmetic/src/virtual_polynomial.rs
  3. +2
    -2
      hyperplonk/src/mock.rs
  4. +2
    -2
      hyperplonk/src/selectors.rs
  5. +16
    -13
      hyperplonk/src/snark.rs
  6. +3
    -3
      hyperplonk/src/structs.rs
  7. +8
    -8
      hyperplonk/src/utils.rs
  8. +2
    -2
      hyperplonk/src/witness.rs
  9. +4
    -4
      subroutines/benches/iop_bench.rs
  10. +2
    -2
      subroutines/benches/pcs_bench.rs
  11. +2
    -8
      subroutines/src/pcs/mod.rs
  12. +17
    -14
      subroutines/src/pcs/multilinear_kzg/batching.rs
  13. +5
    -5
      subroutines/src/pcs/multilinear_kzg/mod.rs
  14. +17
    -17
      subroutines/src/poly_iop/perm_check/mod.rs
  15. +8
    -8
      subroutines/src/poly_iop/perm_check/util.rs
  16. +13
    -13
      subroutines/src/poly_iop/prod_check/mod.rs
  17. +18
    -16
      subroutines/src/poly_iop/prod_check/util.rs
  18. +4
    -4
      subroutines/src/poly_iop/sum_check/mod.rs
  19. +11
    -13
      subroutines/src/poly_iop/sum_check/prover.rs

+ 18
- 32
arithmetic/src/multilinear_polynomial.rs

@ -4,7 +4,7 @@ use ark_poly::MultilinearExtension;
use ark_std::{end_timer, rand::RngCore, start_timer}; use ark_std::{end_timer, rand::RngCore, start_timer};
#[cfg(feature = "parallel")] #[cfg(feature = "parallel")]
use rayon::prelude::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator}; use rayon::prelude::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator};
use std::rc::Rc;
use std::sync::Arc;
pub use ark_poly::DenseMultilinearExtension; pub use ark_poly::DenseMultilinearExtension;
@ -16,7 +16,7 @@ pub fn random_mle_list(
nv: usize, nv: usize,
degree: usize, degree: usize,
rng: &mut R, rng: &mut R,
) -> (Vec<Rc<DenseMultilinearExtension<F>>>, F) {
) -> (Vec<Arc<DenseMultilinearExtension<F>>>, F) {
let start = start_timer!(|| "sample random mle list"); let start = start_timer!(|| "sample random mle list");
let mut multiplicands = Vec::with_capacity(degree); let mut multiplicands = Vec::with_capacity(degree);
for _ in 0..degree { for _ in 0..degree {
@ -37,7 +37,7 @@ pub fn random_mle_list(
let list = multiplicands let list = multiplicands
.into_iter() .into_iter()
.map(|x| Rc::new(DenseMultilinearExtension::from_evaluations_vec(nv, x)))
.map(|x| Arc::new(DenseMultilinearExtension::from_evaluations_vec(nv, x)))
.collect(); .collect();
end_timer!(start); end_timer!(start);
@ -49,7 +49,7 @@ pub fn random_zero_mle_list(
nv: usize, nv: usize,
degree: usize, degree: usize,
rng: &mut R, rng: &mut R,
) -> Vec<Rc<DenseMultilinearExtension<F>>> {
) -> Vec<Arc<DenseMultilinearExtension<F>>> {
let start = start_timer!(|| "sample random zero mle list"); let start = start_timer!(|| "sample random zero mle list");
let mut multiplicands = Vec::with_capacity(degree); let mut multiplicands = Vec::with_capacity(degree);
@ -65,7 +65,7 @@ pub fn random_zero_mle_list(
let list = multiplicands let list = multiplicands
.into_iter() .into_iter()
.map(|x| Rc::new(DenseMultilinearExtension::from_evaluations_vec(nv, x)))
.map(|x| Arc::new(DenseMultilinearExtension::from_evaluations_vec(nv, x)))
.collect(); .collect();
end_timer!(start); end_timer!(start);
@ -81,12 +81,12 @@ pub fn identity_permutation(num_vars: usize, num_chunks: usize) -
pub fn identity_permutation_mles<F: PrimeField>( pub fn identity_permutation_mles<F: PrimeField>(
num_vars: usize, num_vars: usize,
num_chunks: usize, num_chunks: usize,
) -> Vec<Rc<DenseMultilinearExtension<F>>> {
) -> Vec<Arc<DenseMultilinearExtension<F>>> {
let mut res = vec![]; let mut res = vec![];
for i in 0..num_chunks { for i in 0..num_chunks {
let shift = (i * (1 << num_vars)) as u64; let shift = (i * (1 << num_vars)) as u64;
let s_id_vec = (shift..shift + (1u64 << num_vars)).map(F::from).collect(); let s_id_vec = (shift..shift + (1u64 << num_vars)).map(F::from).collect();
res.push(Rc::new(DenseMultilinearExtension::from_evaluations_vec(
res.push(Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_vars, s_id_vec, num_vars, s_id_vec,
))); )));
} }
@ -113,12 +113,12 @@ pub fn random_permutation_mles(
num_vars: usize, num_vars: usize,
num_chunks: usize, num_chunks: usize,
rng: &mut R, rng: &mut R,
) -> Vec<Rc<DenseMultilinearExtension<F>>> {
) -> Vec<Arc<DenseMultilinearExtension<F>>> {
let s_perm_vec = random_permutation(num_vars, num_chunks, rng); let s_perm_vec = random_permutation(num_vars, num_chunks, rng);
let mut res = vec![]; let mut res = vec![];
let n = 1 << num_vars; let n = 1 << num_vars;
for i in 0..num_chunks { for i in 0..num_chunks {
res.push(Rc::new(DenseMultilinearExtension::from_evaluations_vec(
res.push(Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_vars, num_vars,
s_perm_vec[i * n..i * n + n].to_vec(), s_perm_vec[i * n..i * n + n].to_vec(),
))); )));
@ -160,16 +160,9 @@ fn fix_one_variable_helper(data: &[F], nv: usize, point: &F) -> Vec
} }
#[cfg(feature = "parallel")] #[cfg(feature = "parallel")]
if nv >= 13 {
// on my computer we parallelization doesn't help till nv >= 13
res.par_iter_mut().enumerate().for_each(|(i, x)| {
*x = data[i << 1] + (data[(i << 1) + 1] - data[i << 1]) * point;
});
} else {
for i in 0..(1 << (nv - 1)) {
res[i] = data[i << 1] + (data[(i << 1) + 1] - data[i << 1]) * point;
}
}
res.par_iter_mut().enumerate().for_each(|(i, x)| {
*x = data[i << 1] + (data[(i << 1) + 1] - data[i << 1]) * point;
});
res res
} }
@ -203,8 +196,8 @@ fn fix_variables_no_par(
/// merge a set of polynomials. Returns an error if the /// merge a set of polynomials. Returns an error if the
/// polynomials do not share a same number of nvs. /// polynomials do not share a same number of nvs.
pub fn merge_polynomials<F: PrimeField>( pub fn merge_polynomials<F: PrimeField>(
polynomials: &[Rc<DenseMultilinearExtension<F>>],
) -> Result<Rc<DenseMultilinearExtension<F>>, ArithErrors> {
polynomials: &[Arc<DenseMultilinearExtension<F>>],
) -> Result<Arc<DenseMultilinearExtension<F>>, ArithErrors> {
let nv = polynomials[0].num_vars(); let nv = polynomials[0].num_vars();
for poly in polynomials.iter() { for poly in polynomials.iter() {
if nv != poly.num_vars() { if nv != poly.num_vars() {
@ -220,7 +213,7 @@ pub fn merge_polynomials(
scalars.extend_from_slice(poly.to_evaluations().as_slice()); scalars.extend_from_slice(poly.to_evaluations().as_slice());
} }
scalars.extend_from_slice(vec![F::zero(); (1 << merged_nv) - scalars.len()].as_ref()); scalars.extend_from_slice(vec![F::zero(); (1 << merged_nv) - scalars.len()].as_ref());
Ok(Rc::new(DenseMultilinearExtension::from_evaluations_vec(
Ok(Arc::new(DenseMultilinearExtension::from_evaluations_vec(
merged_nv, scalars, merged_nv, scalars,
))) )))
} }
@ -279,16 +272,9 @@ fn fix_last_variable_helper(data: &[F], nv: usize, point: &F) -> Vec
} }
#[cfg(feature = "parallel")] #[cfg(feature = "parallel")]
if nv >= 13 {
// on my computer we parallelization doesn't help till nv >= 13
res.par_iter_mut().enumerate().for_each(|(i, x)| {
*x = data[i] + (data[i + half_len] - data[i]) * point;
});
} else {
for b in 0..(1 << (nv - 1)) {
res[b] = data[b] + (data[b + half_len] - data[b]) * point;
}
}
res.par_iter_mut().enumerate().for_each(|(i, x)| {
*x = data[i] + (data[i + half_len] - data[i]) * point;
});
res res
} }

+ 14
- 20
arithmetic/src/virtual_polynomial.rs

@ -11,7 +11,7 @@ use ark_std::{
start_timer, start_timer,
}; };
use rayon::prelude::*; use rayon::prelude::*;
use std::{cmp::max, collections::HashMap, marker::PhantomData, ops::Add, rc::Rc};
use std::{cmp::max, collections::HashMap, marker::PhantomData, ops::Add, sync::Arc};
#[rustfmt::skip] #[rustfmt::skip]
/// A virtual polynomial is a sum of products of multilinear polynomials; /// A virtual polynomial is a sum of products of multilinear polynomials;
@ -48,7 +48,7 @@ pub struct VirtualPolynomial {
pub products: Vec<(F, Vec<usize>)>, pub products: Vec<(F, Vec<usize>)>,
/// Stores multilinear extensions in which product multiplicand can refer /// Stores multilinear extensions in which product multiplicand can refer
/// to. /// to.
pub flattened_ml_extensions: Vec<Rc<DenseMultilinearExtension<F>>>,
pub flattened_ml_extensions: Vec<Arc<DenseMultilinearExtension<F>>>,
/// Pointers to the above poly extensions /// Pointers to the above poly extensions
raw_pointers_lookup_table: HashMap<*const DenseMultilinearExtension<F>, usize>, raw_pointers_lookup_table: HashMap<*const DenseMultilinearExtension<F>, usize>,
} }
@ -71,7 +71,7 @@ impl Add for &VirtualPolynomial {
let start = start_timer!(|| "virtual poly add"); let start = start_timer!(|| "virtual poly add");
let mut res = self.clone(); let mut res = self.clone();
for products in other.products.iter() { for products in other.products.iter() {
let cur: Vec<Rc<DenseMultilinearExtension<F>>> = products
let cur: Vec<Arc<DenseMultilinearExtension<F>>> = products
.1 .1
.iter() .iter()
.map(|&x| other.flattened_ml_extensions[x].clone()) .map(|&x| other.flattened_ml_extensions[x].clone())
@ -102,8 +102,8 @@ impl VirtualPolynomial {
} }
/// Creates an new virtual polynomial from a MLE and its coefficient. /// Creates an new virtual polynomial from a MLE and its coefficient.
pub fn new_from_mle(mle: &Rc<DenseMultilinearExtension<F>>, coefficient: F) -> Self {
let mle_ptr: *const DenseMultilinearExtension<F> = Rc::as_ptr(mle);
pub fn new_from_mle(mle: &Arc<DenseMultilinearExtension<F>>, coefficient: F) -> Self {
let mle_ptr: *const DenseMultilinearExtension<F> = Arc::as_ptr(mle);
let mut hm = HashMap::new(); let mut hm = HashMap::new();
hm.insert(mle_ptr, 0); hm.insert(mle_ptr, 0);
@ -129,10 +129,10 @@ impl VirtualPolynomial {
/// `coefficient`. /// `coefficient`.
pub fn add_mle_list( pub fn add_mle_list(
&mut self, &mut self,
mle_list: impl IntoIterator<Item = Rc<DenseMultilinearExtension<F>>>,
mle_list: impl IntoIterator<Item = Arc<DenseMultilinearExtension<F>>>,
coefficient: F, coefficient: F,
) -> Result<(), ArithErrors> { ) -> Result<(), ArithErrors> {
let mle_list: Vec<Rc<DenseMultilinearExtension<F>>> = mle_list.into_iter().collect();
let mle_list: Vec<Arc<DenseMultilinearExtension<F>>> = mle_list.into_iter().collect();
let mut indexed_product = Vec::with_capacity(mle_list.len()); let mut indexed_product = Vec::with_capacity(mle_list.len());
if mle_list.is_empty() { if mle_list.is_empty() {
@ -151,7 +151,7 @@ impl VirtualPolynomial {
))); )));
} }
let mle_ptr: *const DenseMultilinearExtension<F> = Rc::as_ptr(&mle);
let mle_ptr: *const DenseMultilinearExtension<F> = Arc::as_ptr(&mle);
if let Some(index) = self.raw_pointers_lookup_table.get(&mle_ptr) { if let Some(index) = self.raw_pointers_lookup_table.get(&mle_ptr) {
indexed_product.push(*index) indexed_product.push(*index)
} else { } else {
@ -171,7 +171,7 @@ impl VirtualPolynomial {
/// Returns an error if the MLE has a different `num_vars` from self. /// Returns an error if the MLE has a different `num_vars` from self.
pub fn mul_by_mle( pub fn mul_by_mle(
&mut self, &mut self,
mle: Rc<DenseMultilinearExtension<F>>,
mle: Arc<DenseMultilinearExtension<F>>,
coefficient: F, coefficient: F,
) -> Result<(), ArithErrors> { ) -> Result<(), ArithErrors> {
let start = start_timer!(|| "mul by mle"); let start = start_timer!(|| "mul by mle");
@ -183,7 +183,7 @@ impl VirtualPolynomial {
))); )));
} }
let mle_ptr: *const DenseMultilinearExtension<F> = Rc::as_ptr(&mle);
let mle_ptr: *const DenseMultilinearExtension<F> = Arc::as_ptr(&mle);
// check if this mle already exists in the virtual polynomial // check if this mle already exists in the virtual polynomial
let mle_index = match self.raw_pointers_lookup_table.get(&mle_ptr) { let mle_index = match self.raw_pointers_lookup_table.get(&mle_ptr) {
@ -350,11 +350,11 @@ pub fn eq_eval(x: &[F], y: &[F]) -> Result {
/// eq(x,y) = \prod_i=1^num_var (x_i * r_i + (1-x_i)*(1-r_i)) /// eq(x,y) = \prod_i=1^num_var (x_i * r_i + (1-x_i)*(1-r_i))
pub fn build_eq_x_r<F: PrimeField>( pub fn build_eq_x_r<F: PrimeField>(
r: &[F], r: &[F],
) -> Result<Rc<DenseMultilinearExtension<F>>, ArithErrors> {
) -> Result<Arc<DenseMultilinearExtension<F>>, ArithErrors> {
let evals = build_eq_x_r_vec(r)?; let evals = build_eq_x_r_vec(r)?;
let mle = DenseMultilinearExtension::from_evaluations_vec(r.len(), evals); let mle = DenseMultilinearExtension::from_evaluations_vec(r.len(), evals);
Ok(Rc::new(mle))
Ok(Arc::new(mle))
} }
/// This function build the eq(x, r) polynomial for any given r, and output the /// This function build the eq(x, r) polynomial for any given r, and output the
/// evaluation of eq(x, r) in its vector form. /// evaluation of eq(x, r) in its vector form.
@ -364,8 +364,6 @@ pub fn build_eq_x_r(
/// over r, which is /// over r, which is
/// eq(x,y) = \prod_i=1^num_var (x_i * r_i + (1-x_i)*(1-r_i)) /// eq(x,y) = \prod_i=1^num_var (x_i * r_i + (1-x_i)*(1-r_i))
pub fn build_eq_x_r_vec<F: PrimeField>(r: &[F]) -> Result<Vec<F>, ArithErrors> { pub fn build_eq_x_r_vec<F: PrimeField>(r: &[F]) -> Result<Vec<F>, ArithErrors> {
let start = start_timer!(|| format!("build eq_x_r of size {}", r.len()));
// we build eq(x,r) from its evaluations // we build eq(x,r) from its evaluations
// we want to evaluate eq(x,r) over x \in {0, 1}^num_vars // we want to evaluate eq(x,r) over x \in {0, 1}^num_vars
// for example, with num_vars = 4, x is a binary vector of 4, then // for example, with num_vars = 4, x is a binary vector of 4, then
@ -380,7 +378,6 @@ pub fn build_eq_x_r_vec(r: &[F]) -> Result, ArithErrors> {
let mut eval = Vec::new(); let mut eval = Vec::new();
build_eq_x_r_helper(r, &mut eval)?; build_eq_x_r_helper(r, &mut eval)?;
end_timer!(start);
Ok(eval) Ok(eval)
} }
@ -511,9 +508,7 @@ mod test {
// eq(x,y) = \prod_i=1^num_var (x_i * y_i + (1-x_i)*(1-y_i)) // eq(x,y) = \prod_i=1^num_var (x_i * y_i + (1-x_i)*(1-y_i))
// over r, which is // over r, which is
// eq(x,y) = \prod_i=1^num_var (x_i * r_i + (1-x_i)*(1-r_i)) // eq(x,y) = \prod_i=1^num_var (x_i * r_i + (1-x_i)*(1-r_i))
fn build_eq_x_r_for_test<F: PrimeField>(r: &[F]) -> Rc<DenseMultilinearExtension<F>> {
let start = start_timer!(|| "zero check naive build eq_x_r");
fn build_eq_x_r_for_test<F: PrimeField>(r: &[F]) -> Arc<DenseMultilinearExtension<F>> {
// we build eq(x,r) from its evaluations // we build eq(x,r) from its evaluations
// we want to evaluate eq(x,r) over x \in {0, 1}^num_vars // we want to evaluate eq(x,r) over x \in {0, 1}^num_vars
// for example, with num_vars = 4, x is a binary vector of 4, then // for example, with num_vars = 4, x is a binary vector of 4, then
@ -545,8 +540,7 @@ mod test {
let mle = DenseMultilinearExtension::from_evaluations_vec(num_var, eval); let mle = DenseMultilinearExtension::from_evaluations_vec(num_var, eval);
let res = Rc::new(mle);
end_timer!(start);
let res = Arc::new(mle);
res res
} }
} }

+ 2
- 2
hyperplonk/src/mock.rs

@ -238,8 +238,8 @@ mod test {
MultilinearKzgPCS::<Bls12_381>::gen_srs_for_testing(&mut rng, SUPPORTED_SIZE)?; MultilinearKzgPCS::<Bls12_381>::gen_srs_for_testing(&mut rng, SUPPORTED_SIZE)?;
let nv = MAX_NUM_VARS; let nv = MAX_NUM_VARS;
let vanilla_gate = CustomizedGates::vanilla_plonk_gate();
test_mock_circuit_zkp_helper(nv, &vanilla_gate, &pcs_srs)?;
let turboplonk_gate = CustomizedGates::jellyfish_turbo_plonk_gate();
test_mock_circuit_zkp_helper(nv, &turboplonk_gate, &pcs_srs)?;
Ok(()) Ok(())
} }

+ 2
- 2
hyperplonk/src/selectors.rs

@ -2,7 +2,7 @@ use crate::{build_mle, errors::HyperPlonkErrors};
use ark_ff::PrimeField; use ark_ff::PrimeField;
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use ark_std::log2; use ark_std::log2;
use std::rc::Rc;
use std::sync::Arc;
/// A row of selector of width `#selectors` /// A row of selector of width `#selectors`
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
@ -67,7 +67,7 @@ impl SelectorRow {
/// output mle(a1,b1,c1, ...), mle(a2,b2,c2, ...), ... /// output mle(a1,b1,c1, ...), mle(a2,b2,c2, ...), ...
pub fn build_mles( pub fn build_mles(
matrix: &[Self], matrix: &[Self],
) -> Result<Vec<Rc<DenseMultilinearExtension<F>>>, HyperPlonkErrors> {
) -> Result<Vec<Arc<DenseMultilinearExtension<F>>>, HyperPlonkErrors> {
build_mle!(matrix) build_mle!(matrix)
} }
} }

+ 16
- 13
hyperplonk/src/snark.rs

@ -9,7 +9,10 @@ use arithmetic::{evaluate_opt, gen_eval_point, VPAuxInfo};
use ark_ec::PairingEngine; use ark_ec::PairingEngine;
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use ark_std::{end_timer, log2, start_timer, One, Zero}; use ark_std::{end_timer, log2, start_timer, One, Zero};
use std::{marker::PhantomData, rc::Rc};
use rayon::iter::IntoParallelRefIterator;
#[cfg(feature = "parallel")]
use rayon::iter::ParallelIterator;
use std::{marker::PhantomData, sync::Arc};
use subroutines::{ use subroutines::{
pcs::prelude::{Commitment, PolynomialCommitmentScheme}, pcs::prelude::{Commitment, PolynomialCommitmentScheme},
poly_iop::{ poly_iop::{
@ -28,7 +31,7 @@ where
// we cannot bound PCS::Polynomial with a property trait bound. // we cannot bound PCS::Polynomial with a property trait bound.
PCS: PolynomialCommitmentScheme< PCS: PolynomialCommitmentScheme<
E, E,
Polynomial = Rc<DenseMultilinearExtension<E::Fr>>,
Polynomial = Arc<DenseMultilinearExtension<E::Fr>>,
Point = Vec<E::Fr>, Point = Vec<E::Fr>,
Evaluation = E::Fr, Evaluation = E::Fr,
Commitment = Commitment<E>, Commitment = Commitment<E>,
@ -56,7 +59,7 @@ where
let mut perm_comms = vec![]; let mut perm_comms = vec![];
let chunk_size = 1 << num_vars; let chunk_size = 1 << num_vars;
for i in 0..index.num_witness_columns() { for i in 0..index.num_witness_columns() {
let perm_oracle = Rc::new(DenseMultilinearExtension::from_evaluations_slice(
let perm_oracle = Arc::new(DenseMultilinearExtension::from_evaluations_slice(
num_vars, num_vars,
&index.permutation[i * chunk_size..(i + 1) * chunk_size], &index.permutation[i * chunk_size..(i + 1) * chunk_size],
)); ));
@ -66,14 +69,14 @@ where
} }
// build selector oracles and commit to it // build selector oracles and commit to it
let selector_oracles: Vec<Rc<DenseMultilinearExtension<E::Fr>>> = index
let selector_oracles: Vec<Arc<DenseMultilinearExtension<E::Fr>>> = index
.selectors .selectors
.iter() .iter()
.map(|s| Rc::new(DenseMultilinearExtension::from(s)))
.map(|s| Arc::new(DenseMultilinearExtension::from(s)))
.collect(); .collect();
let selector_commitments = selector_oracles let selector_commitments = selector_oracles
.iter()
.par_iter()
.map(|poly| PCS::commit(&pcs_prover_param, poly)) .map(|poly| PCS::commit(&pcs_prover_param, poly))
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
@ -168,13 +171,13 @@ where
// ======================================================================= // =======================================================================
let step = start_timer!(|| "commit witnesses"); let step = start_timer!(|| "commit witnesses");
let witness_polys: Vec<Rc<DenseMultilinearExtension<E::Fr>>> = witnesses
let witness_polys: Vec<Arc<DenseMultilinearExtension<E::Fr>>> = witnesses
.iter() .iter()
.map(|w| Rc::new(DenseMultilinearExtension::from(w)))
.map(|w| Arc::new(DenseMultilinearExtension::from(w)))
.collect(); .collect();
let witness_commits = witness_polys let witness_commits = witness_polys
.iter()
.par_iter()
.map(|x| PCS::commit(&pk.pcs_param, x).unwrap()) .map(|x| PCS::commit(&pk.pcs_param, x).unwrap())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
for w_com in witness_commits.iter() { for w_com in witness_commits.iter() {
@ -663,15 +666,15 @@ mod tests {
let w1 = WitnessColumn(vec![ let w1 = WitnessColumn(vec![
E::Fr::zero(), E::Fr::zero(),
E::Fr::one(), E::Fr::one(),
E::Fr::from(2u64),
E::Fr::from(3u64),
E::Fr::from(2u128),
E::Fr::from(3u128),
]); ]);
// w2 := [0^5, 1^5, 2^5, 3^5] // w2 := [0^5, 1^5, 2^5, 3^5]
let w2 = WitnessColumn(vec![ let w2 = WitnessColumn(vec![
E::Fr::zero(), E::Fr::zero(),
E::Fr::one(), E::Fr::one(),
E::Fr::from(32u64),
E::Fr::from(243u64),
E::Fr::from(32u128),
E::Fr::from(243u128),
]); ]);
// public input = w1 // public input = w1
let pi = w1.clone(); let pi = w1.clone();

+ 3
- 3
hyperplonk/src/structs.rs

@ -5,7 +5,7 @@ use ark_ec::PairingEngine;
use ark_ff::PrimeField; use ark_ff::PrimeField;
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use ark_std::log2; use ark_std::log2;
use std::rc::Rc;
use std::sync::Arc;
use subroutines::{ use subroutines::{
pcs::PolynomialCommitmentScheme, pcs::PolynomialCommitmentScheme,
poly_iop::prelude::{PermutationCheck, ZeroCheck}, poly_iop::prelude::{PermutationCheck, ZeroCheck},
@ -126,9 +126,9 @@ pub struct HyperPlonkProvingKey
/// Hyperplonk instance parameters /// Hyperplonk instance parameters
pub params: HyperPlonkParams, pub params: HyperPlonkParams,
/// The preprocessed permutation polynomials /// The preprocessed permutation polynomials
pub permutation_oracles: Vec<Rc<DenseMultilinearExtension<E::Fr>>>,
pub permutation_oracles: Vec<Arc<DenseMultilinearExtension<E::Fr>>>,
/// The preprocessed selector polynomials /// The preprocessed selector polynomials
pub selector_oracles: Vec<Rc<DenseMultilinearExtension<E::Fr>>>,
pub selector_oracles: Vec<Arc<DenseMultilinearExtension<E::Fr>>>,
/// Commitments to the preprocessed selector polynomials /// Commitments to the preprocessed selector polynomials
pub selector_commitments: Vec<PCS::Commitment>, pub selector_commitments: Vec<PCS::Commitment>,
/// Commitments to the preprocessed permutation polynomials /// Commitments to the preprocessed permutation polynomials

+ 8
- 8
hyperplonk/src/utils.rs

@ -6,7 +6,7 @@ use arithmetic::{evaluate_opt, VirtualPolynomial};
use ark_ec::PairingEngine; use ark_ec::PairingEngine;
use ark_ff::PrimeField; use ark_ff::PrimeField;
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use std::{borrow::Borrow, rc::Rc};
use std::{borrow::Borrow, sync::Arc};
use subroutines::pcs::{prelude::Commitment, PolynomialCommitmentScheme}; use subroutines::pcs::{prelude::Commitment, PolynomialCommitmentScheme};
use transcript::IOPTranscript; use transcript::IOPTranscript;
@ -32,7 +32,7 @@ where
E: PairingEngine, E: PairingEngine,
PCS: PolynomialCommitmentScheme< PCS: PolynomialCommitmentScheme<
E, E,
Polynomial = Rc<DenseMultilinearExtension<E::Fr>>,
Polynomial = Arc<DenseMultilinearExtension<E::Fr>>,
Point = Vec<E::Fr>, Point = Vec<E::Fr>,
Evaluation = E::Fr, Evaluation = E::Fr,
Commitment = Commitment<E>, Commitment = Commitment<E>,
@ -104,7 +104,7 @@ macro_rules! build_mle {
for row in $rows.iter() { for row in $rows.iter() {
cur_coeffs.push(row.0[i]) cur_coeffs.push(row.0[i])
} }
res.push(Rc::new(DenseMultilinearExtension::from_evaluations_vec(
res.push(Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_vars, cur_coeffs, num_vars, cur_coeffs,
))) )))
} }
@ -178,8 +178,8 @@ pub(crate) fn prover_sanity_check(
pub(crate) fn build_f<F: PrimeField>( pub(crate) fn build_f<F: PrimeField>(
gates: &CustomizedGates, gates: &CustomizedGates,
num_vars: usize, num_vars: usize,
selector_mles: &[Rc<DenseMultilinearExtension<F>>],
witness_mles: &[Rc<DenseMultilinearExtension<F>>],
selector_mles: &[Arc<DenseMultilinearExtension<F>>],
witness_mles: &[Arc<DenseMultilinearExtension<F>>],
) -> Result<VirtualPolynomial<F>, HyperPlonkErrors> { ) -> Result<VirtualPolynomial<F>, HyperPlonkErrors> {
// TODO: check that selector and witness lengths match what is in // TODO: check that selector and witness lengths match what is in
// the gate definition // the gate definition
@ -306,7 +306,7 @@ mod test {
// 1, 0 |-> 0 // 1, 0 |-> 0
// 1, 1 |-> 5 // 1, 1 |-> 5
let ql_eval = vec![F::zero(), F::from(2u64), F::zero(), F::from(5u64)]; let ql_eval = vec![F::zero(), F::from(2u64), F::zero(), F::from(5u64)];
let ql = Rc::new(DenseMultilinearExtension::from_evaluations_vec(2, ql_eval));
let ql = Arc::new(DenseMultilinearExtension::from_evaluations_vec(2, ql_eval));
// W1 = x1x2 + x1 whose evaluations are // W1 = x1x2 + x1 whose evaluations are
// 0, 0 |-> 0 // 0, 0 |-> 0
@ -314,7 +314,7 @@ mod test {
// 1, 0 |-> 1 // 1, 0 |-> 1
// 1, 1 |-> 2 // 1, 1 |-> 2
let w_eval = vec![F::zero(), F::zero(), F::from(1u64), F::from(2u64)]; let w_eval = vec![F::zero(), F::zero(), F::from(1u64), F::from(2u64)];
let w1 = Rc::new(DenseMultilinearExtension::from_evaluations_vec(2, w_eval));
let w1 = Arc::new(DenseMultilinearExtension::from_evaluations_vec(2, w_eval));
// W2 = x1 + x2 whose evaluations are // W2 = x1 + x2 whose evaluations are
// 0, 0 |-> 0 // 0, 0 |-> 0
@ -322,7 +322,7 @@ mod test {
// 1, 0 |-> 1 // 1, 0 |-> 1
// 1, 1 |-> 2 // 1, 1 |-> 2
let w_eval = vec![F::zero(), F::one(), F::from(1u64), F::from(2u64)]; let w_eval = vec![F::zero(), F::one(), F::from(1u64), F::from(2u64)];
let w2 = Rc::new(DenseMultilinearExtension::from_evaluations_vec(2, w_eval));
let w2 = Arc::new(DenseMultilinearExtension::from_evaluations_vec(2, w_eval));
// Example: // Example:
// q_L(X) * W_1(X)^5 - W_2(X) // q_L(X) * W_1(X)^5 - W_2(X)

+ 2
- 2
hyperplonk/src/witness.rs

@ -2,7 +2,7 @@ use crate::{build_mle, errors::HyperPlonkErrors};
use ark_ff::PrimeField; use ark_ff::PrimeField;
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use ark_std::log2; use ark_std::log2;
use std::rc::Rc;
use std::sync::Arc;
/// A row of witnesses of width `#wires` /// A row of witnesses of width `#wires`
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -71,7 +71,7 @@ impl WitnessRow {
/// output mle(a1,b1,c1, ...), mle(a2,b2,c2, ...), ... /// output mle(a1,b1,c1, ...), mle(a2,b2,c2, ...), ...
pub fn build_mles( pub fn build_mles(
matrix: &[Self], matrix: &[Self],
) -> Result<Vec<Rc<DenseMultilinearExtension<F>>>, HyperPlonkErrors> {
) -> Result<Vec<Arc<DenseMultilinearExtension<F>>>, HyperPlonkErrors> {
build_mle!(matrix) build_mle!(matrix)
} }
} }

+ 4
- 4
subroutines/benches/iop_bench.rs

@ -2,7 +2,7 @@ use arithmetic::{identity_permutation_mles, VPAuxInfo, VirtualPolynomial};
use ark_bls12_381::{Bls12_381, Fr}; use ark_bls12_381::{Bls12_381, Fr};
use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; use ark_poly::{DenseMultilinearExtension, MultilinearExtension};
use ark_std::test_rng; use ark_std::test_rng;
use std::{marker::PhantomData, rc::Rc, time::Instant};
use std::{marker::PhantomData, sync::Arc, time::Instant};
use subroutines::{ use subroutines::{
pcs::{prelude::MultilinearKzgPCS, PolynomialCommitmentScheme}, pcs::{prelude::MultilinearKzgPCS, PolynomialCommitmentScheme},
poly_iop::prelude::{ poly_iop::prelude::{
@ -144,7 +144,7 @@ fn bench_permutation_check() -> Result<(), PolyIOPErrors> {
10 10
}; };
let ws = vec![Rc::new(DenseMultilinearExtension::rand(nv, &mut rng))];
let ws = vec![Arc::new(DenseMultilinearExtension::rand(nv, &mut rng))];
// identity map // identity map
let perms = identity_permutation_mles(nv, 1); let perms = identity_permutation_mles(nv, 1);
@ -218,8 +218,8 @@ fn bench_prod_check() -> Result<(), PolyIOPErrors> {
let f: DenseMultilinearExtension<Fr> = DenseMultilinearExtension::rand(nv, &mut rng); let f: DenseMultilinearExtension<Fr> = DenseMultilinearExtension::rand(nv, &mut rng);
let mut g = f.clone(); let mut g = f.clone();
g.evaluations.reverse(); g.evaluations.reverse();
let fs = vec![Rc::new(f)];
let gs = vec![Rc::new(g)];
let fs = vec![Arc::new(f)];
let gs = vec![Arc::new(g)];
let proof = { let proof = {
let start = Instant::now(); let start = Instant::now();

+ 2
- 2
subroutines/benches/pcs_bench.rs

@ -1,7 +1,7 @@
use ark_bls12_381::{Bls12_381, Fr}; use ark_bls12_381::{Bls12_381, Fr};
use ark_ff::UniformRand; use ark_ff::UniformRand;
use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; use ark_poly::{DenseMultilinearExtension, MultilinearExtension};
use ark_std::{rc::Rc, test_rng};
use ark_std::{sync::Arc, test_rng};
use std::time::Instant; use std::time::Instant;
use subroutines::pcs::{ use subroutines::pcs::{
prelude::{MultilinearKzgPCS, PCSError, PolynomialCommitmentScheme}, prelude::{MultilinearKzgPCS, PCSError, PolynomialCommitmentScheme},
@ -27,7 +27,7 @@ fn bench_pcs() -> Result<(), PCSError> {
2 2
}; };
let poly = Rc::new(DenseMultilinearExtension::rand(nv, &mut rng));
let poly = Arc::new(DenseMultilinearExtension::rand(nv, &mut rng));
let (ck, vk) = uni_params.trim(nv)?; let (ck, vk) = uni_params.trim(nv)?;
let point: Vec<_> = (0..nv).map(|_| Fr::rand(&mut rng)).collect(); let point: Vec<_> = (0..nv).map(|_| Fr::rand(&mut rng)).collect();

+ 2
- 8
subroutines/src/pcs/mod.rs

@ -17,19 +17,13 @@ use transcript::IOPTranscript;
/// Note that for our usage of PCS, we do not require the hiding property. /// Note that for our usage of PCS, we do not require the hiding property.
pub trait PolynomialCommitmentScheme<E: PairingEngine> { pub trait PolynomialCommitmentScheme<E: PairingEngine> {
/// Prover parameters /// Prover parameters
type ProverParam: Clone;
type ProverParam: Clone + Sync;
/// Verifier parameters /// Verifier parameters
type VerifierParam: Clone + CanonicalSerialize + CanonicalDeserialize; type VerifierParam: Clone + CanonicalSerialize + CanonicalDeserialize;
/// Structured reference string /// Structured reference string
type SRS: Clone + Debug; type SRS: Clone + Debug;
/// Polynomial and its associated types /// Polynomial and its associated types
type Polynomial: Clone
+ Debug
+ Hash
+ PartialEq
+ Eq
+ CanonicalSerialize
+ CanonicalDeserialize;
type Polynomial: Clone + Debug + Hash + PartialEq + Eq;
/// Polynomial input domain /// Polynomial input domain
type Point: Clone + Ord + Debug + Sync + Hash + PartialEq + Eq; type Point: Clone + Ord + Debug + Sync + Hash + PartialEq + Eq;
/// Polynomial Evaluation /// Polynomial Evaluation

+ 17
- 14
subroutines/src/pcs/multilinear_kzg/batching.rs

@ -17,7 +17,8 @@ use arithmetic::{build_eq_x_r_vec, DenseMultilinearExtension, VPAuxInfo, Virtual
use ark_ec::{msm::VariableBaseMSM, PairingEngine, ProjectiveCurve}; use ark_ec::{msm::VariableBaseMSM, PairingEngine, ProjectiveCurve};
use ark_ff::PrimeField; use ark_ff::PrimeField;
use ark_std::{end_timer, log2, start_timer, One, Zero}; use ark_std::{end_timer, log2, start_timer, One, Zero};
use std::{marker::PhantomData, rc::Rc};
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
use std::{marker::PhantomData, sync::Arc};
use transcript::IOPTranscript; use transcript::IOPTranscript;
#[derive(Clone, Debug, Default, PartialEq, Eq)] #[derive(Clone, Debug, Default, PartialEq, Eq)]
@ -53,7 +54,7 @@ where
E: PairingEngine, E: PairingEngine,
PCS: PolynomialCommitmentScheme< PCS: PolynomialCommitmentScheme<
E, E,
Polynomial = Rc<DenseMultilinearExtension<E::Fr>>,
Polynomial = Arc<DenseMultilinearExtension<E::Fr>>,
Point = Vec<E::Fr>, Point = Vec<E::Fr>,
Evaluation = E::Fr, Evaluation = E::Fr,
>, >,
@ -79,7 +80,7 @@ where
for (j, &f_i_eval) in f_i.iter().enumerate() { for (j, &f_i_eval) in f_i.iter().enumerate() {
tilde_g_eval[j] = f_i_eval * eq_t_i_list[index]; tilde_g_eval[j] = f_i_eval * eq_t_i_list[index];
} }
tilde_gs.push(Rc::new(DenseMultilinearExtension::from_evaluations_vec(
tilde_gs.push(Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_var, num_var,
tilde_g_eval, tilde_g_eval,
))); )));
@ -87,13 +88,15 @@ where
end_timer!(timer); end_timer!(timer);
let timer = start_timer!(|| format!("compute tilde eq for {} points", points.len())); let timer = start_timer!(|| format!("compute tilde eq for {} points", points.len()));
let mut tilde_eqs = vec![];
for point in points.iter() {
let eq_b_zi = build_eq_x_r_vec(point)?;
tilde_eqs.push(Rc::new(DenseMultilinearExtension::from_evaluations_vec(
num_var, eq_b_zi,
)));
}
let tilde_eqs: Vec<Arc<DenseMultilinearExtension<<E as PairingEngine>::Fr>>> = points
.par_iter()
.map(|point| {
let eq_b_zi = build_eq_x_r_vec(point).unwrap();
Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_var, eq_b_zi,
))
})
.collect();
end_timer!(timer); end_timer!(timer);
// built the virtual polynomial for SumCheck // built the virtual polynomial for SumCheck
@ -131,7 +134,7 @@ where
g_prime_evals[j] += tilde_g_eval * eq_i_a2; g_prime_evals[j] += tilde_g_eval * eq_i_a2;
} }
} }
let g_prime = Rc::new(DenseMultilinearExtension::from_evaluations_vec(
let g_prime = Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_var, num_var,
g_prime_evals, g_prime_evals,
)); ));
@ -169,7 +172,7 @@ where
E: PairingEngine, E: PairingEngine,
PCS: PolynomialCommitmentScheme< PCS: PolynomialCommitmentScheme<
E, E,
Polynomial = Rc<DenseMultilinearExtension<E::Fr>>,
Polynomial = Arc<DenseMultilinearExtension<E::Fr>>,
Point = Vec<E::Fr>, Point = Vec<E::Fr>,
Evaluation = E::Fr, Evaluation = E::Fr,
Commitment = Commitment<E>, Commitment = Commitment<E>,
@ -265,7 +268,7 @@ mod tests {
fn test_multi_open_helper<R: RngCore + CryptoRng>( fn test_multi_open_helper<R: RngCore + CryptoRng>(
ml_params: &MultilinearUniversalParams<E>, ml_params: &MultilinearUniversalParams<E>,
polys: &[Rc<DenseMultilinearExtension<Fr>>],
polys: &[Arc<DenseMultilinearExtension<Fr>>],
rng: &mut R, rng: &mut R,
) -> Result<(), PCSError> { ) -> Result<(), PCSError> {
let merged_nv = get_batched_nv(polys[0].num_vars(), polys.len()); let merged_nv = get_batched_nv(polys[0].num_vars(), polys.len());
@ -323,7 +326,7 @@ mod tests {
for num_poly in 5..6 { for num_poly in 5..6 {
for nv in 15..16 { for nv in 15..16 {
let polys1: Vec<_> = (0..num_poly) let polys1: Vec<_> = (0..num_poly)
.map(|_| Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)))
.map(|_| Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)))
.collect(); .collect();
test_multi_open_helper(&ml_params, &polys1, &mut rng)?; test_multi_open_helper(&ml_params, &polys1, &mut rng)?;
} }

+ 5
- 5
subroutines/src/pcs/multilinear_kzg/mod.rs

@ -27,9 +27,9 @@ use ark_std::{
end_timer, format, end_timer, format,
marker::PhantomData, marker::PhantomData,
rand::{CryptoRng, RngCore}, rand::{CryptoRng, RngCore},
rc::Rc,
start_timer, start_timer,
string::ToString, string::ToString,
sync::Arc,
vec, vec,
vec::Vec, vec::Vec,
One, Zero, One, Zero,
@ -59,7 +59,7 @@ impl PolynomialCommitmentScheme for MultilinearKzgPCS {
type VerifierParam = MultilinearVerifierParam<E>; type VerifierParam = MultilinearVerifierParam<E>;
type SRS = MultilinearUniversalParams<E>; type SRS = MultilinearUniversalParams<E>;
// Polynomial and its associated types // Polynomial and its associated types
type Polynomial = Rc<DenseMultilinearExtension<E::Fr>>;
type Polynomial = Arc<DenseMultilinearExtension<E::Fr>>;
type Point = Vec<E::Fr>; type Point = Vec<E::Fr>;
type Evaluation = E::Fr; type Evaluation = E::Fr;
// Commitments and proofs // Commitments and proofs
@ -356,7 +356,7 @@ mod tests {
fn test_single_helper<R: RngCore + CryptoRng>( fn test_single_helper<R: RngCore + CryptoRng>(
params: &MultilinearUniversalParams<E>, params: &MultilinearUniversalParams<E>,
poly: &Rc<DenseMultilinearExtension<Fr>>,
poly: &Arc<DenseMultilinearExtension<Fr>>,
rng: &mut R, rng: &mut R,
) -> Result<(), PCSError> { ) -> Result<(), PCSError> {
let nv = poly.num_vars(); let nv = poly.num_vars();
@ -385,11 +385,11 @@ mod tests {
let params = MultilinearKzgPCS::<E>::gen_srs_for_testing(&mut rng, 10)?; let params = MultilinearKzgPCS::<E>::gen_srs_for_testing(&mut rng, 10)?;
// normal polynomials // normal polynomials
let poly1 = Rc::new(DenseMultilinearExtension::rand(8, &mut rng));
let poly1 = Arc::new(DenseMultilinearExtension::rand(8, &mut rng));
test_single_helper(&params, &poly1, &mut rng)?; test_single_helper(&params, &poly1, &mut rng)?;
// single-variate polynomials // single-variate polynomials
let poly2 = Rc::new(DenseMultilinearExtension::rand(1, &mut rng));
let poly2 = Arc::new(DenseMultilinearExtension::rand(1, &mut rng));
test_single_helper(&params, &poly2, &mut rng)?; test_single_helper(&params, &poly2, &mut rng)?;
Ok(()) Ok(())

+ 17
- 17
subroutines/src/poly_iop/perm_check/mod.rs

@ -8,7 +8,7 @@ use crate::{
use ark_ec::PairingEngine; use ark_ec::PairingEngine;
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use ark_std::{end_timer, start_timer}; use ark_std::{end_timer, start_timer};
use std::rc::Rc;
use std::sync::Arc;
use transcript::IOPTranscript; use transcript::IOPTranscript;
/// A permutation subclaim consists of /// A permutation subclaim consists of
@ -95,7 +95,7 @@ where
impl<E, PCS> PermutationCheck<E, PCS> for PolyIOP<E::Fr> impl<E, PCS> PermutationCheck<E, PCS> for PolyIOP<E::Fr>
where where
E: PairingEngine, E: PairingEngine,
PCS: PolynomialCommitmentScheme<E, Polynomial = Rc<DenseMultilinearExtension<E::Fr>>>,
PCS: PolynomialCommitmentScheme<E, Polynomial = Arc<DenseMultilinearExtension<E::Fr>>>,
{ {
type PermutationCheckSubClaim = PermutationCheckSubClaim<E, PCS, Self>; type PermutationCheckSubClaim = PermutationCheckSubClaim<E, PCS, Self>;
type PermutationProof = Self::ProductCheckProof; type PermutationProof = Self::ProductCheckProof;
@ -192,19 +192,19 @@ mod test {
use ark_ec::PairingEngine; use ark_ec::PairingEngine;
use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; use ark_poly::{DenseMultilinearExtension, MultilinearExtension};
use ark_std::test_rng; use ark_std::test_rng;
use std::{marker::PhantomData, rc::Rc};
use std::{marker::PhantomData, sync::Arc};
type KZG = MultilinearKzgPCS<Bls12_381>; type KZG = MultilinearKzgPCS<Bls12_381>;
fn test_permutation_check_helper<E, PCS>( fn test_permutation_check_helper<E, PCS>(
pcs_param: &PCS::ProverParam, pcs_param: &PCS::ProverParam,
fxs: &[Rc<DenseMultilinearExtension<E::Fr>>],
gxs: &[Rc<DenseMultilinearExtension<E::Fr>>],
perms: &[Rc<DenseMultilinearExtension<E::Fr>>],
fxs: &[Arc<DenseMultilinearExtension<E::Fr>>],
gxs: &[Arc<DenseMultilinearExtension<E::Fr>>],
perms: &[Arc<DenseMultilinearExtension<E::Fr>>],
) -> Result<(), PolyIOPErrors> ) -> Result<(), PolyIOPErrors>
where where
E: PairingEngine, E: PairingEngine,
PCS: PolynomialCommitmentScheme<E, Polynomial = Rc<DenseMultilinearExtension<E::Fr>>>,
PCS: PolynomialCommitmentScheme<E, Polynomial = Arc<DenseMultilinearExtension<E::Fr>>>,
{ {
let nv = fxs[0].num_vars; let nv = fxs[0].num_vars;
// what's AuxInfo used for? // what's AuxInfo used for?
@ -257,8 +257,8 @@ mod test {
// good path: (w1, w2) is a permutation of (w1, w2) itself under the identify // good path: (w1, w2) is a permutation of (w1, w2) itself under the identify
// map // map
let ws = vec![ let ws = vec![
Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
]; ];
// perms is the identity map // perms is the identity map
test_permutation_check_helper::<Bls12_381, KZG>(&pcs_param, &ws, &ws, &id_perms)?; test_permutation_check_helper::<Bls12_381, KZG>(&pcs_param, &ws, &ws, &id_perms)?;
@ -267,8 +267,8 @@ mod test {
{ {
// good path: f = (w1, w2) is a permutation of g = (w2, w1) itself under a map // good path: f = (w1, w2) is a permutation of g = (w2, w1) itself under a map
let mut fs = vec![ let mut fs = vec![
Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
]; ];
let gs = fs.clone(); let gs = fs.clone();
fs.reverse(); fs.reverse();
@ -281,8 +281,8 @@ mod test {
{ {
// bad path 1: w is a not permutation of w itself under a random map // bad path 1: w is a not permutation of w itself under a random map
let ws = vec![ let ws = vec![
Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
]; ];
// perms is a random map // perms is a random map
let perms = random_permutation_mles(nv, 2, &mut rng); let perms = random_permutation_mles(nv, 2, &mut rng);
@ -296,12 +296,12 @@ mod test {
{ {
// bad path 2: f is a not permutation of g under a identity map // bad path 2: f is a not permutation of g under a identity map
let fs = vec![ let fs = vec![
Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
]; ];
let gs = vec![ let gs = vec![
Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Rc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
Arc::new(DenseMultilinearExtension::rand(nv, &mut rng)),
]; ];
// s_perm is the identity map // s_perm is the identity map

+ 8
- 8
subroutines/src/poly_iop/perm_check/util.rs

@ -5,7 +5,7 @@ use arithmetic::identity_permutation_mles;
use ark_ff::PrimeField; use ark_ff::PrimeField;
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use ark_std::{end_timer, start_timer}; use ark_std::{end_timer, start_timer};
use std::rc::Rc;
use std::sync::Arc;
/// Returns the evaluations of two list of MLEs: /// Returns the evaluations of two list of MLEs:
/// - numerators = (a1, ..., ak) /// - numerators = (a1, ..., ak)
@ -24,13 +24,13 @@ use std::rc::Rc;
pub(super) fn computer_nums_and_denoms<F: PrimeField>( pub(super) fn computer_nums_and_denoms<F: PrimeField>(
beta: &F, beta: &F,
gamma: &F, gamma: &F,
fxs: &[Rc<DenseMultilinearExtension<F>>],
gxs: &[Rc<DenseMultilinearExtension<F>>],
perms: &[Rc<DenseMultilinearExtension<F>>],
fxs: &[Arc<DenseMultilinearExtension<F>>],
gxs: &[Arc<DenseMultilinearExtension<F>>],
perms: &[Arc<DenseMultilinearExtension<F>>],
) -> Result< ) -> Result<
( (
Vec<Rc<DenseMultilinearExtension<F>>>,
Vec<Rc<DenseMultilinearExtension<F>>>,
Vec<Arc<DenseMultilinearExtension<F>>>,
Vec<Arc<DenseMultilinearExtension<F>>>,
), ),
PolyIOPErrors, PolyIOPErrors,
> { > {
@ -54,11 +54,11 @@ pub(super) fn computer_nums_and_denoms(
numerator_evals.push(numerator); numerator_evals.push(numerator);
denominator_evals.push(denominator); denominator_evals.push(denominator);
} }
numerators.push(Rc::new(DenseMultilinearExtension::from_evaluations_vec(
numerators.push(Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_vars, num_vars,
numerator_evals, numerator_evals,
))); )));
denominators.push(Rc::new(DenseMultilinearExtension::from_evaluations_vec(
denominators.push(Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_vars, num_vars,
denominator_evals, denominator_evals,
))); )));

+ 13
- 13
subroutines/src/poly_iop/prod_check/mod.rs

@ -14,7 +14,7 @@ use ark_ec::PairingEngine;
use ark_ff::{One, PrimeField, Zero}; use ark_ff::{One, PrimeField, Zero};
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use ark_std::{end_timer, start_timer}; use ark_std::{end_timer, start_timer};
use std::rc::Rc;
use std::sync::Arc;
use transcript::IOPTranscript; use transcript::IOPTranscript;
mod util; mod util;
@ -142,7 +142,7 @@ pub struct ProductCheckProof<
impl<E, PCS> ProductCheck<E, PCS> for PolyIOP<E::Fr> impl<E, PCS> ProductCheck<E, PCS> for PolyIOP<E::Fr>
where where
E: PairingEngine, E: PairingEngine,
PCS: PolynomialCommitmentScheme<E, Polynomial = Rc<DenseMultilinearExtension<E::Fr>>>,
PCS: PolynomialCommitmentScheme<E, Polynomial = Arc<DenseMultilinearExtension<E::Fr>>>,
{ {
type ProductCheckSubClaim = ProductCheckSubClaim<E::Fr, Self>; type ProductCheckSubClaim = ProductCheckSubClaim<E::Fr, Self>;
type ProductCheckProof = ProductCheckProof<E, PCS, Self>; type ProductCheckProof = ProductCheckProof<E, PCS, Self>;
@ -257,12 +257,12 @@ mod test {
use ark_ec::PairingEngine; use ark_ec::PairingEngine;
use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; use ark_poly::{DenseMultilinearExtension, MultilinearExtension};
use ark_std::test_rng; use ark_std::test_rng;
use std::{marker::PhantomData, rc::Rc};
use std::{marker::PhantomData, sync::Arc};
fn check_frac_poly<E>( fn check_frac_poly<E>(
frac_poly: &Rc<DenseMultilinearExtension<E::Fr>>,
fs: &[Rc<DenseMultilinearExtension<E::Fr>>],
gs: &[Rc<DenseMultilinearExtension<E::Fr>>],
frac_poly: &Arc<DenseMultilinearExtension<E::Fr>>,
fs: &[Arc<DenseMultilinearExtension<E::Fr>>],
gs: &[Arc<DenseMultilinearExtension<E::Fr>>],
) where ) where
E: PairingEngine, E: PairingEngine,
{ {
@ -285,14 +285,14 @@ mod test {
// fs and gs are guaranteed to have the same product // fs and gs are guaranteed to have the same product
// fs and hs doesn't have the same product // fs and hs doesn't have the same product
fn test_product_check_helper<E, PCS>( fn test_product_check_helper<E, PCS>(
fs: &[Rc<DenseMultilinearExtension<E::Fr>>],
gs: &[Rc<DenseMultilinearExtension<E::Fr>>],
hs: &[Rc<DenseMultilinearExtension<E::Fr>>],
fs: &[Arc<DenseMultilinearExtension<E::Fr>>],
gs: &[Arc<DenseMultilinearExtension<E::Fr>>],
hs: &[Arc<DenseMultilinearExtension<E::Fr>>],
pcs_param: &PCS::ProverParam, pcs_param: &PCS::ProverParam,
) -> Result<(), PolyIOPErrors> ) -> Result<(), PolyIOPErrors>
where where
E: PairingEngine, E: PairingEngine,
PCS: PolynomialCommitmentScheme<E, Polynomial = Rc<DenseMultilinearExtension<E::Fr>>>,
PCS: PolynomialCommitmentScheme<E, Polynomial = Arc<DenseMultilinearExtension<E::Fr>>>,
{ {
let mut transcript = <PolyIOP<E::Fr> as ProductCheck<E, PCS>>::init_transcript(); let mut transcript = <PolyIOP<E::Fr> as ProductCheck<E, PCS>>::init_transcript();
transcript.append_message(b"testing", b"initializing transcript for testing")?; transcript.append_message(b"testing", b"initializing transcript for testing")?;
@ -352,11 +352,11 @@ mod test {
let f2: DenseMultilinearExtension<Fr> = DenseMultilinearExtension::rand(nv, &mut rng); let f2: DenseMultilinearExtension<Fr> = DenseMultilinearExtension::rand(nv, &mut rng);
let mut g2 = f2.clone(); let mut g2 = f2.clone();
g2.evaluations.reverse(); g2.evaluations.reverse();
let fs = vec![Rc::new(f1), Rc::new(f2)];
let gs = vec![Rc::new(g2), Rc::new(g1)];
let fs = vec![Arc::new(f1), Arc::new(f2)];
let gs = vec![Arc::new(g2), Arc::new(g1)];
let mut hs = vec![]; let mut hs = vec![];
for _ in 0..fs.len() { for _ in 0..fs.len() {
hs.push(Rc::new(DenseMultilinearExtension::rand(
hs.push(Arc::new(DenseMultilinearExtension::rand(
fs[0].num_vars, fs[0].num_vars,
&mut rng, &mut rng,
))); )));

+ 18
- 16
subroutines/src/poly_iop/prod_check/util.rs

@ -2,10 +2,10 @@
use crate::poly_iop::{errors::PolyIOPErrors, structs::IOPProof, zero_check::ZeroCheck, PolyIOP}; use crate::poly_iop::{errors::PolyIOPErrors, structs::IOPProof, zero_check::ZeroCheck, PolyIOP};
use arithmetic::{get_index, VirtualPolynomial}; use arithmetic::{get_index, VirtualPolynomial};
use ark_ff::PrimeField;
use ark_ff::{batch_inversion, PrimeField};
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use ark_std::{end_timer, start_timer}; use ark_std::{end_timer, start_timer};
use std::rc::Rc;
use std::sync::Arc;
use transcript::IOPTranscript; use transcript::IOPTranscript;
/// Compute multilinear fractional polynomial s.t. frac(x) = f1(x) * ... * fk(x) /// Compute multilinear fractional polynomial s.t. frac(x) = f1(x) * ... * fk(x)
@ -14,9 +14,9 @@ use transcript::IOPTranscript;
/// The caller needs to sanity-check that the number of polynomials and /// The caller needs to sanity-check that the number of polynomials and
/// variables match in fxs and gxs; and gi(x) has no zero entries. /// variables match in fxs and gxs; and gi(x) has no zero entries.
pub(super) fn compute_frac_poly<F: PrimeField>( pub(super) fn compute_frac_poly<F: PrimeField>(
fxs: &[Rc<DenseMultilinearExtension<F>>],
gxs: &[Rc<DenseMultilinearExtension<F>>],
) -> Result<Rc<DenseMultilinearExtension<F>>, PolyIOPErrors> {
fxs: &[Arc<DenseMultilinearExtension<F>>],
gxs: &[Arc<DenseMultilinearExtension<F>>],
) -> Result<Arc<DenseMultilinearExtension<F>>, PolyIOPErrors> {
let start = start_timer!(|| "compute frac(x)"); let start = start_timer!(|| "compute frac(x)");
let mut f_evals = vec![F::one(); 1 << fxs[0].num_vars]; let mut f_evals = vec![F::one(); 1 << fxs[0].num_vars];
@ -31,17 +31,19 @@ pub(super) fn compute_frac_poly(
*g_eval *= gi; *g_eval *= gi;
} }
} }
batch_inversion(&mut g_evals[..]);
for (f_eval, g_eval) in f_evals.iter_mut().zip(g_evals.iter()) { for (f_eval, g_eval) in f_evals.iter_mut().zip(g_evals.iter()) {
if *g_eval == F::zero() { if *g_eval == F::zero() {
return Err(PolyIOPErrors::InvalidParameters( return Err(PolyIOPErrors::InvalidParameters(
"gxs has zero entries in the boolean hypercube".to_string(), "gxs has zero entries in the boolean hypercube".to_string(),
)); ));
} }
*f_eval /= g_eval;
*f_eval *= g_eval;
} }
end_timer!(start); end_timer!(start);
Ok(Rc::new(DenseMultilinearExtension::from_evaluations_vec(
Ok(Arc::new(DenseMultilinearExtension::from_evaluations_vec(
fxs[0].num_vars, fxs[0].num_vars,
f_evals, f_evals,
))) )))
@ -55,8 +57,8 @@ pub(super) fn compute_frac_poly(
/// The caller needs to check num_vars matches in f and g /// The caller needs to check num_vars matches in f and g
/// Cost: linear in N. /// Cost: linear in N.
pub(super) fn compute_product_poly<F: PrimeField>( pub(super) fn compute_product_poly<F: PrimeField>(
frac_poly: &Rc<DenseMultilinearExtension<F>>,
) -> Result<Rc<DenseMultilinearExtension<F>>, PolyIOPErrors> {
frac_poly: &Arc<DenseMultilinearExtension<F>>,
) -> Result<Arc<DenseMultilinearExtension<F>>, PolyIOPErrors> {
let start = start_timer!(|| "compute evaluations of prod polynomial"); let start = start_timer!(|| "compute evaluations of prod polynomial");
let num_vars = frac_poly.num_vars; let num_vars = frac_poly.num_vars;
let frac_evals = &frac_poly.evaluations; let frac_evals = &frac_poly.evaluations;
@ -96,7 +98,7 @@ pub(super) fn compute_product_poly(
prod_x_evals.push(F::zero()); prod_x_evals.push(F::zero());
end_timer!(start); end_timer!(start);
Ok(Rc::new(DenseMultilinearExtension::from_evaluations_vec(
Ok(Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_vars, num_vars,
prod_x_evals, prod_x_evals,
))) )))
@ -111,10 +113,10 @@ pub(super) fn compute_product_poly(
/// ///
/// Cost: O(N) /// Cost: O(N)
pub(super) fn prove_zero_check<F: PrimeField>( pub(super) fn prove_zero_check<F: PrimeField>(
fxs: &[Rc<DenseMultilinearExtension<F>>],
gxs: &[Rc<DenseMultilinearExtension<F>>],
frac_poly: &Rc<DenseMultilinearExtension<F>>,
prod_x: &Rc<DenseMultilinearExtension<F>>,
fxs: &[Arc<DenseMultilinearExtension<F>>],
gxs: &[Arc<DenseMultilinearExtension<F>>],
frac_poly: &Arc<DenseMultilinearExtension<F>>,
prod_x: &Arc<DenseMultilinearExtension<F>>,
alpha: &F, alpha: &F,
transcript: &mut IOPTranscript<F>, transcript: &mut IOPTranscript<F>,
) -> Result<(IOPProof<F>, VirtualPolynomial<F>), PolyIOPErrors> { ) -> Result<(IOPProof<F>, VirtualPolynomial<F>), PolyIOPErrors> {
@ -135,10 +137,10 @@ pub(super) fn prove_zero_check(
p2_evals[x] = prod_x.evaluations[x1]; p2_evals[x] = prod_x.evaluations[x1];
} }
} }
let p1 = Rc::new(DenseMultilinearExtension::from_evaluations_vec(
let p1 = Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_vars, p1_evals, num_vars, p1_evals,
)); ));
let p2 = Rc::new(DenseMultilinearExtension::from_evaluations_vec(
let p2 = Arc::new(DenseMultilinearExtension::from_evaluations_vec(
num_vars, p2_evals, num_vars, p2_evals,
)); ));

+ 4
- 4
subroutines/src/poly_iop/sum_check/mod.rs

@ -9,7 +9,7 @@ use arithmetic::{VPAuxInfo, VirtualPolynomial};
use ark_ff::PrimeField; use ark_ff::PrimeField;
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use ark_std::{end_timer, start_timer}; use ark_std::{end_timer, start_timer};
use std::{fmt::Debug, rc::Rc};
use std::{fmt::Debug, sync::Arc};
use transcript::IOPTranscript; use transcript::IOPTranscript;
mod prover; mod prover;
@ -127,7 +127,7 @@ impl SumCheck for PolyIOP {
type SumCheckProof = IOPProof<F>; type SumCheckProof = IOPProof<F>;
type VirtualPolynomial = VirtualPolynomial<F>; type VirtualPolynomial = VirtualPolynomial<F>;
type VPAuxInfo = VPAuxInfo<F>; type VPAuxInfo = VPAuxInfo<F>;
type MultilinearExtension = Rc<DenseMultilinearExtension<F>>;
type MultilinearExtension = Arc<DenseMultilinearExtension<F>>;
type SumCheckSubClaim = SumCheckSubClaim<F>; type SumCheckSubClaim = SumCheckSubClaim<F>;
type Transcript = IOPTranscript<F>; type Transcript = IOPTranscript<F>;
@ -210,7 +210,7 @@ mod test {
use ark_ff::UniformRand; use ark_ff::UniformRand;
use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; use ark_poly::{DenseMultilinearExtension, MultilinearExtension};
use ark_std::test_rng; use ark_std::test_rng;
use std::rc::Rc;
use std::sync::Arc;
fn test_sumcheck( fn test_sumcheck(
nv: usize, nv: usize,
@ -326,7 +326,7 @@ mod test {
fn test_shared_reference() -> Result<(), PolyIOPErrors> { fn test_shared_reference() -> Result<(), PolyIOPErrors> {
let mut rng = test_rng(); let mut rng = test_rng();
let ml_extensions: Vec<_> = (0..5) let ml_extensions: Vec<_> = (0..5)
.map(|_| Rc::new(DenseMultilinearExtension::<Fr>::rand(8, &mut rng)))
.map(|_| Arc::new(DenseMultilinearExtension::<Fr>::rand(8, &mut rng)))
.collect(); .collect();
let mut poly = VirtualPolynomial::new(8); let mut poly = VirtualPolynomial::new(8);
poly.add_mle_list( poly.add_mle_list(

+ 11
- 13
subroutines/src/poly_iop/sum_check/prover.rs

@ -9,8 +9,8 @@ use arithmetic::{fix_variables, VirtualPolynomial};
use ark_ff::PrimeField; use ark_ff::PrimeField;
use ark_poly::DenseMultilinearExtension; use ark_poly::DenseMultilinearExtension;
use ark_std::{end_timer, start_timer, vec::Vec}; use ark_std::{end_timer, start_timer, vec::Vec};
use rayon::prelude::IntoParallelIterator;
use std::rc::Rc;
use rayon::prelude::{IntoParallelIterator, IntoParallelRefIterator};
use std::sync::Arc;
#[cfg(feature = "parallel")] #[cfg(feature = "parallel")]
use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator}; use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
@ -71,7 +71,7 @@ impl SumCheckProver for IOPProverState {
let mut flattened_ml_extensions: Vec<DenseMultilinearExtension<F>> = self let mut flattened_ml_extensions: Vec<DenseMultilinearExtension<F>> = self
.poly .poly
.flattened_ml_extensions .flattened_ml_extensions
.iter()
.par_iter()
.map(|x| x.as_ref().clone()) .map(|x| x.as_ref().clone())
.collect(); .collect();
@ -132,13 +132,11 @@ impl SumCheckProver for IOPProverState {
} }
}) })
.collect::<Vec<F>>(); .collect::<Vec<F>>();
for val in evals.iter() {
*e += val
}
*e += evals.par_iter().sum::<F>();
} }
} else { } else {
for (t, e) in products_sum.iter_mut().enumerate() { for (t, e) in products_sum.iter_mut().enumerate() {
let t = F::from(t as u64);
let t = F::from(t as u128);
let products = (0..1 << (self.poly.aux_info.num_variables - self.round)) let products = (0..1 << (self.poly.aux_info.num_variables - self.round))
.into_par_iter() .into_par_iter()
.map(|b| { .map(|b| {
@ -149,6 +147,9 @@ impl SumCheckProver for IOPProverState {
let mut product = *coefficient; let mut product = *coefficient;
for &f in products.iter().take(num_mles) { for &f in products.iter().take(num_mles) {
let table = &flattened_ml_extensions[f]; // f's range is checked in init let table = &flattened_ml_extensions[f]; // f's range is checked in init
// TODO: Could be done faster by cashing the results from the
// previous t and adding the diff
// Also possible to use Karatsuba multiplication
product *= product *=
table[b << 1] + (table[(b << 1) + 1] - table[b << 1]) * t; table[b << 1] + (table[(b << 1) + 1] - table[b << 1]) * t;
} }
@ -158,10 +159,7 @@ impl SumCheckProver for IOPProverState {
tmp tmp
}) })
.collect::<Vec<F>>(); .collect::<Vec<F>>();
for i in products.iter() {
*e += i
}
*e += products.par_iter().sum::<F>();
} }
} }
} }
@ -187,8 +185,8 @@ impl SumCheckProver for IOPProverState {
// update prover's state to the partial evaluated polynomial // update prover's state to the partial evaluated polynomial
self.poly.flattened_ml_extensions = flattened_ml_extensions self.poly.flattened_ml_extensions = flattened_ml_extensions
.iter()
.map(|x| Rc::new(x.clone()))
.par_iter()
.map(|x| Arc::new(x.clone()))
.collect(); .collect();
// end_timer!(compute_sum); // end_timer!(compute_sum);

Loading…
Cancel
Save