From 2e6ca274a456e6f3f2f77c7b7dddddd248b73677 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 1 Dec 2020 22:34:18 +0000 Subject: [PATCH] Fix challenge types in poly::multiopen and poly::commitment The argument to the poly::commitment prover and verifier was mistakenly represented as a challenge, when in fact the commitments may be opened at any scalar (which just happens to be a challenge within poly::multiopen). The poly::commitment APIs are now public again. --- src/poly/commitment.rs | 12 ++++-------- src/poly/commitment/prover.rs | 8 ++++---- src/poly/commitment/verifier.rs | 8 ++++---- src/poly/multiopen.rs | 11 +++++++++++ src/poly/multiopen/prover.rs | 19 +++++++++++-------- src/poly/multiopen/verifier.rs | 29 ++++++++++++++++------------- 6 files changed, 50 insertions(+), 37 deletions(-) diff --git a/src/poly/commitment.rs b/src/poly/commitment.rs index 787bd8b..3de7d21 100644 --- a/src/poly/commitment.rs +++ b/src/poly/commitment.rs @@ -86,10 +86,6 @@ impl Deref for ChallengeScalar { } } -#[derive(Clone, Copy, Debug)] -pub(crate) struct Z {} -pub(crate) type ChallengeZ = ChallengeScalar; - /// These are the public parameters for the polynomial commitment scheme. #[derive(Debug)] pub struct Params { @@ -346,16 +342,16 @@ fn test_opening_proof() { let mut transcript = Transcript::<_, DummyHash<_>, DummyHash<_>>::new(); transcript.absorb_point(&p).unwrap(); - let z = ChallengeZ::get(&mut transcript); + let x = ChallengeScalar::<_, ()>::get(&mut transcript); // Evaluate the polynomial - let v = eval_polynomial(&px, *z); + let v = eval_polynomial(&px, *x); transcript.absorb_base(Fp::from_bytes(&v.to_bytes()).unwrap()); // unlikely to fail since p ~ q loop { let mut transcript_dup = transcript.clone(); - let opening_proof = Proof::create(¶ms, &mut transcript, &px, blind, z); + let opening_proof = Proof::create(¶ms, &mut transcript, &px, blind, *x); if let Ok(opening_proof) = opening_proof { // Verify the opening proof let mut commitment_msm = params.empty_msm(); @@ -365,7 +361,7 @@ fn test_opening_proof() { ¶ms, params.empty_msm(), &mut transcript_dup, - z, + *x, commitment_msm, v, ) diff --git a/src/poly/commitment/prover.rs b/src/poly/commitment/prover.rs index 22d8956..1245daf 100644 --- a/src/poly/commitment/prover.rs +++ b/src/poly/commitment/prover.rs @@ -1,7 +1,7 @@ use ff::Field; use super::super::{Coeff, Error, Polynomial}; -use super::{Blind, Challenge, ChallengeScalar, ChallengeZ, Params, Proof}; +use super::{Blind, Challenge, ChallengeScalar, Params, Proof}; use crate::arithmetic::{ best_multiexp, compute_inner_product, parallelize, small_multiexp, Curve, CurveAffine, FieldExt, }; @@ -21,12 +21,12 @@ impl Proof { /// opening v, and the point x. It's probably also nice for the transcript /// to have seen the elliptic curve description and the SRS, if you want to /// be rigorous. - pub(crate) fn create( + pub fn create( params: &Params, transcript: &mut Transcript, px: &Polynomial, blind: Blind, - z: ChallengeZ, + x: C::Scalar, ) -> Result where HBase: Hasher, @@ -61,7 +61,7 @@ impl Proof { let mut cur = C::Scalar::one(); for _ in 0..(1 << params.k) { b.push(cur); - cur *= &z; + cur *= &x; } } diff --git a/src/poly/commitment/verifier.rs b/src/poly/commitment/verifier.rs index 3c34928..eee7d05 100644 --- a/src/poly/commitment/verifier.rs +++ b/src/poly/commitment/verifier.rs @@ -1,7 +1,7 @@ use ff::Field; use super::super::Error; -use super::{Challenge, ChallengeScalar, ChallengeZ, Params, Proof, MSM}; +use super::{Challenge, ChallengeScalar, Params, Proof, MSM}; use crate::transcript::{Hasher, Transcript}; use crate::arithmetic::{best_multiexp, Curve, CurveAffine, FieldExt}; @@ -66,12 +66,12 @@ impl Proof { /// Checks to see if an [`Proof`] is valid given the current `transcript`, /// and a point `x` that the polynomial commitment `p` opens purportedly to /// the value `v`. - pub(crate) fn verify<'a, HBase, HScalar>( + pub fn verify<'a, HBase, HScalar>( &self, params: &'a Params, mut msm: MSM<'a, C>, transcript: &mut Transcript, - z: ChallengeZ, + x: C::Scalar, mut commitment_msm: MSM<'a, C>, v: C::Scalar, ) -> Result, Error> @@ -164,7 +164,7 @@ impl Proof { // The computation of [z1] (G + H) happens in either Guard::use_challenges() // or Guard::use_g(). - let b = compute_b(*z, &challenges, &challenges_inv); + let b = compute_b(x, &challenges, &challenges_inv); let neg_z1 = -self.z1; diff --git a/src/poly/multiopen.rs b/src/poly/multiopen.rs index 82859a7..abaa736 100644 --- a/src/poly/multiopen.rs +++ b/src/poly/multiopen.rs @@ -22,6 +22,17 @@ struct X2 {} /// Challenge for keeping the multi-point quotient polynomial terms linearly independent. type ChallengeX2 = commitment::ChallengeScalar; +#[derive(Clone, Copy, Debug)] +struct X3 {} +/// Challenge point at which the commitments are opened. +type ChallengeX3 = commitment::ChallengeScalar; + +#[derive(Clone, Copy, Debug)] +struct X4 {} +/// Challenge for collapsing the openings of the various remaining polynomials at x_3 +/// together. +type ChallengeX4 = commitment::ChallengeScalar; + /// This is a multi-point opening proof used in the polynomial commitment scheme opening. #[derive(Debug, Clone)] pub struct Proof { diff --git a/src/poly/multiopen/prover.rs b/src/poly/multiopen/prover.rs index 63cfa1c..6e6fa47 100644 --- a/src/poly/multiopen/prover.rs +++ b/src/poly/multiopen/prover.rs @@ -1,8 +1,11 @@ use super::super::{ - commitment::{self, Blind, ChallengeScalar, ChallengeZ, Params}, + commitment::{self, Blind, Params}, Coeff, Error, Polynomial, }; -use super::{construct_intermediate_sets, ChallengeX1, ChallengeX2, Proof, ProverQuery, Query}; +use super::{ + construct_intermediate_sets, ChallengeX1, ChallengeX2, ChallengeX3, ChallengeX4, Proof, + ProverQuery, Query, +}; use crate::arithmetic::{ eval_polynomial, kate_division, lagrange_interpolate, Curve, CurveAffine, FieldExt, @@ -113,31 +116,31 @@ impl Proof { .absorb_point(&f_commitment) .map_err(|_| Error::SamplingError)?; - let z = ChallengeZ::get(&mut transcript); + let x_3 = ChallengeX3::get(&mut transcript); let q_evals: Vec = q_polys .iter() - .map(|poly| eval_polynomial(poly.as_ref().unwrap(), *z)) + .map(|poly| eval_polynomial(poly.as_ref().unwrap(), *x_3)) .collect(); for eval in q_evals.iter() { transcript.absorb_scalar(*eval); } - let x_7 = ChallengeScalar::<_, ()>::get(&mut transcript); + let x_4 = ChallengeX4::get(&mut transcript); let (f_poly, f_blind_try) = q_polys.iter().zip(q_blinds.iter()).fold( (f_poly.clone(), f_blind), |(f_poly, f_blind), (poly, blind)| { ( - f_poly * *x_7 + poly.as_ref().unwrap(), - Blind((f_blind.0 * &x_7) + &blind.0), + f_poly * *x_4 + poly.as_ref().unwrap(), + Blind((f_blind.0 * &x_4) + &blind.0), ) }, ); if let Ok(opening) = - commitment::Proof::create(¶ms, &mut transcript, &f_poly, f_blind_try, z) + commitment::Proof::create(¶ms, &mut transcript, &f_poly, f_blind_try, *x_3) { break (opening, q_evals); } else { diff --git a/src/poly/multiopen/verifier.rs b/src/poly/multiopen/verifier.rs index 53699b6..e47e1d0 100644 --- a/src/poly/multiopen/verifier.rs +++ b/src/poly/multiopen/verifier.rs @@ -1,10 +1,13 @@ use ff::Field; use super::super::{ - commitment::{ChallengeScalar, ChallengeZ, Guard, Params, MSM}, + commitment::{Guard, Params, MSM}, Error, }; -use super::{construct_intermediate_sets, ChallengeX1, ChallengeX2, Proof, Query, VerifierQuery}; +use super::{ + construct_intermediate_sets, ChallengeX1, ChallengeX2, ChallengeX3, ChallengeX4, Proof, Query, + VerifierQuery, +}; use crate::arithmetic::{eval_polynomial, lagrange_interpolate, CurveAffine, FieldExt}; use crate::transcript::{Hasher, Transcript}; @@ -77,15 +80,15 @@ impl Proof { .absorb_point(&self.f_commitment) .map_err(|_| Error::SamplingError)?; - // Sample a challenge z for checking that f(X) was committed to + // Sample a challenge x_3 for checking that f(X) was committed to // correctly. - let z = ChallengeZ::get(transcript); + let x_3 = ChallengeX3::get(transcript); for eval in self.q_evals.iter() { transcript.absorb_scalar(*eval); } - // We can compute the expected msm_eval at z using the q_evals provided + // We can compute the expected msm_eval at x_3 using the q_evals provided // by the prover and from x_2 let msm_eval = point_sets .iter() @@ -95,17 +98,17 @@ impl Proof { C::Scalar::zero(), |msm_eval, ((points, evals), proof_eval)| { let r_poly = lagrange_interpolate(points, evals); - let r_eval = eval_polynomial(&r_poly, *z); + let r_eval = eval_polynomial(&r_poly, *x_3); let eval = points.iter().fold(*proof_eval - &r_eval, |eval, point| { - eval * &(*z - point).invert().unwrap() + eval * &(*x_3 - point).invert().unwrap() }); msm_eval * &x_2 + &eval }, ); - // Sample a challenge x_7 that we will use to collapse the openings of - // the various remaining polynomials at z together. - let x_7 = ChallengeScalar::<_, ()>::get(transcript); + // Sample a challenge x_4 that we will use to collapse the openings of + // the various remaining polynomials at x_3 together. + let x_4 = ChallengeX4::get(transcript); // Compute the final commitment that has to be opened let mut commitment_msm = params.empty_msm(); @@ -113,15 +116,15 @@ impl Proof { let (commitment_msm, msm_eval) = q_commitments.into_iter().zip(self.q_evals.iter()).fold( (commitment_msm, msm_eval), |(mut commitment_msm, msm_eval), (q_commitment, q_eval)| { - commitment_msm.scale(*x_7); + commitment_msm.scale(*x_4); commitment_msm.add_msm(&q_commitment); - (commitment_msm, msm_eval * &x_7 + q_eval) + (commitment_msm, msm_eval * &x_4 + q_eval) }, ); // Verify the opening proof self.opening - .verify(params, msm, transcript, z, commitment_msm, msm_eval) + .verify(params, msm, transcript, *x_3, commitment_msm, msm_eval) } }