From 435602f33b6af86b9e96c6d186e3ded9a32b0796 Mon Sep 17 00:00:00 2001 From: Hossein Moghaddas Date: Wed, 10 Jan 2024 13:48:04 +0100 Subject: [PATCH 1/3] Use the sponge generic and rearrange `use`s --- poly-commit/src/hyrax/mod.rs | 46 +++++++++++++++--------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/poly-commit/src/hyrax/mod.rs b/poly-commit/src/hyrax/mod.rs index b1b92e13..1a4aabc0 100644 --- a/poly-commit/src/hyrax/mod.rs +++ b/poly-commit/src/hyrax/mod.rs @@ -1,11 +1,10 @@ -mod data_structures; -mod utils; -pub use data_structures::*; - -#[cfg(test)] -mod tests; - -use ark_crypto_primitives::sponge::poseidon::PoseidonSponge; +use crate::hyrax::utils::tensor_prime; +use crate::utils::{inner_product, scalar_by_vector, vector_sum, IOPTranscript, Matrix}; +use crate::{ + hyrax::utils::flat_to_matrix_column_major, Error, LabeledCommitment, LabeledPolynomial, + PolynomialCommitment, +}; +use ark_crypto_primitives::sponge::CryptographicSponge; use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM}; use ark_ff::PrimeField; use ark_poly::MultilinearExtension; @@ -17,14 +16,11 @@ use digest::Digest; #[cfg(feature = "parallel")] use rayon::prelude::*; -use crate::hyrax::utils::tensor_prime; -use crate::utils::{inner_product, scalar_by_vector, vector_sum, IOPTranscript, Matrix}; - -use crate::{ - hyrax::utils::flat_to_matrix_column_major, Error, - LabeledCommitment, LabeledPolynomial, PolynomialCommitment, -}; - +mod data_structures; +pub use data_structures::*; +#[cfg(test)] +mod tests; +mod utils; /// String of bytes used to seed the randomness during the setup function. /// Note that the latter should never be used in production environments. pub const PROTOCOL_NAME: &'static [u8] = b"Hyrax protocol"; @@ -116,13 +112,11 @@ impl> HyraxPC { } } -impl> - PolynomialCommitment< - G::ScalarField, - P, - // Dummy sponge - required by the trait, not used in this implementation - PoseidonSponge, - > for HyraxPC +impl PolynomialCommitment for HyraxPC +where + G: AffineRepr, + P: MultilinearExtension, + S: CryptographicSponge, { type UniversalParams = HyraxUniversalParams; type CommitterKey = HyraxCommitterKey; @@ -303,8 +297,7 @@ impl> labeled_polynomials: impl IntoIterator>, commitments: impl IntoIterator>, point: &'a P::Point, - // Not used and not generic on the cryptographic sponge S - _sponge: &mut PoseidonSponge, + _sponge: &mut S, states: impl IntoIterator, rng: Option<&mut dyn RngCore>, ) -> Result @@ -449,8 +442,7 @@ impl> point: &'a P::Point, _values: impl IntoIterator, proof: &Self::Proof, - // Not used and not generic on the cryptographic sponge S - _sponge: &mut PoseidonSponge, + _sponge: &mut S, _rng: Option<&mut dyn RngCore>, ) -> Result where From 32f520c9ac8f6c08b9f19e91465df216aef83ac5 Mon Sep 17 00:00:00 2001 From: Hossein Moghaddas Date: Wed, 10 Jan 2024 14:29:51 +0100 Subject: [PATCH 2/3] Use sponge instead of `IOPTransript` --- poly-commit/src/hyrax/mod.rs | 65 ++++++++++++++--------------- poly-commit/src/hyrax/tests.rs | 76 +++++++++++++++++----------------- poly-commit/src/utils.rs | 73 +++----------------------------- 3 files changed, 73 insertions(+), 141 deletions(-) diff --git a/poly-commit/src/hyrax/mod.rs b/poly-commit/src/hyrax/mod.rs index 1a4aabc0..d5536137 100644 --- a/poly-commit/src/hyrax/mod.rs +++ b/poly-commit/src/hyrax/mod.rs @@ -1,16 +1,16 @@ use crate::hyrax::utils::tensor_prime; -use crate::utils::{inner_product, scalar_by_vector, vector_sum, IOPTranscript, Matrix}; +use crate::to_bytes; +use crate::utils::{inner_product, scalar_by_vector, vector_sum, Matrix}; use crate::{ hyrax::utils::flat_to_matrix_column_major, Error, LabeledCommitment, LabeledPolynomial, PolynomialCommitment, }; -use ark_crypto_primitives::sponge::CryptographicSponge; +use ark_crypto_primitives::sponge::{Absorb, CryptographicSponge}; use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM}; use ark_ff::PrimeField; use ark_poly::MultilinearExtension; -use ark_std::{rand::RngCore, string::ToString, vec::Vec, UniformRand}; +use ark_std::{marker::PhantomData, rand::RngCore, string::ToString, vec::Vec, UniformRand}; use blake2::Blake2s256; -use core::marker::PhantomData; use digest::Digest; #[cfg(feature = "parallel")] @@ -66,11 +66,18 @@ pub struct HyraxPC< G: AffineRepr, // A polynomial type representing multilinear polynomials P: MultilinearExtension, + // The sponge used in the protocol as random oracle + S: CryptographicSponge, > { - _phantom: PhantomData<(G, P)>, + _phantom: PhantomData<(G, P, S)>, } -impl> HyraxPC { +impl HyraxPC +where + G: AffineRepr, + P: MultilinearExtension, + S: CryptographicSponge, +{ /// Pedersen commitment to a vector of scalars as described in appendix A.1 /// of the reference article. /// The caller must either directly pass hiding exponent `r` inside Some, @@ -112,9 +119,10 @@ impl> HyraxPC { } } -impl PolynomialCommitment for HyraxPC +impl PolynomialCommitment for HyraxPC where G: AffineRepr, + G::ScalarField: Absorb, P: MultilinearExtension, S: CryptographicSponge, { @@ -289,15 +297,12 @@ where /// polynomial. /// - The number of variables of a polynomial doesn't match that of the /// point. - /// - /// # Disregarded arguments - /// - `sponge` fn open<'a>( ck: &Self::CommitterKey, labeled_polynomials: impl IntoIterator>, commitments: impl IntoIterator>, point: &'a P::Point, - _sponge: &mut S, + sponge: &mut S, states: impl IntoIterator, rng: Option<&mut dyn RngCore>, ) -> Result @@ -354,17 +359,14 @@ where }); } - // Initialising the transcript - let mut transcript: IOPTranscript = IOPTranscript::new(b"transcript"); - // Absorbing public parameters - transcript.append_serializable_element(b"public parameters", ck)?; + sponge.absorb(&to_bytes!(ck).map_err(|_| Error::TranscriptError)?); // Absorbing the commitment to the polynomial - transcript.append_serializable_element(b"commitment", &com.row_coms)?; + sponge.absorb(&to_bytes!(&com.row_coms).map_err(|_| Error::TranscriptError)?); // Absorbing the point - transcript.append_serializable_element(b"point", point)?; + sponge.absorb(point); // Commiting to the matrix formed by the polynomial coefficients let t = &state.mat; @@ -398,15 +400,15 @@ where let (com_b, r_b) = Self::pedersen_commit(ck, &[b], None, Some(rng_inner)); // Absorbing the commitment to the evaluation - transcript.append_serializable_element(b"com_eval", &com_eval)?; + sponge.absorb(&to_bytes!(&com_eval).map_err(|_| Error::TranscriptError)?); // Absorbing the two auxiliary commitments - transcript.append_serializable_element(b"com_d", &com_d)?; - transcript.append_serializable_element(b"com_b", &com_b)?; + sponge.absorb(&to_bytes!(&com_d).map_err(|_| Error::TranscriptError)?); + sponge.absorb(&to_bytes!(&com_b).map_err(|_| Error::TranscriptError)?); // Receive the random challenge c from the verifier, i.e. squeeze // it from the transcript. - let c = transcript.get_and_append_challenge(b"c").unwrap(); + let c = sponge.squeeze_field_elements(1)[0]; let z = vector_sum(&d, &scalar_by_vector(c, <)); let z_d = c * r_lt + r_d; @@ -434,7 +436,6 @@ where /// point (specifically, commitment length should be 2^(point-length/2)). /// /// # Disregarded arguments - /// - `sponge` /// - `rng` fn check<'a>( vk: &Self::VerifierKey, @@ -442,7 +443,7 @@ where point: &'a P::Point, _values: impl IntoIterator, proof: &Self::Proof, - _sponge: &mut S, + sponge: &mut S, _rng: Option<&mut dyn RngCore>, ) -> Result where @@ -494,29 +495,25 @@ where .collect::>(); let t_prime: G = ::msm_bigint(row_coms, &l_bigint).into(); - // Construct transcript and squeeze the challenge c from it - - let mut transcript: IOPTranscript = IOPTranscript::new(b"transcript"); - // Absorbing public parameters - transcript.append_serializable_element(b"public parameters", vk)?; + sponge.absorb(&to_bytes!(vk).map_err(|_| Error::TranscriptError)?); // Absorbing the commitment to the polynomial - transcript.append_serializable_element(b"commitment", row_coms)?; + sponge.absorb(&to_bytes!(row_coms).map_err(|_| Error::TranscriptError)?); // Absorbing the point - transcript.append_serializable_element(b"point", point)?; + sponge.absorb(point); // Absorbing the commitment to the evaluation - transcript.append_serializable_element(b"com_eval", com_eval)?; + sponge.absorb(&to_bytes!(com_eval).map_err(|_| Error::TranscriptError)?); // Absorbing the two auxiliary commitments - transcript.append_serializable_element(b"com_d", com_d)?; - transcript.append_serializable_element(b"com_b", com_b)?; + sponge.absorb(&to_bytes!(com_d).map_err(|_| Error::TranscriptError)?); + sponge.absorb(&to_bytes!(com_b).map_err(|_| Error::TranscriptError)?); // Receive the random challenge c from the verifier, i.e. squeeze // it from the transcript. - let c = transcript.get_and_append_challenge(b"c").unwrap(); + let c: G::ScalarField = sponge.squeeze_field_elements(1)[0]; // First check let com_z_zd = Self::pedersen_commit(vk, z, Some(*z_d), None).0; diff --git a/poly-commit/src/hyrax/tests.rs b/poly-commit/src/hyrax/tests.rs index 499f8c81..713dd7f3 100644 --- a/poly-commit/src/hyrax/tests.rs +++ b/poly-commit/src/hyrax/tests.rs @@ -1,4 +1,9 @@ +use crate::hyrax::HyraxPC; +use crate::tests::*; +use crate::utils::test_sponge; +use crate::{LabeledPolynomial, PolynomialCommitment}; use ark_bls12_377::G1Affine; +use ark_crypto_primitives::sponge::poseidon::PoseidonSponge; use ark_ec::AffineRepr; use ark_ed_on_bls12_381::EdwardsAffine; use ark_ff::PrimeField; @@ -6,23 +11,16 @@ use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; use ark_std::test_rng; use rand_chacha::{rand_core::SeedableRng, ChaCha20Rng}; -use crate::hyrax::HyraxPC; - -use crate::utils::test_sponge; -use crate::{LabeledPolynomial, PolynomialCommitment}; - -use crate::tests::*; - // The test structure is largely taken from the multilinear_ligero module // inside this crate // ****************** types ****************** -type Fr = ::ScalarField; -type Hyrax381 = HyraxPC>; - type Fq = ::ScalarField; -type Hyrax377 = HyraxPC>; +type Hyrax377 = HyraxPC, PoseidonSponge>; + +type Fr = ::ScalarField; +type Hyrax381 = HyraxPC, PoseidonSponge>; // ******** auxiliary test functions ******** @@ -108,35 +106,35 @@ fn test_hyrax_construction() { #[test] fn hyrax_single_poly_test() { - single_poly_test::<_, _, Hyrax381, _>( + single_poly_test::<_, _, Hyrax377, _>( Some(10), - rand_poly::, - rand_point::, + rand_poly, + rand_point, poseidon_sponge_for_test, ) - .expect("test failed for bls12-381"); - single_poly_test::<_, _, Hyrax377, _>( + .expect("test failed for bls12-377"); + single_poly_test::<_, _, Hyrax381, _>( Some(10), - rand_poly::, - rand_point::, + rand_poly, + rand_point, poseidon_sponge_for_test, ) - .expect("test failed for bls12-377"); + .expect("test failed for bls12-381"); } #[test] fn hyrax_constant_poly_test() { single_poly_test::<_, _, Hyrax377, _>( Some(0), - constant_poly::, - rand_point::, + constant_poly, + rand_point, poseidon_sponge_for_test, ) .expect("test failed for bls12-377"); single_poly_test::<_, _, Hyrax381, _>( Some(0), - constant_poly::, - rand_point::, + constant_poly, + rand_point, poseidon_sponge_for_test, ) .expect("test failed for bls12-381"); @@ -146,15 +144,15 @@ fn hyrax_constant_poly_test() { fn hyrax_full_end_to_end_test() { full_end_to_end_test::<_, _, Hyrax377, _>( Some(8), - rand_poly::, - rand_point::, + rand_poly, + rand_point, poseidon_sponge_for_test, ) .expect("test failed for bls12-377"); full_end_to_end_test::<_, _, Hyrax381, _>( Some(10), - rand_poly::, - rand_point::, + rand_poly, + rand_point, poseidon_sponge_for_test, ) .expect("test failed for bls12-381"); @@ -164,15 +162,15 @@ fn hyrax_full_end_to_end_test() { fn hyrax_single_equation_test() { single_equation_test::<_, _, Hyrax377, _>( Some(6), - rand_poly::, - rand_point::, + rand_poly, + rand_point, poseidon_sponge_for_test, ) .expect("test failed for bls12-377"); single_equation_test::<_, _, Hyrax381, _>( Some(6), - rand_poly::, - rand_point::, + rand_poly, + rand_point, poseidon_sponge_for_test, ) .expect("test failed for bls12-381"); @@ -182,15 +180,15 @@ fn hyrax_single_equation_test() { fn hyrax_two_equation_test() { two_equation_test::<_, _, Hyrax377, _>( Some(10), - rand_poly::, - rand_point::, + rand_poly, + rand_point, poseidon_sponge_for_test, ) .expect("test failed for bls12-377"); two_equation_test::<_, _, Hyrax381, _>( Some(10), - rand_poly::, - rand_point::, + rand_poly, + rand_point, poseidon_sponge_for_test, ) .expect("test failed for bls12-381"); @@ -200,15 +198,15 @@ fn hyrax_two_equation_test() { fn hyrax_full_end_to_end_equation_test() { full_end_to_end_equation_test::<_, _, Hyrax377, _>( Some(8), - rand_poly::, - rand_point::, + rand_poly, + rand_point, poseidon_sponge_for_test, ) .expect("test failed for bls12-377"); full_end_to_end_equation_test::<_, _, Hyrax381, _>( Some(8), - rand_poly::, - rand_point::, + rand_poly, + rand_point, poseidon_sponge_for_test, ) .expect("test failed for bls12-381"); diff --git a/poly-commit/src/utils.rs b/poly-commit/src/utils.rs index 4a2ffeb4..f06ebf96 100644 --- a/poly-commit/src/utils.rs +++ b/poly-commit/src/utils.rs @@ -1,4 +1,6 @@ -use core::marker::PhantomData; +use ark_ff::Field; +use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; +use ark_std::vec::Vec; #[cfg(feature = "parallel")] use rayon::{ @@ -6,13 +8,6 @@ use rayon::{ prelude::IndexedParallelIterator, }; -use ark_ff::{Field, PrimeField}; -use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; -use ark_std::vec::Vec; -use merlin::Transcript; - -use crate::Error; - /// Takes as input a struct, and converts them to a series of bytes. All traits /// that implement `CanonicalSerialize` can be automatically converted to bytes /// in this manner. @@ -109,69 +104,11 @@ pub(crate) fn vector_sum(v1: &[F], v2: &[F]) -> Vec { .collect() } -/// The following struct is taken from jellyfish repository. Once they change -/// their dependency on `crypto-primitive`, we use their crate instead of -/// a copy-paste. We needed the newer `crypto-primitive` for serializing. -#[derive(Clone)] -pub(crate) struct IOPTranscript { - transcript: Transcript, - is_empty: bool, - #[doc(hidden)] - phantom: PhantomData, -} - -// TODO: merge this with jf_plonk::transcript -impl IOPTranscript { - /// Create a new IOP transcript. - pub(crate) fn new(label: &'static [u8]) -> Self { - Self { - transcript: Transcript::new(label), - is_empty: true, - phantom: PhantomData, - } - } - - /// Append the message to the transcript. - pub(crate) fn append_message(&mut self, label: &'static [u8], msg: &[u8]) -> Result<(), Error> { - self.transcript.append_message(label, msg); - self.is_empty = false; - Ok(()) - } - - /// Append the message to the transcript. - pub(crate) fn append_serializable_element( - &mut self, - label: &'static [u8], - group_elem: &S, - ) -> Result<(), Error> { - self.append_message( - label, - &to_bytes!(group_elem).map_err(|_| Error::TranscriptError)?, - ) - } - - /// Generate the challenge from the current transcript - /// and append it to the transcript. - /// - /// The output field element is statistical uniform as long - /// as the field has a size less than 2^384. - pub(crate) fn get_and_append_challenge(&mut self, label: &'static [u8]) -> Result { - // we need to reject when transcript is empty - if self.is_empty { - return Err(Error::TranscriptError); - } - - let mut buf = [0u8; 64]; - self.transcript.challenge_bytes(label, &mut buf); - let challenge = F::from_le_bytes_mod_order(&buf); - self.append_serializable_element(label, &challenge)?; - Ok(challenge) - } -} - // TODO: replace by https://github.com/arkworks-rs/crypto-primitives/issues/112. #[cfg(test)] use ark_crypto_primitives::sponge::poseidon::PoseidonSponge; +#[cfg(test)] +use ark_ff::PrimeField; #[cfg(test)] pub(crate) fn test_sponge() -> PoseidonSponge { From 3e19f3f82dc2d2afa9f73b200eb086e51372d093 Mon Sep 17 00:00:00 2001 From: Hossein Moghaddas Date: Wed, 10 Jan 2024 14:45:51 +0100 Subject: [PATCH 3/3] Fix benches --- poly-commit/benches/hyrax_times.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/poly-commit/benches/hyrax_times.rs b/poly-commit/benches/hyrax_times.rs index 7f579cab..c76753df 100644 --- a/poly-commit/benches/hyrax_times.rs +++ b/poly-commit/benches/hyrax_times.rs @@ -1,3 +1,4 @@ +use ark_crypto_primitives::sponge::poseidon::PoseidonSponge; use ark_pcs_bench_templates::*; use ark_poly::{DenseMultilinearExtension, MultilinearExtension}; @@ -8,7 +9,7 @@ use ark_poly_commit::hyrax::HyraxPC; use rand_chacha::ChaCha20Rng; // Hyrax PCS over BN254 -type Hyrax254 = HyraxPC>; +type Hyrax254 = HyraxPC, PoseidonSponge>; fn rand_poly_hyrax( num_vars: usize,