From 12e8b3fb3c528e44b580eff89278526ccf7126f0 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Thu, 21 Mar 2024 10:30:00 +0100 Subject: [PATCH 1/6] add: ParamsVerifierKZG - modify `verifier_params` -> `into_verifier_params` This function now consumes the Commitment Scheme parameters. --- halo2_proofs/examples/serialization.rs | 6 +- halo2_proofs/src/poly/commitment.rs | 8 +- halo2_proofs/src/poly/ipa/commitment.rs | 9 +- halo2_proofs/src/poly/kzg/commitment.rs | 212 +++++++++++++++++- halo2_proofs/src/poly/kzg/msm.rs | 14 +- .../src/poly/kzg/multiopen/gwc/verifier.rs | 8 +- .../poly/kzg/multiopen/shplonk/verifier.rs | 8 +- halo2_proofs/src/poly/kzg/strategy.rs | 10 +- halo2_proofs/src/poly/multiopen_test.rs | 24 +- halo2_proofs/tests/plonk_api.rs | 12 +- 10 files changed, 259 insertions(+), 52 deletions(-) diff --git a/halo2_proofs/examples/serialization.rs b/halo2_proofs/examples/serialization.rs index 39b6b1192f..3ad8305c08 100644 --- a/halo2_proofs/examples/serialization.rs +++ b/halo2_proofs/examples/serialization.rs @@ -11,6 +11,7 @@ use halo2_proofs::{ ConstraintSystem, Error, Fixed, Instance, ProvingKey, }, poly::{ + commitment::ParamsProver, kzg::{ commitment::{KZGCommitmentScheme, ParamsKZG}, multiopen::{ProverGWC, VerifierGWC}, @@ -173,7 +174,8 @@ fn main() { .expect("prover should not fail"); let proof = transcript.finalize(); - let strategy = SingleStrategy::new(¶ms); + let verifier_params = params.into_verifier_params(); + let strategy = SingleStrategy::new(&verifier_params); let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]); assert!(verify_proof::< KZGCommitmentScheme, @@ -182,7 +184,7 @@ fn main() { Blake2bRead<&[u8], G1Affine, Challenge255>, SingleStrategy<'_, Bn256>, >( - ¶ms, + &verifier_params, pk.get_vk(), strategy, &[instances], diff --git a/halo2_proofs/src/poly/commitment.rs b/halo2_proofs/src/poly/commitment.rs index ebc26fe9c3..97de895a29 100644 --- a/halo2_proofs/src/poly/commitment.rs +++ b/halo2_proofs/src/poly/commitment.rs @@ -91,11 +91,15 @@ pub trait ParamsProver<'params, C: CurveAffine>: Params<'params, C> { fn get_g(&self) -> &[C]; /// Returns verification parameters. - fn verifier_params(&'params self) -> &'params Self::ParamsVerifier; + fn into_verifier_params(self) -> Self::ParamsVerifier; } /// Verifier specific functionality with circuit constraints -pub trait ParamsVerifier<'params, C: CurveAffine>: Params<'params, C> {} +pub trait ParamsVerifier<'params, C: CurveAffine>: Params<'params, C> { + /// Returns the size of the trimed parameters. + /// This is the maximum size of the PI that these params can be used to commit to. + fn trimed_size(&self) -> u64; +} /// Multi scalar multiplication engine pub trait MSM: Clone + Debug + Send + Sync { diff --git a/halo2_proofs/src/poly/ipa/commitment.rs b/halo2_proofs/src/poly/ipa/commitment.rs index 7be053c49c..712a0c3d9e 100644 --- a/halo2_proofs/src/poly/ipa/commitment.rs +++ b/halo2_proofs/src/poly/ipa/commitment.rs @@ -56,7 +56,12 @@ impl CommitmentScheme for IPACommitmentScheme { /// Verifier parameters pub type ParamsVerifierIPA = ParamsIPA; -impl<'params, C: CurveAffine> ParamsVerifier<'params, C> for ParamsIPA {} +impl<'params, C: CurveAffine> ParamsVerifier<'params, C> for ParamsIPA { + fn trimed_size(&self) -> u64 { + // IPA parameters are never trimed so their sized is always the full size of the domain. + self.n + } +} impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA { type MSM = MSMIPA<'params, C>; @@ -145,7 +150,7 @@ impl<'params, C: CurveAffine> Params<'params, C> for ParamsIPA { impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA { type ParamsVerifier = ParamsVerifierIPA; - fn verifier_params(&'params self) -> &'params Self::ParamsVerifier { + fn into_verifier_params(self) -> Self::ParamsVerifier { self } diff --git a/halo2_proofs/src/poly/kzg/commitment.rs b/halo2_proofs/src/poly/kzg/commitment.rs index 114b9ac013..62cbf5b915 100644 --- a/halo2_proofs/src/poly/kzg/commitment.rs +++ b/halo2_proofs/src/poly/kzg/commitment.rs @@ -27,6 +27,24 @@ pub struct ParamsKZG { pub(crate) s_g2: E::G2Affine, } +/// KZG multi-open verification parameters. +/// These parameters need to support the veification of a KZG PLONK proof. +/// As a consequence, they need to support the computation of the PI commitment. +#[derive(Debug, Clone)] +pub struct ParamsVerifierKZG { + // Log-size of the domain. + pub(crate) k: u32, + // Domain size. + pub(crate) n: u64, + // This is the maximum size of PI supported. + pub(crate) trimed_size: u32, + + pub(crate) g_lagrange: Vec, + pub(crate) g: E::G1Affine, + pub(crate) g2: E::G2Affine, + pub(crate) s_g2: E::G2Affine, +} + /// Umbrella commitment scheme construction for all KZG variants #[derive(Debug)] pub struct KZGCommitmentScheme { @@ -267,10 +285,138 @@ where } } -// TODO: see the issue at https://github.com/appliedzkp/halo2/issues/45 -// So we probably need much smaller verifier key. However for new bases in g1 should be in verifier keys. -/// KZG multi-open verification parameters -pub type ParamsVerifierKZG = ParamsKZG; +impl ParamsVerifierKZG +where + E::Scalar: PrimeField, + E::G1Affine: SerdeCurveAffine, + E::G2Affine: SerdeCurveAffine, +{ + /// Reduce the size of the verifier parameters by eliminating elements of `g_lagrange`. + /// The resulting parameters are only able to compute commitments up to the inputed `size`. + /// As a result, this will be the maximum size of PI supported. + pub fn trim(mut self, size: usize) -> Self { + assert!(size as u64 <= self.n); + self.trimed_size = size as u32; + self.g_lagrange.truncate(size); + self + } + + /// Writes verifier parameters to buffer. + pub fn write_custom(&self, writer: &mut W, format: SerdeFormat) -> io::Result<()> + where + E::G2Affine: SerdeCurveAffine, + { + writer.write_all(&self.k.to_le_bytes())?; + writer.write_all(&self.trimed_size.to_le_bytes())?; + for el in self.g_lagrange.iter() { + el.write(writer, format)?; + } + self.g.write(writer, format)?; + self.g2.write(writer, format)?; + self.s_g2.write(writer, format)?; + Ok(()) + } + + /// Reads verifier parameters from a buffer. + pub fn read_custom(reader: &mut R, format: SerdeFormat) -> io::Result + where + E::G2Affine: SerdeCurveAffine, + { + let mut k = [0u8; 4]; + reader.read_exact(&mut k[..])?; + let k = u32::from_le_bytes(k); + let n = 1 << k; + // This is a generous bound on the size of the domain. + debug_assert!(k < 32); + + let mut trimed_size = [0u8; 4]; + reader.read_exact(&mut trimed_size[..])?; + let trimed_size = u32::from_le_bytes(trimed_size); + + let g_lagrange = match format { + SerdeFormat::Processed => { + use group::GroupEncoding; + let load_points_from_file_parallelly = + |reader: &mut R| -> io::Result>> { + let mut points_compressed = vec![ + <::G1Affine as GroupEncoding>::Repr::default(); + trimed_size as usize + ]; + for points_compressed in points_compressed.iter_mut() { + reader.read_exact((*points_compressed).as_mut())?; + } + + let mut points = vec![Option::::None; trimed_size as usize]; + parallelize(&mut points, |points, chunks| { + for (i, point) in points.iter_mut().enumerate() { + *point = Option::from(E::G1Affine::from_bytes( + &points_compressed[chunks + i], + )); + } + }); + Ok(points) + }; + + let g_lagrange = load_points_from_file_parallelly(reader)?; + g_lagrange + .iter() + .map(|point| { + point.ok_or_else(|| { + io::Error::new(io::ErrorKind::Other, "invalid point encoding") + }) + }) + .collect::>()? + } + SerdeFormat::RawBytes => (0..trimed_size) + .map(|_| ::read(reader, format)) + .collect::, _>>()?, + SerdeFormat::RawBytesUnchecked => (0..trimed_size) + .map(|_| ::read(reader, format).unwrap()) + .collect::>(), + }; + let g = ::read(reader, format)?; + let g2 = E::G2Affine::read(reader, format)?; + let s_g2 = E::G2Affine::read(reader, format)?; + + Ok(Self { + k, + n, + trimed_size, + g_lagrange, + g, + g2, + s_g2, + }) + } +} + +impl From> for ParamsVerifierKZG { + fn from(value: ParamsKZG) -> Self { + Self { + k: value.k, + n: value.n, + trimed_size: value.n as u32, + g_lagrange: value.g_lagrange.clone(), + g: value.g[0], + g2: value.g2, + s_g2: value.s_g2, + } + } +} + +impl From<&ParamsKZG> for ParamsVerifierKZG { + fn from(value: &ParamsKZG) -> Self { + Self { + k: value.k, + n: value.n, + trimed_size: value.n as u32, + g_lagrange: value.g_lagrange.clone(), + g: value.g[0], + g2: value.g2, + s_g2: value.s_g2, + } + } +} impl<'params, E: Engine + Debug> Params<'params, E::G1Affine> for ParamsKZG where @@ -322,12 +468,64 @@ where } } -impl<'params, E: Engine + Debug> ParamsVerifier<'params, E::G1Affine> for ParamsKZG +impl<'params, E: Engine + Debug> Params<'params, E::G1Affine> for ParamsVerifierKZG where E::G1Affine: SerdeCurveAffine::Fr, CurveExt = ::G1>, E::G1: CurveExt, E::G2Affine: SerdeCurveAffine, { + type MSM = MSMKZG; + + fn k(&self) -> u32 { + self.k + } + + fn n(&self) -> u64 { + self.n + } + + fn downsize(&mut self, _k: u32) { + // Verifier parameters cannot be downsized since they do not contain the original powers of g. + unimplemented!() + } + + fn empty_msm(&'params self) -> MSMKZG { + MSMKZG::new() + } + + fn commit_lagrange( + &self, + poly: &Polynomial, + _: Blind, + ) -> 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]) + } + + /// Writes params to a buffer. + fn write(&self, writer: &mut W) -> io::Result<()> { + self.write_custom(writer, SerdeFormat::RawBytes) + } + + /// Reads params from a buffer. + fn read(reader: &mut R) -> io::Result { + Self::read_custom(reader, SerdeFormat::RawBytes) + } +} + +impl<'params, E: Engine + Debug> ParamsVerifier<'params, E::G1Affine> for ParamsVerifierKZG +where + E::Scalar: PrimeField, + E::G1Affine: SerdeCurveAffine, + E::G2Affine: SerdeCurveAffine, +{ + fn trimed_size(&self) -> u64 { + self.trimed_size as u64 + } } impl<'params, E: Engine + Debug> ParamsProver<'params, E::G1Affine> for ParamsKZG @@ -338,8 +536,8 @@ where { type ParamsVerifier = ParamsVerifierKZG; - fn verifier_params(&'params self) -> &'params Self::ParamsVerifier { - self + fn into_verifier_params(self) -> Self::ParamsVerifier { + self.into() } fn new(k: u32) -> Self { diff --git a/halo2_proofs/src/poly/kzg/msm.rs b/halo2_proofs/src/poly/kzg/msm.rs index f9b8c284bd..e806014771 100644 --- a/halo2_proofs/src/poly/kzg/msm.rs +++ b/halo2_proofs/src/poly/kzg/msm.rs @@ -1,6 +1,6 @@ use std::fmt::Debug; -use super::commitment::ParamsKZG; +use super::commitment::ParamsVerifierKZG; use crate::{ arithmetic::{best_multiexp, parallelize}, poly::commitment::MSM, @@ -132,12 +132,10 @@ where } } -impl<'params, E: MultiMillerLoop + Debug> From<&'params ParamsKZG> for DualMSM<'params, E> -where - E::G1Affine: CurveAffine::Fr, CurveExt = ::G1>, - E::G1: CurveExt, +impl<'params, E: MultiMillerLoop + Debug> From<&'params ParamsVerifierKZG> + for DualMSM<'params, E> { - fn from(params: &'params ParamsKZG) -> Self { + fn from(params: &'params ParamsVerifierKZG) -> Self { DualMSM::new(params) } } @@ -149,7 +147,7 @@ where E::G1Affine: CurveAffine::Fr, CurveExt = ::G1>, E::G1: CurveExt, { - pub(crate) params: &'a ParamsKZG, + pub(crate) params: &'a ParamsVerifierKZG, pub(crate) left: MSMKZG, pub(crate) right: MSMKZG, } @@ -160,7 +158,7 @@ where E::G1: CurveExt, { /// Create a new two channel MSM accumulator instance - pub fn new(params: &'a ParamsKZG) -> Self { + pub fn new(params: &'a ParamsVerifierKZG) -> Self { Self { params, left: MSMKZG::new(), diff --git a/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs b/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs index fcfda6941f..20dd495015 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs @@ -5,7 +5,7 @@ use crate::arithmetic::powers; use crate::helpers::SerdeCurveAffine; use crate::poly::commitment::Verifier; use crate::poly::commitment::MSM; -use crate::poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG}; +use crate::poly::kzg::commitment::{KZGCommitmentScheme, ParamsVerifierKZG}; use crate::poly::kzg::msm::{DualMSM, MSMKZG}; use crate::poly::kzg::strategy::GuardKZG; use crate::poly::query::Query; @@ -20,7 +20,7 @@ use halo2curves::CurveExt; #[derive(Debug)] /// Concrete KZG verifier with GWC variant pub struct VerifierGWC<'params, E: Engine> { - params: &'params ParamsKZG, + params: &'params ParamsVerifierKZG, } impl<'params, E> Verifier<'params, KZGCommitmentScheme> for VerifierGWC<'params, E> @@ -35,7 +35,7 @@ where const QUERY_INSTANCE: bool = false; - fn new(params: &'params ParamsKZG) -> Self { + fn new(params: &'params ParamsVerifierKZG) -> Self { Self { params } } @@ -116,7 +116,7 @@ where msm_accumulator.right.add_msm(&witness_with_aux); msm_accumulator.right.add_msm(&commitment_multi); - let g0: E::G1 = self.params.g[0].into(); + let g0: E::G1 = self.params.g.into(); msm_accumulator.right.append_term(eval_multi, -g0); Ok(Self::Guard::new(msm_accumulator)) diff --git a/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs b/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs index 5d03940177..cc221511a5 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs @@ -8,7 +8,7 @@ use crate::arithmetic::{ use crate::helpers::SerdeCurveAffine; use crate::poly::commitment::Verifier; use crate::poly::commitment::MSM; -use crate::poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG}; +use crate::poly::kzg::commitment::{KZGCommitmentScheme, ParamsVerifierKZG}; use crate::poly::kzg::msm::DualMSM; use crate::poly::kzg::msm::{PreMSM, MSMKZG}; use crate::poly::kzg::strategy::GuardKZG; @@ -23,7 +23,7 @@ use std::ops::MulAssign; /// Concrete KZG multiopen verifier with SHPLONK variant #[derive(Debug)] pub struct VerifierSHPLONK<'params, E: Engine> { - params: &'params ParamsKZG, + params: &'params ParamsVerifierKZG, } impl<'params, E> Verifier<'params, KZGCommitmentScheme> for VerifierSHPLONK<'params, E> @@ -39,7 +39,7 @@ where const QUERY_INSTANCE: bool = false; - fn new(params: &'params ParamsKZG) -> Self { + fn new(params: &'params ParamsVerifierKZG) -> Self { Self { params } } @@ -126,7 +126,7 @@ where r_outer_acc += power_of_v * r_inner_acc * z_diff_i; } let mut outer_msm = outer_msm.normalize(); - let g1: E::G1 = self.params.g[0].into(); + let g1: E::G1 = self.params.g.into(); outer_msm.append_term(-r_outer_acc, g1); outer_msm.append_term(-z_0, h1.into()); outer_msm.append_term(*u, h2.into()); diff --git a/halo2_proofs/src/poly/kzg/strategy.rs b/halo2_proofs/src/poly/kzg/strategy.rs index ee80d800ac..a837d40a1a 100644 --- a/halo2_proofs/src/poly/kzg/strategy.rs +++ b/halo2_proofs/src/poly/kzg/strategy.rs @@ -1,5 +1,5 @@ use super::{ - commitment::{KZGCommitmentScheme, ParamsKZG}, + commitment::{KZGCommitmentScheme, ParamsVerifierKZG}, msm::DualMSM, }; use crate::{ @@ -66,7 +66,7 @@ where E::G1: CurveExt, { /// Constructs an empty batch verifier - pub fn new(params: &'params ParamsKZG) -> Self { + pub fn new(params: &'params ParamsVerifierKZG) -> Self { AccumulatorStrategy { msm_accumulator: DualMSM::new(params), } @@ -94,7 +94,7 @@ where E::G1: CurveExt, { /// Constructs an empty batch verifier - pub fn new(params: &'params ParamsKZG) -> Self { + pub fn new(params: &'params ParamsVerifierKZG) -> Self { SingleStrategy { msm: DualMSM::new(params), } @@ -118,7 +118,7 @@ where { type Output = Self; - fn new(params: &'params ParamsKZG) -> Self { + fn new(params: &'params ParamsVerifierKZG) -> Self { AccumulatorStrategy::new(params) } @@ -157,7 +157,7 @@ where { type Output = (); - fn new(params: &'params ParamsKZG) -> Self { + fn new(params: &'params ParamsVerifierKZG) -> Self { Self::new(params) } diff --git a/halo2_proofs/src/poly/multiopen_test.rs b/halo2_proofs/src/poly/multiopen_test.rs index 47c6731167..320d07037a 100644 --- a/halo2_proofs/src/poly/multiopen_test.rs +++ b/halo2_proofs/src/poly/multiopen_test.rs @@ -36,7 +36,7 @@ mod test { Blake2bWrite<_, _, Challenge255<_>>, >(¶ms); - let verifier_params = params.verifier_params(); + let verifier_params = params.into_verifier_params(); verify::< IPACommitmentScheme, @@ -44,7 +44,7 @@ mod test { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, - >(verifier_params, &proof[..], false); + >(&verifier_params, &proof[..], false); verify::< IPACommitmentScheme, @@ -52,7 +52,7 @@ mod test { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, - >(verifier_params, &proof[..], true); + >(&verifier_params, &proof[..], true); } #[test] @@ -73,7 +73,7 @@ mod test { Keccak256Write<_, _, Challenge255<_>>, >(¶ms); - let verifier_params = params.verifier_params(); + let verifier_params = params.into_verifier_params(); verify::< IPACommitmentScheme, @@ -81,7 +81,7 @@ mod test { _, Keccak256Read<_, _, Challenge255<_>>, AccumulatorStrategy<_>, - >(verifier_params, &proof[..], false); + >(&verifier_params, &proof[..], false); verify::< IPACommitmentScheme, @@ -89,7 +89,7 @@ mod test { _, Keccak256Read<_, _, Challenge255<_>>, AccumulatorStrategy<_>, - >(verifier_params, &proof[..], true); + >(&verifier_params, &proof[..], true); } #[test] @@ -106,10 +106,10 @@ mod test { let proof = create_proof::<_, ProverGWC<_>, _, Blake2bWrite<_, _, Challenge255<_>>>(¶ms); - let verifier_params = params.verifier_params(); + let verifier_params = params.into_verifier_params(); verify::<_, VerifierGWC<_>, _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>>( - verifier_params, + &verifier_params, &proof[..], false, ); @@ -120,7 +120,7 @@ mod test { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, - >(verifier_params, &proof[..], true); + >(&verifier_params, &proof[..], true); } #[test] @@ -141,7 +141,7 @@ mod test { Blake2bWrite<_, _, Challenge255<_>>, >(¶ms); - let verifier_params = params.verifier_params(); + let verifier_params = params.into_verifier_params(); verify::< KZGCommitmentScheme, @@ -149,7 +149,7 @@ mod test { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, - >(verifier_params, &proof[..], false); + >(&verifier_params, &proof[..], false); verify::< KZGCommitmentScheme, @@ -157,7 +157,7 @@ mod test { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, - >(verifier_params, &proof[..], true); + >(&verifier_params, &proof[..], true); } fn verify< diff --git a/halo2_proofs/tests/plonk_api.rs b/halo2_proofs/tests/plonk_api.rs index 16f2031e35..7b2b3f5006 100644 --- a/halo2_proofs/tests/plonk_api.rs +++ b/halo2_proofs/tests/plonk_api.rs @@ -549,7 +549,7 @@ fn plonk_api() { rng, ¶ms, &pk, ); - let verifier_params = params.verifier_params(); + let verifier_params = params.into_verifier_params(); verify_proof::< _, @@ -557,7 +557,7 @@ fn plonk_api() { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, - >(verifier_params, pk.get_vk(), &proof[..]); + >(&verifier_params, pk.get_vk(), &proof[..]); } fn test_plonk_api_shplonk() { @@ -578,7 +578,7 @@ fn plonk_api() { rng, ¶ms, &pk, ); - let verifier_params = params.verifier_params(); + let verifier_params = params.into_verifier_params(); verify_proof::< _, @@ -586,7 +586,7 @@ fn plonk_api() { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, - >(verifier_params, pk.get_vk(), &proof[..]); + >(&verifier_params, pk.get_vk(), &proof[..]); } fn test_plonk_api_ipa() { @@ -607,7 +607,7 @@ fn plonk_api() { rng, ¶ms, &pk, ); - let verifier_params = params.verifier_params(); + let verifier_params = params.into_verifier_params(); verify_proof::< _, @@ -615,7 +615,7 @@ fn plonk_api() { _, Blake2bRead<_, _, Challenge255<_>>, AccumulatorStrategy<_>, - >(verifier_params, pk.get_vk(), &proof[..]); + >(&verifier_params, pk.get_vk(), &proof[..]); // Check that the verification key has not changed unexpectedly { From 49c60369a0a2279c27f4edca526b44a121d7f08b Mon Sep 17 00:00:00 2001 From: David Nevado Date: Sun, 24 Mar 2024 16:11:33 +0100 Subject: [PATCH 2/6] remove: generators for G1/G2 from VerifierParams --- halo2_proofs/examples/serialization.rs | 2 +- halo2_proofs/src/poly/commitment.rs | 3 -- halo2_proofs/src/poly/ipa/commitment.rs | 4 --- halo2_proofs/src/poly/kzg/commitment.rs | 30 ++++--------------- halo2_proofs/src/poly/kzg/msm.rs | 7 +++-- .../src/poly/kzg/multiopen/gwc/verifier.rs | 16 ++++++---- .../poly/kzg/multiopen/shplonk/verifier.rs | 17 +++++++---- 7 files changed, 33 insertions(+), 46 deletions(-) diff --git a/halo2_proofs/examples/serialization.rs b/halo2_proofs/examples/serialization.rs index 3ad8305c08..8367c2c177 100644 --- a/halo2_proofs/examples/serialization.rs +++ b/halo2_proofs/examples/serialization.rs @@ -179,7 +179,7 @@ fn main() { let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]); assert!(verify_proof::< KZGCommitmentScheme, - VerifierGWC<'_, Bn256>, + VerifierGWC, Challenge255, Blake2bRead<&[u8], G1Affine, Challenge255>, SingleStrategy<'_, Bn256>, diff --git a/halo2_proofs/src/poly/commitment.rs b/halo2_proofs/src/poly/commitment.rs index 97de895a29..f09ca0aba8 100644 --- a/halo2_proofs/src/poly/commitment.rs +++ b/halo2_proofs/src/poly/commitment.rs @@ -87,9 +87,6 @@ pub trait ParamsProver<'params, C: CurveAffine>: Params<'params, C> { fn commit(&self, poly: &Polynomial, r: Blind) -> C::CurveExt; - /// Getter for g generators - fn get_g(&self) -> &[C]; - /// Returns verification parameters. fn into_verifier_params(self) -> Self::ParamsVerifier; } diff --git a/halo2_proofs/src/poly/ipa/commitment.rs b/halo2_proofs/src/poly/ipa/commitment.rs index 712a0c3d9e..24e7ebe777 100644 --- a/halo2_proofs/src/poly/ipa/commitment.rs +++ b/halo2_proofs/src/poly/ipa/commitment.rs @@ -226,10 +226,6 @@ impl<'params, C: CurveAffine> ParamsProver<'params, C> for ParamsIPA { best_multiexp::(&tmp_scalars, &tmp_bases) } - - fn get_g(&self) -> &[C] { - &self.g - } } #[cfg(test)] diff --git a/halo2_proofs/src/poly/kzg/commitment.rs b/halo2_proofs/src/poly/kzg/commitment.rs index 62cbf5b915..5eeb59cfb6 100644 --- a/halo2_proofs/src/poly/kzg/commitment.rs +++ b/halo2_proofs/src/poly/kzg/commitment.rs @@ -40,8 +40,6 @@ pub struct ParamsVerifierKZG { pub(crate) trimed_size: u32, pub(crate) g_lagrange: Vec, - pub(crate) g: E::G1Affine, - pub(crate) g2: E::G2Affine, pub(crate) s_g2: E::G2Affine, } @@ -75,6 +73,7 @@ where impl ParamsKZG where E::G1Affine: SerdeCurveAffine, + E::G2Affine: SerdeCurveAffine, E::G1: CurveExt, { /// Initializes parameters for the curve, draws toxic secret from given rng. @@ -287,7 +286,8 @@ where impl ParamsVerifierKZG where - E::Scalar: PrimeField, + E::Fr: PrimeField, + E::G1: CurveExt, E::G1Affine: SerdeCurveAffine, E::G2Affine: SerdeCurveAffine, { @@ -311,8 +311,6 @@ where for el in self.g_lagrange.iter() { el.write(writer, format)?; } - self.g.write(writer, format)?; - self.g2.write(writer, format)?; self.s_g2.write(writer, format)?; Ok(()) } @@ -374,8 +372,6 @@ where .map(|_| ::read(reader, format).unwrap()) .collect::>(), }; - let g = ::read(reader, format)?; - let g2 = E::G2Affine::read(reader, format)?; let s_g2 = E::G2Affine::read(reader, format)?; Ok(Self { @@ -383,8 +379,6 @@ where n, trimed_size, g_lagrange, - g, - g2, s_g2, }) } @@ -397,8 +391,6 @@ impl From> for ParamsVerifierKZG { n: value.n, trimed_size: value.n as u32, g_lagrange: value.g_lagrange.clone(), - g: value.g[0], - g2: value.g2, s_g2: value.s_g2, } } @@ -411,8 +403,6 @@ impl From<&ParamsKZG> for ParamsVerifierKZG { n: value.n, trimed_size: value.n as u32, g_lagrange: value.g_lagrange.clone(), - g: value.g[0], - g2: value.g2, s_g2: value.s_g2, } } @@ -493,11 +483,7 @@ where MSMKZG::new() } - fn commit_lagrange( - &self, - poly: &Polynomial, - _: Blind, - ) -> E::G1 { + fn commit_lagrange(&self, poly: &Polynomial, _: Blind) -> E::G1 { let mut scalars = Vec::with_capacity(poly.len()); scalars.extend(poly.iter()); let bases = &self.g_lagrange; @@ -519,8 +505,8 @@ where impl<'params, E: Engine + Debug> ParamsVerifier<'params, E::G1Affine> for ParamsVerifierKZG where - E::Scalar: PrimeField, - E::G1Affine: SerdeCurveAffine, + E::G1Affine: SerdeCurveAffine::Fr, CurveExt = ::G1>, + E::G1: CurveExt, E::G2Affine: SerdeCurveAffine, { fn trimed_size(&self) -> u64 { @@ -552,10 +538,6 @@ where assert!(bases.len() >= size); best_multiexp(&scalars, &bases[0..size]) } - - fn get_g(&self) -> &[E::G1Affine] { - &self.g - } } #[cfg(test)] diff --git a/halo2_proofs/src/poly/kzg/msm.rs b/halo2_proofs/src/poly/kzg/msm.rs index e806014771..a37509df15 100644 --- a/halo2_proofs/src/poly/kzg/msm.rs +++ b/halo2_proofs/src/poly/kzg/msm.rs @@ -5,6 +5,7 @@ use crate::{ arithmetic::{best_multiexp, parallelize}, poly::commitment::MSM, }; +use group::prime::PrimeCurveAffine; use group::{Curve, Group}; use halo2curves::{ pairing::{Engine, MillerLoopResult, MultiMillerLoop}, @@ -78,7 +79,6 @@ where } fn eval(&self) -> E::G1 { - use group::prime::PrimeCurveAffine; let mut bases = vec![E::G1Affine::identity(); self.scalars.len()]; E::G1::batch_normalize(&self.bases, &mut bases); best_multiexp(&self.scalars, &bases) @@ -134,6 +134,9 @@ where impl<'params, E: MultiMillerLoop + Debug> From<&'params ParamsVerifierKZG> for DualMSM<'params, E> +where + E::G1Affine: CurveAffine::Fr, CurveExt = ::G1>, + E::G1: CurveExt, { fn from(params: &'params ParamsVerifierKZG) -> Self { DualMSM::new(params) @@ -181,7 +184,7 @@ where /// Performs final pairing check with given verifier params and two channel linear combination pub fn check(self) -> bool { let s_g2_prepared = E::G2Prepared::from(self.params.s_g2); - let n_g2_prepared = E::G2Prepared::from(-self.params.g2); + let n_g2_prepared = E::G2Prepared::from(-E::G2Affine::generator()); let left = self.left.eval(); let right = self.right.eval(); diff --git a/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs b/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs index 20dd495015..71b6fff584 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::marker::PhantomData; use super::{construct_intermediate_sets, ChallengeU, ChallengeV}; use crate::arithmetic::powers; @@ -14,16 +15,17 @@ use crate::poly::Error; use crate::transcript::{EncodedChallenge, TranscriptRead}; use ff::Field; +use group::prime::PrimeCurveAffine; use halo2curves::pairing::{Engine, MultiMillerLoop}; use halo2curves::CurveExt; #[derive(Debug)] /// Concrete KZG verifier with GWC variant -pub struct VerifierGWC<'params, E: Engine> { - params: &'params ParamsVerifierKZG, +pub struct VerifierGWC { + _p0: PhantomData, } -impl<'params, E> Verifier<'params, KZGCommitmentScheme> for VerifierGWC<'params, E> +impl<'params, E> Verifier<'params, KZGCommitmentScheme> for VerifierGWC where E: MultiMillerLoop + Debug, E::G1Affine: SerdeCurveAffine::Fr, CurveExt = ::G1>, @@ -35,8 +37,10 @@ where const QUERY_INSTANCE: bool = false; - fn new(params: &'params ParamsVerifierKZG) -> Self { - Self { params } + fn new(_params: &'params ParamsVerifierKZG) -> Self { + Self { + _p0: PhantomData::default(), + } } fn verify_proof< @@ -116,7 +120,7 @@ where msm_accumulator.right.add_msm(&witness_with_aux); msm_accumulator.right.add_msm(&commitment_multi); - let g0: E::G1 = self.params.g.into(); + let g0: E::G1 = E::G1Affine::generator().into(); msm_accumulator.right.append_term(eval_multi, -g0); Ok(Self::Guard::new(msm_accumulator)) diff --git a/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs b/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs index cc221511a5..9be38e0b93 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs @@ -1,4 +1,5 @@ use std::fmt::Debug; +use std::marker::PhantomData; use super::ChallengeY; use super::{construct_intermediate_sets, ChallengeU, ChallengeV}; @@ -16,17 +17,19 @@ use crate::poly::query::{CommitmentReference, VerifierQuery}; use crate::poly::Error; use crate::transcript::{EncodedChallenge, TranscriptRead}; use ff::Field; +use group::prime::PrimeCurveAffine; use halo2curves::pairing::{Engine, MultiMillerLoop}; use halo2curves::CurveExt; use std::ops::MulAssign; /// Concrete KZG multiopen verifier with SHPLONK variant #[derive(Debug)] -pub struct VerifierSHPLONK<'params, E: Engine> { - params: &'params ParamsVerifierKZG, +pub struct VerifierSHPLONK { + // params: &'params ParamsVerifierKZG, + _p0: PhantomData, } -impl<'params, E> Verifier<'params, KZGCommitmentScheme> for VerifierSHPLONK<'params, E> +impl<'params, E> Verifier<'params, KZGCommitmentScheme> for VerifierSHPLONK where E: MultiMillerLoop + Debug, E::Fr: Ord, @@ -39,8 +42,10 @@ where const QUERY_INSTANCE: bool = false; - fn new(params: &'params ParamsVerifierKZG) -> Self { - Self { params } + fn new(_params: &'params ParamsVerifierKZG) -> Self { + Self { + _p0: PhantomData::default(), + } } /// Verify a multi-opening proof @@ -126,7 +131,7 @@ where r_outer_acc += power_of_v * r_inner_acc * z_diff_i; } let mut outer_msm = outer_msm.normalize(); - let g1: E::G1 = self.params.g.into(); + let g1: E::G1 = E::G1Affine::generator().into(); outer_msm.append_term(-r_outer_acc, g1); outer_msm.append_term(-z_0, h1.into()); outer_msm.append_term(*u, h2.into()); From 0d968863fbef4ed4e97414f877bf4d0ece530c71 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Mon, 25 Mar 2024 11:29:21 +0100 Subject: [PATCH 3/6] fix: check parms len --- halo2_proofs/src/plonk/verifier.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/halo2_proofs/src/plonk/verifier.rs b/halo2_proofs/src/plonk/verifier.rs index 76675bcdfa..fca7e0b1bc 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::{CommitmentScheme, ParamsVerifier, Verifier}; use crate::poly::VerificationStrategy; use crate::poly::{ commitment::{Blind, Params}, @@ -52,7 +52,9 @@ where instance .iter() .map(|instance| { - if instance.len() > params.n() as usize - (vk.cs.blinding_factors() + 1) { + if instance.len() + > params.trimed_size() as usize - (vk.cs.blinding_factors() + 1) + { return Err(Error::InstanceTooLarge); } let mut poly = instance.to_vec(); From 6670166b73ff76f94325ac814390dc257497d078 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Mon, 25 Mar 2024 17:07:09 +0100 Subject: [PATCH 4/6] fix: improve error msg for downsize --- halo2_proofs/src/poly/kzg/commitment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/halo2_proofs/src/poly/kzg/commitment.rs b/halo2_proofs/src/poly/kzg/commitment.rs index 5eeb59cfb6..5e079501ac 100644 --- a/halo2_proofs/src/poly/kzg/commitment.rs +++ b/halo2_proofs/src/poly/kzg/commitment.rs @@ -476,7 +476,7 @@ where fn downsize(&mut self, _k: u32) { // Verifier parameters cannot be downsized since they do not contain the original powers of g. - unimplemented!() + panic!("Verifier parameters cannot be downsized. You may want to use `trim` instead.") } fn empty_msm(&'params self) -> MSMKZG { From fc508c557d2f7e104ab88d46fd5543417f43ac8c Mon Sep 17 00:00:00 2001 From: David Nevado Date: Tue, 2 Apr 2024 11:09:22 +0200 Subject: [PATCH 5/6] fix: arithmetic bench replace IPAParams genration function with manual generation --- halo2_proofs/benches/arithmetic.rs | 42 ++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/halo2_proofs/benches/arithmetic.rs b/halo2_proofs/benches/arithmetic.rs index 4ae88af137..00981ef973 100644 --- a/halo2_proofs/benches/arithmetic.rs +++ b/halo2_proofs/benches/arithmetic.rs @@ -1,13 +1,13 @@ #[macro_use] extern crate criterion; -use crate::arithmetic::small_multiexp; +use crate::arithmetic::{parallelize, small_multiexp, CurveAffine, CurveExt}; use crate::halo2curves::pasta::{EqAffine, Fp}; +use group::cofactor::CofactorCurveAffine; use group::ff::Field; +use group::{Curve, Group}; use halo2_proofs::*; -use halo2_proofs::poly::{commitment::ParamsProver, ipa::commitment::ParamsIPA}; - use criterion::{black_box, Criterion}; use rand_core::OsRng; @@ -16,8 +16,40 @@ fn criterion_benchmark(c: &mut Criterion) { // small multiexp { - let params: ParamsIPA = ParamsIPA::new(5); - let g = &mut params.get_g().to_vec(); + let k = 5u32; + let n: u64 = 1 << k; + let id = ::Curve::identity(); + + let g_projective = { + let mut g = Vec::with_capacity(n as usize); + g.resize(n as usize, id); + + parallelize(&mut g, move |g, start| { + let hasher = ::CurveExt::hash_to_curve("Halo2-Parameters"); + + for (i, g) in g.iter_mut().enumerate() { + let i = (i + start) as u32; + + let mut message = [0u8; 5]; + message[1..5].copy_from_slice(&i.to_le_bytes()); + + *g = hasher(&message); + } + }); + + g + }; + + let mut g = { + let mut g: Vec = vec![id.into(); n as usize]; + parallelize(&mut g, |g, starts| { + ::Curve::batch_normalize( + &g_projective[starts..(starts + g.len())], + g, + ); + }); + g + }; let len = g.len() / 2; let (g_lo, g_hi) = g.split_at_mut(len); From 11ff07d490877b16e4cc50a5e80c3d1f8ff8e7e0 Mon Sep 17 00:00:00 2001 From: David Nevado Date: Tue, 2 Apr 2024 11:26:50 +0200 Subject: [PATCH 6/6] fix: clippy lints --- halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs | 4 +--- halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs b/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs index 71b6fff584..ebadea647a 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/gwc/verifier.rs @@ -38,9 +38,7 @@ where const QUERY_INSTANCE: bool = false; fn new(_params: &'params ParamsVerifierKZG) -> Self { - Self { - _p0: PhantomData::default(), - } + Self { _p0: PhantomData } } fn verify_proof< diff --git a/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs b/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs index 9be38e0b93..fed8abc3eb 100644 --- a/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs +++ b/halo2_proofs/src/poly/kzg/multiopen/shplonk/verifier.rs @@ -43,9 +43,7 @@ where const QUERY_INSTANCE: bool = false; fn new(_params: &'params ParamsVerifierKZG) -> Self { - Self { - _p0: PhantomData::default(), - } + Self { _p0: PhantomData } } /// Verify a multi-opening proof