arnaucube
arnaucube/sonobePublic Self-hosted repository
Adapt Nova usage of commitment to the generic trait (#63)

arnaucube root@arnaucube.com
Tue, 30 Jan 2024 11:16:53 +0100
commit

f85a056b6149045fe8fb1d8b2d965cd9d81464a3

parent

47e47cc2afcb5f988ab2c37f7e0157d4fd6f515c

M rust-toolchain → rust-toolchain

@@ -1,1 +1,1 @@

-1.73.0 +1.75.0
M src/folding/hypernova/circuit.rs → src/folding/hypernova/circuit.rs

@@ -237,7 +237,7 @@

// Initialize cs let cs = ConstraintSystem::<Fr>::new_ref(); let vec_thetas = sigmas_thetas.1; - for (_, thetas) in vec_thetas.iter().enumerate() { + for thetas in vec_thetas.iter() { // sum c_i * prod theta_j let expected = sum_ci_mul_prod_thetaj(&ccs, thetas); // from `compute_c_from_sigmas_and_thetas` let mut prepared_thetas = Vec::new();
M src/folding/nova/circuits.rs → src/folding/nova/circuits.rs

@@ -503,7 +503,7 @@ #[test]

fn test_nifs_gadget() { let (_, _, _, _, ci1, _, ci2, _, ci3, _, cmT, _, r_Fr) = prepare_simple_fold_inputs(); - let ci3_verifier = NIFS::<Projective>::verify(r_Fr, &ci1, &ci2, &cmT); + let ci3_verifier = NIFS::<Projective, Pedersen<Projective>>::verify(r_Fr, &ci1, &ci2, &cmT); assert_eq!(ci3_verifier, ci3); let cs = ConstraintSystem::<Fr>::new_ref();

@@ -721,7 +721,7 @@ r1cs.check_relaxed_instance_relation(&W_i, &U_i).unwrap();

// U_{i+1} let T: Vec<Fr>; - (T, cmT) = NIFS::<Projective>::compute_cmT( + (T, cmT) = NIFS::<Projective, Pedersen<Projective>>::compute_cmT( &pedersen_params, &r1cs, &w_i,

@@ -741,9 +741,10 @@ )

.unwrap(); let r_Fr = Fr::from_bigint(BigInteger::from_bits_le(&r_bits)).unwrap(); - (W_i1, U_i1) = - NIFS::<Projective>::fold_instances(r_Fr, &w_i, &u_i, &W_i, &U_i, &T, cmT) - .unwrap(); + (W_i1, U_i1) = NIFS::<Projective, Pedersen<Projective>>::fold_instances( + r_Fr, &w_i, &u_i, &W_i, &U_i, &T, cmT, + ) + .unwrap(); r1cs.check_relaxed_instance_relation(&W_i1, &U_i1).unwrap();

@@ -782,7 +783,7 @@ cf_cmT,

) .unwrap(); let cf_r_Fq = Fq::from_bigint(BigInteger::from_bits_le(&cf_r_bits)).unwrap(); - let (_, cf_U_i1) = NIFS::<Projective2>::fold_instances( + let (_, cf_U_i1) = NIFS::<Projective2, Pedersen<Projective2>>::fold_instances( cf_r_Fq, &cf_W_i, &cf_U_i, &cf_w_i, &cf_u_i, &cf_T, cf_cmT, ) .unwrap();

@@ -828,7 +829,9 @@

// compute committed instances, w_{i+1}, u_{i+1}, which will be used as w_i, u_i, so we // assign them directly to w_i, u_i. w_i = Witness::<Projective>::new(w_i1.clone(), r1cs.A.n_rows); - u_i = w_i.commit(&pedersen_params, vec![u_i1_x]).unwrap(); + u_i = w_i + .commit::<Pedersen<Projective>>(&pedersen_params, vec![u_i1_x]) + .unwrap(); r1cs.check_relaxed_instance_relation(&w_i, &u_i).unwrap(); r1cs.check_relaxed_instance_relation(&W_i1, &U_i1).unwrap();
M src/folding/nova/decider.rs → src/folding/nova/decider.rs

@@ -18,7 +18,7 @@ use ark_std::{One, Zero};

use core::{borrow::Borrow, marker::PhantomData}; use crate::ccs::r1cs::R1CS; -use crate::commitment::pedersen::Params as PedersenParams; +use crate::commitment::{pedersen::Params as PedersenParams, CommitmentProver}; use crate::folding::nova::{ circuits::{CommittedInstanceVar, CF1, CF2}, ivc::IVC,

@@ -179,17 +179,21 @@ }

/// Circuit that implements the in-circuit checks needed for the onchain (Ethereum's EVM) /// verification. -pub struct DeciderCircuit<C1, GC1, C2, GC2> +pub struct DeciderCircuit<C1, GC1, C2, GC2, CP1, CP2> where C1: CurveGroup, GC1: CurveVar<C1, CF2<C1>>, C2: CurveGroup, GC2: CurveVar<C2, CF2<C2>>, + CP1: CommitmentProver<C1>, + CP2: CommitmentProver<C2>, { _c1: PhantomData<C1>, _gc1: PhantomData<GC1>, _c2: PhantomData<C2>, _gc2: PhantomData<GC2>, + _cp1: PhantomData<CP1>, + _cp2: PhantomData<CP2>, /// E vector's length of the Nova instance witness pub E_len: usize,

@@ -199,7 +203,7 @@ /// R1CS of the Augmented Function circuit

pub r1cs: R1CS<C1::ScalarField>, /// R1CS of the CycleFold circuit pub cf_r1cs: R1CS<C2::ScalarField>, - /// CycleFold PedersenParams, over C2 + /// CycleFold PedersenParams over C2 pub cf_pedersen_params: PedersenParams<C2>, pub poseidon_config: PoseidonConfig<CF1<C1>>, pub i: Option<CF1<C1>>,

@@ -216,25 +220,32 @@ /// CycleFold running instance

pub cf_U_i: Option<CommittedInstance<C2>>, pub cf_W_i: Option<Witness<C2>>, } -impl<C1, GC1, C2, GC2> DeciderCircuit<C1, GC1, C2, GC2> +impl<C1, GC1, C2, GC2, CP1, CP2> DeciderCircuit<C1, GC1, C2, GC2, CP1, CP2> where C1: CurveGroup, C2: CurveGroup, GC1: CurveVar<C1, CF2<C1>>, GC2: CurveVar<C2, CF2<C2>>, + CP1: CommitmentProver<C1>, + // enforce that the CP2 is Pedersen commitment, since we're at Ethereum's EVM decider + CP2: CommitmentProver<C2, Params = PedersenParams<C2>>, { - pub fn from_ivc<FC: FCircuit<C1::ScalarField>>(ivc: IVC<C1, GC1, C2, GC2, FC>) -> Self { + pub fn from_ivc<FC: FCircuit<C1::ScalarField>>( + ivc: IVC<C1, GC1, C2, GC2, FC, CP1, CP2>, + ) -> Self { Self { _c1: PhantomData, _gc1: PhantomData, _c2: PhantomData, _gc2: PhantomData, + _cp1: PhantomData, + _cp2: PhantomData, E_len: ivc.W_i.E.len(), cf_E_len: ivc.cf_W_i.E.len(), r1cs: ivc.r1cs, cf_r1cs: ivc.cf_r1cs, - cf_pedersen_params: ivc.cf_pedersen_params, + cf_pedersen_params: ivc.cf_cm_params, poseidon_config: ivc.poseidon_config, i: Some(ivc.i), z_0: Some(ivc.z_0),

