From e5256cf7737fdb816fd59dae69d14463925478c6 Mon Sep 17 00:00:00 2001 From: iquerejeta Date: Wed, 22 Jan 2025 12:35:51 +0100 Subject: [PATCH] Remove SerdeObject and add read/write functions to hashable --- examples/vector-ops-unblinded.rs | 1 - src/plonk/lookup/prover.rs | 9 ++- src/plonk/lookup/verifier.rs | 5 +- src/plonk/mod.rs | 3 +- src/plonk/permutation.rs | 6 +- src/plonk/permutation/prover.rs | 5 +- src/plonk/permutation/verifier.rs | 9 ++- src/plonk/prover.rs | 4 +- src/plonk/vanishing/prover.rs | 11 ++-- src/plonk/vanishing/verifier.rs | 7 +- src/plonk/verifier.rs | 4 +- src/poly/kzg/mod.rs | 14 ++-- src/poly/kzg/msm.rs | 5 +- src/transcript/implementors.rs | 104 +++++++++++++++++++++++++++++- src/transcript/mod.rs | 26 +++++--- 15 files changed, 151 insertions(+), 62 deletions(-) diff --git a/examples/vector-ops-unblinded.rs b/examples/vector-ops-unblinded.rs index 66b118e01..a7530ed28 100644 --- a/examples/vector-ops-unblinded.rs +++ b/examples/vector-ops-unblinded.rs @@ -473,7 +473,6 @@ where Default + SerdeObject + Hashable + CurveAffine, E::Fr: WithSmallOrderMulGroup<3> + FromUniformBytes<64> - + SerdeObject + Sampleable + Hashable + Ord, diff --git a/src/plonk/lookup/prover.rs b/src/plonk/lookup/prover.rs index c2a73d535..6c4c4c8eb 100644 --- a/src/plonk/lookup/prover.rs +++ b/src/plonk/lookup/prover.rs @@ -9,7 +9,6 @@ use crate::{ }; use ff::{FromUniformBytes, PrimeField, WithSmallOrderMulGroup}; use group::ff::BatchInvert; -use halo2curves::serde::SerdeObject; use rand_core::{CryptoRng, RngCore}; use std::{collections::BTreeMap, iter}; @@ -66,7 +65,7 @@ impl + Ord> Argument { transcript: &mut T, ) -> Result, Error> where - F: FromUniformBytes<64> + SerdeObject, + F: FromUniformBytes<64>, CS::Commitment: Hashable, { // Closure to get values of expressions and compress them @@ -153,7 +152,7 @@ impl> Permuted { transcript: &mut T, ) -> Result, Error> where - F: WithSmallOrderMulGroup<3> + FromUniformBytes<64> + SerdeObject, + F: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, CS::Commitment: Hashable, { let blinding_factors = pk.vk.cs.blinding_factors(); @@ -286,7 +285,7 @@ impl> Committed { transcript: &mut T, ) -> Result, Error> where - F: Hashable + SerdeObject, + F: Hashable, { let domain = &pk.vk.domain; let x_inv = domain.rotate_omega(x, Rotation::prev()); @@ -368,7 +367,7 @@ fn permute_expression_pair, R: RngCore>( table_expression: &Polynomial, ) -> Result, Error> where - F: WithSmallOrderMulGroup<3> + Ord + FromUniformBytes<64> + SerdeObject, + F: WithSmallOrderMulGroup<3> + Ord + FromUniformBytes<64>, { let blinding_factors = pk.vk.cs.blinding_factors(); let usable_rows = pk.vk.n() as usize - (blinding_factors + 1); diff --git a/src/plonk/lookup/verifier.rs b/src/plonk/lookup/verifier.rs index 411293eae..482d8a89d 100644 --- a/src/plonk/lookup/verifier.rs +++ b/src/plonk/lookup/verifier.rs @@ -9,7 +9,6 @@ use crate::{ poly::{Rotation, VerifierQuery}, }; use ff::{PrimeField, WithSmallOrderMulGroup}; -use halo2curves::serde::SerdeObject; pub struct PermutationCommitments> { permuted_input_commitment: CS::Commitment, @@ -57,7 +56,7 @@ impl> PermutationCommitments Result, Error> where - CS::Commitment: Hashable + SerdeObject, + CS::Commitment: Hashable, { let product_commitment = transcript.read()?; @@ -74,7 +73,7 @@ impl> Committed { transcript: &mut T, ) -> Result, Error> where - F: Hashable + SerdeObject, + F: Hashable, { let product_eval = transcript.read()?; let product_next_eval = transcript.read()?; diff --git a/src/plonk/mod.rs b/src/plonk/mod.rs index 7366e3aa4..46ace58a9 100644 --- a/src/plonk/mod.rs +++ b/src/plonk/mod.rs @@ -62,9 +62,8 @@ const VERSION: u8 = 0x03; impl VerifyingKey where - F: WithSmallOrderMulGroup<3> + SerdeObject + FromUniformBytes<64>, + F: WithSmallOrderMulGroup<3> + FromUniformBytes<64>, CS: PolynomialCommitmentScheme, - CS::Commitment: SerdeObject, { /// Returns `n` pub fn n(&self) -> u64 { diff --git a/src/plonk/permutation.rs b/src/plonk/permutation.rs index ab1fb128e..3dc79ac98 100644 --- a/src/plonk/permutation.rs +++ b/src/plonk/permutation.rs @@ -95,7 +95,7 @@ impl> VerifyingKey { pub(crate) fn write(&self, writer: &mut W, format: SerdeFormat) -> io::Result<()> where - CS::Commitment: SerdeObject, + CS::Commitment: ProcessedSerdeObject, { for commitment in &self.commitments { commitment.write(writer, format)?; @@ -109,7 +109,7 @@ impl> VerifyingKey { format: SerdeFormat, ) -> io::Result where - CS::Commitment: SerdeObject, + CS::Commitment: ProcessedSerdeObject, { let commitments = (0..argument.columns.len()) .map(|_| CS::Commitment::read(reader, format)) @@ -119,7 +119,7 @@ impl> VerifyingKey { pub(crate) fn bytes_length(&self, format: SerdeFormat) -> usize where - CS::Commitment: SerdeObject, + CS::Commitment: ProcessedSerdeObject, { self.commitments.len() * byte_length::(format) } diff --git a/src/plonk/permutation/prover.rs b/src/plonk/permutation/prover.rs index 4a1579926..eac8d5d7f 100644 --- a/src/plonk/permutation/prover.rs +++ b/src/plonk/permutation/prover.rs @@ -1,6 +1,5 @@ use ff::{PrimeField, WithSmallOrderMulGroup}; use group::ff::BatchInvert; -use halo2curves::serde::SerdeObject; use rand_core::RngCore; use std::iter::{self, ExactSizeIterator}; @@ -180,7 +179,7 @@ impl super::ProvingKey { transcript: &mut T, ) -> Result<(), Error> where - F: Hashable + SerdeObject, + F: Hashable, { // Hash permutation evals for eval in self.polys.iter().map(|poly| eval_polynomial(poly, x)) { @@ -199,7 +198,7 @@ impl> Committed { transcript: &mut T, ) -> Result, Error> where - F: Hashable + SerdeObject, + F: Hashable, { let domain = &pk.vk.domain; let blinding_factors = pk.vk.cs.blinding_factors(); diff --git a/src/plonk/permutation/verifier.rs b/src/plonk/permutation/verifier.rs index 5afb03db3..3019d74df 100644 --- a/src/plonk/permutation/verifier.rs +++ b/src/plonk/permutation/verifier.rs @@ -1,5 +1,4 @@ use ff::{PrimeField, WithSmallOrderMulGroup}; -use halo2curves::serde::SerdeObject; use std::iter; use super::super::circuit::Any; @@ -41,7 +40,7 @@ impl Argument { transcript: &mut T, ) -> Result, Error> where - CS::Commitment: Hashable + SerdeObject, + CS::Commitment: Hashable, { let chunk_len = vk.cs_degree - 2; @@ -63,7 +62,7 @@ impl> VerifyingKey { transcript: &mut T, ) -> Result, Error> where - F: Hashable + SerdeObject, + F: Hashable, { let permutation_evals = self .commitments @@ -81,8 +80,8 @@ impl> Committed { transcript: &mut T, ) -> Result, Error> where - CS::Commitment: Hashable + SerdeObject, - F: Hashable + SerdeObject, + CS::Commitment: Hashable, + F: Hashable, { let mut sets = vec![]; diff --git a/src/plonk/prover.rs b/src/plonk/prover.rs index 5bc27d696..863c107ae 100644 --- a/src/plonk/prover.rs +++ b/src/plonk/prover.rs @@ -25,7 +25,6 @@ use crate::poly::batch_invert_rational; use crate::poly::commitment::PolynomialCommitmentScheme; use crate::transcript::{Hashable, Sampleable, Transcript}; use crate::utils::rational::Rational; -use halo2curves::serde::SerdeObject; /// This creates a proof for the provided `circuit` when given the public /// parameters `params` and the proving key [`ProvingKey`] that was @@ -45,11 +44,10 @@ pub fn create_proof< transcript: &mut T, ) -> Result<(), Error> where - CS::Commitment: Hashable + SerdeObject, + CS::Commitment: Hashable, F: WithSmallOrderMulGroup<3> + Sampleable + Hashable - + SerdeObject + Ord + FromUniformBytes<64>, { diff --git a/src/plonk/vanishing/prover.rs b/src/plonk/vanishing/prover.rs index 116149e0d..654215b5a 100644 --- a/src/plonk/vanishing/prover.rs +++ b/src/plonk/vanishing/prover.rs @@ -1,7 +1,6 @@ use std::{collections::HashMap, iter}; use ff::{PrimeField, WithSmallOrderMulGroup}; -use halo2curves::serde::SerdeObject; use rand_chacha::ChaCha20Rng; use rand_core::{RngCore, SeedableRng}; @@ -38,8 +37,8 @@ impl, CS: PolynomialCommitmentScheme> Argument Result, Error> where - CS::Commitment: Hashable + SerdeObject, - F: Hashable + SerdeObject, + CS::Commitment: Hashable, + F: Hashable, { // Sample a random polynomial of degree n - 1 let n = 1usize << domain.k() as usize; @@ -88,8 +87,8 @@ impl> Committed { transcript: &mut T, ) -> Result, Error> where - CS::Commitment: Hashable + SerdeObject, - F: Hashable + SerdeObject, + CS::Commitment: Hashable, + F: Hashable, { // Divide by t(X) = X^{params.n} - 1. let h_poly = domain.divide_by_vanishing_poly(h_poly); @@ -129,7 +128,7 @@ impl Constructed { transcript: &mut T, ) -> Result, Error> where - F: Hashable + SerdeObject, + F: Hashable, { self.h_pieces.iter().try_for_each(|p| { let eval = eval_polynomial(p, x); diff --git a/src/plonk/vanishing/verifier.rs b/src/plonk/vanishing/verifier.rs index 184ef0f1b..3904a4522 100644 --- a/src/plonk/vanishing/verifier.rs +++ b/src/plonk/vanishing/verifier.rs @@ -1,7 +1,6 @@ use std::iter; use ff::{PrimeField, WithSmallOrderMulGroup}; -use halo2curves::serde::SerdeObject; use crate::poly::commitment::PolynomialCommitmentScheme; use crate::transcript::{read_n, Hashable, Transcript}; @@ -33,7 +32,7 @@ impl> Argument { transcript: &mut T, ) -> Result, Error> where - CS::Commitment: Hashable + SerdeObject, + CS::Commitment: Hashable, { let random_poly_commitment = transcript.read()?; @@ -50,7 +49,7 @@ impl, CS: PolynomialCommitmentScheme> Committed< transcript: &mut T, ) -> Result, Error> where - CS::Commitment: Hashable + SerdeObject, + CS::Commitment: Hashable, { // Obtain a commitment to h(X) in the form of multiple pieces of degree n - 1 let h_commitments = read_n(transcript, vk.domain.get_quotient_poly_degree())?; @@ -69,7 +68,7 @@ impl, CS: PolynomialCommitmentScheme> Constructe transcript: &mut T, ) -> Result, Error> where - F: Hashable + SerdeObject, + F: Hashable, { let h_evals = read_n(transcript, vk.domain.get_quotient_poly_degree())?; let random_eval = transcript.read()?; diff --git a/src/plonk/verifier.rs b/src/plonk/verifier.rs index a13f92f75..e9018c4e3 100644 --- a/src/plonk/verifier.rs +++ b/src/plonk/verifier.rs @@ -1,5 +1,4 @@ use ff::{FromUniformBytes, WithSmallOrderMulGroup}; -use halo2curves::serde::SerdeObject; use std::iter; use super::{vanishing, Error, VerifyingKey}; @@ -18,10 +17,9 @@ where F: WithSmallOrderMulGroup<3> + Hashable + Sampleable - + SerdeObject + FromUniformBytes<64> + Ord, - CS::Commitment: Hashable + SerdeObject, + CS::Commitment: Hashable, { // Check that instances matches the expected number of instance columns for instances in instances.iter() { diff --git a/src/poly/kzg/mod.rs b/src/poly/kzg/mod.rs index d5cd94716..90013485b 100644 --- a/src/poly/kzg/mod.rs +++ b/src/poly/kzg/mod.rs @@ -32,11 +32,11 @@ use crate::utils::arithmetic::{truncate, truncated_powers}; use crate::poly::commitment::{Params, PolynomialCommitmentScheme}; use crate::poly::kzg::utils::construct_intermediate_sets; use crate::transcript::{Hashable, Sampleable, Transcript}; +use crate::utils::helpers::ProcessedSerdeObject; use ff::Field; use group::Group; use halo2curves::msm::msm_best; use halo2curves::pairing::MultiMillerLoop; -use halo2curves::serde::SerdeObject; use halo2curves::CurveAffine; use rand_core::OsRng; @@ -48,8 +48,7 @@ pub struct KZGCommitmentScheme { impl PolynomialCommitmentScheme for KZGCommitmentScheme where - E::Fr: SerdeObject, - E::G1Affine: Default + SerdeObject + CurveAffine, + E::G1Affine: Default + CurveAffine + ProcessedSerdeObject, { type Parameters = ParamsKZG; type VerifierParameters = ParamsVerifierKZG; @@ -351,7 +350,7 @@ mod tests { proof: &[u8], should_fail: bool, ) where - E::Fr: SerdeObject + Hashable + Sampleable + Ord, + E::Fr: Hashable + Sampleable + Ord, E::G1Affine: CurveAffine::Fr, CurveExt = ::G1> + SerdeObject + Hashable, @@ -397,10 +396,9 @@ mod tests { fn create_proof(kzg_params: &ParamsKZG) -> Vec where - E::Fr: - WithSmallOrderMulGroup<3> + SerdeObject + Hashable + Sampleable + Ord, - E::G1Affine: SerdeObject - + Hashable + E::Fr: WithSmallOrderMulGroup<3> + Hashable + Sampleable + Ord, + E::G1Affine: Hashable + + SerdeObject + Default + CurveAffine, { diff --git a/src/poly/kzg/msm.rs b/src/poly/kzg/msm.rs index fad76373e..3faf1f04d 100644 --- a/src/poly/kzg/msm.rs +++ b/src/poly/kzg/msm.rs @@ -6,10 +6,10 @@ use crate::poly::kzg::KZGCommitmentScheme; use crate::poly::Error; use crate::utils::arithmetic::parallelize; use crate::utils::arithmetic::MSM; +use crate::utils::helpers::ProcessedSerdeObject; use group::prime::PrimeCurveAffine; use group::{Curve, Group}; use halo2curves::msm::msm_best; -use halo2curves::serde::SerdeObject; use halo2curves::{ pairing::{Engine, MillerLoopResult, MultiMillerLoop}, CurveAffine, @@ -111,8 +111,7 @@ where impl Guard> for DualMSM where - E::Fr: SerdeObject, - E::G1Affine: Default + SerdeObject + CurveAffine, + E::G1Affine: Default + CurveAffine + ProcessedSerdeObject, { fn verify( self, diff --git a/src/transcript/implementors.rs b/src/transcript/implementors.rs index 9f403935b..6fc7bbd61 100644 --- a/src/transcript/implementors.rs +++ b/src/transcript/implementors.rs @@ -5,6 +5,8 @@ use blake2b_simd::{Params, State as Blake2bState}; use ff::{FromUniformBytes, PrimeField}; use group::GroupEncoding; use halo2curves::bn256::{Fr, G1Affine}; +use std::io; +use std::io::Read; impl TranscriptHash for Blake2bState { type Input = Vec; @@ -35,7 +37,21 @@ impl TranscriptHash for Blake2bState { impl Hashable for G1Affine { /// Converts it to compressed form in bytes fn to_input(&self) -> Vec { - self.to_bytes().as_ref().to_vec() + Hashable::to_bytes(self) + } + + fn to_bytes(&self) -> Vec { + ::to_bytes(self).as_ref().to_vec() + } + + fn read(buffer: &mut impl Read) -> io::Result { + let mut bytes = ::Repr::default(); + + buffer.read_exact(bytes.as_mut())?; + + Option::from(Self::from_bytes(&bytes)).ok_or_else(|| { + io::Error::new(io::ErrorKind::Other, "Invalid BN point encoding in proof") + }) } } @@ -43,6 +59,20 @@ impl Hashable for Fr { fn to_input(&self) -> Vec { self.to_bytes().to_vec() } + + fn to_bytes(&self) -> Vec { + self.to_bytes().to_vec() + } + + fn read(buffer: &mut impl Read) -> io::Result { + let mut bytes = ::Repr::default(); + + buffer.read_exact(bytes.as_mut())?; + + Option::from(Self::from_repr(bytes)).ok_or_else(|| { + io::Error::new(io::ErrorKind::Other, "Invalid BN scalar encoding in proof") + }) + } } impl Sampleable for Fr { @@ -61,7 +91,24 @@ impl Sampleable for Fr { impl Hashable for blstrs::G1Affine { /// Converts it to compressed form in bytes fn to_input(&self) -> Vec { - self.to_bytes().as_ref().to_vec() + Hashable::to_bytes(self) + } + + fn to_bytes(&self) -> Vec { + ::to_bytes(self).as_ref().to_vec() + } + + fn read(buffer: &mut impl Read) -> io::Result { + let mut bytes = ::Repr::default(); + + buffer.read_exact(bytes.as_mut())?; + + Option::from(Self::from_bytes(&bytes)).ok_or_else(|| { + io::Error::new( + io::ErrorKind::Other, + "Invalid BLS12-381 point encoding in proof", + ) + }) } } @@ -69,6 +116,23 @@ impl Hashable for blstrs::Scalar { fn to_input(&self) -> Vec { self.to_repr().to_vec() } + + fn to_bytes(&self) -> Vec { + self.to_repr().to_vec() + } + + fn read(buffer: &mut impl Read) -> io::Result { + let mut bytes = ::Repr::default(); + + buffer.read_exact(bytes.as_mut())?; + + Option::from(Self::from_repr(bytes)).ok_or_else(|| { + io::Error::new( + io::ErrorKind::Other, + "Invalid BLS12-381 scalar encoding in proof", + ) + }) + } } impl Sampleable for blstrs::Scalar { @@ -84,7 +148,24 @@ impl Sampleable for blstrs::Scalar { impl Hashable for halo2curves::bls12381::G1Affine { /// Converts it to compressed form in bytes fn to_input(&self) -> Vec { - self.to_bytes().as_ref().to_vec() + Hashable::to_bytes(self) + } + + fn to_bytes(&self) -> Vec { + ::to_bytes(self).as_ref().to_vec() + } + + fn read(buffer: &mut impl Read) -> io::Result { + let mut bytes = ::Repr::default(); + + buffer.read_exact(bytes.as_mut())?; + + Option::from(Self::from_bytes(&bytes)).ok_or_else(|| { + io::Error::new( + io::ErrorKind::Other, + "Invalid BLS12-381 point encoding in proof", + ) + }) } } @@ -92,6 +173,23 @@ impl Hashable for halo2curves::bls12381::Fr { fn to_input(&self) -> Vec { self.to_repr().as_ref().to_vec() } + + fn to_bytes(&self) -> Vec { + self.to_bytes().to_vec() + } + + fn read(buffer: &mut impl Read) -> io::Result { + let mut bytes = ::Repr::default(); + + buffer.read_exact(bytes.as_mut())?; + + Option::from(Self::from_repr(bytes)).ok_or_else(|| { + io::Error::new( + io::ErrorKind::Other, + "Invalid BLS12-381 scalar encoding in proof", + ) + }) + } } impl Sampleable for halo2curves::bls12381::Fr { diff --git a/src/transcript/mod.rs b/src/transcript/mod.rs index 005795694..acff17011 100644 --- a/src/transcript/mod.rs +++ b/src/transcript/mod.rs @@ -2,8 +2,7 @@ //! transcripts. mod implementors; -use halo2curves::serde::SerdeObject; -use std::io::{self, Cursor}; +use std::io::{self, Cursor, Read, Write}; /// Prefix to a prover's message soliciting a challenge const BLAKE2B_PREFIX_CHALLENGE: u8 = 0; @@ -27,9 +26,15 @@ pub trait TranscriptHash { } /// Traits to represent values that can be hashed with a `TranscriptHash` -pub trait Hashable { +pub trait Hashable: Sized { /// Converts the hashable type to a format that can be hashed with `H` fn to_input(&self) -> H::Input; + + /// Converts the hashable type to bytes to be added to the transcript. + fn to_bytes(&self) -> Vec; + + /// Reads bytes from a buffer and returns `Self`. + fn read(buffer: &mut impl Read) -> io::Result; } /// Trait to represent values that can be sampled from a `TranscriptHash` @@ -58,10 +63,10 @@ pub trait Transcript { fn common>(&mut self, input: &T) -> io::Result<()>; /// Read a hashable element `T` from the prover. - fn read + SerdeObject>(&mut self) -> io::Result; + fn read>(&mut self) -> io::Result; /// Write a hashable element `T` to the proof and the transcript. - fn write + SerdeObject>(&mut self, input: &T) -> io::Result<()>; + fn write>(&mut self, input: &T) -> io::Result<()>; /// Returns the buffer with the proof fn finalize(self) -> Vec; @@ -109,16 +114,17 @@ impl Transcript for CircuitTranscript { Ok(()) } - fn read + SerdeObject>(&mut self) -> io::Result { - let val = T::read_raw(&mut self.buffer)?; + fn read>(&mut self) -> io::Result { + let val = T::read(&mut self.buffer)?; self.common(&val)?; Ok(val) } - fn write + SerdeObject>(&mut self, input: &T) -> io::Result<()> { + fn write>(&mut self, input: &T) -> io::Result<()> { self.common(input)?; - input.write_raw(&mut self.buffer) + let bytes = input.to_bytes(); + self.buffer.write_all(&bytes) } fn finalize(self) -> Vec { @@ -129,7 +135,7 @@ impl Transcript for CircuitTranscript { pub(crate) fn read_n(transcript: &mut T, n: usize) -> io::Result> where T: Transcript, - C: Hashable + SerdeObject, + C: Hashable, { (0..n).map(|_| transcript.read()).collect() }