From f33232df434dc889b059e3ab75b87307c47718c2 Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Wed, 23 Mar 2022 16:22:22 +0100 Subject: [PATCH] Use `CryptographicSponge` as generic argument Resolves #87 --- Cargo.toml | 35 +++--- src/constraints/ahp.rs | 18 +-- src/constraints/data_structures.rs | 116 +++++++++++--------- src/constraints/snark.rs | 102 ++++++++++------- src/constraints/verifier.rs | 41 +++---- src/constraints/verifier_test.rs | 8 +- src/data_structures.rs | 81 +++++++++----- src/fiat_shamir/mod.rs | 1 + src/fiat_shamir/poseidon/mod.rs | 27 +++++ src/lib.rs | 170 ++++++++++++----------------- src/test.rs | 20 +++- 11 files changed, 349 insertions(+), 270 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5b86e90..f0e06d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,34 +20,35 @@ license = "MIT/Apache-2.0" edition = "2018" [dependencies] -ark-serialize = { version = "^0.2.0", default-features = false, features = [ "derive" ] } -ark-ff = { version = "^0.2.0", default-features = false } -ark-std = { version = "^0.2.0", default-features = false } -ark-poly = { version = "^0.2.0", default-features = false } -ark-relations = { version = "^0.2.0", default-features = false } +ark-serialize = { version = "0.3", default-features = false, features = [ "derive" ] } +ark-ff = { version = "0.3", default-features = false } +ark-std = { version = "0.3", default-features = false } +ark-poly = { version = "0.3", default-features = false } +ark-relations = { version = "0.3", default-features = false } ark-poly-commit = { git = "https://github.com/arkworks-rs/poly-commit", branch = "constraints", default-features = false, features = [ "r1cs" ] } +ark-sponge = { version = "0.3", default-features = false } -rand_chacha = { version = "0.2.1", default-features = false } +rand_chacha = { version = "0.3", default-features = false } rayon = { version = "1", optional = true } digest = { version = "0.9" } derivative = { version = "2", features = ["use_core"] } -ark-ec = { version = "^0.2.0", default-features = false } -ark-crypto-primitives = { version = "^0.2.0", default-features = false, features = [ "r1cs" ] } -ark-r1cs-std = { version = "^0.2.0", default-features = false } -ark-nonnative-field = { version = "^0.2.0", default-features = false } -ark-snark = { version = "^0.2.0", default-features = false } +ark-ec = { version = "0.3", default-features = false } +ark-crypto-primitives = { version = "0.3", default-features = false, features = [ "r1cs" ] } +ark-r1cs-std = { version = "0.3", default-features = false } +ark-nonnative-field = { version = "0.3", default-features = false } +ark-snark = { version = "0.3", default-features = false } hashbrown = "0.9" tracing = { version = "0.1", default-features = false, features = [ "attributes" ] } tracing-subscriber = { version = "0.2", default-features = false, optional = true } [dev-dependencies] blake2 = { version = "0.9", default-features = false } -ark-bls12-381 = { version = "^0.2.0", default-features = false, features = [ "curve" ] } -ark-mnt4-298 = { version = "^0.2.0", default-features = false, features = ["r1cs", "curve"] } -ark-mnt6-298 = { version = "^0.2.0", default-features = false, features = ["r1cs"] } -ark-mnt4-753 = { version = "^0.2.0", default-features = false, features = ["r1cs", "curve"] } -ark-mnt6-753 = { version = "^0.2.0", default-features = false, features = ["r1cs"] } +ark-bls12-381 = { version = "0.3", default-features = false, features = [ "curve" ] } +ark-mnt4-298 = { version = "0.3", default-features = false, features = ["r1cs", "curve"] } +ark-mnt6-298 = { version = "0.3", default-features = false, features = ["r1cs"] } +ark-mnt4-753 = { version = "0.3", default-features = false, features = ["r1cs", "curve"] } +ark-mnt6-753 = { version = "0.3", default-features = false, features = ["r1cs"] } [profile.release] opt-level = 3 @@ -76,4 +77,4 @@ parallel = [ "std", "ark-ff/parallel", "ark-poly/parallel", "ark-std/parallel", name = "marlin-benches" path = "benches/bench.rs" harness = false -required-features = ["std"] \ No newline at end of file +required-features = ["std"] diff --git a/src/constraints/ahp.rs b/src/constraints/ahp.rs index 7d315ba..f22c698 100644 --- a/src/constraints/ahp.rs +++ b/src/constraints/ahp.rs @@ -23,6 +23,7 @@ use ark_r1cs_std::{ ToBitsGadget, ToConstraintFieldGadget, }; use ark_relations::r1cs::ConstraintSystemRef; +use ark_sponge::CryptographicSponge; use hashbrown::{HashMap, HashSet}; #[derive(Clone)] @@ -57,14 +58,16 @@ pub struct VerifierThirdMsgVar { pub struct AHPForR1CS< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, > where PCG::VerifierKeyVar: ToConstraintFieldGadget, PCG::CommitmentVar: ToConstraintFieldGadget, { field: PhantomData, constraint_field: PhantomData, + sponge: PhantomData, polynomial_commitment: PhantomData, pc_check: PhantomData, } @@ -72,9 +75,10 @@ pub struct AHPForR1CS< impl< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, - > AHPForR1CS + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, + > AHPForR1CS where PCG::VerifierKeyVar: ToConstraintFieldGadget, PCG::CommitmentVar: ToConstraintFieldGadget, @@ -529,8 +533,8 @@ where PR: FiatShamirRng, R: FiatShamirRngVar, >( - index_pvk: &PreparedIndexVerifierKeyVar, - proof: &ProofVar, + index_pvk: &PreparedIndexVerifierKeyVar, + proof: &ProofVar, state: &VerifierStateVar, ) -> Result< ( diff --git a/src/constraints/data_structures.rs b/src/constraints/data_structures.rs index ef7d3ec..881bf4a 100644 --- a/src/constraints/data_structures.rs +++ b/src/constraints/data_structures.rs @@ -17,16 +17,19 @@ use ark_r1cs_std::{ R1CSVar, ToBytesGadget, ToConstraintFieldGadget, }; use ark_relations::r1cs::{ConstraintSystemRef, Namespace}; +use ark_sponge::CryptographicSponge; use ark_std::borrow::Borrow; use hashbrown::HashMap; -pub type UniversalSRS = >>::UniversalParams; +pub type UniversalSRS = + , S>>::UniversalParams; pub struct IndexVerifierKeyVar< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, > { pub cs: ConstraintSystemRef, pub domain_h_size: u64, @@ -40,9 +43,10 @@ pub struct IndexVerifierKeyVar< impl< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, - > IndexVerifierKeyVar + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, + > IndexVerifierKeyVar { fn cs(&self) -> ConstraintSystemRef { self.cs.clone() @@ -52,9 +56,10 @@ impl< impl< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, - > AllocVar, CF> for IndexVerifierKeyVar + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, + > AllocVar, CF> for IndexVerifierKeyVar { #[tracing::instrument(target = "r1cs", skip(cs, f))] fn new_variable( @@ -63,7 +68,7 @@ impl< mode: AllocationMode, ) -> Result where - T: Borrow>, + T: Borrow>, { let t = f()?; let ivk = t.borrow(); @@ -117,9 +122,10 @@ impl< impl< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, - > ToBytesGadget for IndexVerifierKeyVar + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, + > ToBytesGadget for IndexVerifierKeyVar { #[tracing::instrument(target = "r1cs", skip(self))] fn to_bytes(&self) -> Result>, SynthesisError> { @@ -140,9 +146,10 @@ impl< impl< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, - > Clone for IndexVerifierKeyVar + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, + > Clone for IndexVerifierKeyVar { fn clone(&self) -> Self { Self { @@ -160,9 +167,10 @@ impl< impl< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, - > IndexVerifierKeyVar + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, + > IndexVerifierKeyVar { pub fn iter(&self) -> impl Iterator { self.index_comms.iter() @@ -172,8 +180,9 @@ impl< pub struct PreparedIndexVerifierKeyVar< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, PR: FiatShamirRng, R: FiatShamirRngVar, > { @@ -192,11 +201,12 @@ pub struct PreparedIndexVerifierKeyVar< impl< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, PR: FiatShamirRng, R: FiatShamirRngVar, - > Clone for PreparedIndexVerifierKeyVar + > Clone for PreparedIndexVerifierKeyVar { fn clone(&self) -> Self { PreparedIndexVerifierKeyVar { @@ -213,24 +223,26 @@ impl< } } -impl PreparedIndexVerifierKeyVar +impl PreparedIndexVerifierKeyVar where F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, PR: FiatShamirRng, R: FiatShamirRngVar, PCG::VerifierKeyVar: ToConstraintFieldGadget, PCG::CommitmentVar: ToConstraintFieldGadget, { #[tracing::instrument(target = "r1cs", skip(vk))] - pub fn prepare(vk: &IndexVerifierKeyVar) -> Result { + pub fn prepare(vk: &IndexVerifierKeyVar) -> Result { let cs = vk.cs(); let mut fs_rng_raw = PR::new(); - fs_rng_raw - .absorb_bytes(&to_bytes![&MarlinVerifierVar::::PROTOCOL_NAME].unwrap()); + fs_rng_raw.absorb_bytes( + &to_bytes![&MarlinVerifierVar::::PROTOCOL_NAME].unwrap(), + ); let index_vk_hash = { let mut vk_hash_rng = PR::new(); @@ -280,13 +292,14 @@ where } } -impl AllocVar, CF> - for PreparedIndexVerifierKeyVar +impl AllocVar, CF> + for PreparedIndexVerifierKeyVar where F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, PR: FiatShamirRng, R: FiatShamirRngVar, PC::VerifierKey: ToConstraintField, @@ -301,7 +314,7 @@ where mode: AllocationMode, ) -> Result where - T: Borrow>, + T: Borrow>, { let t = f()?; let obj = t.borrow(); @@ -342,8 +355,9 @@ where }; let mut fs_rng_raw = PR::new(); - fs_rng_raw - .absorb_bytes(&to_bytes![&MarlinVerifierVar::::PROTOCOL_NAME].unwrap()); + fs_rng_raw.absorb_bytes( + &to_bytes![&MarlinVerifierVar::::PROTOCOL_NAME].unwrap(), + ); let fs_rng = { let mut fs_rng = R::constant(cs.clone(), &fs_rng_raw); @@ -379,8 +393,9 @@ where pub struct ProofVar< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, > { pub cs: ConstraintSystemRef, pub commitments: Vec>, @@ -392,9 +407,10 @@ pub struct ProofVar< impl< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, - > ProofVar + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, + > ProofVar { pub fn new( cs: ConstraintSystemRef, @@ -413,12 +429,13 @@ impl< } } -impl AllocVar, CF> for ProofVar +impl AllocVar, CF> for ProofVar where F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, + S: CryptographicSponge, + PC: PolynomialCommitment, S, BatchProof = DensePolynomial>, + PCG: PCCheckVar, PC, CF, S>, PC::VerifierKey: ToConstraintField, PC::Commitment: ToConstraintField, PCG::VerifierKeyVar: ToConstraintFieldGadget, @@ -431,7 +448,7 @@ where mode: AllocationMode, ) -> Result where - T: Borrow>, + T: Borrow>, { let ns = cs.into(); let cs = ns.cs(); @@ -534,9 +551,10 @@ where impl< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, - > Clone for ProofVar + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, + > Clone for ProofVar { fn clone(&self) -> Self { ProofVar { diff --git a/src/constraints/snark.rs b/src/constraints/snark.rs index 4e9a428..2d8aa68 100644 --- a/src/constraints/snark.rs +++ b/src/constraints/snark.rs @@ -2,7 +2,7 @@ use crate::constraints::{ data_structures::{IndexVerifierKeyVar, PreparedIndexVerifierKeyVar, ProofVar}, verifier::Marlin as MarlinVerifierGadget, }; -use crate::fiat_shamir::{constraints::FiatShamirRngVar, FiatShamirRng}; +use crate::fiat_shamir::{constraints::FiatShamirRngVar, AlgebraicSponge, FiatShamirRng}; use crate::Error::IndexTooLarge; use crate::{ Box, IndexProverKey, IndexVerifierKey, Marlin, MarlinConfig, PreparedIndexVerifierKey, Proof, @@ -21,6 +21,7 @@ use ark_relations::r1cs::{ ConstraintSynthesizer, ConstraintSystemRef, LinearCombination, SynthesisError, Variable, }; use ark_snark::UniversalSetupSNARK; +use ark_sponge::CryptographicSponge; use ark_std::cmp::min; use ark_std::fmt::{Debug, Formatter}; use ark_std::marker::PhantomData; @@ -49,38 +50,41 @@ impl Debug for MarlinBound { pub struct MarlinSNARK< F: PrimeField, FSF: PrimeField, - PC: PolynomialCommitment>, + S: CryptographicSponge + AlgebraicSponge, + PC: PolynomialCommitment, S>, FS: FiatShamirRng, MC: MarlinConfig, > { f_phantom: PhantomData, fsf_phantom: PhantomData, + s_phantom: PhantomData, pc_phantom: PhantomData, fs_phantom: PhantomData, mc_phantom: PhantomData, } -impl SNARK for MarlinSNARK +impl SNARK for MarlinSNARK where F: PrimeField, FSF: PrimeField, - PC: PolynomialCommitment>, + S: CryptographicSponge + AlgebraicSponge, + PC: PolynomialCommitment, S, BatchProof = DensePolynomial>, FS: FiatShamirRng, MC: MarlinConfig, PC::VerifierKey: ToConstraintField, PC::Commitment: ToConstraintField, { - type ProvingKey = IndexProverKey; - type VerifyingKey = IndexVerifierKey; - type ProcessedVerifyingKey = PreparedIndexVerifierKey; - type Proof = Proof; + type ProvingKey = IndexProverKey; + type VerifyingKey = IndexVerifierKey; + type ProcessedVerifyingKey = PreparedIndexVerifierKey; + type Proof = Proof; type Error = Box; fn circuit_specific_setup, R: RngCore + CryptoRng>( circuit: C, rng: &mut R, ) -> Result<(Self::ProvingKey, Self::VerifyingKey), Self::Error> { - Ok(Marlin::::circuit_specific_setup(circuit, rng).unwrap()) + Ok(Marlin::::circuit_specific_setup(circuit, rng).unwrap()) } fn prove, R: RngCore>( @@ -88,14 +92,14 @@ where circuit: C, rng: &mut R, ) -> Result { - match Marlin::::prove(&pk, circuit, rng) { + match Marlin::::prove(&pk, circuit, rng) { Ok(res) => Ok(res), Err(e) => Err(Box::new(MarlinError::from(e))), } } fn verify(vk: &Self::VerifyingKey, x: &[F], proof: &Self::Proof) -> Result { - match Marlin::::verify(vk, x, proof) { + match Marlin::::verify(vk, x, proof) { Ok(res) => Ok(res), Err(e) => Err(Box::new(MarlinError::from(e))), } @@ -111,25 +115,26 @@ where x: &[F], proof: &Self::Proof, ) -> Result { - match Marlin::::prepared_verify(pvk, x, proof) { + match Marlin::::prepared_verify(pvk, x, proof) { Ok(res) => Ok(res), Err(e) => Err(Box::new(MarlinError::from(e))), } } } -impl UniversalSetupSNARK for MarlinSNARK +impl UniversalSetupSNARK for MarlinSNARK where F: PrimeField, FSF: PrimeField, - PC: PolynomialCommitment>, + S: CryptographicSponge + AlgebraicSponge, + PC: PolynomialCommitment, S, BatchProof = DensePolynomial>, FS: FiatShamirRng, MC: MarlinConfig, PC::VerifierKey: ToConstraintField, PC::Commitment: ToConstraintField, { type ComputationBound = MarlinBound; - type PublicParameters = (MarlinBound, UniversalSRS); + type PublicParameters = (MarlinBound, UniversalSRS); fn universal_setup( bound: &Self::ComputationBound, @@ -137,7 +142,7 @@ where ) -> Result { let Self::ComputationBound { max_degree } = bound; - match Marlin::::universal_setup(1, 1, (max_degree + 5) / 3, rng) { + match Marlin::::universal_setup(1, 1, (max_degree + 5) / 3, rng) { Ok(res) => Ok((bound.clone(), res)), Err(e) => Err(Box::new(MarlinError::from(e))), } @@ -152,7 +157,7 @@ where (Self::ProvingKey, Self::VerifyingKey), UniversalSetupIndexError, > { - let index_res = Marlin::::index(&crs.1, circuit); + let index_res = Marlin::::index(&crs.1, circuit); match index_res { Ok(res) => Ok(res), Err(err) => match err { @@ -167,18 +172,20 @@ where } } -pub struct MarlinSNARKGadget +pub struct MarlinSNARKGadget where F: PrimeField, FSF: PrimeField, - PC: PolynomialCommitment>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, FS: FiatShamirRng, MC: MarlinConfig, - PCG: PCCheckVar, PC, FSF>, + PCG: PCCheckVar, PC, FSF, S>, FSG: FiatShamirRngVar, { pub f_phantom: PhantomData, pub fsf_phantom: PhantomData, + pub s_phantom: PhantomData, pub pc_phantom: PhantomData, pub fs_phantom: PhantomData, pub mc_phantom: PhantomData, @@ -186,30 +193,31 @@ where pub fsg_phantom: PhantomData, } -impl SNARKGadget> - for MarlinSNARKGadget +impl SNARKGadget> + for MarlinSNARKGadget where F: PrimeField, FSF: PrimeField, - PC: PolynomialCommitment>, + S: CryptographicSponge + AlgebraicSponge, + PC: PolynomialCommitment, S, BatchProof = DensePolynomial>, FS: FiatShamirRng, MC: MarlinConfig, - PCG: PCCheckVar, PC, FSF>, + PCG: PCCheckVar, PC, FSF, S>, FSG: FiatShamirRngVar, PC::VerifierKey: ToConstraintField, PC::Commitment: ToConstraintField, PCG::VerifierKeyVar: ToConstraintFieldGadget, PCG::CommitmentVar: ToConstraintFieldGadget, { - type ProcessedVerifyingKeyVar = PreparedIndexVerifierKeyVar; - type VerifyingKeyVar = IndexVerifierKeyVar; + type ProcessedVerifyingKeyVar = PreparedIndexVerifierKeyVar; + type VerifyingKeyVar = IndexVerifierKeyVar; type InputVar = NonNativeFieldInputVar; - type ProofVar = ProofVar; + type ProofVar = ProofVar; type VerifierSize = usize; fn verifier_size( - circuit_vk: & as SNARK>::VerifyingKey, + circuit_vk: & as SNARK>::VerifyingKey, ) -> Self::VerifierSize { circuit_vk.index_info.num_instance_variables } @@ -221,8 +229,12 @@ where proof: &Self::ProofVar, ) -> Result, SynthesisError> { Ok( - MarlinVerifierGadget::::prepared_verify(&circuit_pvk, &x.val, proof) - .unwrap(), + MarlinVerifierGadget::::prepared_verify( + &circuit_pvk, + &x.val, + proof, + ) + .unwrap(), ) } @@ -233,8 +245,10 @@ where proof: &Self::ProofVar, ) -> Result, SynthesisError> { Ok( - MarlinVerifierGadget::::verify::(circuit_vk, &x.val, proof) - .unwrap(), + MarlinVerifierGadget::::verify::( + circuit_vk, &x.val, proof, + ) + .unwrap(), ) } } @@ -297,16 +311,17 @@ impl ConstraintSynthesizer for MarlinBoundCircuit { } } -impl - UniversalSetupSNARKGadget> - for MarlinSNARKGadget +impl + UniversalSetupSNARKGadget> + for MarlinSNARKGadget where F: PrimeField, FSF: PrimeField, - PC: PolynomialCommitment>, + S: CryptographicSponge + AlgebraicSponge, + PC: PolynomialCommitment, S, BatchProof = DensePolynomial>, FS: FiatShamirRng, MC: MarlinConfig, - PCG: PCCheckVar, PC, FSF>, + PCG: PCCheckVar, PC, FSF, S>, FSG: FiatShamirRngVar, PC::VerifierKey: ToConstraintField, PC::Commitment: ToConstraintField, @@ -449,12 +464,18 @@ mod test { type TestSNARK = MarlinSNARK< MNT4Fr, MNT4Fq, - MarlinKZG10>, + PoseidonSponge, + MarlinKZG10, PoseidonSponge>, FS4, TestMarlinConfig, >; type FS4 = FiatShamirAlgebraicSpongeRng>; - type PCGadget4 = MarlinKZG10Gadget, MNT4PairingVar>; + type PCGadget4 = MarlinKZG10Gadget< + Mnt64298cycle, + DensePolynomial, + MNT4PairingVar, + PoseidonSponge, + >; type FSG4 = FiatShamirAlgebraicSpongeRngVar< MNT4Fr, MNT4Fq, @@ -464,7 +485,8 @@ mod test { type TestSNARKGadget = MarlinSNARKGadget< MNT4Fr, MNT4Fq, - MarlinKZG10>, + PoseidonSponge, + MarlinKZG10, PoseidonSponge>, FS4, TestMarlinConfig, PCGadget4, diff --git a/src/constraints/verifier.rs b/src/constraints/verifier.rs index 4a50414..80d8c47 100644 --- a/src/constraints/verifier.rs +++ b/src/constraints/verifier.rs @@ -1,8 +1,6 @@ use crate::{ - constraints::{ - ahp::AHPForR1CS, - data_structures::{IndexVerifierKeyVar, PreparedIndexVerifierKeyVar, ProofVar}, - }, + constraints::ahp::AHPForR1CS, + constraints::data_structures::{IndexVerifierKeyVar, PreparedIndexVerifierKeyVar, ProofVar}, fiat_shamir::{constraints::FiatShamirRngVar, FiatShamirRng}, Error, PhantomData, PrimeField, String, Vec, }; @@ -12,25 +10,29 @@ use ark_poly::univariate::DensePolynomial; use ark_poly_commit::{PCCheckRandomDataVar, PCCheckVar, PolynomialCommitment}; use ark_r1cs_std::{bits::boolean::Boolean, fields::FieldVar, R1CSVar, ToConstraintFieldGadget}; use ark_relations::ns; +use ark_sponge::CryptographicSponge; pub struct Marlin< F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, >( PhantomData, PhantomData, + PhantomData, PhantomData, PhantomData, ); -impl Marlin +impl Marlin where F: PrimeField, CF: PrimeField, - PC: PolynomialCommitment>, - PCG: PCCheckVar, PC, CF>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, + PCG: PCCheckVar, PC, CF, S>, PCG::VerifierKeyVar: ToConstraintFieldGadget, PCG::CommitmentVar: ToConstraintFieldGadget, { @@ -39,9 +41,9 @@ where /// verify with an established hashchain initial state #[tracing::instrument(target = "r1cs", skip(index_pvk, proof))] pub fn prepared_verify, R: FiatShamirRngVar>( - index_pvk: &PreparedIndexVerifierKeyVar, + index_pvk: &PreparedIndexVerifierKeyVar, public_input: &[NonNativeFieldVar], - proof: &ProofVar, + proof: &ProofVar, ) -> Result, Error> { let cs = index_pvk .cs @@ -55,7 +57,7 @@ where fs_rng.absorb_nonnative_field_elements(&public_input, OptimizationType::Weight)?; - let (_, verifier_state) = AHPForR1CS::::verifier_first_round( + let (_, verifier_state) = AHPForR1CS::::verifier_first_round( index_pvk.domain_h_size, index_pvk.domain_k_size, &mut fs_rng, @@ -63,14 +65,14 @@ where &proof.prover_messages[0].field_elements, )?; - let (_, verifier_state) = AHPForR1CS::::verifier_second_round( + let (_, verifier_state) = AHPForR1CS::::verifier_second_round( verifier_state, &mut fs_rng, &proof.commitments[1], &proof.prover_messages[1].field_elements, )?; - let verifier_state = AHPForR1CS::::verifier_third_round( + let verifier_state = AHPForR1CS::::verifier_third_round( verifier_state, &mut fs_rng, &proof.commitments[2], @@ -82,7 +84,7 @@ where formatted_public_input.push(elem); } - let lc = AHPForR1CS::::verifier_decision( + let lc = AHPForR1CS::::verifier_decision( ns!(cs, "ahp").cs(), &formatted_public_input, &proof.evaluations, @@ -91,7 +93,7 @@ where )?; let (num_opening_challenges, num_batching_rands, comm, query_set, evaluations) = - AHPForR1CS::::verifier_comm_query_eval_set( + AHPForR1CS::::verifier_comm_query_eval_set( &index_pvk, &proof, &verifier_state, @@ -140,11 +142,12 @@ where #[tracing::instrument(target = "r1cs", skip(index_vk, proof))] pub fn verify, R: FiatShamirRngVar>( - index_vk: &IndexVerifierKeyVar, + index_vk: &IndexVerifierKeyVar, public_input: &[NonNativeFieldVar], - proof: &ProofVar, + proof: &ProofVar, ) -> Result, Error> { - let index_pvk = PreparedIndexVerifierKeyVar::::prepare(&index_vk)?; + let index_pvk = + PreparedIndexVerifierKeyVar::::prepare(&index_vk)?; Self::prepared_verify(&index_pvk, public_input, proof) } } diff --git a/src/constraints/verifier_test.rs b/src/constraints/verifier_test.rs index 6589042..461f493 100644 --- a/src/constraints/verifier_test.rs +++ b/src/constraints/verifier_test.rs @@ -42,10 +42,12 @@ mod tests { } type FS = FiatShamirAlgebraicSpongeRng>; - type MultiPC = MarlinKZG10>; - type MarlinNativeInst = MarlinNative; + type MultiPC = MarlinKZG10, PoseidonSponge>; + type MarlinNativeInst = + MarlinNative, MultiPC, FS, MarlinRecursiveConfig>; - type MultiPCVar = MarlinKZG10Gadget, MNT4PairingVar>; + type MultiPCVar = + MarlinKZG10Gadget, MNT4PairingVar, PoseidonSponge>; #[derive(Copy, Clone)] struct Circuit { diff --git a/src/data_structures.rs b/src/data_structures.rs index eded1b5..99b1ca4 100644 --- a/src/data_structures.rs +++ b/src/data_structures.rs @@ -10,6 +10,7 @@ use ark_poly_commit::{ }; use ark_relations::r1cs::SynthesisError; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError}; +use ark_sponge::CryptographicSponge; use ark_std::{ format, io::{Read, Write}, @@ -20,7 +21,8 @@ use ark_std::{ /* ************************************************************************* */ /// The universal public parameters for the argument system. -pub type UniversalSRS = >>::UniversalParams; +pub type UniversalSRS = + , S>>::UniversalParams; /* ************************************************************************* */ /* ************************************************************************* */ @@ -28,7 +30,11 @@ pub type UniversalSRS = /// Verification key for a specific index (i.e., R1CS matrices). #[derive(CanonicalSerialize, CanonicalDeserialize)] -pub struct IndexVerifierKey>> { +pub struct IndexVerifierKey< + F: PrimeField, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, +> { /// Stores information about the size of the index, as well as its field of /// definition. pub index_info: IndexInfo, @@ -38,8 +44,8 @@ pub struct IndexVerifierKey>> ark_ff::ToBytes - for IndexVerifierKey +impl, S>> + ark_ff::ToBytes for IndexVerifierKey { fn write(&self, mut w: W) -> ark_std::io::Result<()> { self.index_info.write(&mut w)?; @@ -47,8 +53,8 @@ impl>> ark_ff::ToB } } -impl>> Clone - for IndexVerifierKey +impl, S>> + Clone for IndexVerifierKey { fn clone(&self) -> Self { Self { @@ -59,7 +65,9 @@ impl>> Clone } } -impl>> IndexVerifierKey { +impl, S>> + IndexVerifierKey +{ /// Iterate over the commitments to indexed polynomials in `self`. pub fn iter(&self) -> impl Iterator { self.index_comms.iter() @@ -71,8 +79,11 @@ impl>> IndexVerifi /* ************************************************************************* */ /// Verification key, prepared (preprocessed) for use in pairings. -pub struct PreparedIndexVerifierKey>> -{ +pub struct PreparedIndexVerifierKey< + F: PrimeField, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, +> { /// Size of the variable domain. pub domain_h_size: u64, /// Size of the matrix domain. @@ -84,13 +95,14 @@ pub struct PreparedIndexVerifierKey, + pub orig_vk: IndexVerifierKey, } -impl Clone for PreparedIndexVerifierKey +impl Clone for PreparedIndexVerifierKey where F: PrimeField, - PC: PolynomialCommitment>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, { fn clone(&self) -> Self { PreparedIndexVerifierKey { @@ -103,12 +115,13 @@ where } } -impl PreparedIndexVerifierKey +impl PreparedIndexVerifierKey where F: PrimeField, - PC: PolynomialCommitment>, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, { - pub fn prepare(vk: &IndexVerifierKey) -> Self { + pub fn prepare(vk: &IndexVerifierKey) -> Self { let mut prepared_index_comms = Vec::::new(); for (_, comm) in vk.index_comms.iter().enumerate() { prepared_index_comms.push(PC::PreparedCommitment::prepare(comm)); @@ -142,9 +155,13 @@ where /// Proving key for a specific index (i.e., R1CS matrices). #[derive(CanonicalSerialize, CanonicalDeserialize)] -pub struct IndexProverKey>> { +pub struct IndexProverKey< + F: PrimeField, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, +> { /// The index verifier key. - pub index_vk: IndexVerifierKey, + pub index_vk: IndexVerifierKey, /// The randomness for the index polynomial commitments. pub index_comm_rands: Vec, /// The index itself. @@ -153,7 +170,8 @@ pub struct IndexProverKey>> Clone for IndexProverKey +impl, S>> + Clone for IndexProverKey where PC::Commitment: Clone, { @@ -173,7 +191,11 @@ where /// A zkSNARK proof. #[derive(CanonicalSerialize, CanonicalDeserialize)] -pub struct Proof>> { +pub struct Proof< + F: PrimeField, + S: CryptographicSponge, + PC: PolynomialCommitment, S>, +> { /// Commitments to the polynomials produced by the AHP prover. pub commitments: Vec>, /// Evaluations of these polynomials. @@ -181,16 +203,18 @@ pub struct Proof>> /// The field elements sent by the prover. pub prover_messages: Vec>, /// An evaluation proof from the polynomial commitment. - pub pc_proof: BatchLCProof, PC>, + pub pc_proof: BatchLCProof>, } -impl>> Proof { +impl, S>> + Proof +{ /// Construct a new proof. pub fn new( commitments: Vec>, evaluations: Vec, prover_messages: Vec>, - pc_proof: BatchLCProof, PC>, + pc_proof: BatchLCProof>, ) -> Self { Self { commitments, @@ -202,7 +226,7 @@ impl>> Proof>> Proof = self.pc_proof.proof.clone().into(); - let num_proofs = proofs.len(); - for proof in &proofs { - size_bytes_proofs += proof.size_in_bytes(); - } + let num_proofs = 1; + size_bytes_proofs += self.pc_proof.serialized_size(); let num_evals = self.evaluations.len(); let evals_size_in_bytes = num_evals * size_of_fe_in_bytes; @@ -270,7 +291,9 @@ impl>> Proof>> Clone for Proof { +impl, S>> + Clone for Proof +{ fn clone(&self) -> Self { Proof { commitments: self.commitments.clone(), diff --git a/src/fiat_shamir/mod.rs b/src/fiat_shamir/mod.rs index 09bd1af..96df382 100644 --- a/src/fiat_shamir/mod.rs +++ b/src/fiat_shamir/mod.rs @@ -9,6 +9,7 @@ use rand_chacha::ChaChaRng; /// The constraints for Fiat-Shamir pub mod constraints; + /// The Poseidon sponge pub mod poseidon; diff --git a/src/fiat_shamir/poseidon/mod.rs b/src/fiat_shamir/poseidon/mod.rs index 33f6d2a..cdfe483 100644 --- a/src/fiat_shamir/poseidon/mod.rs +++ b/src/fiat_shamir/poseidon/mod.rs @@ -8,6 +8,7 @@ use crate::fiat_shamir::AlgebraicSponge; use crate::Vec; use ark_ff::PrimeField; +use ark_sponge::{Absorb, CryptographicSponge}; use ark_std::rand::SeedableRng; /// constraints for Poseidon @@ -241,3 +242,29 @@ impl AlgebraicSponge for PoseidonSponge { squeezed_elems } } + +impl CryptographicSponge for PoseidonSponge +where + F: PrimeField, +{ + type Parameters = (); + + fn new(_params: &Self::Parameters) -> Self { + >::new() + } + + fn absorb(&mut self, input: &impl Absorb) { + >::absorb( + self, + input.to_sponge_field_elements_as_vec().as_slice(), + ) + } + + fn squeeze_bytes(&mut self, num_bytes: usize) -> Vec { + todo!() + } + + fn squeeze_bits(&mut self, num_bits: usize) -> Vec { + todo!() + } +} diff --git a/src/lib.rs b/src/lib.rs index c130fcf..e643169 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,21 +7,25 @@ //! is the same as the number of constraints (i.e., where the constraint //! matrices are square). Furthermore, Marlin only supports instances where the //! public inputs are of size one less than a power of 2 (i.e., 2^n - 1). -#![deny(unused_import_braces, unused_qualifications, trivial_casts)] -#![deny(trivial_numeric_casts, private_in_public)] -#![deny(stable_features, unreachable_pub, non_shorthand_field_patterns)] -#![deny(unused_attributes, unused_imports, unused_mut)] -#![deny(renamed_and_removed_lints, stable_features, unused_allocation)] -#![deny(unused_comparisons, bare_trait_objects, unused_must_use, const_err)] +//#![deny(unused_import_braces, unused_qualifications, trivial_casts)] +//#![deny(trivial_numeric_casts, private_in_public)] +//#![deny(stable_features, unreachable_pub, non_shorthand_field_patterns)] +//#![deny(unused_attributes, unused_imports, unused_mut)] +//#![deny(renamed_and_removed_lints, stable_features, unused_allocation)] +//#![deny(unused_comparisons, bare_trait_objects, unused_must_use, const_err)] #![forbid(unsafe_code)] #![allow(clippy::op_ref)] +use crate::ahp::prover::ProverMsg; use ark_ff::{to_bytes, PrimeField, ToConstraintField}; +use ark_nonnative_field::params::OptimizationType; use ark_poly::{univariate::DensePolynomial, EvaluationDomain, GeneralEvaluationDomain}; -use ark_poly_commit::Evaluations; -use ark_poly_commit::LabeledPolynomial; -use ark_poly_commit::{LabeledCommitment, PCUniversalParams, PolynomialCommitment}; +use ark_poly_commit::{ + challenge::ChallengeGenerator, Evaluations, LabeledCommitment, LabeledPolynomial, + PCUniversalParams, PolynomialCommitment, +}; use ark_relations::r1cs::{ConstraintSynthesizer, SynthesisError}; +use ark_sponge::CryptographicSponge; use ark_std::rand::RngCore; #[macro_use] @@ -45,7 +49,7 @@ macro_rules! eprintln { /// Implements a Fiat-Shamir based Rng that allows one to incrementally update /// the seed based on new messages in the proof transcript. pub mod fiat_shamir; -use crate::fiat_shamir::FiatShamirRng; +pub use fiat_shamir::*; mod error; pub use error::*; @@ -57,10 +61,7 @@ pub mod constraints; /// Implements an Algebraic Holographic Proof (AHP) for the R1CS indexed relation. pub mod ahp; -use crate::ahp::prover::ProverMsg; -pub use ahp::AHPForR1CS; -use ahp::EvaluationsProvider; -use ark_nonnative_field::params::OptimizationType; +pub use ahp::{AHPForR1CS, EvaluationsProvider}; #[cfg(test)] mod test; @@ -87,22 +88,25 @@ impl MarlinConfig for MarlinRecursiveConfig { pub struct Marlin< F: PrimeField, FSF: PrimeField, - PC: PolynomialCommitment>, + S: CryptographicSponge + AlgebraicSponge, + PC: PolynomialCommitment, S>, FS: FiatShamirRng, MC: MarlinConfig, >( #[doc(hidden)] PhantomData, #[doc(hidden)] PhantomData, + #[doc(hidden)] PhantomData, #[doc(hidden)] PhantomData, #[doc(hidden)] PhantomData, #[doc(hidden)] PhantomData, ); -fn compute_vk_hash(vk: &IndexVerifierKey) -> Vec +fn compute_vk_hash(vk: &IndexVerifierKey) -> Vec where F: PrimeField, FSF: PrimeField, - PC: PolynomialCommitment>, + S: CryptographicSponge + AlgebraicSponge, + PC: PolynomialCommitment, S>, FS: FiatShamirRng, PC::Commitment: ToConstraintField, { @@ -111,9 +115,10 @@ where vk_hash_rng.squeeze_native_field_elements(1) } -impl Marlin +impl Marlin where - PC: PolynomialCommitment>, + S: CryptographicSponge + AlgebraicSponge, + PC: PolynomialCommitment, S, BatchProof = DensePolynomial>, PC::VerifierKey: ToConstraintField, PC::Commitment: ToConstraintField, FS: FiatShamirRng, @@ -129,7 +134,7 @@ where num_variables: usize, num_non_zero: usize, rng: &mut R, - ) -> Result, Error> { + ) -> Result, Error> { let max_degree = AHPForR1CS::::max_degree(num_constraints, num_variables, num_non_zero)?; let setup_time = start_timer!(|| { format!( @@ -149,7 +154,7 @@ where pub fn circuit_specific_setup, R: RngCore>( c: C, rng: &mut R, - ) -> Result<(IndexProverKey, IndexVerifierKey), Error> { + ) -> Result<(IndexProverKey, IndexVerifierKey), Error> { let index_time = start_timer!(|| "Marlin::Index"); let for_recursion = MC::FOR_RECURSION; @@ -233,9 +238,9 @@ where /// keys. This is a deterministic algorithm that anyone can rerun. #[allow(clippy::type_complexity)] pub fn index>( - srs: &UniversalSRS, + srs: &UniversalSRS, c: C, - ) -> Result<(IndexProverKey, IndexVerifierKey), Error> { + ) -> Result<(IndexProverKey, IndexVerifierKey), Error> { let index_time = start_timer!(|| "Marlin::Index"); let for_recursion = MC::FOR_RECURSION; @@ -314,10 +319,10 @@ where /// Create a zkSNARK asserting that the constraint system is satisfied. pub fn prove, R: RngCore>( - index_pk: &IndexProverKey, + index_pk: &IndexProverKey, c: C, zk_rng: &mut R, - ) -> Result, Error> { + ) -> Result, Error> { let prover_time = start_timer!(|| "Marlin::Prover"); // TODO: Add check that c is in the correct mode. @@ -332,7 +337,7 @@ where if for_recursion { fs_rng.absorb_bytes(&to_bytes![&Self::PROTOCOL_NAME].unwrap()); - fs_rng.absorb_native_field_elements(&compute_vk_hash::( + fs_rng.absorb_native_field_elements(&compute_vk_hash::( &index_pk.index_vk, )); fs_rng.absorb_nonnative_field_elements(&public_input, OptimizationType::Weight); @@ -537,57 +542,39 @@ where fs_rng.absorb_bytes(&to_bytes![&evaluations].unwrap()); } - let pc_proof = if for_recursion { - let num_open_challenges: usize = 7; - - let mut opening_challenges = Vec::::new(); - opening_challenges - .append(&mut fs_rng.squeeze_128_bits_nonnative_field_elements(num_open_challenges)); - - let opening_challenges_f = |i| opening_challenges[i as usize]; - - PC::open_combinations_individual_opening_challenges( - &index_pk.committer_key, - &lc_s, - polynomials, - &labeled_comms, - &query_set, - &opening_challenges_f, - &comm_rands, - Some(zk_rng), - ) - .map_err(Error::from_pc_err)? - } else { - let opening_challenge: F = fs_rng.squeeze_128_bits_nonnative_field_elements(1)[0]; - - PC::open_combinations( - &index_pk.committer_key, - &lc_s, - polynomials, - &labeled_comms, - &query_set, - opening_challenge, - &comm_rands, - Some(zk_rng), - ) - .map_err(Error::from_pc_err)? - }; + let sponge = >::new(); + let mut opening_challenges = ChallengeGenerator::::new_multivariate(sponge); + + let pc_proof = PC::open_combinations( + &index_pk.committer_key, + &lc_s, + polynomials, + &labeled_comms, + &query_set, + &mut opening_challenges, + &comm_rands, + Some(zk_rng), + ) + .map_err(Error::from_pc_err)?; // Gather prover messages together. let prover_messages = vec![prover_first_msg, prover_second_msg, prover_third_msg]; let proof = Proof::new(commitments, evaluations, prover_messages, pc_proof); + proof.print_size_info(); + end_timer!(prover_time); + Ok(proof) } /// Verify that a proof for the constrain system defined by `C` asserts that /// all constraints are satisfied. pub fn verify( - index_vk: &IndexVerifierKey, + index_vk: &IndexVerifierKey, public_input: &[F], - proof: &Proof, + proof: &Proof, ) -> Result> { let verifier_time = start_timer!(|| "Marlin::Verify"); @@ -609,7 +596,7 @@ where if for_recursion { fs_rng.absorb_bytes(&to_bytes![&Self::PROTOCOL_NAME].unwrap()); - fs_rng.absorb_native_field_elements(&compute_vk_hash::(index_vk)); + fs_rng.absorb_native_field_elements(&compute_vk_hash::(index_vk)); fs_rng.absorb_nonnative_field_elements(&public_input, OptimizationType::Weight); } else { fs_rng @@ -734,56 +721,37 @@ where for_recursion, )?; - let evaluations_are_correct = if for_recursion { - let num_open_challenges: usize = 7; - - let mut opening_challenges = Vec::::new(); - opening_challenges - .append(&mut fs_rng.squeeze_128_bits_nonnative_field_elements(num_open_challenges)); - - let opening_challenges_f = |i| opening_challenges[i as usize]; - - PC::check_combinations_individual_opening_challenges( - &index_vk.verifier_key, - &lc_s, - &commitments, - &query_set, - &evaluations, - &proof.pc_proof, - &opening_challenges_f, - &mut fs_rng, - ) - .map_err(Error::from_pc_err)? - } else { - let opening_challenge: F = fs_rng.squeeze_128_bits_nonnative_field_elements(1)[0]; - - PC::check_combinations( - &index_vk.verifier_key, - &lc_s, - &commitments, - &query_set, - &evaluations, - &proof.pc_proof, - opening_challenge, - &mut fs_rng, - ) - .map_err(Error::from_pc_err)? - }; + let sponge = >::new(); + let mut opening_challenges = ChallengeGenerator::::new_multivariate(sponge); + + let evaluations_are_correct = PC::check_combinations( + &index_vk.verifier_key, + &lc_s, + &commitments, + &query_set, + &evaluations, + &proof.pc_proof, + &mut opening_challenges, + &mut fs_rng, + ) + .map_err(Error::from_pc_err)?; if !evaluations_are_correct { eprintln!("PC::Check failed"); } + end_timer!(verifier_time, || format!( " PC::Check for AHP Verifier linear equations: {}", evaluations_are_correct )); + Ok(evaluations_are_correct) } pub fn prepared_verify( - prepared_vk: &PreparedIndexVerifierKey, + prepared_vk: &PreparedIndexVerifierKey, public_input: &[F], - proof: &Proof, + proof: &Proof, ) -> Result> { Self::verify(&prepared_vk.orig_vk, public_input, proof) } diff --git a/src/test.rs b/src/test.rs index f8d5d1c..6a2285e 100644 --- a/src/test.rs +++ b/src/test.rs @@ -115,7 +115,10 @@ impl ConstraintSynthesizer for OutlineTestCircuit { mod marlin { use super::*; - use crate::{fiat_shamir::FiatShamirChaChaRng, Marlin, MarlinDefaultConfig}; + use crate::{ + fiat_shamir::poseidon::PoseidonSponge, fiat_shamir::FiatShamirChaChaRng, Marlin, + MarlinDefaultConfig, + }; use ark_bls12_381::{Bls12_381, Fq, Fr}; use ark_ff::UniformRand; @@ -124,9 +127,15 @@ mod marlin { use ark_std::ops::MulAssign; use blake2::Blake2s; - type MultiPC = MarlinKZG10>; - type MarlinInst = - Marlin, MarlinDefaultConfig>; + type MultiPC = MarlinKZG10, PoseidonSponge>; + type MarlinInst = Marlin< + Fr, + Fq, + PoseidonSponge, + MultiPC, + FiatShamirChaChaRng, + MarlinDefaultConfig, + >; fn test_circuit(num_constraints: usize, num_variables: usize) { let rng = &mut ark_std::test_rng(); @@ -217,10 +226,11 @@ mod marlin_recursion { use ark_poly_commit::marlin_pc::MarlinKZG10; use core::ops::MulAssign; - type MultiPC = MarlinKZG10>; + type MultiPC = MarlinKZG10, PoseidonSponge>; type MarlinInst = Marlin< Fr, Fq, + PoseidonSponge, MultiPC, FiatShamirAlgebraicSpongeRng>, MarlinRecursiveConfig,