The frontend interface allows to define the circuit to be folded. The available frontends are arkworks are Circom.
We just need to fulfill the FCircuit
trait:
/// FCircuit defines the trait of the circuit of the F function, which is the one being folded (ie.
/// inside the agmented F' function).
/// The parameter z_i denotes the current state, and z_{i+1} denotes the next state after applying
/// the step.
pub trait FCircuit<F: PrimeField>: Clone + Debug {
type Params: Debug;
/// returns a new FCircuit instance
fn new(params: Self::Params) -> Self;
/// returns the number of elements in the state of the FCircuit, which corresponds to the
/// FCircuit inputs.
fn state_len(&self) -> usize;
/// computes the next state values in place, assigning z_{i+1} into z_i, and computing the new
/// z_{i+1}
fn step_native(
// this method uses self, so that each FCircuit implementation (and different frontends)
// can hold a state if needed to store data to compute the next state.
&self,
i: usize,
z_i: Vec<F>,
) -> Result<Vec<F>, Error>;
/// generates the constraints for the step of F for the given z_i
fn generate_step_constraints(
// this method uses self, so that each FCircuit implementation (and different frontends)
// can hold a state if needed to store data to generate the constraints.
&self,
cs: ConstraintSystemRef<F>,
i: usize,
z_i: Vec<FpVar<F>>,
) -> Result<Vec<FpVar<F>>, SynthesisError>;
}