From 1721eb71b4b7e93c2ae654d6846269c8b9c46dec Mon Sep 17 00:00:00 2001 From: kunxian xia Date: Wed, 31 Jan 2024 21:40:57 +0800 Subject: [PATCH] modify proof and vk structure to support fri proof (step 1) --- halo2_proofs/Cargo.toml | 3 +- halo2_proofs/src/plonk.rs | 24 +++--- halo2_proofs/src/plonk/keygen.rs | 1 + halo2_proofs/src/plonk/mv_lookup/verifier.rs | 11 +-- halo2_proofs/src/plonk/permutation.rs | 8 +- .../src/plonk/permutation/verifier.rs | 31 +++++--- halo2_proofs/src/plonk/shuffle/prover.rs | 6 +- halo2_proofs/src/plonk/shuffle/verifier.rs | 48 ++++++++---- halo2_proofs/src/plonk/vanishing/verifier.rs | 44 ++++++++--- halo2_proofs/src/plonk/verifier.rs | 30 +++++++- halo2_proofs/src/poly/commitment.rs | 74 +++++++++++++++++-- halo2_proofs/src/poly/ipa/commitment.rs | 32 ++++++-- .../src/poly/ipa/commitment/prover.rs | 6 +- halo2_proofs/src/poly/ipa/multiopen/prover.rs | 6 +- .../src/poly/ipa/multiopen/verifier.rs | 4 +- halo2_proofs/src/poly/kzg/commitment.rs | 38 ++++++++-- .../src/poly/kzg/multiopen/gwc/prover.rs | 7 +- .../src/poly/kzg/multiopen/gwc/verifier.rs | 5 +- .../src/poly/kzg/multiopen/shplonk/prover.rs | 12 ++- .../poly/kzg/multiopen/shplonk/verifier.rs | 5 +- halo2_proofs/src/poly/query.rs | 21 +++++- 21 files changed, 332 insertions(+), 84 deletions(-) diff --git a/halo2_proofs/Cargo.toml b/halo2_proofs/Cargo.toml index 6353a6e60c..0d0bbfe17c 100644 --- a/halo2_proofs/Cargo.toml +++ b/halo2_proofs/Cargo.toml @@ -120,7 +120,8 @@ logup_skip_inv = [] phase-check = [] multiphase-mock-prover = [] -fri = [] +fri = ["ff/fri"] + [lib] bench = false diff --git a/halo2_proofs/src/plonk.rs b/halo2_proofs/src/plonk.rs index 4da095e197..f8ca3d5fd8 100644 --- a/halo2_proofs/src/plonk.rs +++ b/halo2_proofs/src/plonk.rs @@ -7,6 +7,7 @@ use blake2b_simd::Params as Blake2bParams; use group::ff::{Field, FromUniformBytes, PrimeField}; +use std::fs::read; use crate::arithmetic::CurveAffine; use crate::helpers::{ @@ -22,8 +23,8 @@ mod circuit; mod error; mod evaluation; mod keygen; -#[allow(dead_code)] -mod lookup; +// #[allow(dead_code)] +// mod lookup; mod mv_lookup; pub mod permutation; mod shuffle; @@ -39,6 +40,7 @@ pub use keygen::*; pub use prover::*; pub use verifier::*; +use crate::poly::commitment::{Commitment, CommitmentItem}; use evaluation::Evaluator; use std::io; @@ -47,7 +49,7 @@ use std::io; #[derive(Clone, Debug)] pub struct VerifyingKey { domain: EvaluationDomain, - fixed_commitments: Vec, + fixed_commitments: Commitment, permutation: permutation::VerifyingKey, cs: ConstraintSystem, /// Cached maximum degree of `cs` (which doesn't change after construction). @@ -117,9 +119,13 @@ where reader.read_exact(&mut num_fixed_columns)?; let num_fixed_columns = u32::from_be_bytes(num_fixed_columns); - let fixed_commitments: Vec<_> = (0..num_fixed_columns) - .map(|_| C::read(reader, format)) - .collect::>()?; + let fixed_commitments: Vec<_> = if cfg!(fri) { + vec![CommitmentItem::::read(reader, format)?] + } else { + (0..num_fixed_columns) + .map(|_| CommitmentItem::::read(reader, format)) + .collect::, _>>()? + }; let permutation = permutation::VerifyingKey::read(reader, &cs.permutation, format)?; @@ -178,7 +184,7 @@ where fn from_parts( domain: EvaluationDomain, - fixed_commitments: Vec, + fixed_commitments: Vec>, permutation: permutation::VerifyingKey, cs: ConstraintSystem, // selectors: Vec>, @@ -240,7 +246,7 @@ where } /// Returns commitments of fixed polynomials - pub fn fixed_commitments(&self) -> &Vec { + pub fn fixed_commitments(&self) -> &Vec> { &self.fixed_commitments } @@ -269,7 +275,7 @@ pub struct PinnedVerificationKey<'a, C: CurveAffine> { scalar_modulus: &'static str, domain: PinnedEvaluationDomain<'a, C::Scalar>, cs: PinnedConstraintSystem<'a, C::Scalar>, - fixed_commitments: &'a Vec, + fixed_commitments: &'a Commitment, permutation: &'a permutation::VerifyingKey, } /// This is a proving key which allows for the creation of proofs for a diff --git a/halo2_proofs/src/plonk/keygen.rs b/halo2_proofs/src/plonk/keygen.rs index 89e53b296a..12ca43a4a2 100644 --- a/halo2_proofs/src/plonk/keygen.rs +++ b/halo2_proofs/src/plonk/keygen.rs @@ -15,6 +15,7 @@ use super::{ permutation, Assigned, Challenge, Error, LagrangeCoeff, Polynomial, ProvingKey, VerifyingKey, }; use crate::helpers::CopyCell; +use crate::poly::commitment::CommitmentItem; use crate::{ arithmetic::{parallelize, CurveAffine}, circuit::Value, diff --git a/halo2_proofs/src/plonk/mv_lookup/verifier.rs b/halo2_proofs/src/plonk/mv_lookup/verifier.rs index d406300a26..5d05719ede 100644 --- a/halo2_proofs/src/plonk/mv_lookup/verifier.rs +++ b/halo2_proofs/src/plonk/mv_lookup/verifier.rs @@ -2,6 +2,7 @@ use std::iter; use super::super::{circuit::Expression, ChallengeBeta, ChallengeTheta, ChallengeX}; use super::Argument; +use crate::poly::commitment::CommitmentItem; use crate::{ arithmetic::CurveAffine, plonk::{Error, VerifyingKey}, @@ -11,12 +12,12 @@ use crate::{ use ff::{BatchInvert, Field, PrimeField, WithSmallOrderMulGroup}; pub struct PreparedCommitments { - m_commitment: C, + m_commitment: Vec>, } pub struct Committed { prepared: PreparedCommitments, - phi_commitment: C, + phi_commitment: Vec>, } pub struct Evaluated { @@ -170,17 +171,17 @@ impl Evaluated { let x_next = vk.domain.rotate_omega(*x, Rotation::next()); iter::empty() - .chain(Some(VerifierQuery::new_commitment( + .chain(Some(VerifierQuery::new_general_commitment( &self.committed.phi_commitment, *x, self.phi_eval, ))) - .chain(Some(VerifierQuery::new_commitment( + .chain(Some(VerifierQuery::new_general_commitment( &self.committed.phi_commitment, x_next, self.phi_next_eval, ))) - .chain(Some(VerifierQuery::new_commitment( + .chain(Some(VerifierQuery::new_general_commitment( &self.committed.prepared.m_commitment, *x, self.m_eval, diff --git a/halo2_proofs/src/plonk/permutation.rs b/halo2_proofs/src/plonk/permutation.rs index 2ce6abb8d3..22fce0051e 100644 --- a/halo2_proofs/src/plonk/permutation.rs +++ b/halo2_proofs/src/plonk/permutation.rs @@ -17,6 +17,7 @@ pub(crate) mod verifier; pub use keygen::Assembly; +use crate::poly::commitment::{Commitment, CommitmentItem}; use std::io; /// A permutation argument. @@ -84,18 +85,21 @@ impl Argument { /// The verifying key for a single permutation argument. #[derive(Debug, Clone)] pub struct VerifyingKey { - pub commitments: Vec, + // hash-based: merkle cap of tree built from permutation sigma polys + // pairing-based: ec points + pub commitments: Commitment, } impl VerifyingKey { /// Returns commitments of sigma polynomials - pub fn commitments(&self) -> &Vec { + pub fn commitments(&self) -> &Vec> { &self.commitments } pub(crate) fn write(&self, writer: &mut W, format: SerdeFormat) -> io::Result<()> where C: SerdeCurveAffine, + C::Scalar: SerdePrimeField, { for commitment in &self.commitments { commitment.write(writer, format)?; diff --git a/halo2_proofs/src/plonk/permutation/verifier.rs b/halo2_proofs/src/plonk/permutation/verifier.rs index 080acf24e7..1c42acf8b2 100644 --- a/halo2_proofs/src/plonk/permutation/verifier.rs +++ b/halo2_proofs/src/plonk/permutation/verifier.rs @@ -3,6 +3,7 @@ use std::iter; use super::super::{circuit::Any, ChallengeBeta, ChallengeGamma, ChallengeX}; use super::{Argument, VerifyingKey}; +use crate::poly::commitment::CommitmentItem; use crate::{ arithmetic::CurveAffine, plonk::{self, Error}, @@ -12,12 +13,12 @@ use crate::{ #[derive(Debug)] pub struct Committed { - permutation_product_commitments: Vec, + permutation_product_commitments: Vec>, } #[derive(Debug)] pub struct EvaluatedSet { - pub permutation_product_commitment: C, + pub permutation_product_commitment: Vec>, pub permutation_product_eval: C::Scalar, pub permutation_product_next_eval: C::Scalar, pub permutation_product_last_eval: Option, @@ -221,12 +222,12 @@ impl Evaluated { iter::empty() // Open permutation product commitments at x and \omega^{-1} x // Open permutation product commitments at x and \omega x - .chain(Some(VerifierQuery::new_commitment( + .chain(Some(VerifierQuery::new_general_commitment( &set.permutation_product_commitment, *x, set.permutation_product_eval, ))) - .chain(Some(VerifierQuery::new_commitment( + .chain(Some(VerifierQuery::new_general_commitment( &set.permutation_product_commitment, x_next, set.permutation_product_next_eval, @@ -234,7 +235,7 @@ impl Evaluated { })) // Open it at \omega^{last} x for all but the last set .chain(self.sets.iter().rev().skip(1).flat_map(move |set| { - Some(VerifierQuery::new_commitment( + Some(VerifierQuery::new_general_commitment( &set.permutation_product_commitment, x_last, set.permutation_product_last_eval.unwrap(), @@ -250,9 +251,21 @@ impl CommonEvaluated { x: ChallengeX, ) -> impl Iterator> + Clone { // Open permutation commitments for each permutation argument at x - vkey.commitments - .iter() - .zip(self.permutation_evals.iter()) - .map(move |(commitment, &eval)| VerifierQuery::new_commitment(commitment, *x, eval)) + let ret = if cfg!(fri) { + self.permutation_evals + .iter() + .map(|&eval| { + VerifierQuery::new_general_commitment(vkey.commitments.as_slice(), *x, eval) + }) + .collect::>() + } else { + vkey.commitments + .iter() + .zip(self.permutation_evals.iter()) + .map(move |(commitment, &eval)| VerifierQuery::new_commitment(commitment, *x, eval)) + .collect::>() + }; + + ret.into_iter() } } diff --git a/halo2_proofs/src/plonk/shuffle/prover.rs b/halo2_proofs/src/plonk/shuffle/prover.rs index fd30436a47..93f6415d0a 100644 --- a/halo2_proofs/src/plonk/shuffle/prover.rs +++ b/halo2_proofs/src/plonk/shuffle/prover.rs @@ -14,6 +14,7 @@ use crate::{ use ff::WithSmallOrderMulGroup; use group::{ff::BatchInvert, Curve}; use rand_core::RngCore; +use std::ops::Deref; use std::{ iter, ops::{Mul, MulAssign}, @@ -187,7 +188,10 @@ impl> Argument { } let product_blind = Blind(C::Scalar::random(rng)); - let product_commitment = params.commit_lagrange(&z, product_blind).to_affine(); + let product_commitment = params.commit_lagrange(&z, product_blind)[0] + .deref() + .unwrap() + .to_affine(); let z = pk.vk.domain.lagrange_to_coeff(z); // Hash product commitment diff --git a/halo2_proofs/src/plonk/shuffle/verifier.rs b/halo2_proofs/src/plonk/shuffle/verifier.rs index 379cc5c8a1..4c4042fee3 100644 --- a/halo2_proofs/src/plonk/shuffle/verifier.rs +++ b/halo2_proofs/src/plonk/shuffle/verifier.rs @@ -1,7 +1,9 @@ +use std::io::Read; use std::iter; use super::super::{circuit::Expression, ChallengeGamma, ChallengeTheta, ChallengeX}; use super::Argument; +use crate::poly::commitment::Commitment; use crate::{ arithmetic::CurveAffine, plonk::{Error, VerifyingKey}, @@ -11,7 +13,7 @@ use crate::{ use ff::Field; pub struct Committed { - product_commitment: C, + product_commitment: Commitment, } pub struct Evaluated { @@ -31,7 +33,9 @@ impl Argument { ) -> Result, Error> { let product_commitment = transcript.read_point()?; - Ok(Committed { product_commitment }) + Ok(Committed { + product_commitment: vec![product_commitment.into()], + }) } } @@ -121,18 +125,32 @@ impl Evaluated { ) -> impl Iterator> + Clone { let x_next = vk.domain.rotate_omega(*x, Rotation::next()); - iter::empty() - // Open shuffle product commitment at x - .chain(Some(VerifierQuery::new_commitment( - &self.committed.product_commitment, - *x, - self.product_eval, - ))) - // Open shuffle product commitment at \omega x - .chain(Some(VerifierQuery::new_commitment( - &self.committed.product_commitment, - x_next, - self.product_next_eval, - ))) + if cfg!(fri) { + iter::empty() + // Open shuffle product commitment at x + .chain(Some(VerifierQuery::new_general_commitment( + &self.committed.product_commitment, + *x, + self.product_eval, + ))) + // Open shuffle product commitment at \omega x + .chain(Some(VerifierQuery::new_general_commitment( + &self.committed.product_commitment, + x_next, + self.product_next_eval, + ))) + } else { + iter::empty() + .chain(Some(VerifierQuery::new_commitment( + &self.committed.product_commitment[0], + *x, + self.product_eval, + ))) + .chain(Some(VerifierQuery::new_commitment( + &self.committed.product_commitment[0], + x_next, + self.product_next_eval, + ))) + } } } diff --git a/halo2_proofs/src/plonk/vanishing/verifier.rs b/halo2_proofs/src/plonk/vanishing/verifier.rs index 0881dfb2c0..0c3002eeb9 100644 --- a/halo2_proofs/src/plonk/vanishing/verifier.rs +++ b/halo2_proofs/src/plonk/vanishing/verifier.rs @@ -1,7 +1,10 @@ +use std::io::Read; use std::iter; +use std::marker::PhantomData; use ff::Field; +use crate::poly::commitment::Commitment; use crate::{ arithmetic::CurveAffine, plonk::{Error, VerifyingKey}, @@ -16,25 +19,29 @@ use super::super::{ChallengeX, ChallengeY}; use super::Argument; pub struct Committed { - random_poly_commitment: C, + random_poly_commitment: Commitment, } pub struct Constructed { - h_commitments: Vec, - random_poly_commitment: C, + h_commitments: Commitment, + random_poly_commitment: Commitment, } pub struct PartiallyEvaluated { - h_commitments: Vec, - random_poly_commitment: C, + h_commitments: Commitment, + random_poly_commitment: Commitment, random_eval: C::Scalar, } pub struct Evaluated> { + #[cfg(feature = "fri")] + h_commitment: Commitment, + #[cfg(not(feature = "fri"))] h_commitment: M, - random_poly_commitment: C, + random_poly_commitment: Commitment, expected_h_eval: C::Scalar, random_eval: C::Scalar, + _marker: PhantomData, } impl Argument { @@ -97,6 +104,7 @@ impl PartiallyEvaluated { let expected_h_eval = expressions.fold(C::Scalar::ZERO, |h_eval, v| h_eval * &*y + &v); let expected_h_eval = expected_h_eval * ((xn - C::Scalar::ONE).invert().unwrap()); + #[cfg(not(feature = "fri"))] let h_commitment = self.h_commitments .iter() @@ -108,6 +116,8 @@ impl PartiallyEvaluated { acc }); + #[cfg(feature = "fri")] + let h_commitment = self.h_commitments; Evaluated { expected_h_eval, @@ -123,16 +133,32 @@ impl> Evaluated { &self, x: ChallengeX, ) -> impl Iterator> + Clone { - iter::empty() - .chain(Some(VerifierQuery::new_msm( + #[cfg(feature = "fri")] + let ret = iter::empty() + .chain(Some(VerifierQuery::new_general_commitment( &self.h_commitment, *x, self.expected_h_eval, ))) - .chain(Some(VerifierQuery::new_commitment( + .chain(Some(VerifierQuery::new_general_commitment( &self.random_poly_commitment, *x, self.random_eval, + ))); + + #[cfg(not(feature = "fri"))] + let ret = iter::empty() + .chain(Some(VerifierQuery::new_msm( + &self.h_commitment, + *x, + self.expected_h_eval, ))) + .chain(Some(VerifierQuery::new_general_commitment( + &self.random_poly_commitment, + *x, + self.random_eval, + ))); + + ret } } diff --git a/halo2_proofs/src/plonk/verifier.rs b/halo2_proofs/src/plonk/verifier.rs index a50e49c53b..8be5e821d2 100644 --- a/halo2_proofs/src/plonk/verifier.rs +++ b/halo2_proofs/src/plonk/verifier.rs @@ -7,7 +7,7 @@ use super::{ VerifyingKey, }; use crate::arithmetic::compute_inner_product; -use crate::poly::commitment::{CommitmentScheme, Verifier}; +use crate::poly::commitment::{CommitmentItem, CommitmentScheme, Verifier}; use crate::poly::VerificationStrategy; use crate::poly::{ commitment::{Blind, Params}, @@ -91,7 +91,23 @@ where } // Hash the prover's advice commitments into the transcript and squeeze challenges - let (advice_commitments, challenges) = { + let (advice_commitments, challenges) = if cfg!(fri) { + let advice_commitments = vec![vec![]; num_proofs]; + let mut challenges = vec![]; + // todo: + for phase in vk.cs.phases() { + let merkle_cap = (0..=1) + // .into_iter() + .map(|i| { + transcript + .read_scalar() + .map(|s| CommitmentItem::::Scalar(s)) + }) + .collect::>>>()?; + } + + (advice_commitments, challenges) + } else { let mut advice_commitments = vec![vec![Scheme::Curve::default(); vk.cs.num_advice_columns]; num_proofs]; let mut challenges = vec![Scheme::Scalar::ZERO; vk.cs.num_challenges]; @@ -116,6 +132,16 @@ where } } + let advice_commitments = advice_commitments + .into_iter() + .map(|advice_commitments| { + advice_commitments + .into_iter() + .map(|c| CommitmentItem::Point(c)) + .collect() + }) + .collect::>>>(); + (advice_commitments, challenges) }; diff --git a/halo2_proofs/src/poly/commitment.rs b/halo2_proofs/src/poly/commitment.rs index 590767e68e..cec24fa32e 100644 --- a/halo2_proofs/src/poly/commitment.rs +++ b/halo2_proofs/src/poly/commitment.rs @@ -3,17 +3,65 @@ use super::{ strategy::Guard, Coeff, LagrangeCoeff, Polynomial, }; +use crate::arithmetic::CurveExt; +use crate::helpers::{CurveRead, SerdeCurveAffine, SerdePrimeField}; use crate::poly::Error; use crate::transcript::{EncodedChallenge, TranscriptRead, TranscriptWrite}; +use crate::SerdeFormat; use ff::Field; +use group::Curve; +use halo2curves::serde::SerdeObject; use halo2curves::CurveAffine; use rand_core::RngCore; +use std::ops::Deref; use std::{ fmt::Debug, io::{self}, ops::{Add, AddAssign, Mul, MulAssign}, }; +#[derive(Clone, Debug)] +pub enum CommitmentItem { + Scalar(S), + Point(C), +} + +pub type Commitment = Vec>; + +impl From for CommitmentItem { + fn from(value: C) -> Self { + Self::Point(value) + } +} + +impl Deref for CommitmentItem { + type Target = Option; + + fn deref(&self) -> &Self::Target { + match self { + CommitmentItem::Scalar(_) => &None, + CommitmentItem::Point(c) => &Some(*c), + } + } +} + +impl CommitmentItem { + pub fn read(reader: &mut R, format: SerdeFormat) -> io::Result { + if cfg!(fri) { + S::read(reader, format).map(|s| CommitmentItem::Scalar(s)) + } else { + C::read(reader, format).map(|c| CommitmentItem::Point(c)) + } + } + + pub fn write(&self, writer: &mut W, format: SerdeFormat) -> io::Result<()> { + match self { + CommitmentItem::Scalar(s) => s.write(writer, format), + CommitmentItem::Point(c) => c.write(writer, format), + } + } +} + /// Defines components of a commitment scheme. pub trait CommitmentScheme { /// Application field of this commitment scheme @@ -39,12 +87,12 @@ pub trait CommitmentScheme { fn read_params(reader: &mut R) -> io::Result; } -/// Parameters for circuit sysnthesis and prover parameters. +/// Parameters for circuit synthesis and prover parameters. pub trait Params<'params, C: CurveAffine>: Sized + Clone { /// Multi scalar multiplication engine type MSM: MSM + 'params; - /// Logaritmic size of the circuit + /// Logarithmic size of the circuit fn k(&self) -> u32; /// Size of the circuit @@ -53,7 +101,7 @@ pub trait Params<'params, C: CurveAffine>: Sized + Clone { /// Downsize `Params` with smaller `k`. fn downsize(&mut self, k: u32); - /// Generates an empty multiscalar multiplication struct using the + /// Generates an empty multi-scalar multiplication struct using the /// appropriate params. fn empty_msm(&'params self) -> Self::MSM; @@ -64,7 +112,13 @@ pub trait Params<'params, C: CurveAffine>: Sized + Clone { &self, poly: &Polynomial, r: Blind, - ) -> C::CurveExt; + ) -> Vec>; + + fn commit_lagranges( + &self, + polys: &[Polynomial], + rs: &[Blind], + ) -> Vec>; /// Writes params to a buffer. fn write(&self, writer: &mut W) -> io::Result<()>; @@ -84,8 +138,16 @@ pub trait ParamsProver<'params, C: CurveAffine>: Params<'params, C> { /// This computes a commitment to a polynomial described by the provided /// slice of coefficients. The commitment may be blinded by the blinding /// factor `r`. - fn commit(&self, poly: &Polynomial, r: Blind) - -> C::CurveExt; + fn commit( + &self, + poly: &Polynomial, + r: Blind, + ) -> Vec>; + fn commit_polys( + &self, + polys: &[Polynomial], + rs: &[Blind], + ) -> Vec>; /// Getter for g generators fn get_g(&self) -> &[C]; diff --git a/halo2_proofs/src/poly/ipa/commitment.rs b/halo2_proofs/src/poly/ipa/commitment.rs index 9e30355121..157bd4225a 100644 --- a/halo2_proofs/src/poly/ipa/commitment.rs +++ b/halo2_proofs/src/poly/ipa/commitment.rs @@ -5,7 +5,9 @@ use crate::arithmetic::{best_multiexp, g_to_lagrange, parallelize, CurveAffine, CurveExt}; use crate::helpers::CurveRead; -use crate::poly::commitment::{Blind, CommitmentScheme, Params, ParamsProver, ParamsVerifier}; +use crate::poly::commitment::{ + Blind, CommitmentItem, CommitmentScheme, Params, ParamsProver, ParamsVerifier, +}; use crate::poly::ipa::msm::MSMIPA; use crate::poly::{Coeff, LagrangeCoeff, Polynomial}; @@ -89,7 +91,7 @@ impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA { &self, poly: &Polynomial, r: Blind, - ) -> C::Curve { + ) -> Vec> { let mut tmp_scalars = Vec::with_capacity(poly.len() + 1); let mut tmp_bases = Vec::with_capacity(poly.len() + 1); @@ -99,7 +101,15 @@ impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA { tmp_bases.extend(self.g_lagrange.iter()); tmp_bases.push(self.w); - best_multiexp::(&tmp_scalars, &tmp_bases) + vec![best_multiexp::(&tmp_scalars, &tmp_bases).into()] + } + + fn commit_lagranges( + &self, + polys: &[Polynomial], + rs: &[Blind], + ) -> Vec> { + unimplemented!() } /// Writes params to a buffer. @@ -209,7 +219,11 @@ impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA { /// This computes a commitment to a polynomial described by the provided /// slice of coefficients. The commitment will be blinded by the blinding /// factor `r`. - fn commit(&self, poly: &Polynomial, r: Blind) -> C::Curve { + fn commit( + &self, + poly: &Polynomial, + r: Blind, + ) -> Vec> { let mut tmp_scalars = Vec::with_capacity(poly.len() + 1); let mut tmp_bases = Vec::with_capacity(poly.len() + 1); @@ -219,12 +233,20 @@ impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA { tmp_bases.extend(self.g.iter()); tmp_bases.push(self.w); - best_multiexp::(&tmp_scalars, &tmp_bases) + vec![best_multiexp::(&tmp_scalars, &tmp_bases).into()] } fn get_g(&self) -> &[C] { &self.g } + + fn commit_polys( + &self, + polys: &[Polynomial], + rs: &[Blind], + ) -> Vec> { + unimplemented!() + } } #[cfg(test)] diff --git a/halo2_proofs/src/poly/ipa/commitment/prover.rs b/halo2_proofs/src/poly/ipa/commitment/prover.rs index 344dbc0e65..761a5db7ab 100644 --- a/halo2_proofs/src/poly/ipa/commitment/prover.rs +++ b/halo2_proofs/src/poly/ipa/commitment/prover.rs @@ -12,6 +12,7 @@ use crate::transcript::{EncodedChallenge, TranscriptWrite}; use group::Curve; use std::io::{self}; +use std::ops::Deref; /// Create a polynomial commitment opening proof for the polynomial defined /// by the coefficients `px`, the blinding factor `blind` used for the @@ -56,7 +57,10 @@ pub fn create_proof< let s_poly_blind = Blind(C::Scalar::random(&mut rng)); // Write a commitment to the random polynomial to the transcript - let s_poly_commitment = params.commit(&s_poly, s_poly_blind).to_affine(); + let s_poly_commitment = params.commit(&s_poly, s_poly_blind)[0] + .deref() + .unwrap() + .to_affine(); transcript.write_point(s_poly_commitment)?; // Challenge that will ensure that the prover cannot change P but can only diff --git a/halo2_proofs/src/poly/ipa/multiopen/prover.rs b/halo2_proofs/src/poly/ipa/multiopen/prover.rs index 2ae745d457..57e1e12a68 100644 --- a/halo2_proofs/src/poly/ipa/multiopen/prover.rs +++ b/halo2_proofs/src/poly/ipa/multiopen/prover.rs @@ -12,6 +12,7 @@ use group::Curve; use rand_core::RngCore; use std::io; use std::marker::PhantomData; +use std::ops::Deref; /// IPA multi-open prover #[derive(Debug)] @@ -93,7 +94,10 @@ impl<'params, C: CurveAffine> Prover<'params, IPACommitmentScheme> for Prover .unwrap(); let q_prime_blind = Blind(C::Scalar::random(&mut rng)); - let q_prime_commitment = self.params.commit(&q_prime_poly, q_prime_blind).to_affine(); + let q_prime_commitment = self.params.commit(&q_prime_poly, q_prime_blind)[0] + .deref() + .unwrap() + .to_affine(); transcript.write_point(q_prime_commitment)?; diff --git a/halo2_proofs/src/poly/ipa/multiopen/verifier.rs b/halo2_proofs/src/poly/ipa/multiopen/verifier.rs index d559e33384..c3678b676c 100644 --- a/halo2_proofs/src/poly/ipa/multiopen/verifier.rs +++ b/halo2_proofs/src/poly/ipa/multiopen/verifier.rs @@ -1,4 +1,5 @@ use std::fmt::Debug; +use std::ops::Deref; use ff::Field; @@ -69,7 +70,8 @@ impl<'params, C: CurveAffine> Verifier<'params, IPACommitmentScheme> let (q_commitment, x_1_power) = &mut q_commitments[set_idx]; match new_commitment { CommitmentReference::Commitment(c) => { - q_commitment.append_term(*x_1_power, (*c).into()); + let c = &c[0]; + q_commitment.append_term(*x_1_power, c.deref().unwrap().into()); } CommitmentReference::MSM(msm) => { let mut msm = msm.clone(); diff --git a/halo2_proofs/src/poly/kzg/commitment.rs b/halo2_proofs/src/poly/kzg/commitment.rs index 096dbf2463..fe7adaa1e8 100644 --- a/halo2_proofs/src/poly/kzg/commitment.rs +++ b/halo2_proofs/src/poly/kzg/commitment.rs @@ -1,6 +1,8 @@ -use crate::arithmetic::{best_multiexp, g_to_lagrange, parallelize}; +use crate::arithmetic::{best_multiexp, g_to_lagrange, parallelize, CurveAffine}; use crate::helpers::SerdeCurveAffine; -use crate::poly::commitment::{Blind, CommitmentScheme, Params, ParamsProver, ParamsVerifier}; +use crate::poly::commitment::{ + Blind, CommitmentItem, CommitmentScheme, Params, ParamsProver, ParamsVerifier, +}; use crate::poly::{Coeff, LagrangeCoeff, Polynomial}; use crate::SerdeFormat; @@ -314,13 +316,25 @@ where MSMKZG::new() } - fn commit_lagrange(&self, poly: &Polynomial, _: Blind) -> E::G1 { + fn commit_lagrange( + &self, + poly: &Polynomial, + _: Blind, + ) -> Vec::ScalarExt, E::G1>> { let mut scalars = Vec::with_capacity(poly.len()); scalars.extend(poly.iter()); let bases = &self.g_lagrange; let size = scalars.len(); assert!(bases.len() >= size); - best_multiexp(&scalars, &bases[0..size]) + vec![best_multiexp(&scalars, &bases[0..size]).into()] + } + + fn commit_lagranges( + &self, + polys: &[Polynomial], + rs: &[Blind], + ) -> Vec> { + unimplemented!() } /// Writes params to a buffer. @@ -358,18 +372,30 @@ where Self::setup(k, OsRng) } - fn commit(&self, poly: &Polynomial, _: Blind) -> E::G1 { + fn commit( + &self, + poly: &Polynomial, + _: Blind, + ) -> Vec::ScalarExt, E::G1>> { let mut scalars = Vec::with_capacity(poly.len()); scalars.extend(poly.iter()); let bases = &self.g; let size = scalars.len(); assert!(bases.len() >= size); - best_multiexp(&scalars, &bases[0..size]) + vec![best_multiexp(&scalars, &bases[0..size]).into()] } fn get_g(&self) -> &[E::G1Affine] { &self.g } + + fn commit_polys( + &self, + polys: &[Polynomial], + rs: &[Blind], + ) -> Vec> { + unimplemented!() + } } #[cfg(test)] diff --git a/halo2_proofs/src/poly/kzg/multiopen/gwc/prover.rs b/halo2_proofs/src/poly/kzg/multiopen/gwc/prover.rs index 56fffa096f..6c7f0e8294 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/gwc/prover.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/gwc/prover.rs @@ -15,6 +15,7 @@ use rand_core::RngCore; use std::fmt::Debug; use std::io; use std::marker::PhantomData; +use std::ops::Deref; /// Concrete KZG prover with GWC variant #[derive(Debug)] @@ -77,9 +78,9 @@ where values: kate_division(&poly_batch.values, z), _marker: PhantomData, }; - let w = self - .params - .commit(&witness_poly, Blind::default()) + let w = self.params.commit(&witness_poly, Blind::default())[0] + .deref() + .unwrap() .to_affine(); transcript.write_point(w)?; diff --git a/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs b/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs index df2b1039ce..d90343b6b7 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs @@ -1,4 +1,5 @@ use std::fmt::Debug; +use std::ops::Deref; use super::{construct_intermediate_sets, ChallengeU, ChallengeV}; use crate::arithmetic::powers; @@ -84,8 +85,10 @@ where let commitment = match query.get_commitment() { CommitmentReference::Commitment(c) => { + // for pairing-based pcs, each commitment has only one CommitmentItem. + let c = &c[0]; let mut msm = MSMKZG::::new(); - msm.append_term(power_of_v, (*c).into()); + msm.append_term(power_of_v, c.deref().unwrap().into()); msm } CommitmentReference::MSM(msm) => { diff --git a/halo2_proofs/src/poly/kzg/multiopen/shplonk/prover.rs b/halo2_proofs/src/poly/kzg/multiopen/shplonk/prover.rs index b18bf4919f..ab607e8bbc 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/shplonk/prover.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/shplonk/prover.rs @@ -21,7 +21,7 @@ use rand_core::RngCore; use std::fmt::Debug; use std::io; use std::marker::PhantomData; -use std::ops::MulAssign; +use std::ops::{Deref, MulAssign}; #[cfg(feature = "multicore")] use crate::multicore::ParallelIterator; @@ -211,7 +211,10 @@ where .reduce(|acc, poly| acc + &poly) .unwrap(); - let h = self.params.commit(&h_x, Blind::default()).to_affine(); + let h = self.params.commit(&h_x, Blind::default())[0] + .deref() + .unwrap() + .to_affine(); transcript.write_point(h)?; let u: ChallengeU<_> = transcript.squeeze_challenge_scalar(); @@ -293,7 +296,10 @@ where _marker: PhantomData, }; - let h = self.params.commit(&h_x, Blind::default()).to_affine(); + let h = self.params.commit(&h_x, Blind::default())[0] + .deref() + .unwrap() + .to_affine(); transcript.write_point(h)?; Ok(()) diff --git a/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs b/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs index 5d03940177..cd13516d31 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs @@ -18,7 +18,7 @@ use crate::transcript::{EncodedChallenge, TranscriptRead}; use ff::Field; use halo2curves::pairing::{Engine, MultiMillerLoop}; use halo2curves::CurveExt; -use std::ops::MulAssign; +use std::ops::{Deref, MulAssign}; /// Concrete KZG multiopen verifier with SHPLONK variant #[derive(Debug)] @@ -103,8 +103,9 @@ where let r_eval = power_of_y * eval_polynomial(&r_x[..], *u); let msm = match commitment_data.get() { CommitmentReference::Commitment(c) => { + let c = &c[0]; let mut msm = MSMKZG::::new(); - msm.append_term(power_of_y, (*c).into()); + msm.append_term(power_of_y, c.deref().unwrap().into()); msm } CommitmentReference::MSM(msm) => { diff --git a/halo2_proofs/src/poly/query.rs b/halo2_proofs/src/poly/query.rs index b9894edd38..7e8a2cd31b 100644 --- a/halo2_proofs/src/poly/query.rs +++ b/halo2_proofs/src/poly/query.rs @@ -1,6 +1,7 @@ use std::fmt::Debug; use super::commitment::{Blind, MSM}; +use crate::poly::commitment::CommitmentItem; use crate::{ arithmetic::eval_polynomial, poly::{Coeff, Polynomial}, @@ -60,7 +61,11 @@ impl<'com, C: CurveAffine> Query for ProverQuery<'com, C> { impl<'com, C: CurveAffine, M: MSM> VerifierQuery<'com, C, M> { /// Create a new verifier query based on a commitment - pub fn new_commitment(commitment: &'com C, point: C::Scalar, eval: C::Scalar) -> Self { + pub fn new_general_commitment( + commitment: &'com [CommitmentItem], + point: C::Scalar, + eval: C::Scalar, + ) -> Self { VerifierQuery { point, eval, @@ -68,6 +73,18 @@ impl<'com, C: CurveAffine, M: MSM> VerifierQuery<'com, C, M> { } } + pub fn new_commitment( + commitment: &'com CommitmentItem, + point: C::Scalar, + eval: C::Scalar, + ) -> Self { + VerifierQuery { + point, + eval, + commitment: CommitmentReference::Commitment(&[*commitment]), + } + } + /// Create a new verifier query based on a linear combination of commitments pub fn new_msm(msm: &'com M, point: C::Scalar, eval: C::Scalar) -> VerifierQuery<'com, C, M> { VerifierQuery { @@ -102,7 +119,7 @@ impl<'com, C: CurveAffine, M: MSM> Clone for VerifierQuery<'com, C, M> { #[allow(clippy::upper_case_acronyms)] #[derive(Clone, Debug)] pub enum CommitmentReference<'r, C: CurveAffine, M: MSM> { - Commitment(&'r C), + Commitment(&'r [CommitmentItem]), MSM(&'r M), }