Skip to content

Commit

Permalink
chore: add example of folding a circom circuit and explain how to use a
Browse files Browse the repository at this point in the history
custom `step_native` function
  • Loading branch information
dmpierre committed Jun 6, 2024
1 parent 74a5f3b commit d05ceab
Showing 1 changed file with 46 additions and 1 deletion.
47 changes: 46 additions & 1 deletion src/usage/frontend-circom.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,50 @@ template Example () {
ivc_output[0] <== temp1 * ivc_input[0] + temp2 + external_inputs[1];
}
component main {public [ivc_input]} = Example();
component main {public [ivc_input]} = CubicCircuit();
```

Once your `circom` circuit is ready, you can instantiate it with Sonobe. To do this, you will need the `struct CircomFCircuit`.

```rust
// we load our circom compiled R1CS, along with the witness wasm calculator
let r1cs_path = PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit.r1cs");
let wasm_path =
PathBuf::from("./src/frontend/circom/test_folder/cubic_circuit_js/cubic_circuit.wasm");
let mut circom_fcircuit = CircomFCircuit::<Fr>::new((r1cs_path, wasm_path, 1, 2)).unwrap(); // state_len:1, external_inputs_len:2

// to speed things up, you can define a custom step function to avoid defaulting to the snarkjs witness calculator
circom_fcircuit.set_custom_step_native(Rc::new(|_i, z_i, _external| {
let z = z_i[0];
Ok(vec![z * z * z + z + Fr::from(5)])
}));

// we initialize the required folding schemes parameters, the folding scheme and the final decider that we want to use
let (fs_prover_params, kzg_vk, g16_pk, g16_vk) =
init_ivc_and_decider_params::<CircomFCircuit<Fr>>(f_circuit.clone());

pub type NOVA = Nova<G1, GVar, G2, GVar2, CircomFCircuit<Fr>, KZG<'static, Bn254>, Pedersen<G2>>;
pub type DECIDERETH_FCircuit = DeciderEth<
G1,
GVar,
G2,
GVar2,
CircomFCircuit<Fr>,
KZG<'static, Bn254>,
Pedersen<G2>,
Groth16<Bn254>,
NOVA,
>;

// initialize the folding scheme engine, in our case we use Nova
let mut nova = NOVA::init(&fs_prover_params, f_circuit.clone(), z_0).unwrap();

// run n steps of the folding iteration
for (i, external_inputs_at_step) in external_inputs.iter().enumerate() {
let start = Instant::now();
nova.prove_step(external_inputs_at_step.clone()).unwrap();
println!("Nova::prove_step {}: {:?}", i, start.elapsed());
}

```
You can find an example for using Nova over a circom circuit [here](https://github.com/privacy-scaling-explorations/sonobe/blob/main/examples/circom_full_flow.rs).

0 comments on commit d05ceab

Please sign in to comment.