From a6f5d0ad5e6588e6619ef6894c301473815ce527 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Sat, 19 Sep 2020 13:21:05 +0800 Subject: [PATCH 1/4] Remove fork from OpeningProof prover; add loop in PLONK prover to try different f_blind values --- src/plonk/prover.rs | 102 +++++++++++++++++++------------- src/poly.rs | 2 + src/poly/commitment.rs | 1 - src/poly/commitment/prover.rs | 33 +++-------- src/poly/commitment/verifier.rs | 2 - 5 files changed, 70 insertions(+), 70 deletions(-) diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index b42ea0d..4790ad3 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -529,51 +529,71 @@ impl Proof { }) .or_else(|| Some(poly)); } - let mut f_poly = f_poly.unwrap(); - let mut f_blind = Blind(C::Scalar::random()); - let f_commitment = params.commit(&f_poly, f_blind).to_affine(); + let final_opening; + let final_f_commitment; + let final_q_evals; - hash_point(&mut transcript, &f_commitment)?; + loop { + let mut transcript_dup = transcript.clone(); + let mut transcript_scalar_dup = transcript_scalar.clone(); + let mut f_poly_dup = f_poly.clone().unwrap(); - let x_6: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); + let mut f_blind = Blind(C::Scalar::random()); + let f_commitment = params.commit(&f_poly_dup, f_blind).to_affine(); + hash_point(&mut transcript_dup, &f_commitment)?; - let mut q_evals = vec![C::Scalar::zero(); meta.rotations.len()]; + let x_6: C::Scalar = + get_challenge_scalar(Challenge(transcript_dup.squeeze().get_lower_128())); - for (_, &point_index) in meta.rotations.iter() { - q_evals[point_index.0] = - eval_polynomial(&q_polys[point_index.0].as_ref().unwrap(), x_6); + let mut q_evals = vec![C::Scalar::zero(); meta.rotations.len()]; + + for (_, &point_index) in meta.rotations.iter() { + q_evals[point_index.0] = + eval_polynomial(&q_polys[point_index.0].as_ref().unwrap(), x_6); + } + + for eval in q_evals.iter() { + transcript_scalar_dup.absorb(*eval); + } + + let transcript_scalar_point = + C::Base::from_bytes(&(transcript_scalar_dup.squeeze()).to_bytes()).unwrap(); + transcript_dup.absorb(transcript_scalar_point); + + let x_7: C::Scalar = + get_challenge_scalar(Challenge(transcript_dup.squeeze().get_lower_128())); + + for (_, &point_index) in meta.rotations.iter() { + f_blind *= x_7; + f_blind += q_blinds[point_index.0]; + + parallelize(&mut f_poly_dup, |f, start| { + for (f, a) in f + .iter_mut() + .zip(q_polys[point_index.0].as_ref().unwrap()[start..].iter()) + { + *f *= &x_7; + *f += a; + } + }); + } + + // Check U + let u_x = transcript_dup.clone().squeeze(); + // y^2 = x^3 + B + let u_y2 = u_x.square() * &u_x + &C::b(); + + if let Some(_) = u_y2.deterministic_sqrt() { + final_q_evals = q_evals; + final_f_commitment = f_commitment; + final_opening = + OpeningProof::create(¶ms, &mut transcript_dup, &f_poly_dup, f_blind, x_6) + .unwrap(); + break; + } } - for eval in q_evals.iter() { - transcript_scalar.absorb(*eval); - } - - let transcript_scalar_point = - C::Base::from_bytes(&(transcript_scalar.squeeze()).to_bytes()).unwrap(); - transcript.absorb(transcript_scalar_point); - - let x_7: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); - - for (_, &point_index) in meta.rotations.iter() { - f_blind *= x_7; - f_blind += q_blinds[point_index.0]; - - parallelize(&mut f_poly, |f, start| { - for (f, a) in f - .iter_mut() - .zip(q_polys[point_index.0].as_ref().unwrap()[start..].iter()) - { - *f *= &x_7; - *f += a; - } - }); - } - - // Let's prove that the q_commitment opens at x to the expected value. - let opening = OpeningProof::create(¶ms, &mut transcript, &f_poly, f_blind, x_6) - .map_err(|_| Error::ConstraintSystemFailure)?; - Ok(Proof { advice_commitments, h_commitments, @@ -584,9 +604,9 @@ impl Proof { advice_evals, fixed_evals, h_evals, - f_commitment, - q_evals, - opening, + f_commitment: final_f_commitment, + q_evals: final_q_evals, + opening: final_opening, }) } } diff --git a/src/poly.rs b/src/poly.rs index 07f32e3..d5f1153 100644 --- a/src/poly.rs +++ b/src/poly.rs @@ -19,6 +19,8 @@ pub use domain::*; pub enum Error { /// OpeningProof is not well-formed OpeningError, + /// Caller needs to re-sample a point + SamplingError, } /// The basis over which a polynomial is described. diff --git a/src/poly/commitment.rs b/src/poly/commitment.rs index 2eaa9ef..77ac408 100644 --- a/src/poly/commitment.rs +++ b/src/poly/commitment.rs @@ -16,7 +16,6 @@ mod verifier; /// This is a proof object for the polynomial commitment scheme opening. #[derive(Debug, Clone)] pub struct OpeningProof { - fork: u8, rounds: Vec<(C, C)>, delta: C, z1: C::Scalar, diff --git a/src/poly/commitment/prover.rs b/src/poly/commitment/prover.rs index c66fe82..0bf2a10 100644 --- a/src/poly/commitment/prover.rs +++ b/src/poly/commitment/prover.rs @@ -1,4 +1,4 @@ -use super::super::{Coeff, Polynomial}; +use super::super::{Coeff, Error, Polynomial}; use super::{Blind, OpeningProof, Params}; use crate::arithmetic::{ best_multiexp, compute_inner_product, get_challenge_scalar, parallelize, small_multiexp, @@ -26,40 +26,22 @@ impl OpeningProof { px: &Polynomial, blind: Blind, x: C::Scalar, - ) -> Result { + ) -> Result { let mut blind = blind.0; // We're limited to polynomials of degree n - 1. assert!(px.len() <= params.n as usize); - let mut fork = 0; - - // TODO: remove this hack and force the caller to deal with it - loop { - let mut transcript = transcript.clone(); - transcript.absorb(C::Base::from_u64(fork as u64)); - let u_x = transcript.squeeze(); - // y^2 = x^3 + B - let u_y2 = u_x.square() * &u_x + &C::b(); - let u_y = u_y2.deterministic_sqrt(); - - if u_y.is_none() { - fork += 1; - } else { - break; - } - } - - transcript.absorb(C::Base::from_u64(fork as u64)); - // Compute U let u = { let u_x = transcript.squeeze(); // y^2 = x^3 + B let u_y2 = u_x.square() * &u_x + &C::b(); - let u_y = u_y2.deterministic_sqrt().unwrap(); - - C::from_xy(u_x, u_y).unwrap() + if let Some(u_y) = u_y2.deterministic_sqrt() { + C::from_xy(u_x, u_y).unwrap() + } else { + return Err(Error::SamplingError); + } }; // Initialize the vector `a` as the coefficients of the polynomial, @@ -205,7 +187,6 @@ impl OpeningProof { let z2 = c * &blind + &s; Ok(OpeningProof { - fork, rounds, delta, z1, diff --git a/src/poly/commitment/verifier.rs b/src/poly/commitment/verifier.rs index c7673ac..937bd46 100644 --- a/src/poly/commitment/verifier.rs +++ b/src/poly/commitment/verifier.rs @@ -22,8 +22,6 @@ impl OpeningProof { return Err(Error::OpeningError); } - transcript.absorb(C::Base::from_u64(self.fork as u64)); - // Compute U let u = { let u_x = transcript.squeeze(); From 69a612fb597d92da5fc48a32ae5d01d74f50ccaa Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Sat, 19 Sep 2020 23:04:17 +0800 Subject: [PATCH 2/4] Increment blinding factor instead of choosing new random blinding factor --- src/plonk/prover.rs | 54 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index 4790ad3..a39e65c 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -530,21 +530,19 @@ impl Proof { .or_else(|| Some(poly)); } - let final_opening; - let final_f_commitment; + let f_poly = f_poly.unwrap(); + let mut f_blind = Blind(C::Scalar::random()); + let mut f_commitment = params.commit(&f_poly, f_blind).to_affine(); + let final_q_evals; - loop { - let mut transcript_dup = transcript.clone(); - let mut transcript_scalar_dup = transcript_scalar.clone(); - let mut f_poly_dup = f_poly.clone().unwrap(); - - let mut f_blind = Blind(C::Scalar::random()); - let f_commitment = params.commit(&f_poly_dup, f_blind).to_affine(); - hash_point(&mut transcript_dup, &f_commitment)?; + let opening = loop { + let mut transcript = transcript.clone(); + let mut transcript_scalar = transcript_scalar.clone(); + hash_point(&mut transcript, &f_commitment)?; let x_6: C::Scalar = - get_challenge_scalar(Challenge(transcript_dup.squeeze().get_lower_128())); + get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); let mut q_evals = vec![C::Scalar::zero(); meta.rotations.len()]; @@ -554,21 +552,23 @@ impl Proof { } for eval in q_evals.iter() { - transcript_scalar_dup.absorb(*eval); + transcript_scalar.absorb(*eval); } let transcript_scalar_point = - C::Base::from_bytes(&(transcript_scalar_dup.squeeze()).to_bytes()).unwrap(); - transcript_dup.absorb(transcript_scalar_point); + C::Base::from_bytes(&(transcript_scalar.squeeze()).to_bytes()).unwrap(); + transcript.absorb(transcript_scalar_point); let x_7: C::Scalar = - get_challenge_scalar(Challenge(transcript_dup.squeeze().get_lower_128())); + get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); + let mut f_blind_dup = f_blind.clone(); + let mut f_poly = f_poly.clone(); for (_, &point_index) in meta.rotations.iter() { - f_blind *= x_7; - f_blind += q_blinds[point_index.0]; + f_blind_dup *= x_7; + f_blind_dup += q_blinds[point_index.0]; - parallelize(&mut f_poly_dup, |f, start| { + parallelize(&mut f_poly, |f, start| { for (f, a) in f .iter_mut() .zip(q_polys[point_index.0].as_ref().unwrap()[start..].iter()) @@ -580,19 +580,21 @@ impl Proof { } // Check U - let u_x = transcript_dup.clone().squeeze(); + let u_x = transcript.clone().squeeze(); // y^2 = x^3 + B let u_y2 = u_x.square() * &u_x + &C::b(); if let Some(_) = u_y2.deterministic_sqrt() { final_q_evals = q_evals; - final_f_commitment = f_commitment; - final_opening = - OpeningProof::create(¶ms, &mut transcript_dup, &f_poly_dup, f_blind, x_6) + let opening = + OpeningProof::create(¶ms, &mut transcript, &f_poly, f_blind_dup, x_6) .unwrap(); - break; + break opening; + } else { + f_blind += C::Scalar::one(); + f_commitment = (f_commitment + params.h).to_affine(); } - } + }; Ok(Proof { advice_commitments, @@ -604,9 +606,9 @@ impl Proof { advice_evals, fixed_evals, h_evals, - f_commitment: final_f_commitment, + f_commitment, q_evals: final_q_evals, - opening: final_opening, + opening, }) } } From 33261ec1a0a84673656e903e6eed61f60d734206 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Sat, 19 Sep 2020 23:19:30 +0800 Subject: [PATCH 3/4] Recover from OpeningProof::create() failure in PLONK prover --- src/plonk/prover.rs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index a39e65c..27e3fc1 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -578,18 +578,11 @@ impl Proof { } }); } + let opening = OpeningProof::create(¶ms, &mut transcript, &f_poly, f_blind_dup, x_6); - // Check U - let u_x = transcript.clone().squeeze(); - // y^2 = x^3 + B - let u_y2 = u_x.square() * &u_x + &C::b(); - - if let Some(_) = u_y2.deterministic_sqrt() { + if opening.is_ok() { final_q_evals = q_evals; - let opening = - OpeningProof::create(¶ms, &mut transcript, &f_poly, f_blind_dup, x_6) - .unwrap(); - break opening; + break opening.unwrap(); } else { f_blind += C::Scalar::one(); f_commitment = (f_commitment + params.h).to_affine(); From 76c49a4df373f6d45fe71429598002c2eb243848 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Sat, 19 Sep 2020 23:44:00 +0800 Subject: [PATCH 4/4] Minor refactor --- src/plonk/prover.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index 27e3fc1..93c6942 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -534,9 +534,7 @@ impl Proof { let mut f_blind = Blind(C::Scalar::random()); let mut f_commitment = params.commit(&f_poly, f_blind).to_affine(); - let final_q_evals; - - let opening = loop { + let (opening, q_evals) = loop { let mut transcript = transcript.clone(); let mut transcript_scalar = transcript_scalar.clone(); hash_point(&mut transcript, &f_commitment)?; @@ -581,8 +579,7 @@ impl Proof { let opening = OpeningProof::create(¶ms, &mut transcript, &f_poly, f_blind_dup, x_6); if opening.is_ok() { - final_q_evals = q_evals; - break opening.unwrap(); + break (opening.unwrap(), q_evals); } else { f_blind += C::Scalar::one(); f_commitment = (f_commitment + params.h).to_affine(); @@ -600,7 +597,7 @@ impl Proof { fixed_evals, h_evals, f_commitment, - q_evals: final_q_evals, + q_evals, opening, }) }