add rayon
This commit is contained in:
Родитель
f465aed924
Коммит
a05d0f42f3
|
@ -17,7 +17,7 @@ rand = "0.7.3"
|
|||
digest = "0.8.1"
|
||||
sha3 = "0.8.2"
|
||||
byteorder = "1.3.4"
|
||||
rayon = { version = "1.3.0", optional = true }
|
||||
rayon = { version = "1.3.0"}
|
||||
serde = { version = "1.0.106", features = ["derive"] }
|
||||
bincode = "1.2.1"
|
||||
subtle = { version = "^2.2.3", default-features = false }
|
||||
|
@ -52,5 +52,4 @@ name = "nizk"
|
|||
harness = false
|
||||
|
||||
[features]
|
||||
multicore = ["rayon"]
|
||||
profile = []
|
||||
|
|
|
@ -11,7 +11,6 @@ use core::ops::Index;
|
|||
use merlin::Transcript;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[cfg(feature = "multicore")]
|
||||
use rayon::prelude::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -66,6 +65,9 @@ impl EqPolynomial {
|
|||
|
||||
pub fn evals(&self) -> Vec<Scalar> {
|
||||
let ell = self.r.len();
|
||||
let mut evals: Vec<Scalar> = vec![Scalar::zero(); ell.pow2()];
|
||||
|
||||
/*let ell = self.r.len();
|
||||
|
||||
let mut evals: Vec<Scalar> = vec![Scalar::one(); ell.pow2()];
|
||||
let mut size = 1;
|
||||
|
@ -80,6 +82,24 @@ impl EqPolynomial {
|
|||
}
|
||||
}
|
||||
evals
|
||||
*/
|
||||
|
||||
// in each iteration, we double the size of chis
|
||||
let mut size = 1;
|
||||
evals[0] = Scalar::one();
|
||||
for r in self.r.iter().rev() {
|
||||
let (evals_left, evals_right) = evals.split_at_mut(size);
|
||||
let (evals_right, _) = evals_right.split_at_mut(size);
|
||||
|
||||
let iter = evals_left.par_iter_mut().zip(evals_right.par_iter_mut());
|
||||
// copy each element from the prior iteration twice
|
||||
iter.for_each(|(x, y)| {
|
||||
*y = *x * r;
|
||||
*x -= &*y;
|
||||
});
|
||||
size *= 2;
|
||||
}
|
||||
evals
|
||||
}
|
||||
|
||||
pub fn compute_factored_lens(ell: usize) -> (usize, usize) {
|
||||
|
@ -142,7 +162,6 @@ impl DensePolynomial {
|
|||
)
|
||||
}
|
||||
|
||||
#[cfg(feature = "multicore")]
|
||||
fn commit_inner(&self, blinds: &Vec<Scalar>, gens: &MultiCommitGens) -> PolyCommitment {
|
||||
let L_size = blinds.len();
|
||||
let R_size = self.Z.len() / L_size;
|
||||
|
@ -158,21 +177,6 @@ impl DensePolynomial {
|
|||
PolyCommitment { C }
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "multicore"))]
|
||||
fn commit_inner(&self, blinds: &[Scalar], gens: &MultiCommitGens) -> PolyCommitment {
|
||||
let L_size = blinds.len();
|
||||
let R_size = self.Z.len() / L_size;
|
||||
assert_eq!(L_size * R_size, self.Z.len());
|
||||
let C = (0..L_size)
|
||||
.map(|i| {
|
||||
self.Z[R_size * i..R_size * (i + 1)]
|
||||
.commit(&blinds[i], gens)
|
||||
.compress()
|
||||
})
|
||||
.collect();
|
||||
PolyCommitment { C }
|
||||
}
|
||||
|
||||
pub fn commit(
|
||||
&self,
|
||||
gens: &PolyCommitmentGens,
|
||||
|
@ -211,9 +215,18 @@ impl DensePolynomial {
|
|||
|
||||
pub fn bound_poly_var_top(&mut self, r: &Scalar) {
|
||||
let n = self.len() / 2;
|
||||
for i in 0..n {
|
||||
self.Z[i] = self.Z[i] + r * (self.Z[i + n] - self.Z[i]);
|
||||
}
|
||||
|
||||
// The following code is a parallel version of this code snippet
|
||||
// for i in 0..n {
|
||||
// self.Z[i] = self.Z[i] + r * (self.Z[i + n] - self.Z[i]);
|
||||
// }
|
||||
let (left, right) = self.Z.split_at_mut(n);
|
||||
let (right, _) = right.split_at(n);
|
||||
let iter = left.par_iter_mut().zip(right.par_iter());
|
||||
iter.for_each(|(a, b)| {
|
||||
*a += r * (b - *a);
|
||||
});
|
||||
|
||||
self.num_vars -= 1;
|
||||
self.len = n;
|
||||
}
|
||||
|
|
|
@ -10,12 +10,10 @@ extern crate curve25519_dalek;
|
|||
extern crate digest;
|
||||
extern crate merlin;
|
||||
extern crate rand;
|
||||
extern crate rayon;
|
||||
extern crate sha3;
|
||||
extern crate test;
|
||||
|
||||
#[cfg(feature = "multicore")]
|
||||
extern crate rayon;
|
||||
|
||||
mod commitments;
|
||||
mod dense_mlpoly;
|
||||
mod errors;
|
||||
|
|
|
@ -10,6 +10,7 @@ use super::super::scalar::Scalar;
|
|||
use super::super::transcript::ProofTranscript;
|
||||
use core::iter;
|
||||
use merlin::Transcript;
|
||||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
|
@ -67,8 +68,6 @@ impl BulletReductionProof {
|
|||
assert_eq!(G_factors.len(), n);
|
||||
assert_eq!(blinds_vec.len(), 2 * lg_n);
|
||||
|
||||
//transcript.innerproduct_domain_sep(n as u64);
|
||||
|
||||
let mut L_vec = Vec::with_capacity(lg_n);
|
||||
let mut R_vec = Vec::with_capacity(lg_n);
|
||||
let mut blinds_iter = blinds_vec.iter();
|
||||
|
@ -107,11 +106,31 @@ impl BulletReductionProof {
|
|||
let u = transcript.challenge_scalar(b"u");
|
||||
let u_inv = u.invert().unwrap();
|
||||
|
||||
let a_L_vec = (0..n)
|
||||
.into_par_iter()
|
||||
.map(|i| a_L[i] * u + u_inv * a_R[i])
|
||||
.collect::<Vec<Scalar>>();
|
||||
|
||||
let b_L_vec = (0..n)
|
||||
.into_par_iter()
|
||||
.map(|i| b_L[i] * u_inv + u * b_R[i])
|
||||
.collect::<Vec<Scalar>>();
|
||||
|
||||
let G_L_vec = (0..n)
|
||||
.into_par_iter()
|
||||
.map(|i| GroupElement::vartime_multiscalar_mul(&[u_inv, u], &[G_L[i], G_R[i]]))
|
||||
.collect::<Vec<GroupElement>>();
|
||||
|
||||
for i in 0..n {
|
||||
a_L[i] = a_L[i] * u + u_inv * a_R[i];
|
||||
b_L[i] = b_L[i] * u_inv + u * b_R[i];
|
||||
G_L[i] = GroupElement::vartime_multiscalar_mul(&[u_inv, u], &[G_L[i], G_R[i]]);
|
||||
a_L[i] = a_L_vec[i];
|
||||
b_L[i] = b_L_vec[i];
|
||||
G_L[i] = G_L_vec[i];
|
||||
}
|
||||
//for i in 0..n {
|
||||
//a_L[i] = a_L[i] * u + u_inv * a_R[i];
|
||||
//b_L[i] = b_L[i] * u_inv + u * b_R[i];
|
||||
//G_L[i] = GroupElement::vartime_multiscalar_mul(&[u_inv, u], &[G_L[i], G_R[i]]);
|
||||
//}
|
||||
|
||||
blind_fin = blind_fin + blind_L * u * u + blind_R * u_inv * u_inv;
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ use super::sparse_mlpoly::{
|
|||
};
|
||||
use super::timer::Timer;
|
||||
use merlin::Transcript;
|
||||
use rand::rngs::OsRng;
|
||||
use rand::thread_rng;
|
||||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -144,8 +145,6 @@ impl R1CSInstance {
|
|||
Timer::print(&format!("number_of_variables {}", num_vars));
|
||||
Timer::print(&format!("number_of_inputs {}", num_inputs));
|
||||
|
||||
let mut csprng: OsRng = OsRng;
|
||||
|
||||
// assert num_cons and num_vars are power of 2
|
||||
assert_eq!(num_cons.log2().pow2(), num_cons);
|
||||
assert_eq!(num_vars.log2().pow2(), num_vars);
|
||||
|
@ -159,37 +158,54 @@ impl R1CSInstance {
|
|||
// produce a random satisfying assignment
|
||||
let Z = {
|
||||
let mut Z: Vec<Scalar> = (0..size_z)
|
||||
.map(|_i| Scalar::random(&mut csprng))
|
||||
.collect::<Vec<Scalar>>();
|
||||
.into_par_iter()
|
||||
.map(|_| Scalar::random(&mut thread_rng()))
|
||||
.collect();
|
||||
Z[num_vars] = Scalar::one(); // set the constant term to 1
|
||||
Z
|
||||
};
|
||||
|
||||
// three sparse matrices
|
||||
let mut A: Vec<SparseMatEntry> = Vec::new();
|
||||
let mut B: Vec<SparseMatEntry> = Vec::new();
|
||||
let mut C: Vec<SparseMatEntry> = Vec::new();
|
||||
let one = Scalar::one();
|
||||
for i in 0..num_cons {
|
||||
let A_idx = i % size_z;
|
||||
let B_idx = (i + 2) % size_z;
|
||||
A.push(SparseMatEntry::new(i, A_idx, one));
|
||||
B.push(SparseMatEntry::new(i, B_idx, one));
|
||||
let AB_val = Z[A_idx] * Z[B_idx];
|
||||
let A: Vec<SparseMatEntry> = {
|
||||
(0..num_cons)
|
||||
.into_par_iter()
|
||||
.map(|i| {
|
||||
let A_idx = i % size_z;
|
||||
SparseMatEntry::new(i, A_idx, one)
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
let C_idx = (i + 3) % size_z;
|
||||
let C_val = Z[C_idx];
|
||||
let B: Vec<SparseMatEntry> = {
|
||||
(0..num_cons)
|
||||
.into_par_iter()
|
||||
.map(|i| {
|
||||
let B_idx = (i + 2) % size_z;
|
||||
SparseMatEntry::new(i, B_idx, one)
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
if C_val == Scalar::zero() {
|
||||
C.push(SparseMatEntry::new(i, num_vars, AB_val));
|
||||
} else {
|
||||
C.push(SparseMatEntry::new(
|
||||
i,
|
||||
C_idx,
|
||||
AB_val * C_val.invert().unwrap(),
|
||||
));
|
||||
}
|
||||
}
|
||||
let C: Vec<SparseMatEntry> = {
|
||||
(0..num_cons)
|
||||
.into_par_iter()
|
||||
.map(|i| {
|
||||
let A_idx = i % size_z;
|
||||
let B_idx = (i + 2) % size_z;
|
||||
let AB_val = Z[A_idx] * Z[B_idx];
|
||||
|
||||
let C_idx = (i + 3) % size_z;
|
||||
let C_val = Z[C_idx];
|
||||
|
||||
if C_val == Scalar::zero() {
|
||||
SparseMatEntry::new(i, num_vars, AB_val)
|
||||
} else {
|
||||
SparseMatEntry::new(i, C_idx, AB_val * C_val.invert().unwrap())
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
Timer::print(&format!("number_non-zero_entries_A {}", A.len()));
|
||||
Timer::print(&format!("number_non-zero_entries_B {}", B.len()));
|
||||
|
@ -259,11 +275,18 @@ impl R1CSInstance {
|
|||
assert_eq!(num_rows, self.num_cons);
|
||||
assert_eq!(z.len(), num_cols);
|
||||
assert!(num_cols > self.num_vars);
|
||||
(
|
||||
DensePolynomial::new(self.A.multiply_vec(num_rows, num_cols, z)),
|
||||
DensePolynomial::new(self.B.multiply_vec(num_rows, num_cols, z)),
|
||||
DensePolynomial::new(self.C.multiply_vec(num_rows, num_cols, z)),
|
||||
)
|
||||
|
||||
let (A, (B, C)) = rayon::join(
|
||||
|| DensePolynomial::new(self.A.multiply_vec(num_rows, num_cols, z)),
|
||||
|| {
|
||||
rayon::join(
|
||||
|| DensePolynomial::new(self.B.multiply_vec(num_rows, num_cols, z)),
|
||||
|| DensePolynomial::new(self.C.multiply_vec(num_rows, num_cols, z)),
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
(A, B, C)
|
||||
}
|
||||
|
||||
pub fn compute_eval_table_sparse(
|
||||
|
@ -275,9 +298,15 @@ impl R1CSInstance {
|
|||
assert_eq!(num_rows, self.num_cons);
|
||||
assert!(num_cols > self.num_vars);
|
||||
|
||||
let evals_A = self.A.compute_eval_table_sparse(&evals, num_rows, num_cols);
|
||||
let evals_B = self.B.compute_eval_table_sparse(&evals, num_rows, num_cols);
|
||||
let evals_C = self.C.compute_eval_table_sparse(&evals, num_rows, num_cols);
|
||||
let (evals_A, (evals_B, evals_C)) = rayon::join(
|
||||
|| self.A.compute_eval_table_sparse(evals, num_rows, num_cols),
|
||||
|| {
|
||||
rayon::join(
|
||||
|| self.B.compute_eval_table_sparse(evals, num_rows, num_cols),
|
||||
|| self.C.compute_eval_table_sparse(evals, num_rows, num_cols),
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
(evals_A, evals_B, evals_C)
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ use super::timer::Timer;
|
|||
use super::transcript::{AppendToTranscript, ProofTranscript};
|
||||
use core::iter;
|
||||
use merlin::Transcript;
|
||||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
@ -274,6 +275,7 @@ impl R1CSProof {
|
|||
assert_eq!(evals_A.len(), evals_B.len());
|
||||
assert_eq!(evals_A.len(), evals_C.len());
|
||||
(0..evals_A.len())
|
||||
.into_par_iter()
|
||||
.map(|i| r_A * evals_A[i] + r_B * evals_B[i] + r_C * evals_C[i])
|
||||
.collect::<Vec<Scalar>>()
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@ use super::timer::Timer;
|
|||
use super::transcript::{AppendToTranscript, ProofTranscript};
|
||||
use core::cmp::Ordering;
|
||||
use merlin::Transcript;
|
||||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -423,6 +424,7 @@ impl SparseMatPolynomial {
|
|||
assert_eq!(self.num_vars_y.pow2(), eval_table_ry.len());
|
||||
|
||||
(0..self.M.len())
|
||||
.into_par_iter()
|
||||
.map(|i| {
|
||||
let row = self.M[i].row;
|
||||
let col = self.M[i].col;
|
||||
|
|
306
src/sumcheck.rs
306
src/sumcheck.rs
|
@ -12,6 +12,7 @@ use super::unipoly::{CompressedUniPoly, UniPoly};
|
|||
use core::iter;
|
||||
use itertools::izip;
|
||||
use merlin::Transcript;
|
||||
use rayon::prelude::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
|
@ -188,42 +189,49 @@ impl SumcheckInstanceProof {
|
|||
transcript: &mut Transcript,
|
||||
) -> (Self, Vec<Scalar>, Vec<Scalar>)
|
||||
where
|
||||
F: Fn(&Scalar, &Scalar, &Scalar) -> Scalar,
|
||||
F: Fn(&Scalar, &Scalar, &Scalar) -> Scalar + Sync,
|
||||
{
|
||||
let mut e = *claim;
|
||||
let mut r: Vec<Scalar> = Vec::new();
|
||||
let mut cubic_polys: Vec<CompressedUniPoly> = Vec::new();
|
||||
for _j in 0..num_rounds {
|
||||
let mut eval_point_0 = Scalar::zero();
|
||||
let mut eval_point_2 = Scalar::zero();
|
||||
let mut eval_point_3 = Scalar::zero();
|
||||
|
||||
let len = poly_A.len() / 2;
|
||||
for i in 0..len {
|
||||
// eval 0: bound_func is A(low)
|
||||
eval_point_0 += comb_func(&poly_A[i], &poly_B[i], &poly_C[i]);
|
||||
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C[len + i] + poly_C[len + i] - poly_C[i];
|
||||
eval_point_2 += comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
);
|
||||
let (eval_point_0, eval_point_2, eval_point_3) = {
|
||||
// make an iterator returning contributions to the three evaluations
|
||||
let eval_iter = (0..len).into_par_iter().map(|i| {
|
||||
// eval 0: bound_func is A(low)
|
||||
let eval_point_0 = comb_func(&poly_A[i], &poly_B[i], &poly_C[i]);
|
||||
|
||||
// eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
|
||||
let poly_A_bound_point = poly_A_bound_point + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C_bound_point + poly_C[len + i] - poly_C[i];
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C[len + i] + poly_C[len + i] - poly_C[i];
|
||||
let eval_point_2 = comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
);
|
||||
|
||||
eval_point_3 += comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
);
|
||||
}
|
||||
// eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
|
||||
let poly_A_bound_point = poly_A_bound_point + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C_bound_point + poly_C[len + i] - poly_C[i];
|
||||
let eval_point_3 = comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
);
|
||||
|
||||
(eval_point_0, eval_point_2, eval_point_3)
|
||||
});
|
||||
|
||||
// accumulate contributions using the iter
|
||||
eval_iter.reduce(
|
||||
|| (Scalar::zero(), Scalar::zero(), Scalar::zero()),
|
||||
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
||||
)
|
||||
};
|
||||
|
||||
let evals = vec![eval_point_0, e - eval_point_0, eval_point_2, eval_point_3];
|
||||
let poly = UniPoly::from_evals(&evals);
|
||||
|
@ -234,10 +242,18 @@ impl SumcheckInstanceProof {
|
|||
//derive the verifier's challenge for the next round
|
||||
let r_j = transcript.challenge_scalar(b"challenge_nextround");
|
||||
r.push(r_j);
|
||||
|
||||
// bound all tables to the verifier's challenege
|
||||
poly_A.bound_poly_var_top(&r_j);
|
||||
poly_B.bound_poly_var_top(&r_j);
|
||||
poly_C.bound_poly_var_top(&r_j);
|
||||
rayon::join(
|
||||
|| poly_A.bound_poly_var_top(&r_j),
|
||||
|| {
|
||||
rayon::join(
|
||||
|| poly_B.bound_poly_var_top(&r_j),
|
||||
|| poly_C.bound_poly_var_top(&r_j),
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
e = poly.evaluate(&r_j);
|
||||
cubic_polys.push(poly.compress());
|
||||
}
|
||||
|
@ -272,12 +288,11 @@ impl SumcheckInstanceProof {
|
|||
(Vec<Scalar>, Vec<Scalar>, Vec<Scalar>),
|
||||
)
|
||||
where
|
||||
F: Fn(&Scalar, &Scalar, &Scalar) -> Scalar,
|
||||
F: Fn(&Scalar, &Scalar, &Scalar) -> Scalar + Sync,
|
||||
{
|
||||
let (poly_A_vec_par, poly_B_vec_par, poly_C_par) = poly_vec_par;
|
||||
let (poly_A_vec_seq, poly_B_vec_seq, poly_C_vec_seq) = poly_vec_seq;
|
||||
|
||||
//let (poly_A_vec_seq, poly_B_vec_seq, poly_C_vec_seq) = poly_vec_seq;
|
||||
let mut e = *claim;
|
||||
let mut r: Vec<Scalar> = Vec::new();
|
||||
let mut cubic_polys: Vec<CompressedUniPoly> = Vec::new();
|
||||
|
@ -286,20 +301,18 @@ impl SumcheckInstanceProof {
|
|||
let mut evals: Vec<(Scalar, Scalar, Scalar)> = Vec::new();
|
||||
|
||||
for (poly_A, poly_B) in poly_A_vec_par.iter().zip(poly_B_vec_par.iter()) {
|
||||
let mut eval_point_0 = Scalar::zero();
|
||||
let mut eval_point_2 = Scalar::zero();
|
||||
let mut eval_point_3 = Scalar::zero();
|
||||
|
||||
let len = poly_A.len() / 2;
|
||||
for i in 0..len {
|
||||
|
||||
// make an iterator returning the contributions to the evaluations
|
||||
let eval_iter = (0..len).into_par_iter().map(|i| {
|
||||
// eval 0: bound_func is A(low)
|
||||
eval_point_0 += comb_func(&poly_A[i], &poly_B[i], &poly_C_par[i]);
|
||||
let eval_point_0 = comb_func(&poly_A[i], &poly_B[i], &poly_C_par[i]);
|
||||
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C_par[len + i] + poly_C_par[len + i] - poly_C_par[i];
|
||||
eval_point_2 += comb_func(
|
||||
let eval_point_2 = comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
|
@ -310,12 +323,19 @@ impl SumcheckInstanceProof {
|
|||
let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C_bound_point + poly_C_par[len + i] - poly_C_par[i];
|
||||
|
||||
eval_point_3 += comb_func(
|
||||
let eval_point_3 = comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
);
|
||||
}
|
||||
(eval_point_0, eval_point_2, eval_point_3)
|
||||
});
|
||||
|
||||
// Sum the iterator to get the evaluations
|
||||
let (eval_point_0, eval_point_2, eval_point_3) = eval_iter.reduce(
|
||||
|| (Scalar::zero(), Scalar::zero(), Scalar::zero()),
|
||||
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
||||
);
|
||||
|
||||
evals.push((eval_point_0, eval_point_2, eval_point_3));
|
||||
}
|
||||
|
@ -325,32 +345,43 @@ impl SumcheckInstanceProof {
|
|||
poly_B_vec_seq.iter(),
|
||||
poly_C_vec_seq.iter()
|
||||
) {
|
||||
let mut eval_point_0 = Scalar::zero();
|
||||
let mut eval_point_2 = Scalar::zero();
|
||||
let mut eval_point_3 = Scalar::zero();
|
||||
let len = poly_A.len() / 2;
|
||||
for i in 0..len {
|
||||
// eval 0: bound_func is A(low)
|
||||
eval_point_0 += comb_func(&poly_A[i], &poly_B[i], &poly_C[i]);
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C[len + i] + poly_C[len + i] - poly_C[i];
|
||||
eval_point_2 += comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
);
|
||||
// eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
|
||||
let poly_A_bound_point = poly_A_bound_point + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C_bound_point + poly_C[len + i] - poly_C[i];
|
||||
eval_point_3 += comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
);
|
||||
}
|
||||
let (eval_point_0, eval_point_2, eval_point_3) = {
|
||||
// create an iterator to get contributions to each of the evaluation points
|
||||
let eval_iter = (0..len).into_par_iter().map(|i| {
|
||||
// eval 0: bound_func is A(low)
|
||||
let eval_point_0 = comb_func(&poly_A[i], &poly_B[i], &poly_C[i]);
|
||||
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C[len + i] + poly_C[len + i] - poly_C[i];
|
||||
let eval_point_2 = comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
);
|
||||
|
||||
// eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
|
||||
let poly_A_bound_point = poly_A_bound_point + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C_bound_point + poly_C[len + i] - poly_C[i];
|
||||
let eval_point_3 = comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
);
|
||||
|
||||
(eval_point_0, eval_point_2, eval_point_3)
|
||||
});
|
||||
|
||||
// Sum the iterator to get the evaluations
|
||||
eval_iter.reduce(
|
||||
|| (Scalar::zero(), Scalar::zero(), Scalar::zero()),
|
||||
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
||||
)
|
||||
};
|
||||
|
||||
evals.push((eval_point_0, eval_point_2, eval_point_3));
|
||||
}
|
||||
|
||||
|
@ -375,8 +406,10 @@ impl SumcheckInstanceProof {
|
|||
|
||||
// bound all tables to the verifier's challenege
|
||||
for (poly_A, poly_B) in poly_A_vec_par.iter_mut().zip(poly_B_vec_par.iter_mut()) {
|
||||
poly_A.bound_poly_var_top(&r_j);
|
||||
poly_B.bound_poly_var_top(&r_j);
|
||||
rayon::join(
|
||||
|| poly_A.bound_poly_var_top(&r_j),
|
||||
|| poly_B.bound_poly_var_top(&r_j),
|
||||
);
|
||||
}
|
||||
poly_C_par.bound_poly_var_top(&r_j);
|
||||
|
||||
|
@ -385,9 +418,15 @@ impl SumcheckInstanceProof {
|
|||
poly_B_vec_seq.iter_mut(),
|
||||
poly_C_vec_seq.iter_mut()
|
||||
) {
|
||||
poly_A.bound_poly_var_top(&r_j);
|
||||
poly_B.bound_poly_var_top(&r_j);
|
||||
poly_C.bound_poly_var_top(&r_j);
|
||||
rayon::join(
|
||||
|| poly_A.bound_poly_var_top(&r_j),
|
||||
|| {
|
||||
rayon::join(
|
||||
|| poly_B.bound_poly_var_top(&r_j),
|
||||
|| poly_C.bound_poly_var_top(&r_j),
|
||||
)
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
e = poly.evaluate(&r_j);
|
||||
|
@ -436,7 +475,7 @@ impl ZKSumcheckInstanceProof {
|
|||
random_tape: &mut RandomTape,
|
||||
) -> (Self, Vec<Scalar>, Vec<Scalar>, Scalar)
|
||||
where
|
||||
F: Fn(&Scalar, &Scalar) -> Scalar,
|
||||
F: Fn(&Scalar, &Scalar) -> Scalar + Sync,
|
||||
{
|
||||
let (blinds_poly, blinds_evals) = (
|
||||
random_tape.random_vector(b"blinds_poly", num_rounds),
|
||||
|
@ -452,19 +491,27 @@ impl ZKSumcheckInstanceProof {
|
|||
|
||||
for j in 0..num_rounds {
|
||||
let (poly, comm_poly) = {
|
||||
let mut eval_point_0 = Scalar::zero();
|
||||
let mut eval_point_2 = Scalar::zero();
|
||||
|
||||
let len = poly_A.len() / 2;
|
||||
for i in 0..len {
|
||||
// eval 0: bound_func is A(low)
|
||||
eval_point_0 += comb_func(&poly_A[i], &poly_B[i]);
|
||||
let (eval_point_0, eval_point_2) = {
|
||||
// make an iterator returning contributions to the three evaluations
|
||||
let eval_iter = (0..len).into_par_iter().map(|i| {
|
||||
// eval 0: bound_func is A(low)
|
||||
let eval_point_0 = comb_func(&poly_A[i], &poly_B[i]);
|
||||
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
||||
eval_point_2 += comb_func(&poly_A_bound_point, &poly_B_bound_point);
|
||||
}
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
||||
let eval_point_2 = comb_func(&poly_A_bound_point, &poly_B_bound_point);
|
||||
|
||||
(eval_point_0, eval_point_2)
|
||||
});
|
||||
|
||||
// accumulate contributions using the iter
|
||||
eval_iter.reduce(
|
||||
|| (Scalar::zero(), Scalar::zero()),
|
||||
|a, b| (a.0 + b.0, a.1 + b.1),
|
||||
)
|
||||
};
|
||||
|
||||
let evals = vec![eval_point_0, claim_per_round - eval_point_0, eval_point_2];
|
||||
let poly = UniPoly::from_evals(&evals);
|
||||
|
@ -480,8 +527,10 @@ impl ZKSumcheckInstanceProof {
|
|||
let r_j = transcript.challenge_scalar(b"challenge_nextround");
|
||||
|
||||
// bound all tables to the verifier's challenege
|
||||
poly_A.bound_poly_var_top(&r_j);
|
||||
poly_B.bound_poly_var_top(&r_j);
|
||||
rayon::join(
|
||||
|| poly_A.bound_poly_var_top(&r_j),
|
||||
|| poly_B.bound_poly_var_top(&r_j),
|
||||
);
|
||||
|
||||
// produce a proof of sum-check and of evaluation
|
||||
let (proof, claim_next_round, comm_claim_next_round) = {
|
||||
|
@ -598,7 +647,7 @@ impl ZKSumcheckInstanceProof {
|
|||
random_tape: &mut RandomTape,
|
||||
) -> (Self, Vec<Scalar>, Vec<Scalar>, Scalar)
|
||||
where
|
||||
F: Fn(&Scalar, &Scalar, &Scalar, &Scalar) -> Scalar,
|
||||
F: Fn(&Scalar, &Scalar, &Scalar, &Scalar) -> Scalar + Sync,
|
||||
{
|
||||
let (blinds_poly, blinds_evals) = (
|
||||
random_tape.random_vector(b"blinds_poly", num_rounds),
|
||||
|
@ -615,39 +664,46 @@ impl ZKSumcheckInstanceProof {
|
|||
|
||||
for j in 0..num_rounds {
|
||||
let (poly, comm_poly) = {
|
||||
let mut eval_point_0 = Scalar::zero();
|
||||
let mut eval_point_2 = Scalar::zero();
|
||||
let mut eval_point_3 = Scalar::zero();
|
||||
|
||||
let len = poly_A.len() / 2;
|
||||
for i in 0..len {
|
||||
// eval 0: bound_func is A(low)
|
||||
eval_point_0 += comb_func(&poly_A[i], &poly_B[i], &poly_C[i], &poly_D[i]);
|
||||
let (eval_point_0, eval_point_2, eval_point_3) = {
|
||||
// make an iterator returning contributions to the three evaluations
|
||||
let eval_iter = (0..len).into_par_iter().map(|i| {
|
||||
// eval 0: bound_func is A(low)
|
||||
let eval_point_0 = comb_func(&poly_A[i], &poly_B[i], &poly_C[i], &poly_D[i]);
|
||||
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C[len + i] + poly_C[len + i] - poly_C[i];
|
||||
let poly_D_bound_point = poly_D[len + i] + poly_D[len + i] - poly_D[i];
|
||||
eval_point_2 += comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
&poly_D_bound_point,
|
||||
);
|
||||
// eval 2: bound_func is -A(low) + 2*A(high)
|
||||
let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C[len + i] + poly_C[len + i] - poly_C[i];
|
||||
let poly_D_bound_point = poly_D[len + i] + poly_D[len + i] - poly_D[i];
|
||||
let eval_point_2 = comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
&poly_D_bound_point,
|
||||
);
|
||||
|
||||
// eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
|
||||
let poly_A_bound_point = poly_A_bound_point + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C_bound_point + poly_C[len + i] - poly_C[i];
|
||||
let poly_D_bound_point = poly_D_bound_point + poly_D[len + i] - poly_D[i];
|
||||
eval_point_3 += comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
&poly_D_bound_point,
|
||||
);
|
||||
}
|
||||
// eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
|
||||
let poly_A_bound_point = poly_A_bound_point + poly_A[len + i] - poly_A[i];
|
||||
let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
|
||||
let poly_C_bound_point = poly_C_bound_point + poly_C[len + i] - poly_C[i];
|
||||
let poly_D_bound_point = poly_D_bound_point + poly_D[len + i] - poly_D[i];
|
||||
let eval_point_3 = comb_func(
|
||||
&poly_A_bound_point,
|
||||
&poly_B_bound_point,
|
||||
&poly_C_bound_point,
|
||||
&poly_D_bound_point,
|
||||
);
|
||||
|
||||
(eval_point_0, eval_point_2, eval_point_3)
|
||||
});
|
||||
|
||||
// accumulate contributions using the iter
|
||||
eval_iter.reduce(
|
||||
|| (Scalar::zero(), Scalar::zero(), Scalar::zero()),
|
||||
|a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
|
||||
)
|
||||
};
|
||||
|
||||
let evals = vec![
|
||||
eval_point_0,
|
||||
|
@ -668,10 +724,20 @@ impl ZKSumcheckInstanceProof {
|
|||
let r_j = transcript.challenge_scalar(b"challenge_nextround");
|
||||
|
||||
// bound all tables to the verifier's challenege
|
||||
poly_A.bound_poly_var_top(&r_j);
|
||||
poly_B.bound_poly_var_top(&r_j);
|
||||
poly_C.bound_poly_var_top(&r_j);
|
||||
poly_D.bound_poly_var_top(&r_j);
|
||||
rayon::join(
|
||||
|| poly_A.bound_poly_var_top(&r_j),
|
||||
|| {
|
||||
rayon::join(
|
||||
|| poly_B.bound_poly_var_top(&r_j),
|
||||
|| {
|
||||
rayon::join(
|
||||
|| poly_C.bound_poly_var_top(&r_j),
|
||||
|| poly_D.bound_poly_var_top(&r_j),
|
||||
)
|
||||
},
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
// produce a proof of sum-check and of evaluation
|
||||
let (proof, claim_next_round, comm_claim_next_round) = {
|
||||
|
|
Загрузка…
Ссылка в новой задаче