prepare for cleanup of SONIC feature

This commit is contained in:
Alex Vlasov 2019-03-31 09:00:50 +03:00
parent c53de6eee8
commit ca1f41c7ff
5 changed files with 157 additions and 61 deletions

@ -172,6 +172,9 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
value value
} }
use std::time::Instant;
let start = Instant::now();
let mut c_openings = vec![]; let mut c_openings = vec![];
for y in &y_values { for y in &y_values {
let value = compute_value::<E>(y, &s_poly_positive, &s_poly_negative); let value = compute_value::<E>(y, &s_poly_positive, &s_poly_negative);
@ -206,6 +209,8 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
c_openings.push((opening, value)); 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. // 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 // 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. // challenges instead and open up a random linear combination.
@ -215,6 +220,8 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
let mut expected_value = E::Fr::zero(); let mut expected_value = E::Fr::zero();
// TODO: this part can be further parallelized due to synthesis of S(X, y) being singlethreaded // 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()) { for (y, c_opening) in y_values.iter().zip(c_openings.iter()) {
// Compute s(X, y_i) // Compute s(X, y_i)
let (s_poly_negative, s_poly_positive) = { let (s_poly_negative, s_poly_positive) = {
@ -243,6 +250,8 @@ pub fn create_aggregate_on_srs_using_information<E: Engine, C: Circuit<E>, S: Sy
// } // }
} }
println!("Re-evaluation of {} S polynomials taken {:?}", y_values.len(), start.elapsed());
let s_opening = { let s_opening = {
let mut value = expected_value; let mut value = expected_value;
value.negate(); value.negate();

@ -41,18 +41,27 @@ impl<E: Engine> SxEval<E> {
let u = vec![E::Fr::zero(); n]; let u = vec![E::Fr::zero(); n];
let v = 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 minus_one = E::Fr::one();
let mut tmp2 = y_inv; minus_one.negate();
for w in &mut w {
let mut new = tmp1; let mut w = vec![minus_one; n];
new.add_assign(&tmp2); let mut w_neg = vec![minus_one; n];
new.negate(); mut_distribute_consequitive_powers(&mut w[..], y, y);
*w = new; mut_distribute_consequitive_powers(&mut w_neg[..], y_inv, y_inv);
tmp1.mul_assign(&y); add_polynomials(&mut w[..], &w_neg[..]);
tmp2.mul_assign(&y_inv);
} // 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 { SxEval {
y, y,
@ -169,36 +178,54 @@ pub struct SyEval<E: Engine> {
impl<E: Engine> SyEval<E> { impl<E: Engine> SyEval<E> {
pub fn new(x: E::Fr, n: usize, q: usize) -> Self { pub fn new(x: E::Fr, n: usize, q: usize) -> Self {
let xinv = x.inverse().unwrap(); let xinv = x.inverse().unwrap();
let mut tmp = E::Fr::one(); let mut a = vec![E::Fr::one(); n];
let mut a = vec![E::Fr::zero(); n]; let mut b = vec![E::Fr::one(); n];
for a in &mut a {
tmp.mul_assign(&xinv); // tmp = x^{-i}
*a = tmp;
}
let mut tmp = E::Fr::one(); mut_distribute_consequitive_powers(&mut a[..], xinv, xinv);
let mut b = vec![E::Fr::zero(); n]; mut_distribute_consequitive_powers(&mut b[..], x, x);
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 c = vec![E::Fr::one(); n];
let mut negative_coeffs = vec![E::Fr::zero(); n]; mut_distribute_consequitive_powers(&mut c[..], x.pow(&[(n+1) as u64]), x);
let mut c = vec![E::Fr::zero(); n]; let mut minus_one = E::Fr::one();
for ((c, positive_coeff), negative_coeff) in c.iter_mut().zip(&mut positive_coeffs).zip(&mut negative_coeffs) { minus_one.negate();
tmp.mul_assign(&x); // tmp = x^{i+N}
*c = tmp;
// - \sum\limits_{i=1}^N Y^i X^{i+N} let mut positive_coeffs = vec![minus_one; n];
let mut tmp = tmp; mut_distribute_consequitive_powers(&mut positive_coeffs[..], x.pow(&[(n+1) as u64]), x);
tmp.negate(); let negative_coeffs = positive_coeffs.clone();
*positive_coeff = tmp;
// - \sum\limits_{i=1}^N Y^{-i} X^{i+N} positive_coeffs.resize(n + q, E::Fr::zero());
*negative_coeff = tmp;
} // 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 { SyEval {
a, a,

@ -51,22 +51,28 @@ pub fn create_advice_on_information_and_srs<E: Engine, C: Circuit<E>, S: Synthes
// Compute s(z, y) // Compute s(z, y)
let mut szy = E::Fr::zero(); let mut szy = E::Fr::zero();
{ {
let mut tmp = z; szy.add_assign(& evaluate_at_consequitive_powers(& s_poly_positive[..], z, z));
for &p in &s_poly_positive { szy.add_assign(& evaluate_at_consequitive_powers(& s_poly_negative[..], z_inv, z_inv));
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);
}
} }
// 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 // Compute kate opening
let opening = { let opening = {
let mut open = szy; let mut open = szy;
@ -232,7 +238,6 @@ pub fn create_proof_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
// create r(X, 1) by observation that it's just a series of coefficients. // 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} // 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 // 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; let mut rx1 = wires.b;
rx1.extend(wires.c); rx1.extend(wires.c);
rx1.extend(blindings.clone()); rx1.extend(blindings.clone());
@ -260,7 +265,6 @@ pub fn create_proof_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
tmp.poly() tmp.poly()
}; };
// TODO: Parallelize
// r'(X, y) = r(X, y) + s(X, y). Note `y` - those are evaluated at the point already // r'(X, y) = r(X, y) + s(X, y). Note `y` - those are evaluated at the point already
let mut rxy_prime = rxy.clone(); let mut rxy_prime = rxy.clone();
{ {

@ -9,4 +9,5 @@ mod grand_product_argument;
mod permutation_argument; mod permutation_argument;
pub mod padding; pub mod padding;
pub use self::wellformed_argument::{WellformednessArgument, WellformednessProof}; pub use self::wellformed_argument::{WellformednessArgument, WellformednessProof};
pub use self::permutation_argument::{PermutationArgument, PermutationProof, Proof};

@ -125,15 +125,15 @@ pub fn polynomial_commitment_opening<
{ {
// let poly = parallel_kate_divison::<E, _>(polynomial_coefficients, point); // let poly = parallel_kate_divison::<E, _>(polynomial_coefficients, point);
use std::time::Instant; // use std::time::Instant;
let start = Instant::now(); // let start = Instant::now();
let poly = kate_divison( let poly = kate_divison(
polynomial_coefficients, polynomial_coefficients,
point, 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 negative_poly = poly[0..largest_negative_power].iter().rev();
let positive_poly = poly[largest_negative_power..].iter(); 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<Item = &'a G>,
// IS: IntoIterator<Item = &'a G::Scalar>,
// >(
// 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<<G::Scalar as PrimeField>::Repr> = s.into_iter().map(|e| e.into_repr()).collect::<Vec<_>>();
// let g: Vec<G> = g.into_iter().map(|e| *e).collect::<Vec<_>>();
// 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< pub fn multiexp<
'a, 'a,
G: CurveAffine, G: CurveAffine,
@ -292,7 +335,10 @@ where
IS::IntoIter: ExactSizeIterator, IS::IntoIter: ExactSizeIterator,
{ {
use crate::multicore::Worker; 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<<G::Scalar as PrimeField>::Repr> = s.into_iter().map(|e| e.into_repr()).collect::<Vec<_>>(); let s: Vec<<G::Scalar as PrimeField>::Repr> = s.into_iter().map(|e| e.into_repr()).collect::<Vec<_>>();
let g: Vec<G> = g.into_iter().map(|e| *e).collect::<Vec<_>>(); let g: Vec<G> = g.into_iter().map(|e| *e).collect::<Vec<_>>();
@ -301,15 +347,24 @@ where
let pool = Worker::new(); let pool = Worker::new();
let result = dense_multiexp( // use std::time::Instant;
// let start = Instant::now();
let result = multiexp(
&pool, &pool,
&g, (Arc::new(g), 0),
&s FullDensity,
).unwrap(); Arc::new(s)
).wait().unwrap();
// println!("Multiexp taken {:?}", start.elapsed());
result result
} }
pub fn multiexp_serial< pub fn multiexp_serial<
'a, 'a,
G: CurveAffine, G: CurveAffine,