# \`StepCircuit\` trait

Check [#step-circuit](https://docs.snarkify.io/terminologies#step-circuit "mention") first.

Also, due to the support of the halo2 ecosystem, you can learn more [#circuit](https://docs.snarkify.io/terminologies#circuit "mention") development from the [halo2 book](https://zcash.github.io/halo2/).&#x20;

#### Trait

```rust
pub trait StepCircuit<const ARITY: usize, F: PrimeField> {
    type Config: Clone;

    fn configure(cs: &mut ConstraintSystem<F>) -> Self::Config;

    fn synthesize_step(
        &self,
        config: Self::Config,
        layouter: &mut impl Layouter<F>,
        z_i: &[AssignedCell<F, F>; ARITY],
    ) -> Result<[AssignedCell<F, F>; ARITY], SynthesisError>;

    fn process_step(
        &self,
        z_i: &[F; ARITY],
        k_table_size: u32,
    ) -> Result<[F; ARITY], SynthesisError>;
}
```

* `const ARITY: usize` - Each step of [ivc-struct](https://docs.snarkify.io/sirius-folding/sirius-folding-apis/ivc-struct "mention")has an input and an output (`z_in`, `z_out`), this parameter determines the size of this input.
* `type Config`- This type stores information about which columns and challenges we need for the circuit.
* `fn configure`- The function should create Config, as well as create all gates.\
  \
  Gadgets and chips from halo2 can be reused in this method.
* `fn synthesize_step` - Directly synthesize the witness, at this stage the PLONKish table must be filled in using `Layouter`.\
  \
  Gadgets and chips from halo2 can be reused in this method.
* `fn process_step` (optional for implementation) - This function must do the same `F(z_in) -> z_out` as `synthesize_step`. Due to some restrictions, we must supply as one of the public inputs (instance column) inside the folding scheme a hash that depends on `z_out`. \
  \
  By default, this method is done through the `synthesize_step` call, however, if the synthesis is long, it is possible to optimize it through a manual implementation in the off-circuit mode.
