arnaucube
arnaucube/sonobePublic Self-hosted repository
sonobe/folding-schemes/src/frontend/mod.rs
folding-schemes/src/frontend/mod.rsRaw
 1use crate::Error;
 2use ark_ff::PrimeField;
 3use ark_r1cs_std::fields::fp::FpVar;
 4use ark_relations::r1cs::{ConstraintSystemRef, SynthesisError};
 5use ark_std::fmt::Debug;
 6
 7pub mod utils;
 8
 9/// FCircuit defines the trait of the circuit of the F function, which is the one being folded (ie.
10/// inside the agmented F' function).
11/// The parameter z_i denotes the current state, and z_{i+1} denotes the next state after applying
12/// the step.
13pub trait FCircuit<F: PrimeField>: Clone + Debug {
14    type Params: Debug;
15
16    /// returns a new FCircuit instance
17    fn new(params: Self::Params) -> Result<Self, Error>;
18
19    /// returns the number of elements in the state of the FCircuit, which corresponds to the
20    /// FCircuit inputs.
21    fn state_len(&self) -> usize;
22
23    /// returns the number of elements in the external inputs used by the FCircuit. External inputs
24    /// are optional, and in case no external inputs are used, this method should return 0.
25    fn external_inputs_len(&self) -> usize;
26
27    /// computes the next state values in place, assigning z_{i+1} into z_i, and computing the new
28    /// z_{i+1}
29    fn step_native(
30        // this method uses self, so that each FCircuit implementation (and different frontends)
31        // can hold a state if needed to store data to compute the next state.
32        &self,
33        i: usize,
34        z_i: Vec<F>,
35        external_inputs: Vec<F>, // inputs that are not part of the state
36    ) -> Result<Vec<F>, Error>;
37
38    /// generates the constraints for the step of F for the given z_i
39    fn generate_step_constraints(
40        // this method uses self, so that each FCircuit implementation (and different frontends)
41        // can hold a state if needed to store data to generate the constraints.
42        &self,
43        cs: ConstraintSystemRef<F>,
44        i: usize,
45        z_i: Vec<FpVar<F>>,
46        external_inputs: Vec<FpVar<F>>, // inputs that are not part of the state
47    ) -> Result<Vec<FpVar<F>>, SynthesisError>;
48}
49
50#[cfg(test)]
51pub mod tests {
52    use super::*;
53    use ark_bn254::Fr;
54    use ark_relations::r1cs::{ConstraintSynthesizer, ConstraintSystem};
55
56    use utils::{CubicFCircuit, CustomFCircuit, WrapperCircuit};
57
58    #[test]
59    fn test_testfcircuit() {
60        let cs = ConstraintSystem::<Fr>::new_ref();
61        let F_circuit = CubicFCircuit::<Fr>::new(()).unwrap();
62
63        let wrapper_circuit = WrapperCircuit::<Fr, CubicFCircuit<Fr>> {
64            FC: F_circuit,
65            z_i: Some(vec![Fr::from(3_u32)]),
66            z_i1: Some(vec![Fr::from(35_u32)]),
67        };
68        wrapper_circuit.generate_constraints(cs.clone()).unwrap();
69        assert_eq!(cs.num_constraints(), 3);
70    }
71
72    #[test]
73    fn test_customtestfcircuit() {
74        let cs = ConstraintSystem::<Fr>::new_ref();
75        let n_constraints = 1000;
76        let custom_circuit = CustomFCircuit::<Fr>::new(n_constraints).unwrap();
77        let z_i = vec![Fr::from(5_u32)];
78        let wrapper_circuit = WrapperCircuit::<Fr, CustomFCircuit<Fr>> {
79            FC: custom_circuit,
80            z_i: Some(z_i.clone()),
81            z_i1: Some(custom_circuit.step_native(0, z_i, vec![]).unwrap()),
82        };
83        wrapper_circuit.generate_constraints(cs.clone()).unwrap();
84        assert_eq!(cs.num_constraints(), n_constraints);
85    }
86}