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