@@ -249,18 +260,21 @@ }

} } -impl<C1, GC1, C2, GC2> ConstraintSynthesizer<CF1<C1>> for DeciderCircuit<C1, GC1, C2, GC2> +impl<C1, GC1, C2, GC2, CP1, CP2> ConstraintSynthesizer<CF1<C1>> + for DeciderCircuit<C1, GC1, C2, GC2, CP1, CP2> where C1: CurveGroup, C2: CurveGroup, GC1: CurveVar<C1, CF2<C1>>, GC2: CurveVar<C2, CF2<C2>>, + CP1: CommitmentProver<C1>, + CP2: CommitmentProver<C2>, <C1 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField, <C1 as Group>::ScalarField: Absorb, <C2 as Group>::ScalarField: Absorb, C1: CurveGroup<BaseField = C2::ScalarField, ScalarField = C2::BaseField>, - for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>, + for<'b> &'b GC2: GroupOpsBounds<'b, C2, GC2>, { fn generate_constraints(self, cs: ConstraintSystemRef<CF1<C1>>) -> Result<(), SynthesisError> { let r1cs =

@@ -437,7 +451,8 @@ };

use ark_relations::r1cs::ConstraintSystem; use ark_vesta::{constraints::GVar as GVar2, Projective as Projective2}; - use crate::folding::nova::ivc::IVC; + use crate::commitment::pedersen::Pedersen; + use crate::folding::nova::ivc::tests::get_pedersen_params_len; use crate::frontend::tests::{CubicFCircuit, CustomFCircuit, WrapperCircuit}; use crate::transcript::poseidon::tests::poseidon_test_config;

@@ -604,10 +619,25 @@

