From ca1f41c7ff153d461d3c84f49b1c355dd27430d7 Mon Sep 17 00:00:00 2001 From: Alex Vlasov Date: Sun, 31 Mar 2019 09:00:50 +0300 Subject: [PATCH] prepare for cleanup of SONIC feature --- src/sonic/helped/helper.rs | 9 ++++ src/sonic/helped/poly.rs | 99 ++++++++++++++++++++++++-------------- src/sonic/helped/prover.rs | 36 ++++++++------ src/sonic/unhelped/mod.rs | 3 +- src/sonic/util.rs | 71 ++++++++++++++++++++++++--- 5 files changed, 157 insertions(+), 61 deletions(-) diff --git a/src/sonic/helped/helper.rs b/src/sonic/helped/helper.rs index c9f22ca..43b1995 100644 --- a/src/sonic/helped/helper.rs +++ b/src/sonic/helped/helper.rs @@ -172,6 +172,9 @@ pub fn create_aggregate_on_srs_using_information, S: Sy value } + use std::time::Instant; + let start = Instant::now(); + let mut c_openings = vec![]; for y in &y_values { let value = compute_value::(y, &s_poly_positive, &s_poly_negative); @@ -206,6 +209,8 @@ pub fn create_aggregate_on_srs_using_information, S: Sy c_openings.push((opening, value)); } + println!("Evaluation of s(z, Y) taken {:?}", start.elapsed()); + // Okay, great. Now we need to open up each S at the same point z to the same value. // Since we're opening up all the S's at the same point, we create a bunch of random // challenges instead and open up a random linear combination. @@ -215,6 +220,8 @@ pub fn create_aggregate_on_srs_using_information, S: Sy let mut expected_value = E::Fr::zero(); // TODO: this part can be further parallelized due to synthesis of S(X, y) being singlethreaded + let start = Instant::now(); + for (y, c_opening) in y_values.iter().zip(c_openings.iter()) { // Compute s(X, y_i) let (s_poly_negative, s_poly_positive) = { @@ -243,6 +250,8 @@ pub fn create_aggregate_on_srs_using_information, S: Sy // } } + println!("Re-evaluation of {} S polynomials taken {:?}", y_values.len(), start.elapsed()); + let s_opening = { let mut value = expected_value; value.negate(); diff --git a/src/sonic/helped/poly.rs b/src/sonic/helped/poly.rs index b541b55..023791b 100644 --- a/src/sonic/helped/poly.rs +++ b/src/sonic/helped/poly.rs @@ -41,18 +41,27 @@ impl SxEval { let u = vec![E::Fr::zero(); n]; let v = vec![E::Fr::zero(); n]; - let mut w = vec![E::Fr::zero(); n]; - let mut tmp1 = y; - let mut tmp2 = y_inv; - for w in &mut w { - let mut new = tmp1; - new.add_assign(&tmp2); - new.negate(); - *w = new; - tmp1.mul_assign(&y); - tmp2.mul_assign(&y_inv); - } + let mut minus_one = E::Fr::one(); + minus_one.negate(); + + let mut w = vec![minus_one; n]; + let mut w_neg = vec![minus_one; n]; + mut_distribute_consequitive_powers(&mut w[..], y, y); + mut_distribute_consequitive_powers(&mut w_neg[..], y_inv, y_inv); + add_polynomials(&mut w[..], &w_neg[..]); + + // let mut w = vec![E::Fr::zero(); n]; + // let mut tmp1 = y; + // let mut tmp2 = y_inv; + // for w in &mut w { + // let mut new = tmp1; + // new.add_assign(&tmp2); + // new.negate(); + // *w = new; + // tmp1.mul_assign(&y); + // tmp2.mul_assign(&y_inv); + // } SxEval { y, @@ -169,36 +178,54 @@ pub struct SyEval { impl SyEval { pub fn new(x: E::Fr, n: usize, q: usize) -> Self { let xinv = x.inverse().unwrap(); - let mut tmp = E::Fr::one(); - let mut a = vec![E::Fr::zero(); n]; - for a in &mut a { - tmp.mul_assign(&xinv); // tmp = x^{-i} - *a = tmp; - } + let mut a = vec![E::Fr::one(); n]; + let mut b = vec![E::Fr::one(); n]; - let mut tmp = E::Fr::one(); - let mut b = vec![E::Fr::zero(); n]; - for b in &mut b { - tmp.mul_assign(&x); // tmp = x^{i} - *b = tmp; - } + mut_distribute_consequitive_powers(&mut a[..], xinv, xinv); + mut_distribute_consequitive_powers(&mut b[..], x, x); - let mut positive_coeffs = vec![E::Fr::zero(); n + q]; - let mut negative_coeffs = vec![E::Fr::zero(); n]; + let mut c = vec![E::Fr::one(); n]; + mut_distribute_consequitive_powers(&mut c[..], x.pow(&[(n+1) as u64]), x); - let mut c = vec![E::Fr::zero(); n]; - for ((c, positive_coeff), negative_coeff) in c.iter_mut().zip(&mut positive_coeffs).zip(&mut negative_coeffs) { - tmp.mul_assign(&x); // tmp = x^{i+N} - *c = tmp; + let mut minus_one = E::Fr::one(); + minus_one.negate(); - // - \sum\limits_{i=1}^N Y^i X^{i+N} - let mut tmp = tmp; - tmp.negate(); - *positive_coeff = tmp; + let mut positive_coeffs = vec![minus_one; n]; + mut_distribute_consequitive_powers(&mut positive_coeffs[..], x.pow(&[(n+1) as u64]), x); + let negative_coeffs = positive_coeffs.clone(); - // - \sum\limits_{i=1}^N Y^{-i} X^{i+N} - *negative_coeff = tmp; - } + positive_coeffs.resize(n + q, E::Fr::zero()); + + // let mut tmp = E::Fr::one(); + // let mut a = vec![E::Fr::zero(); n]; + // for a in &mut a { + // tmp.mul_assign(&xinv); // tmp = x^{-i} + // *a = tmp; + // } + + // let mut tmp = E::Fr::one(); + // let mut b = vec![E::Fr::zero(); n]; + // for b in &mut b { + // tmp.mul_assign(&x); // tmp = x^{i} + // *b = tmp; + // } + + // let mut positive_coeffs = vec![E::Fr::zero(); n + q]; + // let mut negative_coeffs = vec![E::Fr::zero(); n]; + + // let mut c = vec![E::Fr::zero(); n]; + // for ((c, positive_coeff), negative_coeff) in c.iter_mut().zip(&mut positive_coeffs).zip(&mut negative_coeffs) { + // tmp.mul_assign(&x); // tmp = x^{i+N} + // *c = tmp; + + // // - \sum\limits_{i=1}^N Y^i X^{i+N} + // let mut tmp = tmp; + // tmp.negate(); + // *positive_coeff = tmp; + + // // - \sum\limits_{i=1}^N Y^{-i} X^{i+N} + // *negative_coeff = tmp; + // } SyEval { a, diff --git a/src/sonic/helped/prover.rs b/src/sonic/helped/prover.rs index d84eef0..58a4278 100644 --- a/src/sonic/helped/prover.rs +++ b/src/sonic/helped/prover.rs @@ -51,22 +51,28 @@ pub fn create_advice_on_information_and_srs, S: Synthes // Compute s(z, y) let mut szy = E::Fr::zero(); { - let mut tmp = z; - for &p in &s_poly_positive { - let mut p = p; - p.mul_assign(&tmp); - szy.add_assign(&p); - tmp.mul_assign(&z); - } - let mut tmp = z_inv; - for &p in &s_poly_negative { - let mut p = p; - p.mul_assign(&tmp); - szy.add_assign(&p); - tmp.mul_assign(&z_inv); - } + szy.add_assign(& evaluate_at_consequitive_powers(& s_poly_positive[..], z, z)); + szy.add_assign(& evaluate_at_consequitive_powers(& s_poly_negative[..], z_inv, z_inv)); } + // let mut szy = E::Fr::zero(); + // { + // let mut tmp = z; + // for &p in &s_poly_positive { + // let mut p = p; + // p.mul_assign(&tmp); + // szy.add_assign(&p); + // tmp.mul_assign(&z); + // } + // let mut tmp = z_inv; + // for &p in &s_poly_negative { + // let mut p = p; + // p.mul_assign(&tmp); + // szy.add_assign(&p); + // tmp.mul_assign(&z_inv); + // } + // } + // Compute kate opening let opening = { let mut open = szy; @@ -232,7 +238,6 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( // create r(X, 1) by observation that it's just a series of coefficients. // Used representation is for powers X^{-2n}...X^{-n-1}, X^{-n}...X^{-1}, X^{1}...X^{n} // Same representation is ok for r(X, Y) too cause powers always match - // TODO: add blindings c_{n+1}*X^{-2n - 1}, c_{n+2}*X^{-2n - 2}, c_{n+3}*X^{-2n - 3}, c_{n+4}*X^{-2n - 4} let mut rx1 = wires.b; rx1.extend(wires.c); rx1.extend(blindings.clone()); @@ -260,7 +265,6 @@ pub fn create_proof_on_srs, S: SynthesisDriver>( tmp.poly() }; - // TODO: Parallelize // r'(X, y) = r(X, y) + s(X, y). Note `y` - those are evaluated at the point already let mut rxy_prime = rxy.clone(); { diff --git a/src/sonic/unhelped/mod.rs b/src/sonic/unhelped/mod.rs index 4cece77..7da3f6a 100644 --- a/src/sonic/unhelped/mod.rs +++ b/src/sonic/unhelped/mod.rs @@ -9,4 +9,5 @@ mod grand_product_argument; mod permutation_argument; pub mod padding; -pub use self::wellformed_argument::{WellformednessArgument, WellformednessProof}; \ No newline at end of file +pub use self::wellformed_argument::{WellformednessArgument, WellformednessProof}; +pub use self::permutation_argument::{PermutationArgument, PermutationProof, Proof}; \ No newline at end of file diff --git a/src/sonic/util.rs b/src/sonic/util.rs index be87754..fefc4d6 100644 --- a/src/sonic/util.rs +++ b/src/sonic/util.rs @@ -125,15 +125,15 @@ pub fn polynomial_commitment_opening< { // let poly = parallel_kate_divison::(polynomial_coefficients, point); - use std::time::Instant; - let start = Instant::now(); + // use std::time::Instant; + // let start = Instant::now(); let poly = kate_divison( polynomial_coefficients, point, ); - println!("Kate division of size {} taken {:?}", poly.len(), start.elapsed()); + // println!("Kate division of size {} taken {:?}", poly.len(), start.elapsed()); let negative_poly = poly[0..largest_negative_power].iter().rev(); let positive_poly = poly[largest_negative_power..].iter(); @@ -278,6 +278,49 @@ pub fn mut_distribute_consequitive_powers<'a, F: Field> ( }); } +// pub fn multiexp< +// 'a, +// G: CurveAffine, +// IB: IntoIterator, +// IS: IntoIterator, +// >( +// g: IB, +// s: IS, +// ) -> G::Projective +// where +// IB::IntoIter: ExactSizeIterator + Clone, +// IS::IntoIter: ExactSizeIterator, +// { +// use crate::multicore::Worker; +// use crate::multiexp::dense_multiexp; + +// use std::time::Instant; +// let start = Instant::now(); + +// let s: Vec<::Repr> = s.into_iter().map(|e| e.into_repr()).collect::>(); +// let g: Vec = g.into_iter().map(|e| *e).collect::>(); + +// println!("Multiexp collecting taken {:?}", start.elapsed()); + +// assert_eq!(s.len(), g.len(), "scalars and exponents must have the same length"); + +// let start = Instant::now(); +// let pool = Worker::new(); +// println!("Multiexp pool creation taken {:?}", start.elapsed()); + +// let start = Instant::now(); + +// let result = dense_multiexp( +// &pool, +// &g, +// &s +// ).unwrap(); + +// println!("Multiexp taken {:?}", start.elapsed()); + +// result +// } + pub fn multiexp< 'a, G: CurveAffine, @@ -292,7 +335,10 @@ where IS::IntoIter: ExactSizeIterator, { use crate::multicore::Worker; - use crate::multiexp::dense_multiexp; + use crate::multiexp::multiexp; + use crate::source::FullDensity; + use futures::Future; + use std::sync::Arc; let s: Vec<::Repr> = s.into_iter().map(|e| e.into_repr()).collect::>(); let g: Vec = g.into_iter().map(|e| *e).collect::>(); @@ -301,15 +347,24 @@ where let pool = Worker::new(); - let result = dense_multiexp( + // use std::time::Instant; + // let start = Instant::now(); + + let result = multiexp( &pool, - &g, - &s - ).unwrap(); + (Arc::new(g), 0), + FullDensity, + Arc::new(s) + ).wait().unwrap(); + + // println!("Multiexp taken {:?}", start.elapsed()); result } + + + pub fn multiexp_serial< 'a, G: CurveAffine,