parallelize almost everything
This commit is contained in:
parent
57a6ce94e8
commit
2d69758c18
@ -19,6 +19,9 @@ use std::io::{self, Read, Write};
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
|
use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
|
||||||
|
|
||||||
|
pub const NUM_BLINDINGS: usize = 4;
|
||||||
|
// pub const NUM_BLINDINGS: usize = 0;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq)]
|
#[derive(Clone, Debug, Eq)]
|
||||||
pub struct SxyAdvice<E: Engine> {
|
pub struct SxyAdvice<E: Engine> {
|
||||||
pub s: E::G1Affine,
|
pub s: E::G1Affine,
|
||||||
@ -34,7 +37,6 @@ impl<E: Engine> PartialEq for SxyAdvice<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq)]
|
#[derive(Clone, Debug, Eq)]
|
||||||
pub struct Proof<E: Engine> {
|
pub struct Proof<E: Engine> {
|
||||||
pub r: E::G1Affine,
|
pub r: E::G1Affine,
|
||||||
|
@ -5,7 +5,7 @@ use std::marker::PhantomData;
|
|||||||
use super::{Proof, SxyAdvice};
|
use super::{Proof, SxyAdvice};
|
||||||
use super::batch::Batch;
|
use super::batch::Batch;
|
||||||
use super::poly::{SxEval, SyEval};
|
use super::poly::{SxEval, SyEval};
|
||||||
use super::parameters::{Parameters};
|
use super::parameters::{Parameters, NUM_BLINDINGS};
|
||||||
|
|
||||||
use crate::SynthesisError;
|
use crate::SynthesisError;
|
||||||
|
|
||||||
@ -139,6 +139,9 @@ pub fn create_proof<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
|||||||
create_proof_on_srs::<E, C, S>(circuit, ¶meters.srs)
|
create_proof_on_srs::<E, C, S>(circuit, ¶meters.srs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern crate rand;
|
||||||
|
use self::rand::{Rand, Rng, thread_rng};
|
||||||
|
|
||||||
pub fn create_proof_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
pub fn create_proof_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
||||||
circuit: &C,
|
circuit: &C,
|
||||||
srs: &SRS<E>
|
srs: &SRS<E>
|
||||||
@ -204,13 +207,108 @@ pub fn create_proof_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
|||||||
|
|
||||||
let mut transcript = Transcript::new(&[]);
|
let mut transcript = Transcript::new(&[]);
|
||||||
|
|
||||||
let r = multiexp(
|
let rng = &mut thread_rng();
|
||||||
srs.g_positive_x_alpha[(srs.d - 3*n - 1)..].iter(),
|
|
||||||
wires.c.iter().rev()
|
// c_{n+1}, c_{n+2}, c_{n+3}, c_{n+4}
|
||||||
|
let blindings: Vec<E::Fr> = (0..NUM_BLINDINGS).into_iter().map(|_| E::Fr::rand(rng)).collect();
|
||||||
|
|
||||||
|
// let blindings: Vec<E::Fr> = vec![E::Fr::zero(); NUM_BLINDINGS];
|
||||||
|
|
||||||
|
// let max_n = 3*n + 1 + NUM_BLINDINGS;
|
||||||
|
|
||||||
|
// let max_n = 3*n + 1;
|
||||||
|
|
||||||
|
fn polynomial_commitment<
|
||||||
|
'a,
|
||||||
|
EE: Engine,
|
||||||
|
IS: IntoIterator<Item = &'a EE::Fr>,
|
||||||
|
>(
|
||||||
|
max: usize,
|
||||||
|
largest_negative_power: usize,
|
||||||
|
largest_positive_power: usize,
|
||||||
|
srs: &'a SRS<EE>,
|
||||||
|
s: IS,
|
||||||
|
) -> EE::G1Affine
|
||||||
|
where
|
||||||
|
IS::IntoIter: ExactSizeIterator,
|
||||||
|
{
|
||||||
|
// smallest power is d - max - largest_negative_power; It should either be 1 for use of positive powers only,
|
||||||
|
// of we should use part of the negative powers
|
||||||
|
let d = srs.d;
|
||||||
|
assert!(max >= largest_positive_power);
|
||||||
|
if d < max + largest_negative_power + 1 {
|
||||||
|
println!("Use negative powers for polynomial commitment");
|
||||||
|
let min_power = largest_negative_power + max - d;
|
||||||
|
let max_power = d + largest_positive_power - max;
|
||||||
|
println!("Min power = {}, max = {}", min_power, max_power);
|
||||||
|
// need to use negative powers to make a proper commitment
|
||||||
|
return multiexp(
|
||||||
|
srs.g_negative_x_alpha[0..min_power].iter().rev()
|
||||||
|
.chain_ext(srs.g_positive_x_alpha[..max_power].iter()),
|
||||||
|
s
|
||||||
|
).into_affine();
|
||||||
|
} else {
|
||||||
|
println!("Use positive powers only for polynomial commitment");
|
||||||
|
return multiexp(
|
||||||
|
srs.g_positive_x_alpha[(srs.d - max - largest_negative_power - 1)..].iter(),
|
||||||
|
s
|
||||||
|
).into_affine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn polynomial_commitment_opening<
|
||||||
|
'a,
|
||||||
|
EE: Engine,
|
||||||
|
I: IntoIterator<Item = &'a EE::Fr>
|
||||||
|
>(
|
||||||
|
largest_negative_power: usize,
|
||||||
|
largest_positive_power: usize,
|
||||||
|
polynomial_coefficients: I,
|
||||||
|
mut point: EE::Fr,
|
||||||
|
srs: &'a SRS<EE>,
|
||||||
|
) -> EE::G1Affine
|
||||||
|
where I::IntoIter: DoubleEndedIterator + ExactSizeIterator,
|
||||||
|
{
|
||||||
|
let poly = kate_divison(
|
||||||
|
polynomial_coefficients,
|
||||||
|
point,
|
||||||
|
);
|
||||||
|
|
||||||
|
let negative_poly = poly[0..largest_negative_power].iter().rev();
|
||||||
|
let positive_poly = poly[largest_negative_power..].iter();
|
||||||
|
multiexp(
|
||||||
|
srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
||||||
|
srs.g_positive_x[0..positive_poly.len()].iter()
|
||||||
|
),
|
||||||
|
negative_poly.chain_ext(positive_poly)
|
||||||
|
).into_affine()
|
||||||
|
}
|
||||||
|
|
||||||
|
let r = polynomial_commitment::<E, _>(
|
||||||
|
n,
|
||||||
|
2*n + NUM_BLINDINGS,
|
||||||
|
n,
|
||||||
|
&srs,
|
||||||
|
blindings.iter().rev()
|
||||||
|
.chain_ext(wires.c.iter().rev())
|
||||||
|
// wires.c.iter().rev()
|
||||||
.chain_ext(wires.b.iter().rev())
|
.chain_ext(wires.b.iter().rev())
|
||||||
.chain_ext(Some(E::Fr::zero()).iter())
|
.chain_ext(Some(E::Fr::zero()).iter())
|
||||||
.chain_ext(wires.a.iter()),
|
.chain_ext(wires.a.iter()),
|
||||||
).into_affine();
|
);
|
||||||
|
|
||||||
|
// let r = multiexp(
|
||||||
|
// // F <- g^{alpha*x^{d-max}*f(x)} = g^{alpha*x^{d-n}*\sum_{i = -2n - 4}^{n} k_i*x^{i}} =
|
||||||
|
// // = g^{alpha*\sum_{i = d - 3n - 4}^{n} k_i*x^{i}}
|
||||||
|
// // g^{alpha*(x^{d - 3n - 4}*k_{-2n-4} + ... + x^{d - n}*k_{0} + ... + x^{d + n + 1}*k_{n})
|
||||||
|
// srs.g_positive_x_alpha[(srs.d - max_n)..].iter(),
|
||||||
|
// blindings.iter().rev()
|
||||||
|
// .chain_ext(wires.c.iter().rev())
|
||||||
|
// // wires.c.iter().rev()
|
||||||
|
// .chain_ext(wires.b.iter().rev())
|
||||||
|
// .chain_ext(Some(E::Fr::zero()).iter())
|
||||||
|
// .chain_ext(wires.a.iter()),
|
||||||
|
// ).into_affine();
|
||||||
|
|
||||||
transcript.commit_point(&r);
|
transcript.commit_point(&r);
|
||||||
|
|
||||||
@ -226,17 +324,48 @@ pub fn create_proof_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
|||||||
rx1.push(E::Fr::zero());
|
rx1.push(E::Fr::zero());
|
||||||
rx1.extend(wires.a);
|
rx1.extend(wires.a);
|
||||||
|
|
||||||
let mut rxy = rx1.clone();
|
|
||||||
|
// let mut rxy = rx1.clone();
|
||||||
|
// it's not yet blinded, so blind explicitly here
|
||||||
|
let mut rxy = rx1;
|
||||||
|
let mut rx1 = {
|
||||||
|
// 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 tmp = blindings.clone();
|
||||||
|
// c_{n+4}*X^{-2n - 4}, c_{n+3}*X^{-2n - 3}, c_{n+2}*X^{-2n - 2}, c_{n+1}*X^{-2n - 1},
|
||||||
|
tmp.reverse();
|
||||||
|
tmp.extend(rxy.clone());
|
||||||
|
|
||||||
|
tmp
|
||||||
|
};
|
||||||
|
|
||||||
let y_inv = y.inverse().ok_or(SynthesisError::DivisionByZero)?;
|
let y_inv = y.inverse().ok_or(SynthesisError::DivisionByZero)?;
|
||||||
let mut tmp = y.pow(&[n as u64]);
|
|
||||||
|
|
||||||
// evaluate r(X, y)
|
// y^{-2n}
|
||||||
for rxy in rxy.iter_mut().rev() {
|
let tmp = y_inv.pow(&[2*n as u64]);
|
||||||
rxy.mul_assign(&tmp);
|
mut_distribute_consequitive_powers(
|
||||||
tmp.mul_assign(&y_inv);
|
&mut rxy,
|
||||||
}
|
tmp,
|
||||||
|
y,
|
||||||
|
);
|
||||||
|
|
||||||
// negative powers [-n, -1], positive [1, 2n]
|
// let mut tmp = y.pow(&[n as u64]);
|
||||||
|
// // evaluate r(X, y)
|
||||||
|
// for rxy in rxy.iter_mut().rev() {
|
||||||
|
// rxy.mul_assign(&tmp);
|
||||||
|
// tmp.mul_assign(&y_inv);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Blindings are not affected by evaluation on Y cause blindings make constant term over Y
|
||||||
|
// We just add them here to have it now in a form of coefficients over X
|
||||||
|
let rxy = {
|
||||||
|
let mut tmp = blindings.clone();
|
||||||
|
tmp.reverse();
|
||||||
|
tmp.extend(rxy);
|
||||||
|
|
||||||
|
tmp
|
||||||
|
};
|
||||||
|
|
||||||
|
// negative powers [-1, -2n], positive [1, n]
|
||||||
let (s_poly_negative, s_poly_positive) = {
|
let (s_poly_negative, s_poly_positive) = {
|
||||||
let mut tmp = SxEval::new(y, n);
|
let mut tmp = SxEval::new(y, n);
|
||||||
S::synthesize(&mut tmp, circuit)?;
|
S::synthesize(&mut tmp, circuit)?;
|
||||||
@ -244,12 +373,14 @@ 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();
|
||||||
{
|
{
|
||||||
rxy_prime.resize(4 * n + 1, E::Fr::zero());
|
// extend to have powers [n+1, 2n]
|
||||||
|
rxy_prime.resize(4 * n + 1 + NUM_BLINDINGS, E::Fr::zero());
|
||||||
// add coefficients in front of X^{-2n}...X^{-n-1}, X^{-n}...X^{-1}
|
// add coefficients in front of X^{-2n}...X^{-n-1}, X^{-n}...X^{-1}
|
||||||
for (r, s) in rxy_prime[0..(2 * n)]
|
for (r, s) in rxy_prime[NUM_BLINDINGS..(2 * n + NUM_BLINDINGS)]
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.rev()
|
.rev()
|
||||||
.zip(s_poly_negative)
|
.zip(s_poly_negative)
|
||||||
@ -257,54 +388,79 @@ pub fn create_proof_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
|||||||
r.add_assign(&s);
|
r.add_assign(&s);
|
||||||
}
|
}
|
||||||
// add coefficients in front of X^{1}...X^{n}, X^{n+1}...X^{2*n}
|
// add coefficients in front of X^{1}...X^{n}, X^{n+1}...X^{2*n}
|
||||||
for (r, s) in rxy_prime[(2 * n + 1)..].iter_mut().zip(s_poly_positive) {
|
for (r, s) in rxy_prime[(2 * n + 1 + NUM_BLINDINGS)..].iter_mut().zip(s_poly_positive) {
|
||||||
r.add_assign(&s);
|
r.add_assign(&s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// by this point all R related polynomials are blinded and evaluated for Y variable
|
||||||
|
|
||||||
// t(X, y) = r'(X, y)*r(X, 1) and will be later evaluated at z
|
// t(X, y) = r'(X, y)*r(X, 1) and will be later evaluated at z
|
||||||
// contained degree in respect to X are from -4*n to 3*n including X^0
|
// contained degree in respect to X are from -4*n to 3*n including X^0
|
||||||
let mut txy = multiply_polynomials::<E>(rx1.clone(), rxy_prime);
|
let mut txy = multiply_polynomials::<E>(rx1.clone(), rxy_prime);
|
||||||
txy[4 * n] = E::Fr::zero(); // -k(y)
|
txy[4 * n + 2 * NUM_BLINDINGS] = E::Fr::zero(); // -k(y)
|
||||||
|
|
||||||
// commit to t(X, y) to later open at z
|
// commit to t(X, y) to later open at z
|
||||||
let t = multiexp(
|
|
||||||
srs.g_positive_x_alpha[0..(3 * n)]
|
let t = polynomial_commitment(
|
||||||
.iter()
|
srs.d,
|
||||||
.chain_ext(srs.g_negative_x_alpha[0..(4 * n)].iter()),
|
(4 * n) + 2*NUM_BLINDINGS,
|
||||||
txy[(4 * n + 1)..]
|
3 * n,
|
||||||
.iter()
|
srs,
|
||||||
.chain_ext(txy[0..4 * n].iter().rev()),
|
// skip what would be zero power
|
||||||
).into_affine();
|
txy[0..(4 * n) + 2*NUM_BLINDINGS].iter()
|
||||||
|
.chain_ext(txy[(4 * n + 2*NUM_BLINDINGS + 1)..].iter()),
|
||||||
|
);
|
||||||
|
|
||||||
|
// let t = multiexp(
|
||||||
|
// srs.g_positive_x_alpha[0..(3 * n)]
|
||||||
|
// .iter()
|
||||||
|
// .chain_ext(srs.g_negative_x_alpha[0..(4 * n) + 2*NUM_BLINDINGS].iter()),
|
||||||
|
// txy[(4 * n + 1 + 2*NUM_BLINDINGS)..]
|
||||||
|
// .iter()
|
||||||
|
// .chain_ext(txy[0..(4 * n + 2*NUM_BLINDINGS)].iter().rev()),
|
||||||
|
// ).into_affine();
|
||||||
|
|
||||||
transcript.commit_point(&t);
|
transcript.commit_point(&t);
|
||||||
|
|
||||||
|
|
||||||
let z: E::Fr = transcript.get_challenge_scalar();
|
let z: E::Fr = transcript.get_challenge_scalar();
|
||||||
let z_inv = z.inverse().ok_or(SynthesisError::DivisionByZero)?;
|
let z_inv = z.inverse().ok_or(SynthesisError::DivisionByZero)?;
|
||||||
|
|
||||||
// TODO: use the faster way to evaluate the polynomials
|
let rz = {
|
||||||
let mut rz = E::Fr::zero();
|
let tmp = z_inv.pow(&[(2*n + NUM_BLINDINGS) as u64]);
|
||||||
{
|
|
||||||
let mut tmp = z.pow(&[n as u64]);
|
|
||||||
|
|
||||||
for coeff in rx1.iter().rev() {
|
evaluate_at_consequitive_powers(&rx1, tmp, z)
|
||||||
let mut coeff = *coeff;
|
};
|
||||||
coeff.mul_assign(&tmp);
|
|
||||||
rz.add_assign(&coeff);
|
|
||||||
tmp.mul_assign(&z_inv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut rzy = E::Fr::zero();
|
// let mut rz = E::Fr::zero();
|
||||||
{
|
// {
|
||||||
let mut tmp = z.pow(&[n as u64]);
|
// let mut tmp = z.pow(&[n as u64]);
|
||||||
|
|
||||||
for mut coeff in rxy.into_iter().rev() {
|
// for coeff in rx1.iter().rev() {
|
||||||
coeff.mul_assign(&tmp);
|
// let mut coeff = *coeff;
|
||||||
rzy.add_assign(&coeff);
|
// coeff.mul_assign(&tmp);
|
||||||
tmp.mul_assign(&z_inv);
|
// rz.add_assign(&coeff);
|
||||||
}
|
// tmp.mul_assign(&z_inv);
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
let rzy = {
|
||||||
|
let tmp = z_inv.pow(&[(2*n + NUM_BLINDINGS) as u64]);
|
||||||
|
|
||||||
|
evaluate_at_consequitive_powers(&rxy, tmp, z)
|
||||||
|
};
|
||||||
|
|
||||||
|
// let mut rzy = E::Fr::zero();
|
||||||
|
// {
|
||||||
|
// let mut tmp = z.pow(&[n as u64]);
|
||||||
|
|
||||||
|
// for mut coeff in rxy.into_iter().rev() {
|
||||||
|
// coeff.mul_assign(&tmp);
|
||||||
|
// rzy.add_assign(&coeff);
|
||||||
|
// tmp.mul_assign(&z_inv);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
transcript.commit_scalar(&rz);
|
transcript.commit_scalar(&rz);
|
||||||
transcript.commit_scalar(&rzy);
|
transcript.commit_scalar(&rzy);
|
||||||
@ -313,62 +469,88 @@ pub fn create_proof_on_srs<E: Engine, C: Circuit<E>, S: SynthesisDriver>(
|
|||||||
|
|
||||||
let zy_opening = {
|
let zy_opening = {
|
||||||
// r(X, 1) - r(z, y)
|
// r(X, 1) - r(z, y)
|
||||||
rx1[2 * n].sub_assign(&rzy);
|
// subtract constant term from R(X, 1)
|
||||||
|
rx1[(2 * n + NUM_BLINDINGS)].sub_assign(&rzy);
|
||||||
|
|
||||||
let mut point = y;
|
let mut point = y;
|
||||||
point.mul_assign(&z);
|
point.mul_assign(&z);
|
||||||
let poly = kate_divison(
|
|
||||||
rx1.iter(),
|
|
||||||
point,
|
|
||||||
);
|
|
||||||
|
|
||||||
let negative_poly = poly[0..2*n].iter().rev();
|
polynomial_commitment_opening(
|
||||||
let positive_poly = poly[2*n..].iter();
|
2 * n + NUM_BLINDINGS,
|
||||||
multiexp(
|
n,
|
||||||
srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
&rx1,
|
||||||
srs.g_positive_x[0..positive_poly.len()].iter()
|
point,
|
||||||
),
|
srs
|
||||||
negative_poly.chain_ext(positive_poly)
|
)
|
||||||
).into_affine()
|
|
||||||
|
// let poly = kate_divison(
|
||||||
|
// rx1.iter(),
|
||||||
|
// point,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// let negative_poly = poly[0..(2*n + NUM_BLINDINGS)].iter().rev();
|
||||||
|
// let positive_poly = poly[(2*n + NUM_BLINDINGS)..].iter();
|
||||||
|
// multiexp(
|
||||||
|
// srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
||||||
|
// srs.g_positive_x[0..positive_poly.len()].iter()
|
||||||
|
// ),
|
||||||
|
// negative_poly.chain_ext(positive_poly)
|
||||||
|
// ).into_affine()
|
||||||
};
|
};
|
||||||
|
|
||||||
let z_opening = {
|
assert_eq!(rx1.len(), 3*n + NUM_BLINDINGS + 1);
|
||||||
rx1[2 * n].add_assign(&rzy); // restore
|
|
||||||
|
|
||||||
for (t, &r) in txy[2 * n..].iter_mut().zip(rx1.iter()) {
|
let z_opening = {
|
||||||
|
rx1[(2 * n + NUM_BLINDINGS)].add_assign(&rzy); // restore
|
||||||
|
|
||||||
|
// skip powers from until reach -2n - NUM_BLINDINGS
|
||||||
|
for (t, &r) in txy[(2 * n + NUM_BLINDINGS)..].iter_mut().zip(rx1.iter()) {
|
||||||
let mut r = r;
|
let mut r = r;
|
||||||
r.mul_assign(&r1);
|
r.mul_assign(&r1);
|
||||||
t.add_assign(&r);
|
t.add_assign(&r);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut val = E::Fr::zero();
|
let val = {
|
||||||
{
|
let tmp = z_inv.pow(&[(4*n + 2*NUM_BLINDINGS) as u64]);
|
||||||
assert_eq!(txy.len(), 3*n + 1 + 4*n);
|
|
||||||
let mut tmp = z.pow(&[(3*n) as u64]);
|
|
||||||
|
|
||||||
for coeff in txy.iter().rev() {
|
evaluate_at_consequitive_powers(&txy, tmp, z)
|
||||||
let mut coeff = *coeff;
|
};
|
||||||
coeff.mul_assign(&tmp);
|
|
||||||
val.add_assign(&coeff);
|
|
||||||
tmp.mul_assign(&z_inv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
txy[4 * n].sub_assign(&val);
|
// let mut val = E::Fr::zero();
|
||||||
|
// {
|
||||||
|
// assert_eq!(txy.len(), 3*n + 1 + 4*n + 2*NUM_BLINDINGS);
|
||||||
|
// let mut tmp = z.pow(&[(3*n) as u64]);
|
||||||
|
|
||||||
let poly = kate_divison(
|
// for coeff in txy.iter().rev() {
|
||||||
txy.iter(),
|
// let mut coeff = *coeff;
|
||||||
z,
|
// coeff.mul_assign(&tmp);
|
||||||
);
|
// val.add_assign(&coeff);
|
||||||
|
// tmp.mul_assign(&z_inv);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
let negative_poly = poly[0..4*n].iter().rev();
|
txy[(4 * n + 2*NUM_BLINDINGS)].sub_assign(&val);
|
||||||
let positive_poly = poly[4*n..].iter();
|
|
||||||
multiexp(
|
polynomial_commitment_opening(
|
||||||
srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
4*n + 2*NUM_BLINDINGS,
|
||||||
srs.g_positive_x[0..positive_poly.len()].iter()
|
3*n,
|
||||||
),
|
&txy,
|
||||||
negative_poly.chain_ext(positive_poly)
|
z,
|
||||||
).into_affine()
|
srs)
|
||||||
|
|
||||||
|
// let poly = kate_divison(
|
||||||
|
// txy.iter(),
|
||||||
|
// z,
|
||||||
|
// );
|
||||||
|
|
||||||
|
// let negative_poly = poly[0..(4*n + 2*NUM_BLINDINGS)].iter().rev();
|
||||||
|
// let positive_poly = poly[(4*n + 2*NUM_BLINDINGS)..].iter();
|
||||||
|
// multiexp(
|
||||||
|
// srs.g_negative_x[1..(negative_poly.len() + 1)].iter().chain_ext(
|
||||||
|
// srs.g_positive_x[0..positive_poly.len()].iter()
|
||||||
|
// ),
|
||||||
|
// negative_poly.chain_ext(positive_poly)
|
||||||
|
// ).into_affine()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Proof {
|
Ok(Proof {
|
||||||
@ -427,3 +609,67 @@ fn my_fun_circuit_test() {
|
|||||||
let elapsed = start.elapsed();
|
let elapsed = start.elapsed();
|
||||||
println!("time to verify: {:?}", elapsed);
|
println!("time to verify: {:?}", elapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn polynomial_commitment_test() {
|
||||||
|
use ff::PrimeField;
|
||||||
|
use pairing::bls12_381::{Bls12, Fr};
|
||||||
|
use super::*;
|
||||||
|
use crate::sonic::cs::{Basic, ConstraintSystem, LinearCombination};
|
||||||
|
use rand::{thread_rng};
|
||||||
|
|
||||||
|
struct MyCircuit;
|
||||||
|
|
||||||
|
impl<E: Engine> Circuit<E> for MyCircuit {
|
||||||
|
fn synthesize<CS: ConstraintSystem<E>>(&self, cs: &mut CS) -> Result<(), SynthesisError> {
|
||||||
|
let (a, b, _) = cs.multiply(|| {
|
||||||
|
Ok((
|
||||||
|
E::Fr::from_str("10").unwrap(),
|
||||||
|
E::Fr::from_str("20").unwrap(),
|
||||||
|
E::Fr::from_str("200").unwrap(),
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
cs.enforce_zero(LinearCombination::from(a) + a - b);
|
||||||
|
|
||||||
|
//let multiplier = cs.alloc_input(|| Ok(E::Fr::from_str("20").unwrap()))?;
|
||||||
|
|
||||||
|
//cs.enforce_zero(LinearCombination::from(b) - multiplier);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let srs = SRS::<Bls12>::new(
|
||||||
|
20,
|
||||||
|
Fr::from_str("22222").unwrap(),
|
||||||
|
Fr::from_str("33333333").unwrap(),
|
||||||
|
);
|
||||||
|
let proof = self::create_proof_on_srs::<Bls12, _, Basic>(&MyCircuit, &srs).unwrap();
|
||||||
|
|
||||||
|
let z: Fr;
|
||||||
|
let y: Fr;
|
||||||
|
{
|
||||||
|
let mut transcript = Transcript::new(&[]);
|
||||||
|
transcript.commit_point(&proof.r);
|
||||||
|
y = transcript.get_challenge_scalar();
|
||||||
|
transcript.commit_point(&proof.t);
|
||||||
|
z = transcript.get_challenge_scalar();
|
||||||
|
}
|
||||||
|
|
||||||
|
use std::time::{Instant};
|
||||||
|
|
||||||
|
let rng = thread_rng();
|
||||||
|
let mut batch = MultiVerifier::<Bls12, _, Basic, _>::new(MyCircuit, &srs, rng).unwrap().batch;
|
||||||
|
|
||||||
|
// try to open commitment to r at r(z, 1);
|
||||||
|
|
||||||
|
let mut random = Fr::one();
|
||||||
|
random.double();
|
||||||
|
|
||||||
|
batch.add_opening(proof.z_opening, random, z);
|
||||||
|
batch.add_commitment_max_n(proof.r, random);
|
||||||
|
batch.add_opening_value(proof.rz, random);
|
||||||
|
|
||||||
|
assert!(batch.check_all());
|
||||||
|
}
|
||||||
|
@ -19,7 +19,7 @@ use crate::sonic::srs::SRS;
|
|||||||
|
|
||||||
pub struct MultiVerifier<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> {
|
pub struct MultiVerifier<E: Engine, C: Circuit<E>, S: SynthesisDriver, R: Rng> {
|
||||||
circuit: C,
|
circuit: C,
|
||||||
batch: Batch<E>,
|
pub(crate) batch: Batch<E>,
|
||||||
k_map: Vec<usize>,
|
k_map: Vec<usize>,
|
||||||
n: usize,
|
n: usize,
|
||||||
q: usize,
|
q: usize,
|
||||||
|
@ -183,6 +183,35 @@ pub fn mut_evaluate_at_consequitive_powers<'a, F: Field> (
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Multiply each coefficient by some power of the base in a form
|
||||||
|
/// `first_power * base^{i}`
|
||||||
|
pub fn mut_distribute_consequitive_powers<'a, F: Field> (
|
||||||
|
coeffs: &mut [F],
|
||||||
|
first_power: F,
|
||||||
|
base: F
|
||||||
|
)
|
||||||
|
{
|
||||||
|
use crate::multicore::Worker;
|
||||||
|
|
||||||
|
let worker = Worker::new();
|
||||||
|
|
||||||
|
worker.scope(coeffs.len(), |scope, chunk| {
|
||||||
|
for (i, coeffs_chunk) in coeffs.chunks_mut(chunk).enumerate()
|
||||||
|
{
|
||||||
|
scope.spawn(move |_| {
|
||||||
|
let mut current_power = base.pow(&[(i*chunk) as u64]);
|
||||||
|
current_power.mul_assign(&first_power);
|
||||||
|
|
||||||
|
for mut p in coeffs_chunk {
|
||||||
|
p.mul_assign(¤t_power);
|
||||||
|
|
||||||
|
current_power.mul_assign(&base);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn multiexp<
|
pub fn multiexp<
|
||||||
'a,
|
'a,
|
||||||
G: CurveAffine,
|
G: CurveAffine,
|
||||||
@ -202,6 +231,8 @@ where
|
|||||||
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<_>>();
|
||||||
|
|
||||||
|
assert_eq!(s.len(), g.len(), "scalars and exponents must have the same length");
|
||||||
|
|
||||||
let pool = Worker::new();
|
let pool = Worker::new();
|
||||||
|
|
||||||
let result = dense_multiexp(
|
let result = dense_multiexp(
|
||||||
@ -588,5 +619,34 @@ fn test_mut_eval_at_powers() {
|
|||||||
let acc_parallel = mut_evaluate_at_consequitive_powers(&mut b[..], first_power, x);
|
let acc_parallel = mut_evaluate_at_consequitive_powers(&mut b[..], first_power, x);
|
||||||
|
|
||||||
assert_eq!(acc_parallel, acc);
|
assert_eq!(acc_parallel, acc);
|
||||||
|
assert!(a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mut_distribute_powers() {
|
||||||
|
use rand::{self, Rand, Rng};
|
||||||
|
use pairing::bls12_381::Bls12;
|
||||||
|
use pairing::bls12_381::Fr;
|
||||||
|
|
||||||
|
const SAMPLES: usize = 100000;
|
||||||
|
|
||||||
|
let rng = &mut rand::thread_rng();
|
||||||
|
let mut a = (0..SAMPLES).map(|_| Fr::rand(rng)).collect::<Vec<_>>();
|
||||||
|
let mut b = a.clone();
|
||||||
|
let x: Fr = rng.gen();
|
||||||
|
let n: u32 = rng.gen();
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut tmp = x.pow(&[n as u64]);
|
||||||
|
|
||||||
|
for mut coeff in a.iter_mut() {
|
||||||
|
coeff.mul_assign(&tmp);
|
||||||
|
tmp.mul_assign(&x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let first_power = x.pow(&[n as u64]);
|
||||||
|
mut_distribute_consequitive_powers(&mut b[..], first_power, x);
|
||||||
|
|
||||||
assert!(a == b);
|
assert!(a == b);
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user