Parallelize and rename methods in msm.rs

This commit is contained in:
therealyingtong 2020-11-12 14:14:01 +08:00
parent f86fce83ef
commit d168f5c21b
4 changed files with 35 additions and 29 deletions

View File

@ -293,7 +293,7 @@ fn test_opening_proof() {
let opening_proof = opening_proof.unwrap(); let opening_proof = opening_proof.unwrap();
// Verify the opening proof // Verify the opening proof
let mut commitment_msm = params.empty_msm(); let mut commitment_msm = params.empty_msm();
commitment_msm.add_term(Field::one(), p); commitment_msm.append_term(Field::one(), p);
let guard = opening_proof let guard = opening_proof
.verify( .verify(
&params, &params,
@ -320,7 +320,7 @@ fn test_opening_proof() {
// Check another proof to populate `msm.g_scalars` // Check another proof to populate `msm.g_scalars`
let msm = guard.use_challenges(); let msm = guard.use_challenges();
let mut commitment_msm = params.empty_msm(); let mut commitment_msm = params.empty_msm();
commitment_msm.add_term(Field::one(), p); commitment_msm.append_term(Field::one(), p);
let guard = opening_proof let guard = opening_proof
.verify( .verify(
&params, &params,

View File

@ -1,5 +1,5 @@
use super::Params; use super::Params;
use crate::arithmetic::{best_multiexp, Curve, CurveAffine}; use crate::arithmetic::{best_multiexp, parallelize, Curve, CurveAffine};
/// A multiscalar multiplication in the polynomial commitment scheme /// A multiscalar multiplication in the polynomial commitment scheme
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -34,52 +34,58 @@ impl<'a, C: CurveAffine> MSM<'a, C> {
self.other_bases.extend(other.other_bases.iter()); self.other_bases.extend(other.other_bases.iter());
if let Some(g_scalars) = &other.g_scalars { if let Some(g_scalars) = &other.g_scalars {
self.add_to_g(&g_scalars); self.add_to_g_scalars(&g_scalars);
} }
if let Some(h_scalar) = &other.h_scalar { if let Some(h_scalar) = &other.h_scalar {
self.add_to_h(*h_scalar); self.add_to_h_scalar(*h_scalar);
} }
} }
/// Add arbitrary term (the scalar and the point) /// Add arbitrary term (the scalar and the point)
pub fn add_term(&mut self, scalar: C::Scalar, point: C) { pub fn append_term(&mut self, scalar: C::Scalar, point: C) {
self.other_scalars.push(scalar); self.other_scalars.push(scalar);
self.other_bases.push(point); self.other_bases.push(point);
} }
/// Add a vector of scalars to `g_scalars`. This function will panic if the /// Add a vector of scalars to `g_scalars`. This function will panic if the
/// caller provides a slice of scalars that is not of length `params.n`. /// caller provides a slice of scalars that is not of length `params.n`.
// TODO: parallelize pub fn add_to_g_scalars(&mut self, scalars: &[C::Scalar]) {
pub fn add_to_g(&mut self, scalars: &[C::Scalar]) {
assert_eq!(scalars.len(), self.params.n as usize); assert_eq!(scalars.len(), self.params.n as usize);
if let Some(g_scalars) = &mut self.g_scalars { if let Some(g_scalars) = &mut self.g_scalars {
for (g_scalar, scalar) in g_scalars.iter_mut().zip(scalars.iter()) { parallelize(g_scalars, |g_scalars, start| {
*g_scalar += scalar; for (g_scalar, scalar) in g_scalars.iter_mut().zip(scalars[start..].iter()) {
} *g_scalar += scalar;
}
})
} else { } else {
self.g_scalars = Some(scalars.to_vec()); self.g_scalars = Some(scalars.to_vec());
} }
} }
/// Add term to h /// Add to `h_scalar`
pub fn add_to_h(&mut self, scalar: C::Scalar) { pub fn add_to_h_scalar(&mut self, scalar: C::Scalar) {
self.h_scalar = self.h_scalar.map_or(Some(scalar), |a| Some(a + &scalar)); self.h_scalar = self.h_scalar.map_or(Some(scalar), |a| Some(a + &scalar));
} }
/// Scale all scalars in the MSM by some scaling factor /// Scale all scalars in the MSM by some scaling factor
// TODO: parallelize
pub fn scale(&mut self, factor: C::Scalar) { pub fn scale(&mut self, factor: C::Scalar) {
if let Some(g_scalars) = &mut self.g_scalars { if let Some(g_scalars) = &mut self.g_scalars {
for g_scalar in g_scalars.iter_mut() { parallelize(g_scalars, |g_scalars, _| {
*g_scalar *= &factor; for g_scalar in g_scalars {
} *g_scalar *= &factor;
}
})
} }
// TODO: parallelize if !self.other_scalars.is_empty() {
for other_scalar in self.other_scalars.iter_mut() { parallelize(&mut self.other_scalars, |other_scalars, _| {
*other_scalar *= &factor; for other_scalar in other_scalars {
*other_scalar *= &factor;
}
})
} }
self.h_scalar = self.h_scalar.map(|a| a * &factor); self.h_scalar = self.h_scalar.map(|a| a * &factor);
} }

View File

@ -32,8 +32,8 @@ impl<'a, C: CurveAffine> Guard<'a, C> {
/// scalars and points. /// scalars and points.
pub fn use_challenges(mut self) -> MSM<'a, C> { pub fn use_challenges(mut self) -> MSM<'a, C> {
let s = compute_s(&self.challenges_sq, self.allinv * &self.neg_z1); let s = compute_s(&self.challenges_sq, self.allinv * &self.neg_z1);
self.msm.add_to_g(&s); self.msm.add_to_g_scalars(&s);
self.msm.add_to_h(self.neg_z1); self.msm.add_to_h_scalar(self.neg_z1);
self.msm self.msm
} }
@ -41,7 +41,7 @@ impl<'a, C: CurveAffine> Guard<'a, C> {
/// Lets caller supply the purported G point and simply appends it to /// Lets caller supply the purported G point and simply appends it to
/// return an updated MSM. /// return an updated MSM.
pub fn use_g(mut self, g: C) -> (MSM<'a, C>, Accumulator<C>) { pub fn use_g(mut self, g: C) -> (MSM<'a, C>, Accumulator<C>) {
self.msm.add_term(self.neg_z1, g); self.msm.append_term(self.neg_z1, g);
let accumulator = Accumulator { let accumulator = Accumulator {
g, g,
@ -176,17 +176,17 @@ impl<C: CurveAffine> Proof<C> {
} }
for (scalar, base) in extra_scalars.iter().zip(extra_bases.iter()) { for (scalar, base) in extra_scalars.iter().zip(extra_bases.iter()) {
msm.add_term(*scalar, *base); msm.append_term(*scalar, *base);
} }
// [c * v] U - [z1 * b] U // [c * v] U - [z1 * b] U
msm.add_term((c * &v) + &(neg_z1 * &b), u); msm.append_term((c * &v) + &(neg_z1 * &b), u);
// delta // delta
msm.add_term(Field::one(), self.delta); msm.append_term(Field::one(), self.delta);
// - [z1 - z2] H // - [z1 - z2] H
msm.add_to_h(self.z1 - &self.z2); msm.add_to_h_scalar(self.z1 - &self.z2);
let guard = Guard { let guard = Guard {
msm, msm,

View File

@ -54,7 +54,7 @@ impl<C: CurveAffine> Proof<C> {
{ {
let mut accumulate = |set_idx: usize, new_commitment, evals: Vec<C::Scalar>| { let mut accumulate = |set_idx: usize, new_commitment, evals: Vec<C::Scalar>| {
q_commitments[set_idx].scale(x_4); q_commitments[set_idx].scale(x_4);
q_commitments[set_idx].add_term(C::Scalar::one(), new_commitment); q_commitments[set_idx].append_term(C::Scalar::one(), new_commitment);
for (eval, set_eval) in evals.iter().zip(q_eval_sets[set_idx].iter_mut()) { for (eval, set_eval) in evals.iter().zip(q_eval_sets[set_idx].iter_mut()) {
*set_eval *= &x_4; *set_eval *= &x_4;
*set_eval += eval; *set_eval += eval;
@ -109,7 +109,7 @@ impl<C: CurveAffine> Proof<C> {
// Compute the final commitment that has to be opened // Compute the final commitment that has to be opened
let mut commitment_msm = params.empty_msm(); let mut commitment_msm = params.empty_msm();
commitment_msm.add_term(C::Scalar::one(), self.f_commitment); commitment_msm.append_term(C::Scalar::one(), self.f_commitment);
let (commitment_msm, msm_eval) = q_commitments.into_iter().zip(self.q_evals.iter()).fold( let (commitment_msm, msm_eval) = q_commitments.into_iter().zip(self.q_evals.iter()).fold(
(commitment_msm, msm_eval), (commitment_msm, msm_eval),
|(mut commitment_msm, msm_eval), (q_commitment, q_eval)| { |(mut commitment_msm, msm_eval), (q_commitment, q_eval)| {