let F_circuit = CubicFCircuit::<Fr>::new(()); let z_0 = vec![Fr::from(3_u32)]; + let (pedersen_len, cf_pedersen_len) = + get_pedersen_params_len::<CubicFCircuit<Fr>>(&poseidon_config, F_circuit).unwrap(); + // generate the Pedersen params + let pedersen_params = Pedersen::<Projective>::new_params(&mut rng, pedersen_len); + let cf_pedersen_params = Pedersen::<Projective2>::new_params(&mut rng, cf_pedersen_len); + // generate an IVC and do a step of it - let mut ivc = IVC::<Projective, GVar, Projective2, GVar2, CubicFCircuit<Fr>>::new( - &mut rng, + let mut ivc = IVC::< + Projective, + GVar, + Projective2, + GVar2, + CubicFCircuit<Fr>, + Pedersen<Projective>, + Pedersen<Projective2>, + >::new( poseidon_config, + pedersen_params, + cf_pedersen_params, F_circuit, z_0.clone(), )

@@ -616,7 +646,14 @@ ivc.prove_step().unwrap();

ivc.verify(z_0, 1).unwrap(); // load the DeciderCircuit from the generated IVC - let decider_circuit = DeciderCircuit::<Projective, GVar, Projective2, GVar2>::from_ivc(ivc); + let decider_circuit = DeciderCircuit::< + Projective, + GVar, + Projective2, + GVar2, + Pedersen<Projective>, + Pedersen<Projective2>, + >::from_ivc(ivc); let cs = ConstraintSystem::<Fr>::new_ref();
M src/folding/nova/ivc.rs → src/folding/nova/ivc.rs

@@ -3,7 +3,6 @@ use ark_ec::{AffineRepr, CurveGroup, Group};

use ark_ff::{BigInteger, PrimeField}; use ark_r1cs_std::{groups::GroupOpsBounds, prelude::CurveVar}; use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem}; -use ark_std::rand::Rng; use ark_std::{One, Zero}; use core::marker::PhantomData;

@@ -12,9 +11,8 @@ circuits::{AugmentedFCircuit, ChallengeGadget, CF2},

cyclefold::{CycleFoldChallengeGadget, CycleFoldCircuit}, }; use super::{nifs::NIFS, traits::NovaR1CS, CommittedInstance, Witness}; -use crate::ccs::r1cs::R1CS; -use crate::ccs::r1cs::{extract_r1cs, extract_w_x}; -use crate::commitment::pedersen::{Params as PedersenParams, Pedersen}; +use crate::ccs::r1cs::{extract_r1cs, extract_w_x, R1CS}; +use crate::commitment::CommitmentProver; use crate::frontend::FCircuit; use crate::Error;

@@ -23,13 +21,15 @@ use super::cyclefold::CF_IO_LEN;

/// Implements the Incremental Verifiable Computation described in sections 1.2 and 5 of /// [Nova](https://eprint.iacr.org/2021/370.pdf) -pub struct IVC<C1, GC1, C2, GC2, FC> +pub struct IVC<C1, GC1, C2, GC2, FC, CP1, CP2> where C1: CurveGroup, GC1: CurveVar<C1, CF2<C1>>, C2: CurveGroup, GC2: CurveVar<C2, CF2<C2>>, FC: FCircuit<C1::ScalarField>, + CP1: CommitmentProver<C1>, + CP2: CommitmentProver<C2>, { _gc1: PhantomData<GC1>, _c2: PhantomData<C2>,

@@ -39,10 +39,10 @@ pub r1cs: R1CS<C1::ScalarField>,

/// R1CS of the CycleFold circuit pub cf_r1cs: R1CS<C2::ScalarField>, pub poseidon_config: PoseidonConfig<C1::ScalarField>, - /// PedersenParams over C1 - pub pedersen_params: PedersenParams<C1>, - /// CycleFold PedersenParams, over C2 - pub cf_pedersen_params: PedersenParams<C2>, + /// CommitmentProver::Params over C1 + pub cm_params: CP1::Params, + /// CycleFold CommitmentProver::Params, over C2 + pub cf_cm_params: CP2::Params, /// F circuit, the circuit that is being folded pub F: FC, pub i: C1::ScalarField,

@@ -61,13 +61,15 @@ pub cf_W_i: Witness<C2>,

pub cf_U_i: CommittedInstance<C2>, } -impl<C1, GC1, C2, GC2, FC> IVC<C1, GC1, C2, GC2, FC> +impl<C1, GC1, C2, GC2, FC, CP1, CP2> IVC<C1, GC1, C2, GC2, FC, CP1, CP2> where C1: CurveGroup, GC1: CurveVar<C1, CF2<C1>>, C2: CurveGroup, GC2: CurveVar<C2, CF2<C2>>, FC: FCircuit<C1::ScalarField>, + CP1: CommitmentProver<C1>, + CP2: CommitmentProver<C2>, <C1 as CurveGroup>::BaseField: PrimeField, <C2 as CurveGroup>::BaseField: PrimeField, <C1 as Group>::ScalarField: Absorb,

@@ -77,9 +79,10 @@ for<'a> &'a GC1: GroupOpsBounds<'a, C1, GC1>,

