diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index b42ea0d5..93c69420 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -529,50 +529,62 @@ impl Proof { }) .or_else(|| Some(poly)); } - let mut f_poly = f_poly.unwrap(); + + 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 f_commitment = params.commit(&f_poly, f_blind).to_affine(); + let (opening, q_evals) = loop { + let mut transcript = transcript.clone(); + let mut transcript_scalar = transcript_scalar.clone(); + hash_point(&mut transcript, &f_commitment)?; - hash_point(&mut transcript, &f_commitment)?; + let x_6: C::Scalar = + get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); - let x_6: C::Scalar = get_challenge_scalar(Challenge(transcript.squeeze().get_lower_128())); + let mut q_evals = vec![C::Scalar::zero(); meta.rotations.len()]; - 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 (_, &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.absorb(*eval); + } - 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 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())); - let x_7: C::Scalar = 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_dup *= x_7; + f_blind_dup += q_blinds[point_index.0]; - 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 opening = OpeningProof::create(¶ms, &mut transcript, &f_poly, f_blind_dup, x_6); - 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)?; + if opening.is_ok() { + break (opening.unwrap(), q_evals); + } else { + f_blind += C::Scalar::one(); + f_commitment = (f_commitment + params.h).to_affine(); + } + }; Ok(Proof { advice_commitments, diff --git a/src/poly.rs b/src/poly.rs index 07f32e34..d5f11535 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 2eaa9efb..77ac4088 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 c66fe827..0bf2a101 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 c7673acd..937bd463 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();