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
}
use std::time::Instant;
let start = Instant::now();
let mut c_openings = vec![];
for y in &y_values {
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));
}
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<E: Engine, C: Circuit<E>, 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<E: Engine, C: Circuit<E>, S: Sy
// }
}
println!("Re-evaluation of {} S polynomials taken {:?}", y_values.len(), start.elapsed());
let s_opening = {
let mut value = expected_value;
value.negate();

@ -41,18 +41,27 @@ impl<E: Engine> SxEval<E> {
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<E: Engine> {
impl<E: Engine> SyEval<E> {
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,

@ -51,22 +51,28 @@ pub fn create_advice_on_information_and_srs<E: Engine, C: Circuit<E>, 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<E: Engine, C: Circuit<E>, 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<E: Engine, C: Circuit<E>, 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();
{

@ -10,3 +10,4 @@ mod permutation_argument;
pub mod padding;
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);
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<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<
'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<<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<_>>();
@ -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,