for<'a> &'a GC2: GroupOpsBounds<'a, C2, GC2>, { /// Initializes the IVC for the given parameters and initial state `z_0`. - pub fn new<R: Rng>( - rng: &mut R, + pub fn new( poseidon_config: PoseidonConfig<C1::ScalarField>, + cm_params: CP1::Params, + cf_cm_params: CP2::Params, F: FC, z_0: Vec<C1::ScalarField>, ) -> Result<Self, Error> {

@@ -100,11 +103,6 @@ cs2.finalize();

let cs2 = cs2.into_inner().ok_or(Error::NoInnerConstraintSystem)?; let cf_r1cs = extract_r1cs::<C1::BaseField>(&cs2); - // this will not be randomly generated in this method, and will come from above levels, so - // the same params can be loaded on multiple instances - let pedersen_params = Pedersen::<C1>::new_params(rng, r1cs.A.n_rows); - let cf_pedersen_params = Pedersen::<C2>::new_params(rng, cf_r1cs.A.n_rows); - // setup the dummy instances let (w_dummy, u_dummy) = r1cs.dummy_instance(); let (cf_w_dummy, cf_u_dummy) = cf_r1cs.dummy_instance();

@@ -118,8 +116,8 @@ _gc2: PhantomData,

r1cs, cf_r1cs, poseidon_config, - pedersen_params, - cf_pedersen_params, + cm_params, + cf_cm_params, F, i: C1::ScalarField::zero(), z_0: z_0.clone(),

@@ -154,8 +152,9 @@ let r_Fr = C1::ScalarField::from_bigint(BigInteger::from_bits_le(&r_bits))

.ok_or(Error::OutOfBounds)?; // fold Nova instances - let (W_i1, U_i1): (Witness<C1>, CommittedInstance<C1>) = - NIFS::<C1>::fold_instances(r_Fr, &self.w_i, &self.u_i, &self.W_i, &self.U_i, &T, cmT)?; + let (W_i1, U_i1): (Witness<C1>, CommittedInstance<C1>) = NIFS::<C1, CP1>::fold_instances( + r_Fr, &self.w_i, &self.u_i, &self.W_i, &self.U_i, &T, cmT, + )?; // folded instance output (public input, x) // u_{i+1}.x = H(i+1, z_0, z_{i+1}, U_{i+1})

@@ -188,7 +187,7 @@ cf_r_nonnat: None,

}; #[cfg(test)] - NIFS::verify_folded_instance(r_Fr, &self.u_i, &self.U_i, &U_i1, &cmT)?; + NIFS::<C1, CP1>::verify_folded_instance(r_Fr, &self.u_i, &self.U_i, &U_i1, &cmT)?; } else { // CycleFold part: // get the vector used as public inputs 'x' in the CycleFold circuit

@@ -226,7 +225,7 @@

// fold cyclefold instances let cf_w_i = Witness::<C2>::new(cf_w_i.clone(), self.cf_r1cs.A.n_rows); let cf_u_i: CommittedInstance<C2> = - cf_w_i.commit(&self.cf_pedersen_params, cf_x_i.clone())?; + cf_w_i.commit::<CP2>(&self.cf_cm_params, cf_x_i.clone())?; // compute T* and cmT* for CycleFoldCircuit let (cf_T, cf_cmT) = self.compute_cf_cmT(&cf_w_i, &cf_u_i)?;

@@ -240,7 +239,7 @@ )?;

