From a32002de82b003670f6878fa9442fb591fdf979b Mon Sep 17 00:00:00 2001 From: arnaucube Date: Fri, 27 Oct 2023 12:41:15 +0200 Subject: [PATCH] refactor FCircuit to make it more suitable inside the AugmentedFCircuit --- Cargo.toml | 4 +-- src/folding/nova/circuits.rs | 56 ++++++++++++++++++++---------------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f01fe220..dde7c9ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ ark-poly = "^0.4.0" ark-std = "^0.4.0" ark-crypto-primitives = { version = "^0.4.0", default-features = false, features = ["r1cs", "sponge", "crh"] } ark-relations = { version = "^0.4.0", default-features = false } -ark-r1cs-std = { default-features = false } # use latest version of the patch +ark-r1cs-std = { default-features = false } # use latest version from the patch ark-circom = { git = "https://github.com/gakonst/ark-circom.git" } thiserror = "1.0" rayon = "1.7.0" @@ -42,7 +42,7 @@ parallel = [ # The following patch is to use a version of ark-r1cs-std compatible with # v0.4.0 but that includes a cherry-picked commit from after v0.4.0 which fixes -# the in-circuit scalar multiplication of the zero point from +# the in-circuit scalar multiplication of the zero point. The commit is from # https://github.com/arkworks-rs/r1cs-std/pull/124, without including other # changes done between v0.4.0 and this fix which would break compatibility. [patch.crates-io] diff --git a/src/folding/nova/circuits.rs b/src/folding/nova/circuits.rs index aaf349dc..58995eb3 100644 --- a/src/folding/nova/circuits.rs +++ b/src/folding/nova/circuits.rs @@ -213,13 +213,18 @@ where /// FCircuit defines the trait of the circuit of the F function, which is the one being executed /// inside the agmented F' function. -pub trait FCircuit: ConstraintSynthesizer + Copy { +pub trait FCircuit: Copy { /// method that returns z_i (input), z_{i+1} (output) fn public(self) -> (F, F); /// method that computes the next state values in place, assigning z_{i+1} into z_i, and /// computing the new z_i - fn step(&mut self); + fn step_native(&mut self); + fn step_circuit( + self, + cs: ConstraintSystemRef, + z_i: FpVar, + ) -> Result, SynthesisError>; } /// AugmentedFCircuit implements the F' circuit (augmented F) defined in @@ -230,6 +235,7 @@ pub struct AugmentedFCircuit>> { pub poseidon_config: PoseidonConfig>, pub i: Option>, pub z_0: Option, + pub z_i: Option, pub u_i: Option>, pub U_i: Option>, pub U_i1: Option>, @@ -251,11 +257,12 @@ where let z_0 = FpVar::>::new_witness(cs.clone(), || { Ok(self.z_0.unwrap_or_else(CF1::::zero)) })?; + let z_i = FpVar::>::new_witness(cs.clone(), || { + Ok(self.z_i.unwrap_or_else(CF1::::zero)) + })?; - // get z_i & z_{i+1} from the folded circuit - let (z_i_native, z_i1_native) = self.F.public(); - let z_i = FpVar::>::new_witness(cs.clone(), || Ok(z_i_native))?; - let z_i1 = FpVar::>::new_witness(cs.clone(), || Ok(z_i1_native))?; + // get z_{i+1} from the F circuit + let z_i1 = self.F.step_circuit(cs.clone(), z_i.clone())?; let u_dummy_native = CommittedInstance { cmE: C::zero(), @@ -331,9 +338,6 @@ where // else: check x==u_{i+1}.x u_i1_x.conditional_enforce_equal(&x, &is_not_basecase)?; - // WIP assert that z_i1 == F(z_i) - self.F.generate_constraints(cs.clone())?; - Ok(()) } } @@ -350,6 +354,7 @@ mod tests { use tracing_subscriber::layer::SubscriberExt; use crate::ccs::r1cs::tests::{get_test_r1cs, get_test_z}; + use crate::constants::N_BITS_CHALLENGE; use crate::folding::nova::{check_instance_relation, nifs::NIFS, Witness}; use crate::frontend::arkworks::{extract_r1cs, extract_z}; use crate::pedersen::Pedersen; @@ -369,20 +374,18 @@ mod tests { fn public(self) -> (F, F) { (self.z_i, self.z_i1) } - fn step(&mut self) { + fn step_native(&mut self) { self.z_i = self.z_i1; self.z_i1 = self.z_i * self.z_i * self.z_i + self.z_i + F::from(5_u32); } - } - impl ConstraintSynthesizer for TestFCircuit { - fn generate_constraints(self, cs: ConstraintSystemRef) -> Result<(), SynthesisError> { - let z_i = FpVar::::new_witness(cs.clone(), || Ok(self.z_i))?; - let z_i1 = FpVar::::new_witness(cs.clone(), || Ok(self.z_i1))?; + fn step_circuit( + self, + cs: ConstraintSystemRef, + z_i: FpVar, + ) -> Result, SynthesisError> { let five = FpVar::::new_constant(cs.clone(), F::from(5u32))?; - let y = &z_i * &z_i * &z_i + &z_i + &five; - y.enforce_equal(&z_i1)?; - Ok(()) + Ok(&z_i * &z_i * &z_i + &z_i + &five) } } @@ -435,7 +438,7 @@ mod tests { // get challenge from transcript let poseidon_config = poseidon_test_config::(); let mut tr = PoseidonTranscript::::new(&poseidon_config); - let r_bits = tr.get_challenge_nbits(128); + let r_bits = tr.get_challenge_nbits(N_BITS_CHALLENGE); let r_Fr = Fr::from_bigint(BigInteger::from_bits_le(&r_bits)).unwrap(); let (_w3, ci3, _T, cmT) = @@ -559,6 +562,7 @@ mod tests { poseidon_config: poseidon_config.clone(), i: None, z_0: None, + z_i: None, u_i: None, U_i: None, U_i1: None, @@ -583,7 +587,7 @@ mod tests { // first step let z_0 = Fr::from(3_u32); - let z_i = z_0; + let mut z_i = z_0; let mut z_i1 = Fr::from(35_u32); // set the circuit to be folded with z_i=z_0=3 and z_{i+1}=35 (initial values) @@ -623,8 +627,9 @@ mod tests { augmented_F_circuit = AugmentedFCircuit::> { _c: PhantomData, poseidon_config: poseidon_config.clone(), - i: Some(i), // = 0 - z_0: Some(z_0), // = z_i=3 + i: Some(i), // = 0 + z_0: Some(z_0), // = z_i=3 + z_i: Some(z_i), u_i: Some(u_i.clone()), // = dummy U_i: Some(U_i.clone()), // = dummy U_i1: Some(U_i1.clone()), // = dummy @@ -636,7 +641,7 @@ mod tests { } else { // get challenge from transcript (since this is a test, we skip absorbing values to // the transcript for simplicity) - let r_bits = tr.get_challenge_nbits(128); // TODO N_BITS_CHALLENGE + let r_bits = tr.get_challenge_nbits(N_BITS_CHALLENGE); let r_Fr = Fr::from_bigint(BigInteger::from_bits_le(&r_bits)).unwrap(); check_instance_relation(&r1cs, &w_i, &u_i).unwrap(); @@ -667,6 +672,7 @@ mod tests { poseidon_config: poseidon_config.clone(), i: Some(i), z_0: Some(z_0), + z_i: Some(z_i), u_i: Some(u_i), U_i: Some(U_i.clone()), U_i1: Some(U_i1.clone()), @@ -707,8 +713,8 @@ mod tests { // set values for next iteration i += Fr::one(); - test_F_circuit.step(); // advance the F circuit state - (_, z_i1) = test_F_circuit.public(); + test_F_circuit.step_native(); // advance the F circuit state + (z_i, z_i1) = test_F_circuit.public(); U_i = U_i1.clone(); W_i = W_i1.clone(); }