From 3db368b40ec25652651376387b3f12a36489c4ec Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 25 Sep 2020 09:11:37 -0600 Subject: [PATCH 1/5] Move `Guard` and `Accumulator` implementations into `verifier` submodule. --- src/poly/commitment.rs | 74 ++------------------------------- src/poly/commitment/verifier.rs | 74 ++++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 73 deletions(-) diff --git a/src/poly/commitment.rs b/src/poly/commitment.rs index eaec55f..73572ed 100644 --- a/src/poly/commitment.rs +++ b/src/poly/commitment.rs @@ -4,15 +4,15 @@ //! [halo]: https://eprint.iacr.org/2019/1021 use super::{Coeff, LagrangeCoeff, Polynomial}; -use crate::arithmetic::{ - best_fft, best_multiexp, parallelize, Challenge, Curve, CurveAffine, Field, -}; +use crate::arithmetic::{best_fft, best_multiexp, parallelize, Curve, CurveAffine, Field}; use crate::transcript::Hasher; use std::ops::{Add, AddAssign, Mul, MulAssign}; mod prover; mod verifier; +pub use verifier::{Accumulator, Guard}; + /// This is a proof object for the polynomial commitment scheme opening. #[derive(Debug, Clone)] pub struct Proof { @@ -22,17 +22,6 @@ pub struct Proof { z2: C::Scalar, } -/// An accumulator instance consisting of an evaluation claim and a proof. -#[derive(Debug, Clone)] -pub struct Accumulator { - /// The claimed output of the linear-time polycommit opening protocol - pub g: C, - - /// A vector of 128-bit challenges sampled by the verifier, to be used in - /// computing g. - pub challenges_sq_packed: Vec, -} - /// A multiscalar multiplication in the polynomial commitment scheme #[derive(Debug, Clone)] pub struct MSM<'a, C: CurveAffine> { @@ -281,46 +270,6 @@ impl Params { } } -/// A guard returned by the verifier -#[derive(Debug, Clone)] -pub struct Guard<'a, C: CurveAffine> { - msm: MSM<'a, C>, - neg_z1: C::Scalar, - allinv: C::Scalar, - challenges_sq: Vec, - challenges_sq_packed: Vec, -} - -impl<'a, C: CurveAffine> Guard<'a, C> { - /// Lets caller supply the challenges and obtain an MSM with updated - /// scalars and points. - pub fn use_challenges(mut self) -> MSM<'a, C> { - let s = compute_s(&self.challenges_sq, self.allinv * &self.neg_z1); - self.msm.add_to_g(&s); - - self.msm - } - - /// Lets caller supply the purported G point and simply appends it to - /// return an updated MSM. - pub fn use_g(mut self, g: C) -> (MSM<'a, C>, Accumulator) { - self.msm.add_term(self.neg_z1, g); - - let accumulator = Accumulator { - g, - challenges_sq_packed: self.challenges_sq_packed, - }; - - (self.msm, accumulator) - } - - /// Computes the g value when given a potential scalar as input. - pub fn compute_g(&self) -> C { - let s = compute_s(&self.challenges_sq, self.allinv); - best_multiexp(&s, &self.msm.params.g).to_affine() - } -} - /// Wrapper type around a blinding factor. #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub struct Blind(pub F); @@ -494,20 +443,3 @@ fn test_opening_proof() { } } } - -// TODO: parallelize -fn compute_s(challenges_sq: &[F], allinv: F) -> Vec { - let lg_n = challenges_sq.len(); - let n = 1 << lg_n; - - let mut s = Vec::with_capacity(n); - s.push(allinv); - for i in 1..n { - let lg_i = (32 - 1 - (i as u32).leading_zeros()) as usize; - let k = 1 << lg_i; - let u_lg_i_sq = challenges_sq[(lg_n - 1) - lg_i]; - s.push(s[i - k] * u_lg_i_sq); - } - - s -} diff --git a/src/poly/commitment/verifier.rs b/src/poly/commitment/verifier.rs index 0154934..06e6fd2 100644 --- a/src/poly/commitment/verifier.rs +++ b/src/poly/commitment/verifier.rs @@ -1,8 +1,61 @@ use super::super::Error; -use super::{Guard, Params, Proof, MSM}; +use super::{Proof, Params, MSM}; use crate::transcript::Hasher; -use crate::arithmetic::{get_challenge_scalar, Challenge, CurveAffine, Field}; +use crate::arithmetic::{ + best_multiexp, get_challenge_scalar, Challenge, Curve, CurveAffine, Field, +}; + +/// A guard returned by the verifier +#[derive(Debug, Clone)] +pub struct Guard<'a, C: CurveAffine> { + msm: MSM<'a, C>, + neg_z1: C::Scalar, + allinv: C::Scalar, + challenges_sq: Vec, + challenges_sq_packed: Vec, +} + +/// An accumulator instance consisting of an evaluation claim and a proof. +#[derive(Debug, Clone)] +pub struct Accumulator { + /// The claimed output of the linear-time polycommit opening protocol + pub g: C, + + /// A vector of 128-bit challenges sampled by the verifier, to be used in + /// computing g. + pub challenges_sq_packed: Vec, +} + +impl<'a, C: CurveAffine> Guard<'a, C> { + /// Lets caller supply the challenges and obtain an MSM with updated + /// scalars and points. + pub fn use_challenges(mut self) -> MSM<'a, C> { + let s = compute_s(&self.challenges_sq, self.allinv * &self.neg_z1); + self.msm.add_to_g(&s); + + self.msm + } + + /// Lets caller supply the purported G point and simply appends it to + /// return an updated MSM. + pub fn use_g(mut self, g: C) -> (MSM<'a, C>, Accumulator) { + self.msm.add_term(self.neg_z1, g); + + let accumulator = Accumulator { + g, + challenges_sq_packed: self.challenges_sq_packed, + }; + + (self.msm, accumulator) + } + + /// Computes the g value when given a potential scalar as input. + pub fn compute_g(&self) -> C { + let s = compute_s(&self.challenges_sq, self.allinv); + best_multiexp(&s, &self.msm.params.g).to_affine() + } +} impl Proof { /// Checks to see if an [`Proof`] is valid given the current `transcript`, @@ -160,3 +213,20 @@ fn compute_b(x: F, challenges: &[F], challenges_inv: &[F]) -> F { ) } } + +// TODO: parallelize +fn compute_s(challenges_sq: &[F], allinv: F) -> Vec { + let lg_n = challenges_sq.len(); + let n = 1 << lg_n; + + let mut s = Vec::with_capacity(n); + s.push(allinv); + for i in 1..n { + let lg_i = (32 - 1 - (i as u32).leading_zeros()) as usize; + let k = 1 << lg_i; + let u_lg_i_sq = challenges_sq[(lg_n - 1) - lg_i]; + s.push(s[i - k] * u_lg_i_sq); + } + + s +} From 316a02778407a276ab5b1f0815b75580e6087560 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 25 Sep 2020 09:22:19 -0600 Subject: [PATCH 2/5] Modify commitment opening argument so that G element can be foux blinded to align with wire blinding in PLONK. --- src/poly/commitment/verifier.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/poly/commitment/verifier.rs b/src/poly/commitment/verifier.rs index 06e6fd2..6827c09 100644 --- a/src/poly/commitment/verifier.rs +++ b/src/poly/commitment/verifier.rs @@ -33,6 +33,7 @@ impl<'a, C: CurveAffine> Guard<'a, C> { pub fn use_challenges(mut self) -> MSM<'a, C> { let s = compute_s(&self.challenges_sq, self.allinv * &self.neg_z1); self.msm.add_to_g(&s); + self.msm.add_to_h(self.neg_z1); self.msm } @@ -53,7 +54,10 @@ impl<'a, C: CurveAffine> Guard<'a, C> { /// Computes the g value when given a potential scalar as input. pub fn compute_g(&self) -> C { let s = compute_s(&self.challenges_sq, self.allinv); - best_multiexp(&s, &self.msm.params.g).to_affine() + + let mut tmp = best_multiexp(&s, &self.msm.params.g); + tmp += self.msm.params.h; + tmp.to_affine() } } @@ -159,7 +163,7 @@ impl Proof { let c: C::Scalar = get_challenge_scalar(Challenge(c_packed)); // Check - // [c] P + [c * v] U + [c] sum(L_i * u_i^2) + [c] sum(R_i * u_i^-2) + delta - [z1] G - [z1 * b] U - [z2] H + // [c] P + [c * v] U + [c] sum(L_i * u_i^2) + [c] sum(R_i * u_i^-2) + delta - [z1] G - [z1 * b] U - [z1 - z2] H // = 0 let b = compute_b(x, &challenges, &challenges_inv); @@ -184,8 +188,8 @@ impl Proof { // delta msm.add_term(Field::one(), self.delta); - // - [z2] H - msm.add_to_h(-self.z2); + // - [z1 - z2] H + msm.add_to_h(self.z1 - &self.z2); let guard = Guard { msm, From 56b6d8bd0385fa1fbd813440ee97165b21b1c0df Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 25 Sep 2020 09:28:49 -0600 Subject: [PATCH 3/5] Auxilary wires in PLONK are foux blinded just like fixed wires. --- src/plonk.rs | 2 +- src/plonk/prover.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plonk.rs b/src/plonk.rs index 968afb2..1dc9ab1 100644 --- a/src/plonk.rs +++ b/src/plonk.rs @@ -375,7 +375,7 @@ fn test_proving() { pubinputs[0] = Fp::one(); pubinputs[0] += Fp::one(); let pubinput = params - .commit_lagrange(&pubinputs, Blind(Field::zero())) + .commit_lagrange(&pubinputs, Blind(Field::one())) .to_affine(); for _ in 0..100 { diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index 4b6573e..f036b95 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -96,7 +96,7 @@ impl Proof { // Compute commitments to aux wire polynomials let aux_commitments_projective: Vec<_> = aux .iter() - .map(|poly| params.commit_lagrange(poly, Blind(C::Scalar::zero()))) // TODO: bad blind? + .map(|poly| params.commit_lagrange(poly, Blind::default())) .collect(); let mut aux_commitments = vec![C::zero(); aux_commitments_projective.len()]; C::Projective::batch_to_affine(&aux_commitments_projective, &mut aux_commitments); @@ -501,7 +501,7 @@ impl Proof { accumulate( point_index, &aux_polys[wire.0], - Blind(C::Scalar::zero()), + Blind::default(), aux_evals[query_index], ); } From 6d41693af5668ef50177d304fa5a91b34c2945bf Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 25 Sep 2020 09:58:19 -0600 Subject: [PATCH 4/5] Use Blind::default(). --- src/plonk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plonk.rs b/src/plonk.rs index 1dc9ab1..86be0de 100644 --- a/src/plonk.rs +++ b/src/plonk.rs @@ -375,7 +375,7 @@ fn test_proving() { pubinputs[0] = Fp::one(); pubinputs[0] += Fp::one(); let pubinput = params - .commit_lagrange(&pubinputs, Blind(Field::one())) + .commit_lagrange(&pubinputs, Blind::default()) .to_affine(); for _ in 0..100 { From 4a37e05f492e75a191ac318e8a1a5d4477971bb2 Mon Sep 17 00:00:00 2001 From: Sean Bowe Date: Fri, 25 Sep 2020 10:21:54 -0600 Subject: [PATCH 5/5] cargo fmt --- src/poly/commitment/verifier.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/poly/commitment/verifier.rs b/src/poly/commitment/verifier.rs index 6827c09..649c2c3 100644 --- a/src/poly/commitment/verifier.rs +++ b/src/poly/commitment/verifier.rs @@ -1,5 +1,5 @@ use super::super::Error; -use super::{Proof, Params, MSM}; +use super::{Params, Proof, MSM}; use crate::transcript::Hasher; use crate::arithmetic::{