let cf_r_Fq = C1::BaseField::from_bigint(BigInteger::from_bits_le(&cf_r_bits)) .ok_or(Error::OutOfBounds)?; - let (cf_W_i1, cf_U_i1) = NIFS::<C2>::fold_instances( + let (cf_W_i1, cf_U_i1) = NIFS::<C2, CP2>::fold_instances( cf_r_Fq, &self.cf_W_i, &self.cf_U_i,

@@ -300,7 +299,7 @@ // set values for next iteration

self.i += C1::ScalarField::one(); self.z_i = z_i1.clone(); self.w_i = Witness::<C1>::new(w_i1, self.r1cs.A.n_rows); - self.u_i = self.w_i.commit(&self.pedersen_params, vec![u_i1_x])?; + self.u_i = self.w_i.commit::<CP1>(&self.cm_params, vec![u_i1_x])?; self.W_i = W_i1.clone(); self.U_i = U_i1.clone();

@@ -353,8 +352,8 @@ }

// computes T and cmT for the AugmentedFCircuit fn compute_cmT(&self) -> Result<(Vec<C1::ScalarField>, C1), Error> { - NIFS::<C1>::compute_cmT( - &self.pedersen_params, + NIFS::<C1, CP1>::compute_cmT( + &self.cm_params, &self.r1cs, &self.w_i, &self.u_i,

@@ -368,8 +367,8 @@ &self,

cf_w_i: &Witness<C2>, cf_u_i: &CommittedInstance<C2>, ) -> Result<(Vec<C2::ScalarField>, C2), Error> { - NIFS::<C2>::compute_cyclefold_cmT( - &self.cf_pedersen_params, + NIFS::<C2, CP2>::compute_cyclefold_cmT( + &self.cf_cm_params, &self.cf_r1cs, cf_w_i, cf_u_i,

@@ -393,14 +392,43 @@ vec![*cmE_x, *cmE_y, *cmW_x, *cmW_y]

} #[cfg(test)] -mod tests { +pub mod tests { use super::*; use ark_pallas::{constraints::GVar, Fr, Projective}; use ark_vesta::{constraints::GVar as GVar2, Projective as Projective2}; + use crate::commitment::pedersen::Pedersen; use crate::frontend::tests::CubicFCircuit; use crate::transcript::poseidon::tests::poseidon_test_config; + /// helper method to get the r1cs from the circuit + pub fn get_r1cs<F: PrimeField>( + circuit: impl ConstraintSynthesizer<F>, + ) -> Result<R1CS<F>, Error> { + let cs = ConstraintSystem::<F>::new_ref(); + circuit.generate_constraints(cs.clone())?; + cs.finalize(); + let cs = cs.into_inner().ok_or(Error::NoInnerConstraintSystem)?; + let r1cs = extract_r1cs::<F>(&cs); + Ok(r1cs) + } + + /// helper method to get the pedersen params length for both the AugmentedFCircuit and the + /// CycleFold circuit + pub fn get_pedersen_params_len<FC: FCircuit<Fr>>( + poseidon_config: &PoseidonConfig<Fr>, + F_circuit: FC, + ) -> Result<(usize, usize), Error> { + let augmented_F_circuit = AugmentedFCircuit::<Projective, Projective2, GVar2, FC>::empty( + poseidon_config, + F_circuit, + ); + let cf_circuit = CycleFoldCircuit::<Projective, GVar>::empty(); + let r1cs = get_r1cs(augmented_F_circuit)?; + let cf_r1cs = get_r1cs(cf_circuit)?; + Ok((r1cs.A.n_rows, cf_r1cs.A.n_rows)) + } + #[test] fn test_ivc() { let mut rng = ark_std::test_rng();

@@ -409,9 +437,24 @@

let F_circuit = CubicFCircuit::<Fr>::new(()); let z_0 = vec![Fr::from(3_u32)]; - let mut ivc = IVC::<Projective, GVar, Projective2, GVar2, CubicFCircuit<Fr>>::new( - &mut rng, + let (pedersen_len, cf_pedersen_len) = + get_pedersen_params_len::<CubicFCircuit<Fr>>(&poseidon_config, F_circuit).unwrap(); + // generate the Pedersen params + let pedersen_params = Pedersen::<Projective>::new_params(&mut rng, pedersen_len); + let cf_pedersen_params = Pedersen::<Projective2>::new_params(&mut rng, cf_pedersen_len); + + let mut ivc = IVC::< + Projective, + GVar, + Projective2, + GVar2, + CubicFCircuit<Fr>, + Pedersen<Projective>, + Pedersen<Projective2>, + >::new( poseidon_config, + pedersen_params, + cf_pedersen_params, F_circuit, z_0.clone(), )
M src/folding/nova/mod.rs → src/folding/nova/mod.rs

@@ -7,10 +7,7 @@ use ark_ec::{CurveGroup, Group};

use ark_std::fmt::Debug; use ark_std::{One, Zero}; -use crate::commitment::{ - pedersen::{Params as PedersenParams, Pedersen}, - CommitmentProver, -}; +use crate::commitment::CommitmentProver; use crate::folding::circuits::nonnative::point_to_nonnative_limbs; use crate::utils::vec::is_zero_vec; use crate::Error;

@@ -101,16 +98,16 @@ W: w,

rW: C::ScalarField::zero(), } } - pub fn commit( + pub fn commit<CP: CommitmentProver<C>>( &self, - params: &PedersenParams<C>, + params: &CP::Params, x: Vec<C::ScalarField>, ) -> Result<CommittedInstance<C>, Error> { let mut cmE = C::zero(); if !is_zero_vec::<C::ScalarField>(&self.E) { - cmE = Pedersen::commit(params, &self.E, &self.rE)?; + cmE = CP::commit(params, &self.E, &self.rE)?; } - let cmW = Pedersen::commit(params, &self.W, &self.rW)?; + let cmW = CP::commit(params, &self.W, &self.rW)?; Ok(CommittedInstance { cmE, u: C::ScalarField::one(),
M src/folding/nova/nifs.rs → src/folding/nova/nifs.rs

@@ -5,21 +5,19 @@ use std::marker::PhantomData;

use super::{CommittedInstance, Witness}; use crate::ccs::r1cs::R1CS; -use crate::commitment::{ - pedersen::{Params as PedersenParams, Pedersen, Proof as PedersenProof}, - CommitmentProver, -}; +use crate::commitment::CommitmentProver; use crate::transcript::Transcript; use crate::utils::vec::*; use crate::Error; /// Implements the Non-Interactive Folding Scheme described in section 4 of /// [Nova](https://eprint.iacr.org/2021/370.pdf) -pub struct NIFS<C: CurveGroup> { - _phantom: PhantomData<C>, +pub struct NIFS<C: CurveGroup, CP: CommitmentProver<C>> { + _c: PhantomData<C>, + _cp: PhantomData<CP>, } -impl<C: CurveGroup> NIFS<C> +impl<C: CurveGroup, CP: CommitmentProver<C>> NIFS<C, CP> where <C as Group>::ScalarField: Absorb, {

@@ -92,7 +90,7 @@ /// NIFS.P is the consecutive combination of compute_cmT with fold_instances

/// compute_cmT is part of the NIFS.P logic pub fn compute_cmT( - pedersen_params: &PedersenParams<C>, + cm_prover_params: &CP::Params, r1cs: &R1CS<C::ScalarField>, w1: &Witness<C>, ci1: &CommittedInstance<C>,

@@ -105,11 +103,11 @@

// compute cross terms let T = Self::compute_T(r1cs, ci1.u, ci2.u, &z1, &z2)?; // use r_T=1 since we don't need hiding property for cm(T) - let cmT = Pedersen::commit(pedersen_params, &T, &C::ScalarField::one())?; + let cmT = CP::commit(cm_prover_params, &T, &C::ScalarField::one())?; Ok((T, cmT)) } pub fn compute_cyclefold_cmT( - pedersen_params: &PedersenParams<C>, + cm_prover_params: &CP::Params, r1cs: &R1CS<C::ScalarField>, // R1CS over C2.Fr=C1.Fq (here C=C2) w1: &Witness<C>, ci1: &CommittedInstance<C>,

@@ -125,7 +123,7 @@

// compute cross terms let T = Self::compute_T(r1cs, ci1.u, ci2.u, &z1, &z2)?; // use r_T=1 since we don't need hiding property for cm(T) - let cmT = Pedersen::commit(pedersen_params, &T, &C::ScalarField::one())?; + let cmT = CP::commit(cm_prover_params, &T, &C::ScalarField::one())?; Ok((T, cmT)) }

@@ -143,10 +141,10 @@ cmT: C,

) -> Result<(Witness<C>, CommittedInstance<C>), Error> { // fold witness // use r_T=1 since we don't need hiding property for cm(T) - let w3 = NIFS::<C>::fold_witness(r, w1, w2, T, C::ScalarField::one())?; + let w3 = NIFS::<C, CP>::fold_witness(r, w1, w2, T, C::ScalarField::one())?; // fold committed instancs - let ci3 = NIFS::<C>::fold_committed_instance(r, ci1, ci2, &cmT); + let ci3 = NIFS::<C, CP>::fold_committed_instance(r, ci1, ci2, &cmT); Ok((w3, ci3)) }

@@ -160,7 +158,7 @@ ci1: &CommittedInstance<C>,

ci2: &CommittedInstance<C>, cmT: &C, ) -> CommittedInstance<C> { - NIFS::<C>::fold_committed_instance(r, ci1, ci2, cmT) + NIFS::<C, CP>::fold_committed_instance(r, ci1, ci2, cmT) } /// Verify commited folded instance (ci) relations. Notice that this method does not open the

@@ -184,50 +182,35 @@ }

Ok(()) } - pub fn open_commitments( + pub fn prove_commitments( tr: &mut impl Transcript<C>, - pedersen_params: &PedersenParams<C>, + cm_prover_params: &CP::Params, w: &Witness<C>, ci: &CommittedInstance<C>, T: Vec<C::ScalarField>, cmT: &C, - ) -> Result<[PedersenProof<C>; 3], Error> { - let cmE_proof = Pedersen::prove(pedersen_params, tr, &ci.cmE, &w.E, &w.rE)?; - let cmW_proof = Pedersen::prove(pedersen_params, tr, &ci.cmW, &w.W, &w.rW)?; - let cmT_proof = Pedersen::prove(pedersen_params, tr, cmT, &T, &C::ScalarField::one())?; // cm(T) is committed with rT=1 + ) -> Result<[CP::Proof; 3], Error> { + let cmE_proof = CP::prove(cm_prover_params, tr, &ci.cmE, &w.E, &w.rE)?; + let cmW_proof = CP::prove(cm_prover_params, tr, &ci.cmW, &w.W, &w.rW)?; + let cmT_proof = CP::prove(cm_prover_params, tr, cmT, &T, &C::ScalarField::one())?; // cm(T) is committed with rT=1 Ok([cmE_proof, cmW_proof, cmT_proof]) } - pub fn verify_commitments( - tr: &mut impl Transcript<C>, - pedersen_params: &PedersenParams<C>, - ci: CommittedInstance<C>, - cmT: C, - cm_proofs: [PedersenProof<C>; 3], - ) -> Result<(), Error> { - if cm_proofs.len() != 3 { - // cm_proofs should have length 3: [cmE_proof, cmW_proof, cmT_proof] - return Err(Error::NotExpectedLength(cm_proofs.len(), 3)); - } - Pedersen::verify(pedersen_params, tr, ci.cmE, cm_proofs[0].clone())?; - Pedersen::verify(pedersen_params, tr, ci.cmW, cm_proofs[1].clone())?; - Pedersen::verify(pedersen_params, tr, cmT, cm_proofs[2].clone())?; - Ok(()) - } } #[cfg(test)] pub mod tests { use super::*; + use ark_crypto_primitives::sponge::poseidon::PoseidonConfig; use ark_ff::{BigInteger, PrimeField}; use ark_pallas::{Fr, Projective}; use ark_std::{ops::Mul, UniformRand, Zero}; use crate::ccs::r1cs::tests::{get_test_r1cs, get_test_z}; + use crate::commitment::pedersen::{Params as PedersenParams, Pedersen}; use crate::folding::nova::circuits::ChallengeGadget; use crate::folding::nova::traits::NovaR1CS; use crate::transcript::poseidon::{tests::poseidon_test_config, PoseidonTranscript}; use crate::utils::vec::vec_scalar_mul; - use ark_crypto_primitives::sponge::poseidon::PoseidonConfig; #[allow(clippy::type_complexity)] pub(crate) fn prepare_simple_fold_inputs() -> (

@@ -258,12 +241,23 @@ let mut rng = ark_std::test_rng();

let pedersen_params = Pedersen::<Projective>::new_params(&mut rng, r1cs.A.n_cols); // compute committed instances - let ci1 = w1.commit(&pedersen_params, x1.clone()).unwrap(); - let ci2 = w2.commit(&pedersen_params, x2.clone()).unwrap(); + let ci1 = w1 + .commit::<Pedersen<Projective>>(&pedersen_params, x1.clone()) + .unwrap(); + let ci2 = w2 + .commit::<Pedersen<Projective>>(&pedersen_params, x2.clone()) + .unwrap(); // NIFS.P - let (T, cmT) = - NIFS::<Projective>::compute_cmT(&pedersen_params, &r1cs, &w1, &ci1, &w2, &ci2).unwrap(); + let (T, cmT) = NIFS::<Projective, Pedersen<Projective>>::compute_cmT( + &pedersen_params, + &r1cs, + &w1, + &ci1, + &w2, + &ci2, + ) + .unwrap(); let poseidon_config = poseidon_test_config::<Fr>();

@@ -276,8 +270,10 @@ )

.unwrap(); let r_Fr = Fr::from_bigint(BigInteger::from_bits_le(&r_bits)).unwrap(); - let (w3, ci3) = - NIFS::<Projective>::fold_instances(r_Fr, &w1, &ci1, &w2, &ci2, &T, cmT).unwrap(); + let (w3, ci3) = NIFS::<Projective, Pedersen<Projective>>::fold_instances( + r_Fr, &w1, &ci1, &w2, &ci2, &T, cmT, + ) + .unwrap(); ( pedersen_params,

@@ -309,7 +305,7 @@

// dummy instance, witness and public inputs zeroes let w_dummy = Witness::<Projective>::new(vec![Fr::zero(); w1.len()], r1cs.A.n_rows); let mut u_dummy = w_dummy - .commit(&pedersen_params, vec![Fr::zero(); x1.len()]) + .commit::<Pedersen<Projective>>(&pedersen_params, vec![Fr::zero(); x1.len()]) .unwrap(); u_dummy.u = Fr::zero();

@@ -322,11 +318,19 @@ r1cs.check_relaxed_instance_relation(&W_i, &U_i).unwrap();

let r_Fr = Fr::from(3_u32); - let (T, cmT) = - NIFS::<Projective>::compute_cmT(&pedersen_params, &r1cs, &w_i, &u_i, &W_i, &U_i) - .unwrap(); - let (W_i1, U_i1) = - NIFS::<Projective>::fold_instances(r_Fr, &w_i, &u_i, &W_i, &U_i, &T, cmT).unwrap(); + let (T, cmT) = NIFS::<Projective, Pedersen<Projective>>::compute_cmT( + &pedersen_params, + &r1cs, + &w_i, + &u_i, + &W_i, + &U_i, + ) + .unwrap(); + let (W_i1, U_i1) = NIFS::<Projective, Pedersen<Projective>>::fold_instances( + r_Fr, &w_i, &u_i, &W_i, &U_i, &T, cmT, + ) + .unwrap(); r1cs.check_relaxed_instance_relation(&W_i1, &U_i1).unwrap(); }

@@ -337,7 +341,7 @@ let (pedersen_params, poseidon_config, r1cs, w1, ci1, w2, ci2, w3, ci3, T, cmT, _, r) =

prepare_simple_fold_inputs(); // NIFS.V - let ci3_v = NIFS::<Projective>::verify(r, &ci1, &ci2, &cmT); + let ci3_v = NIFS::<Projective, Pedersen<Projective>>::verify(r, &ci1, &ci2, &cmT); assert_eq!(ci3_v, ci3); // check that relations hold for the 2 inputted instances and the folded one

@@ -347,7 +351,9 @@ r1cs.check_relaxed_instance_relation(&w3, &ci3).unwrap();

// check that folded commitments from folded instance (ci) are equal to folding the // use folded rE, rW to commit w3 - let ci3_expected = w3.commit(&pedersen_params, ci3.x.clone()).unwrap(); + let ci3_expected = w3 + .commit::<Pedersen<Projective>>(&pedersen_params, ci3.x.clone()) + .unwrap(); assert_eq!(ci3_expected.cmE, ci3.cmE); assert_eq!(ci3_expected.cmW, ci3.cmW);

@@ -356,15 +362,16 @@ assert_eq!(ci3.cmE, cmT.mul(r));

assert_eq!(w3.E, vec_scalar_mul(&T, &r)); // NIFS.Verify_Folded_Instance: - NIFS::<Projective>::verify_folded_instance(r, &ci1, &ci2, &ci3, &cmT).unwrap(); + NIFS::<Projective, Pedersen<Projective>>::verify_folded_instance(r, &ci1, &ci2, &ci3, &cmT) + .unwrap(); // init Prover's transcript let mut transcript_p = PoseidonTranscript::<Projective>::new(&poseidon_config); // init Verifier's transcript let mut transcript_v = PoseidonTranscript::<Projective>::new(&poseidon_config); - // check openings of ci3.cmE, ci3.cmW and cmT - let cm_proofs = NIFS::<Projective>::open_commitments( + // prove the ci3.cmE, ci3.cmW, cmT commitments + let cm_proofs = NIFS::<Projective, Pedersen<Projective>>::prove_commitments( &mut transcript_p, &pedersen_params, &w3,

@@ -374,12 +381,27 @@ &cmT,

) .unwrap(); - NIFS::<Projective>::verify_commitments( + // verify the ci3.cmE, ci3.cmW, cmT commitments + assert_eq!(cm_proofs.len(), 3); + Pedersen::<Projective>::verify( + &pedersen_params, + &mut transcript_v, + ci3.cmE, + cm_proofs[0].clone(), + ) + .unwrap(); + Pedersen::<Projective>::verify( + &pedersen_params, &mut transcript_v, + ci3.cmW, + cm_proofs[1].clone(), + ) + .unwrap(); + Pedersen::<Projective>::verify( &pedersen_params, - ci3, + &mut transcript_v, cmT, - cm_proofs, + cm_proofs[2].clone(), ) .unwrap(); }

@@ -395,8 +417,9 @@ let pedersen_params = Pedersen::<Projective>::new_params(&mut rng, r1cs.A.n_cols);

// prepare the running instance let mut running_instance_w = Witness::<Projective>::new(w.clone(), r1cs.A.n_rows); - let mut running_committed_instance = - running_instance_w.commit(&pedersen_params, x).unwrap(); + let mut running_committed_instance = running_instance_w + .commit::<Pedersen<Projective>>(&pedersen_params, x) + .unwrap(); r1cs.check_relaxed_instance_relation(&running_instance_w, &running_committed_instance) .unwrap();

@@ -407,8 +430,9 @@ // prepare the incomming instance

let incomming_instance_z = get_test_z(i + 4); let (w, x) = r1cs.split_z(&incomming_instance_z); let incomming_instance_w = Witness::<Projective>::new(w.clone(), r1cs.A.n_rows); - let incomming_committed_instance = - incomming_instance_w.commit(&pedersen_params, x).unwrap(); + let incomming_committed_instance = incomming_instance_w + .commit::<Pedersen<Projective>>(&pedersen_params, x) + .unwrap(); r1cs.check_relaxed_instance_relation( &incomming_instance_w, &incomming_committed_instance,

@@ -418,7 +442,7 @@

let r = Fr::rand(&mut rng); // folding challenge would come from the RO // NIFS.P - let (T, cmT) = NIFS::<Projective>::compute_cmT( + let (T, cmT) = NIFS::<Projective, Pedersen<Projective>>::compute_cmT( &pedersen_params, &r1cs, &running_instance_w,

@@ -427,7 +451,7 @@ &incomming_instance_w,

&incomming_committed_instance, ) .unwrap(); - let (folded_w, _) = NIFS::<Projective>::fold_instances( + let (folded_w, _) = NIFS::<Projective, Pedersen<Projective>>::fold_instances( r, &running_instance_w, &running_committed_instance,

@@ -439,7 +463,7 @@ )

.unwrap(); // NIFS.V - let folded_committed_instance = NIFS::<Projective>::verify( + let folded_committed_instance = NIFS::<Projective, Pedersen<Projective>>::verify( r, &running_committed_instance, &incomming_committed_instance,