diff --git a/src/cyclefold/gadgets.rs b/src/cyclefold/gadgets.rs index bdf59eb7b..6a2c0043d 100644 --- a/src/cyclefold/gadgets.rs +++ b/src/cyclefold/gadgets.rs @@ -61,8 +61,6 @@ pub mod emulated { use super::*; - use std::marker::PhantomData; - use crate::{ constants::{/*BN_N_LIMBS,*/ NUM_CHALLENGE_BITS, NUM_FE_IN_EMULATED_POINT, /*NUM_FE_FOR_RO*/}, gadgets::{ @@ -72,37 +70,34 @@ pub mod emulated { conditionally_select_bignat, le_bits_to_num, /*scalar_as_base,*/ }, }, - traits::{Group, ROConstantsCircuit}, + traits::{CurveCycleEquipped, Dual, Group, ROConstantsCircuit}, RelaxedR1CSInstance, }; use ff::Field; #[derive(Clone)] - pub struct AllocatedPoint + pub struct AllocatedPoint where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { - x: BigNat, - y: BigNat, - is_infinity: AllocatedNum, - _p: PhantomData, + x: BigNat, + y: BigNat, + is_infinity: AllocatedNum, } - impl AllocatedPoint + impl AllocatedPoint where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { pub fn alloc( mut cs: CS, - coords: Option<(E2::Base, E2::Base, bool)>, + coords: Option<( as Engine>::Base, as Engine>::Base, bool)>, limb_width: usize, n_limbs: usize, ) -> Result where - CS: ConstraintSystem<::Base>, + CS: ConstraintSystem, { let x = BigNat::alloc_from_nat( cs.namespace(|| "x"), @@ -128,9 +123,9 @@ pub mod emulated { let is_infinity = AllocatedNum::alloc(cs.namespace(|| "is_infinity"), || { Ok(if coords.map_or(true, |c| c.2) { - E1::Base::ONE + E::Base::ONE } else { - E1::Base::ZERO + E::Base::ZERO }) })?; cs.enforce( @@ -139,17 +134,12 @@ pub mod emulated { |lc| lc + CS::one() - is_infinity.get_variable(), |lc| lc, ); - Ok(Self { - x, - y, - is_infinity, - _p: PhantomData, - }) + Ok(Self { x, y, is_infinity }) } - pub fn absorb_in_ro(&self, mut cs: CS, ro: &mut E1::ROCircuit) -> Result<(), SynthesisError> + pub fn absorb_in_ro(&self, mut cs: CS, ro: &mut E::ROCircuit) -> Result<(), SynthesisError> where - CS: ConstraintSystem<::Base>, + CS: ConstraintSystem, { let x_bn = self .x @@ -159,7 +149,7 @@ pub mod emulated { .map(|(i, limb)| { limb.as_allocated_num(cs.namespace(|| format!("convert limb {i} of comm.x to num"))) }) - .collect::>, _>>()?; + .collect::>, _>>()?; for limb in x_bn { ro.absorb(&limb) @@ -173,7 +163,7 @@ pub mod emulated { .map(|(i, limb)| { limb.as_allocated_num(cs.namespace(|| format!("convert limb {i} of comm.y to num"))) }) - .collect::>, _>>()?; + .collect::>, _>>()?; for limb in y_bn { ro.absorb(&limb) @@ -191,25 +181,25 @@ pub mod emulated { n_limbs: usize, ) -> Result<(), SynthesisError> where - CS: ConstraintSystem<::Base>, + CS: ConstraintSystem, { let m_bn = alloc_bignat_constant( cs.namespace(|| "alloc m"), - &E1::GE::group_params().3, + &E::GE::group_params().3, limb_width, n_limbs, )?; let A_bn = alloc_bignat_constant( cs.namespace(|| "alloc A"), - &f_to_nat(&E1::GE::group_params().0), + &f_to_nat(&E::GE::group_params().0), limb_width, n_limbs, )?; let B_bn = alloc_bignat_constant( cs.namespace(|| "alloc B"), - &f_to_nat(&E1::GE::group_params().1), + &f_to_nat(&E::GE::group_params().1), limb_width, n_limbs, )?; @@ -228,7 +218,7 @@ pub mod emulated { self .is_infinity .get_value() - .map(|is_infinity| is_infinity == E1::Base::ONE), + .map(|is_infinity| is_infinity == E::Base::ONE), )?; cs.enforce( @@ -243,7 +233,7 @@ pub mod emulated { Ok(()) } - fn conditionally_select::Base>>( + fn conditionally_select>( &self, mut cs: CS, other: &Self, @@ -270,70 +260,57 @@ pub mod emulated { condition, )?; - Ok(Self { - x, - y, - is_infinity, - _p: PhantomData, - }) + Ok(Self { x, y, is_infinity }) } - pub fn default::Base>>( + pub fn default>( mut cs: CS, limb_width: usize, n_limbs: usize, ) -> Result { let x = BigNat::alloc_from_nat( cs.namespace(|| "allocate x_default = 0"), - || Ok(f_to_nat(&E1::Scalar::ZERO)), + || Ok(f_to_nat(&E::Scalar::ZERO)), limb_width, n_limbs, )?; let y = BigNat::alloc_from_nat( cs.namespace(|| "allocate y_default = 0"), - || Ok(f_to_nat(&E1::Scalar::ZERO)), + || Ok(f_to_nat(&E::Scalar::ZERO)), limb_width, n_limbs, )?; let is_infinity = alloc_one(cs.namespace(|| "one")); - Ok(Self { - x, - y, - is_infinity, - _p: PhantomData, - }) + Ok(Self { x, y, is_infinity }) } } - pub struct AllocatedRelaxedR1CSInstance + pub struct AllocatedRelaxedR1CSInstance where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { - comm_W: AllocatedPoint, - comm_E: AllocatedPoint, - u: AllocatedNum, - x0: AllocatedNum, - x1: AllocatedNum, - pub _p: PhantomData, + comm_W: AllocatedPoint, + comm_E: AllocatedPoint, + u: AllocatedNum, + x0: AllocatedNum, + x1: AllocatedNum, } - impl AllocatedRelaxedR1CSInstance + impl AllocatedRelaxedR1CSInstance where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { pub fn alloc( mut cs: CS, - inst: Option<&RelaxedR1CSInstance>, + inst: Option<&RelaxedR1CSInstance>>, limb_width: usize, n_limbs: usize, ) -> Result where - CS: ConstraintSystem<::Base>, + CS: ConstraintSystem, { let comm_W = AllocatedPoint::alloc( cs.namespace(|| "allocate comm_W"), @@ -350,15 +327,15 @@ pub mod emulated { )?; let u = AllocatedNum::alloc(cs.namespace(|| "allocate u"), || { - inst.map_or(Ok(E1::Base::ZERO), |inst| Ok(inst.u)) + inst.map_or(Ok(E::Base::ZERO), |inst| Ok(inst.u)) })?; let x0 = AllocatedNum::alloc(cs.namespace(|| "allocate x0"), || { - inst.map_or(Ok(E1::Base::ZERO), |inst| Ok(inst.X[0])) + inst.map_or(Ok(E::Base::ZERO), |inst| Ok(inst.X[0])) })?; let x1 = AllocatedNum::alloc(cs.namespace(|| "allocate x1"), || { - inst.map_or(Ok(E1::Base::ZERO), |inst| Ok(inst.X[1])) + inst.map_or(Ok(E::Base::ZERO), |inst| Ok(inst.X[1])) })?; Ok(Self { @@ -367,23 +344,22 @@ pub mod emulated { u, x0, x1, - _p: PhantomData, }) } - pub fn fold_with_r1cs::Base>>( + pub fn fold_with_r1cs>( &self, mut cs: CS, - pp_digest: &AllocatedNum, - W_new: AllocatedPoint, - E_new: AllocatedPoint, - u_W: &AllocatedPoint, - u_x0: &AllocatedNum, - u_x1: &AllocatedNum, - comm_T: &AllocatedPoint, - ro_consts: ROConstantsCircuit, + pp_digest: &AllocatedNum, + W_new: AllocatedPoint, + E_new: AllocatedPoint, + u_W: &AllocatedPoint, + u_x0: &AllocatedNum, + u_x1: &AllocatedNum, + comm_T: &AllocatedPoint, + ro_consts: ROConstantsCircuit, ) -> Result { - let mut ro = E1::ROCircuit::new( + let mut ro = E::ROCircuit::new( ro_consts, 1 + NUM_FE_IN_EMULATED_POINT + 2 + NUM_FE_IN_EMULATED_POINT, // pp_digest + u.W + u.x + comm_T ); @@ -439,13 +415,12 @@ pub mod emulated { u: u_fold, x0: x0_fold, x1: x1_fold, - _p: PhantomData, }) } - pub fn absorb_in_ro(&self, mut cs: CS, ro: &mut E1::ROCircuit) -> Result<(), SynthesisError> + pub fn absorb_in_ro(&self, mut cs: CS, ro: &mut E::ROCircuit) -> Result<(), SynthesisError> where - CS: ConstraintSystem<::Base>, + CS: ConstraintSystem, { self .comm_E @@ -461,7 +436,7 @@ pub mod emulated { Ok(()) } - pub fn conditionally_select::Base>>( + pub fn conditionally_select>( &self, mut cs: CS, other: &Self, @@ -506,11 +481,10 @@ pub mod emulated { u, x0, x1, - _p: PhantomData, }) } - pub fn default::Base>>( + pub fn default>( mut cs: CS, limb_width: usize, n_limbs: usize, @@ -529,36 +503,32 @@ pub mod emulated { u, x0, x1, - _p: PhantomData, }) } } - pub struct AllocatedFoldingData + pub struct AllocatedFoldingData where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { - pub U: AllocatedRelaxedR1CSInstance, - pub u_W: AllocatedPoint, - pub u_x0: AllocatedNum, - pub u_x1: AllocatedNum, - pub T: AllocatedPoint, - _p: PhantomData, + pub U: AllocatedRelaxedR1CSInstance, + pub u_W: AllocatedPoint, + pub u_x0: AllocatedNum, + pub u_x1: AllocatedNum, + pub T: AllocatedPoint, } - impl AllocatedFoldingData + impl AllocatedFoldingData where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { pub fn alloc( mut cs: CS, - inst: Option<&FoldingData>, + inst: Option<&FoldingData>>, limb_width: usize, n_limbs: usize, ) -> Result where - CS: ConstraintSystem<::Base>, + CS: ConstraintSystem, { let U = AllocatedRelaxedR1CSInstance::alloc( cs.namespace(|| "allocate U"), @@ -575,11 +545,11 @@ pub mod emulated { )?; let u_x0 = AllocatedNum::alloc(cs.namespace(|| "allocate u_x0"), || { - inst.map_or(Ok(E1::Base::ZERO), |inst| Ok(inst.u.X[0])) + inst.map_or(Ok(E::Base::ZERO), |inst| Ok(inst.u.X[0])) })?; let u_x1 = AllocatedNum::alloc(cs.namespace(|| "allocate u_x1"), || { - inst.map_or(Ok(E1::Base::ZERO), |inst| Ok(inst.u.X[1])) + inst.map_or(Ok(E::Base::ZERO), |inst| Ok(inst.u.X[1])) })?; let T = AllocatedPoint::alloc( @@ -597,7 +567,6 @@ pub mod emulated { u_x0, u_x1, T, - _p: PhantomData, }) } diff --git a/src/cyclefold/nifs.rs b/src/cyclefold/nifs.rs index c6cf0cb67..1d145cc86 100644 --- a/src/cyclefold/nifs.rs +++ b/src/cyclefold/nifs.rs @@ -1,7 +1,5 @@ //! This module defines the needed wrong-field NIFS prover -use std::marker::PhantomData; - use ff::Field; use crate::{ @@ -12,15 +10,14 @@ use crate::{ utils::scalar_as_base, }, r1cs::{R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness}, - traits::{commitment::CommitmentTrait, /*AbsorbInROTrait,*/ Engine, ROConstants, ROTrait}, + traits::{commitment::CommitmentTrait, CurveCycleEquipped, Dual, Engine, ROConstants, ROTrait}, Commitment, CommitmentKey, CompressedCommitment, }; /// TODO: Docs -pub fn absorb_commitment(comm: &Commitment, ro: &mut E2::RO) +pub fn absorb_commitment(comm: &Commitment, ro: &mut as Engine>::RO) where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { let (x, y, is_infinity) = comm.to_coordinates(); @@ -28,24 +25,23 @@ where let y_limbs = nat_to_limbs(&f_to_nat(&y), BN_LIMB_WIDTH, BN_N_LIMBS).unwrap(); for limb in x_limbs { - ro.absorb(scalar_as_base::(limb)); + ro.absorb(scalar_as_base::>(limb)); } for limb in y_limbs { - ro.absorb(scalar_as_base::(limb)); + ro.absorb(scalar_as_base::>(limb)); } if is_infinity { - ro.absorb(::Scalar::ONE); + ro.absorb(E::Scalar::ONE); } else { - ro.absorb(::Scalar::ZERO); + ro.absorb(E::Scalar::ZERO); } } -fn absorb_r1cs(u: &R1CSInstance, ro: &mut E2::RO) +fn absorb_r1cs(u: &R1CSInstance, ro: &mut as Engine>::RO) where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { - absorb_commitment::(&u.comm_W, ro); + absorb_commitment::(&u.comm_W, ro); for x in &u.X { ro.absorb(*x); } @@ -53,51 +49,48 @@ where /// A SNARK that holds the proof of a step of an incremental computation #[derive(Debug)] -pub struct NIFS +pub struct NIFS where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { - pub(crate) comm_T: CompressedCommitment, - _p: PhantomData, + pub(crate) comm_T: CompressedCommitment, } -impl NIFS +impl NIFS where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { /// Takes a relaxed R1CS instance-witness pair (U1, W1) and an R1CS instance-witness pair (U2, W) /// and folds them into a new relaxed R1CS instance-witness pair (U, W) and a commitment to the /// cross term T. It also provides the challenge r used to fold the instances. pub fn prove( - ck: &CommitmentKey, - ro_consts: &ROConstants, - pp_digest: &E1::Scalar, - S: &R1CSShape, - U1: &RelaxedR1CSInstance, - W1: &RelaxedR1CSWitness, - U2: &R1CSInstance, - W2: &R1CSWitness, + ck: &CommitmentKey, + ro_consts: &ROConstants>, + pp_digest: & as Engine>::Base, + S: &R1CSShape, + U1: &RelaxedR1CSInstance, + W1: &RelaxedR1CSWitness, + U2: &R1CSInstance, + W2: &R1CSWitness, ) -> Result< ( Self, - (RelaxedR1CSInstance, RelaxedR1CSWitness), - E1::Scalar, + (RelaxedR1CSInstance, RelaxedR1CSWitness), + as Engine>::Base, ), NovaError, > { - let mut ro = E2::RO::new(ro_consts.clone(), NUM_FE_FOR_RO); + let mut ro = as Engine>::RO::new(ro_consts.clone(), NUM_FE_FOR_RO); ro.absorb(*pp_digest); - absorb_r1cs::(U2, &mut ro); + absorb_r1cs::(U2, &mut ro); let (T, comm_T) = S.commit_T(ck, U1, W1, U2, W2)?; - absorb_commitment::(&comm_T, &mut ro); + absorb_commitment::(&comm_T, &mut ro); - let r = scalar_as_base::(ro.squeeze(NUM_CHALLENGE_BITS)); + let r: E::Scalar = scalar_as_base::>(ro.squeeze(NUM_CHALLENGE_BITS)); let U = U1.fold(U2, &comm_T, &r); @@ -106,7 +99,6 @@ where Ok(( Self { comm_T: comm_T.compress(), - _p: PhantomData, }, (U, W), r, diff --git a/src/cyclefold/nova_circuit.rs b/src/cyclefold/nova_circuit.rs index 6155684d6..08a58f7d0 100644 --- a/src/cyclefold/nova_circuit.rs +++ b/src/cyclefold/nova_circuit.rs @@ -10,7 +10,8 @@ use crate::{ }, r1cs::{R1CSInstance, RelaxedR1CSInstance}, traits::{ - circuit::StepCircuit, commitment::CommitmentTrait, Engine, ROCircuitTrait, ROConstantsCircuit, + circuit::StepCircuit, commitment::CommitmentTrait, CurveCycleEquipped, Dual, Engine, + ROCircuitTrait, ROConstantsCircuit, }, Commitment, }; @@ -55,40 +56,38 @@ impl FoldingData { // TODO: This needs to take in the initial cyclefold relaxed R1CS instance as well #[derive(Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct AugmentedCircuitInputs +pub struct AugmentedCircuitInputs where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { - pp_digest: E1::Scalar, - i: E1::Base, - z0: Vec, + pp_digest: as Engine>::Base, + i: E::Base, + z0: Vec, - zi: Option>, - data_p: Option>, + zi: Option>, + data_p: Option>>, - data_c_1: Option>, - data_c_2: Option>, + data_c_1: Option>, + data_c_2: Option>, - E_new: Option>, - W_new: Option>, + E_new: Option>>, + W_new: Option>>, } -impl AugmentedCircuitInputs +impl AugmentedCircuitInputs where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { pub fn new( - pp_digest: E1::Scalar, - i: E1::Base, - z0: Vec, - zi: Option>, - data_p: Option>, - data_c_1: Option>, - data_c_2: Option>, - E_new: Option>, - W_new: Option>, + pp_digest: as Engine>::Base, + i: E::Base, + z0: Vec, + zi: Option>, + data_p: Option>>, + data_c_1: Option>, + data_c_2: Option>, + E_new: Option>>, + W_new: Option>>, ) -> Self { Self { pp_digest, @@ -103,28 +102,26 @@ where } } } -pub struct AugmentedCircuit<'a, E1, E2, SC> +pub struct AugmentedCircuit<'a, E, SC> where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - SC: StepCircuit, + E: CurveCycleEquipped, + SC: StepCircuit, { params: &'a AugmentedCircuitParams, - ro_consts: ROConstantsCircuit, - inputs: Option>, + ro_consts: ROConstantsCircuit, + inputs: Option>, step_circuit: &'a SC, } -impl<'a, E1, E2, SC> AugmentedCircuit<'a, E1, E2, SC> +impl<'a, E, SC> AugmentedCircuit<'a, E, SC> where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - SC: StepCircuit, + E: CurveCycleEquipped, + SC: StepCircuit, { pub const fn new( params: &'a AugmentedCircuitParams, - ro_consts: ROConstantsCircuit, - inputs: Option>, + ro_consts: ROConstantsCircuit, + inputs: Option>, step_circuit: &'a SC, ) -> Self { Self { @@ -135,25 +132,25 @@ where } } - fn alloc_witness::Base>>( + fn alloc_witness>( &self, mut cs: CS, arity: usize, ) -> Result< ( - AllocatedNum, // pp_digest - AllocatedNum, // i - Vec>, // z0 - Vec>, // zi - emulated::AllocatedFoldingData, //data_p - AllocatedFoldingData, // data_c_1 - AllocatedFoldingData, // data_c_2 - emulated::AllocatedPoint, // E_new - emulated::AllocatedPoint, // W_new + AllocatedNum, // pp_digest + AllocatedNum, // i + Vec>, // z0 + Vec>, // zi + emulated::AllocatedFoldingData, //data_p + AllocatedFoldingData, // data_c_1 + AllocatedFoldingData, // data_c_2 + emulated::AllocatedPoint, // E_new + emulated::AllocatedPoint, // W_new ), SynthesisError, > { - let pp_digest = alloc_scalar_as_base::( + let pp_digest = alloc_scalar_as_base::( cs.namespace(|| "params"), self.inputs.as_ref().map(|inputs| inputs.pp_digest), )?; @@ -174,17 +171,17 @@ where Ok(self.inputs.get()?.z0[i]) }) }) - .collect::>, _>>()?; + .collect::>, _>>()?; // Allocate zi. If inputs.zi is not provided (base case) allocate default value 0 - let zero = vec![E1::Base::ZERO; arity]; + let zero = vec![E::Base::ZERO; arity]; let z_i = (0..arity) .map(|i| { AllocatedNum::alloc(cs.namespace(|| format!("zi_{i}")), || { Ok(self.inputs.get()?.zi.as_ref().unwrap_or(&zero)[i]) }) }) - .collect::>, _>>()?; + .collect::>, _>>()?; let data_p = emulated::AllocatedFoldingData::alloc( cs.namespace(|| "data_p"), @@ -255,13 +252,13 @@ where )) } - pub fn synthesize_base_case::Base>>( + pub fn synthesize_base_case>( &self, mut cs: CS, ) -> Result< ( - AllocatedRelaxedR1CSInstance, - emulated::AllocatedRelaxedR1CSInstance, + AllocatedRelaxedR1CSInstance, + emulated::AllocatedRelaxedR1CSInstance, ), SynthesisError, > { @@ -280,29 +277,29 @@ where Ok((U_c_default, U_p_default)) } - pub fn synthesize_non_base_case::Base>>( + pub fn synthesize_non_base_case>( &self, mut cs: CS, - pp_digest: &AllocatedNum, - i: &AllocatedNum, - z_0: &[AllocatedNum], - z_i: &[AllocatedNum], - data_p: &emulated::AllocatedFoldingData, - data_c_1: &AllocatedFoldingData, - data_c_2: &AllocatedFoldingData, - E_new: &emulated::AllocatedPoint, - W_new: &emulated::AllocatedPoint, + pp_digest: &AllocatedNum, + i: &AllocatedNum, + z_0: &[AllocatedNum], + z_i: &[AllocatedNum], + data_p: &emulated::AllocatedFoldingData, + data_c_1: &AllocatedFoldingData, + data_c_2: &AllocatedFoldingData, + E_new: &emulated::AllocatedPoint, + W_new: &emulated::AllocatedPoint, arity: usize, ) -> Result< ( - AllocatedRelaxedR1CSInstance, - emulated::AllocatedRelaxedR1CSInstance, + AllocatedRelaxedR1CSInstance, + emulated::AllocatedRelaxedR1CSInstance, AllocatedBit, ), SynthesisError, > { // Follows the outline written down here https://hackmd.io/@mpenciak/HybHrnNFT - let mut ro_p = E1::ROCircuit::new( + let mut ro_p = E::ROCircuit::new( self.ro_consts.clone(), 2 + 2 * arity + 2 * NUM_FE_IN_EMULATED_POINT + 3, ); @@ -328,7 +325,7 @@ where &hash_p, )?; - let mut ro_c = E1::ROCircuit::new(self.ro_consts.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF); + let mut ro_c = E::ROCircuit::new(self.ro_consts.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF); ro_c.absorb(pp_digest); ro_c.absorb(i); @@ -362,7 +359,7 @@ where )?; // Calculate h_int = H(pp, U_c_int) - let mut ro_c_int = E1::ROCircuit::new(self.ro_consts.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF - 1); + let mut ro_c_int = E::ROCircuit::new(self.ro_consts.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF - 1); ro_c_int.absorb(pp_digest); U_int.absorb_in_ro(cs.namespace(|| "absorb U_c_int"), &mut ro_c_int)?; let h_c_int_bits = @@ -370,7 +367,7 @@ where let h_c_int = le_bits_to_num(cs.namespace(|| "intermediate hash"), &h_c_int_bits)?; // Calculate h_1 = H(pp, U_c_1) - let mut ro_c_1 = E1::ROCircuit::new(self.ro_consts.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF - 1); + let mut ro_c_1 = E::ROCircuit::new(self.ro_consts.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF - 1); ro_c_1.absorb(pp_digest); data_c_2 .U @@ -411,10 +408,10 @@ where Ok((U_c, U_p, checks_pass)) } - pub fn synthesize::Base>>( + pub fn synthesize>( self, cs: &mut CS, - ) -> Result>, SynthesisError> { + ) -> Result>, SynthesisError> { // TODO: It's written down here https://hackmd.io/@mpenciak/HybHrnNFT let arity = self.step_circuit.arity(); @@ -468,7 +465,7 @@ where // Compute i + 1 let i_new = AllocatedNum::alloc(cs.namespace(|| "i + 1"), || { - Ok(*i.get_value().get()? + E1::Base::ONE) + Ok(*i.get_value().get()? + E::Base::ONE) })?; cs.enforce( || "check i + 1", @@ -495,7 +492,7 @@ where )); } - let mut ro_p = E1::ROCircuit::new( + let mut ro_p = E::ROCircuit::new( self.ro_consts.clone(), 2 + 2 * arity + 2 * NUM_FE_IN_EMULATED_POINT + 3, ); @@ -511,7 +508,7 @@ where let hash_p_bits = ro_p.squeeze(cs.namespace(|| "hash_p_bits"), NUM_HASH_BITS)?; let hash_p = le_bits_to_num(cs.namespace(|| "hash_p"), &hash_p_bits)?; - let mut ro_c = E1::ROCircuit::new(self.ro_consts, NUM_FE_WITHOUT_IO_FOR_CRHF); + let mut ro_c = E::ROCircuit::new(self.ro_consts, NUM_FE_WITHOUT_IO_FOR_CRHF); ro_c.absorb(&pp_digest); ro_c.absorb(&i_new); Unew_c.absorb_in_ro(cs.namespace(|| "absorb Unew_c"), &mut ro_c)?; @@ -530,32 +527,25 @@ mod test { use crate::{ bellpepper::test_shape_cs::TestShapeCS, constants::{BN_LIMB_WIDTH, BN_N_LIMBS}, - provider::{ - Bn256Engine, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine, - }, + provider::{Bn256Engine, PallasEngine, Secp256k1Engine}, traits::circuit::TrivialCircuit, }; use super::*; - fn test_circuit_size_with() + fn test_circuit_size_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { let params = AugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS); - let ro_consts = ROConstantsCircuit::::default(); + let ro_consts = ROConstantsCircuit::::default(); - let step_circuit = TrivialCircuit::::default(); + let step_circuit = TrivialCircuit::::default(); - let circuit = AugmentedCircuit::>::new( - ¶ms, - ro_consts, - None, - &step_circuit, - ); - let mut cs: TestShapeCS = TestShapeCS::default(); + let circuit = + AugmentedCircuit::>::new(¶ms, ro_consts, None, &step_circuit); + let mut cs: TestShapeCS> = TestShapeCS::default(); let _ = circuit.synthesize(&mut cs); @@ -568,8 +558,8 @@ mod test { #[test] fn test_circuit_size() { - test_circuit_size_with::(); - test_circuit_size_with::(); - test_circuit_size_with::(); + test_circuit_size_with::(); + test_circuit_size_with::(); + test_circuit_size_with::(); } } diff --git a/src/cyclefold/snark.rs b/src/cyclefold/snark.rs index d0acb2173..7c8621331 100644 --- a/src/cyclefold/snark.rs +++ b/src/cyclefold/snark.rs @@ -19,8 +19,8 @@ use crate::{ RelaxedR1CSWitness, }, traits::{ - circuit::StepCircuit, commitment::CommitmentTrait, AbsorbInROTrait, Engine, ROConstantsCircuit, - ROTrait, + circuit::StepCircuit, commitment::CommitmentTrait, AbsorbInROTrait, CurveCycleEquipped, Dual, + Engine, ROConstantsCircuit, ROTrait, }, Commitment, CommitmentKey, DigestComputer, R1CSWithArity, ROConstants, ResourceBuffer, SimpleDigestible, @@ -43,65 +43,60 @@ use serde::{Deserialize, Serialize}; #[serde(bound = "")] #[abomonation_bounds( where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - ::Repr: Abomonation, - ::Repr: Abomonation, + E: CurveCycleEquipped, + C: StepCircuit< as Engine>::Base>, )] -pub struct PublicParams +pub struct PublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, + E: CurveCycleEquipped, + C: StepCircuit< as Engine>::Base>, { F_arity_primary: usize, - ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit, - ck_primary: CommitmentKey, - circuit_shape_primary: R1CSWithArity, + ro_consts_primary: ROConstants>, + ro_consts_circuit_primary: ROConstantsCircuit>, + ck_primary: CommitmentKey, + circuit_shape_primary: R1CSWithArity, augmented_circuit_params: AugmentedCircuitParams, - ro_consts_cyclefold: ROConstants, - ck_cyclefold: CommitmentKey, - circuit_shape_cyclefold: R1CSWithArity, + ro_consts_cyclefold: ROConstants>, + ck_cyclefold: CommitmentKey>, + circuit_shape_cyclefold: R1CSWithArity>, #[abomonation_skip] #[serde(skip, default = "OnceCell::new")] - digest: OnceCell, - _p: PhantomData<(E1, E2, C1)>, + digest: OnceCell< as Engine>::Base>, + _p: PhantomData, } -impl PublicParams +impl PublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, + E: CurveCycleEquipped, + C: StepCircuit< as Engine>::Base>, { /// TODO: docs pub fn setup( - c_primary: &C1, - ck_hint1: &CommitmentKeyHint, - ck_hint_cyclefold: &CommitmentKeyHint, + c_primary: &C, + ck_hint1: &CommitmentKeyHint, + ck_hint_cyclefold: &CommitmentKeyHint>, ) -> Self { let F_arity_primary = c_primary.arity(); - let ro_consts_primary = ROConstants::::default(); - let ro_consts_circuit_primary = ROConstantsCircuit::::default(); + let ro_consts_primary = ROConstants::>::default(); + let ro_consts_circuit_primary = ROConstantsCircuit::>::default(); let augmented_circuit_params = AugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS); - let circuit_primary: AugmentedCircuit<'_, E2, E1, C1> = AugmentedCircuit::new( + let circuit_primary: AugmentedCircuit<'_, E, C> = AugmentedCircuit::new( &augmented_circuit_params, ro_consts_circuit_primary.clone(), None, c_primary, ); - let mut cs: ShapeCS = ShapeCS::new(); + let mut cs: ShapeCS = ShapeCS::new(); let _ = circuit_primary.synthesize(&mut cs); let (r1cs_shape_primary, ck_primary) = cs.r1cs_shape_and_key(ck_hint1); let circuit_shape_primary = R1CSWithArity::new(r1cs_shape_primary, F_arity_primary); - let ro_consts_cyclefold = ROConstants::::default(); - let mut cs: ShapeCS = ShapeCS::new(); - let circuit_cyclefold: CyclefoldCircuit = CyclefoldCircuit::new(None); + let ro_consts_cyclefold = ROConstants::>::default(); + let mut cs: ShapeCS> = ShapeCS::new(); + let circuit_cyclefold: CyclefoldCircuit = CyclefoldCircuit::new(None); let _ = circuit_cyclefold.synthesize(&mut cs); let (r1cs_shape_cyclefold, ck_cyclefold) = cs.r1cs_shape_and_key(ck_hint_cyclefold); let circuit_shape_cyclefold = R1CSWithArity::new(r1cs_shape_cyclefold, 0); @@ -122,7 +117,7 @@ where } /// TODO: docs - pub fn digest(&self) -> E1::Scalar { + pub fn digest(&self) -> as Engine>::Base { self .digest .get_or_try_init(|| DigestComputer::new(self).digest()) @@ -147,57 +142,54 @@ where } } -impl SimpleDigestible for PublicParams +impl SimpleDigestible for PublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, + E: CurveCycleEquipped, + C: StepCircuit< as Engine>::Base>, { } /// TODO: docs #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct RecursiveSNARK +pub struct RecursiveSNARK where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, + E: CurveCycleEquipped, + C: StepCircuit< as Engine>::Base>, { // Input - z0_primary: Vec, + z0_primary: Vec, // primary circuit data - r_W_primary: RelaxedR1CSWitness, - r_U_primary: RelaxedR1CSInstance, - l_w_primary: R1CSWitness, - l_u_primary: R1CSInstance, + r_W_primary: RelaxedR1CSWitness, + r_U_primary: RelaxedR1CSInstance, + l_w_primary: R1CSWitness, + l_u_primary: R1CSInstance, // cyclefold circuit data - r_W_cyclefold: RelaxedR1CSWitness, - r_U_cyclefold: RelaxedR1CSInstance, + r_W_cyclefold: RelaxedR1CSWitness>, + r_U_cyclefold: RelaxedR1CSInstance>, // memory buffers for folding steps - buffer_primary: ResourceBuffer, - buffer_cyclefold: ResourceBuffer, + buffer_primary: ResourceBuffer, + buffer_cyclefold: ResourceBuffer>, i: usize, - zi_primary: Vec, + zi_primary: Vec, - _p: PhantomData, + _p: PhantomData, } -impl RecursiveSNARK +impl RecursiveSNARK where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, + E: CurveCycleEquipped, + C: StepCircuit< as Engine>::Base>, { /// TODO: docs pub fn new( - pp: &PublicParams, - c_primary: &C1, - z0_primary: &[E1::Scalar], + pp: &PublicParams, + c_primary: &C, + z0_primary: &[E::Scalar], ) -> Result { if z0_primary.len() != pp.F_arity_primary { return Err(NovaError::InvalidInitialInputLength); @@ -209,10 +201,10 @@ where let r_U_cyclefold = RelaxedR1CSInstance::default(&pp.ck_cyclefold, r1cs_cyclefold); let r_W_cyclefold = RelaxedR1CSWitness::default(r1cs_cyclefold); - let mut cs_primary = SatisfyingAssignment::::new(); - let inputs_primary: AugmentedCircuitInputs = AugmentedCircuitInputs::new( - scalar_as_base::(pp.digest()), - ::Base::from(0u64), + let mut cs_primary = SatisfyingAssignment::::new(); + let inputs_primary: AugmentedCircuitInputs = AugmentedCircuitInputs::new( + scalar_as_base::(pp.digest()), + as Engine>::Base::from(0u64), z0_primary.to_vec(), None, None, @@ -247,7 +239,7 @@ where l_u: None, ABC_Z_1: R1CSResult::default(r1cs_primary.num_cons), ABC_Z_2: R1CSResult::default(r1cs_primary.num_cons), - T: r1cs::default_T::(r1cs_primary.num_cons), + T: r1cs::default_T::(r1cs_primary.num_cons), }; let buffer_cyclefold = ResourceBuffer { @@ -255,7 +247,7 @@ where l_u: None, ABC_Z_1: R1CSResult::default(r1cs_cyclefold.num_cons), ABC_Z_2: R1CSResult::default(r1cs_cyclefold.num_cons), - T: r1cs::default_T::(r1cs_cyclefold.num_cons), + T: r1cs::default_T::>(r1cs_cyclefold.num_cons), }; Ok(Self { @@ -275,17 +267,13 @@ where } /// TODO: docs - pub fn prove_step( - &mut self, - pp: &PublicParams, - c_primary: &C1, - ) -> Result<(), NovaError> { + pub fn prove_step(&mut self, pp: &PublicParams, c_primary: &C) -> Result<(), NovaError> { if self.i == 0 { self.i = 1; return Ok(()); } - let (nifs_primary, (r_U_primary, r_W_primary), r) = super::nifs::NIFS::::prove( + let (nifs_primary, (r_U_primary, r_W_primary), r) = super::nifs::NIFS::prove( &pp.ck_primary, &pp.ro_consts_primary, &pp.digest(), @@ -314,24 +302,24 @@ where let r_bools = r.to_le_bits().iter().map(|b| Some(*b)).collect::>(); - let comm_T = Commitment::::decompress(&nifs_primary.comm_T)?; + let comm_T = Commitment::decompress(&nifs_primary.comm_T)?; let E_new = self.r_U_primary.comm_E + comm_T * r; let W_new = self.r_U_primary.comm_W + self.l_u_primary.comm_W * r; - let mut cs_cyclefold_E = SatisfyingAssignment::::with_capacity( + let mut cs_cyclefold_E = SatisfyingAssignment::>::with_capacity( pp.circuit_shape_cyclefold.r1cs_shape.num_io + 1, pp.circuit_shape_cyclefold.r1cs_shape.num_vars, ); - let inputs_cyclefold_E: CyclefoldCircuitInputs = CyclefoldCircuitInputs::new( + let inputs_cyclefold_E: CyclefoldCircuitInputs = CyclefoldCircuitInputs::new( Some(self.r_U_primary.comm_E), Some(comm_T), Some(E_new), r_bools.clone(), ); - let circuit_cyclefold_E: CyclefoldCircuit = CyclefoldCircuit::new(Some(inputs_cyclefold_E)); + let circuit_cyclefold_E: CyclefoldCircuit = CyclefoldCircuit::new(Some(inputs_cyclefold_E)); let _output_cyclefold_E = circuit_cyclefold_E.synthesize(&mut cs_cyclefold_E); @@ -343,7 +331,7 @@ where let (nifs_cyclefold_E, (r_U_cyclefold_E, r_W_cyclefold_E), _) = NIFS::prove( &pp.ck_cyclefold, &pp.ro_consts_cyclefold, - &scalar_as_base::(pp.digest()), + &scalar_as_base::(pp.digest()), &pp.circuit_shape_cyclefold.r1cs_shape, &self.r_U_cyclefold, &self.r_W_cyclefold, @@ -351,21 +339,21 @@ where &l_w_cyclefold_E, )?; - let comm_T_E = Commitment::::decompress(&nifs_cyclefold_E.comm_T)?; + let comm_T_E = Commitment::>::decompress(&nifs_cyclefold_E.comm_T)?; - let mut cs_cyclefold_W = SatisfyingAssignment::::with_capacity( + let mut cs_cyclefold_W = SatisfyingAssignment::>::with_capacity( pp.circuit_shape_cyclefold.r1cs_shape.num_io + 1, pp.circuit_shape_cyclefold.r1cs_shape.num_vars, ); - let inputs_cyclefold_W: CyclefoldCircuitInputs = CyclefoldCircuitInputs::new( + let inputs_cyclefold_W: CyclefoldCircuitInputs = CyclefoldCircuitInputs::new( Some(self.r_U_primary.comm_W), Some(self.l_u_primary.comm_W), Some(W_new), r_bools, ); - let circuit_cyclefold_W: CyclefoldCircuit = CyclefoldCircuit::new(Some(inputs_cyclefold_W)); + let circuit_cyclefold_W: CyclefoldCircuit = CyclefoldCircuit::new(Some(inputs_cyclefold_W)); let _output_cyclefold_W = circuit_cyclefold_W.synthesize(&mut cs_cyclefold_W); @@ -377,7 +365,7 @@ where let (nifs_cyclefold_W, (r_U_cyclefold_W, r_W_cyclefold_W), _) = NIFS::prove( &pp.ck_cyclefold, &pp.ro_consts_cyclefold, - &scalar_as_base::(pp.digest()), + &scalar_as_base::(pp.digest()), &pp.circuit_shape_cyclefold.r1cs_shape, &r_U_cyclefold_E, &r_W_cyclefold_E, @@ -385,9 +373,9 @@ where &l_w_cyclefold_W, )?; - let comm_T_W = Commitment::::decompress(&nifs_cyclefold_W.comm_T)?; + let comm_T_W = Commitment::>::decompress(&nifs_cyclefold_W.comm_T)?; - let mut cs_primary = SatisfyingAssignment::::with_capacity( + let mut cs_primary = SatisfyingAssignment::::with_capacity( pp.circuit_shape_primary.r1cs_shape.num_io + 1, pp.circuit_shape_primary.r1cs_shape.num_vars, ); @@ -396,9 +384,9 @@ where let data_c_E = FoldingData::new(self.r_U_cyclefold.clone(), l_u_cyclefold_E, comm_T_E); let data_c_W = FoldingData::new(r_U_cyclefold_E, l_u_cyclefold_W, comm_T_W); - let inputs_primary: AugmentedCircuitInputs = AugmentedCircuitInputs::new( - scalar_as_base::(pp.digest()), - ::Base::from(self.i as u64), + let inputs_primary: AugmentedCircuitInputs = AugmentedCircuitInputs::new( + scalar_as_base::(pp.digest()), + as Engine>::Base::from(self.i as u64), self.z0_primary.clone(), Some(self.zi_primary.clone()), Some(data_p), @@ -408,7 +396,7 @@ where Some(W_new), ); - let circuit_primary: AugmentedCircuit<'_, E2, E1, C1> = AugmentedCircuit::new( + let circuit_primary: AugmentedCircuit<'_, E, C> = AugmentedCircuit::new( &pp.augmented_circuit_params, pp.ro_consts_circuit_primary.clone(), Some(inputs_primary), @@ -441,10 +429,10 @@ where /// TODO: docs pub fn verify( &self, - pp: &PublicParams, + pp: &PublicParams, num_steps: usize, - z0_primary: &[E1::Scalar], - ) -> Result, NovaError> { + z0_primary: &[E::Scalar], + ) -> Result, NovaError> { // number of steps cannot be zero let is_num_steps_zero = num_steps == 0; @@ -466,23 +454,23 @@ where } let (hash_primary, hash_cyclefold) = { - let mut hasher = ::RO::new( + let mut hasher = as Engine>::RO::new( pp.ro_consts_primary.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.F_arity_primary, ); hasher.absorb(pp.digest()); - hasher.absorb(E1::Scalar::from(num_steps as u64)); + hasher.absorb( as Engine>::Base::from(num_steps as u64)); for e in z0_primary { hasher.absorb(*e); } for e in &self.zi_primary { hasher.absorb(*e); } - absorb_relaxed_r1cs::(&self.r_U_primary, &mut hasher); + absorb_relaxed_r1cs::(&self.r_U_primary, &mut hasher); let hash_primary = hasher.squeeze(NUM_HASH_BITS); let mut hasher = - ::RO::new(pp.ro_consts_cyclefold.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF); + as Engine>::RO::new(pp.ro_consts_cyclefold.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF); hasher.absorb(pp.digest()); self.r_U_cyclefold.absorb_in_ro(&mut hasher); let hash_cyclefold = hasher.squeeze(NUM_HASH_BITS); @@ -492,8 +480,8 @@ where // TODO: This seems like it might be a bad sign, I don't know if I should need to use // `scalar_as_base` here - if scalar_as_base::(hash_primary) != self.l_u_primary.X[0] - || scalar_as_base::(hash_cyclefold) != self.l_u_primary.X[1] + if scalar_as_base::>(hash_primary) != self.l_u_primary.X[0] + || scalar_as_base::>(hash_cyclefold) != self.l_u_primary.X[1] { return Err(NovaError::ProofVerifyError); } @@ -534,13 +522,12 @@ where } } -fn absorb_relaxed_r1cs(U: &RelaxedR1CSInstance, ro: &mut E2::RO) +fn absorb_relaxed_r1cs(U: &RelaxedR1CSInstance, ro: &mut as Engine>::RO) where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E: CurveCycleEquipped, { - absorb_commitment::(&U.comm_W, ro); - absorb_commitment::(&U.comm_E, ro); + absorb_commitment::(&U.comm_W, ro); + absorb_commitment::(&U.comm_E, ro); for e in &U.X { ro.absorb(*e); }