Skip to content

Commit

Permalink
readme: add example of FCircuit & folding
Browse files Browse the repository at this point in the history
  • Loading branch information
arnaucube committed Jan 31, 2024
1 parent 7712892 commit 3ec4ba1
Showing 1 changed file with 78 additions and 14 deletions.
92 changes: 78 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,91 @@ Later the user can for example change with few code changes the Folding Scheme b
![](https://hackmd.io/_uploads/H1r7z9I32.png)
*note: this diagram will be improved and done with some non-handwritten tool.*

### Folding the circuit
A complete example can be found at https://github.com/privacy-scaling-explorations/folding-schemes/blob/main/examples/fold_sha256.rs

### Define the circuit to be folded
First let's define our circuit to be folded:
```rust
/// This is the circuit that we want to fold, it implements the FCircuit trait
#[derive(Clone, Copy, Debug)]
pub struct Sha256FCircuit<F: PrimeField> {
_f: PhantomData<F>,
}
impl<F: PrimeField> FCircuit<F> for Sha256FCircuit<F> {
type Params = ();
fn new(_params: Self::Params) -> Self {
Self { _f: PhantomData }
}
fn step_native(self, z_i: Vec<F>) -> Result<Vec<F>, Error> {
let out_bytes = Sha256::evaluate(&(), z_i[0].into_bigint().to_bytes_le()).unwrap();
let out: Vec<F> = out_bytes.to_field_elements().unwrap();
Ok(vec![out[0]])
}
fn generate_step_constraints(
self,
_cs: ConstraintSystemRef<F>,
z_i: Vec<FpVar<F>>,
) -> Result<Vec<FpVar<F>>, SynthesisError> {
let unit_var = UnitVar::default();
let out_bytes = Sha256Gadget::evaluate(&unit_var, &z_i[0].to_bytes()?)?;
let out = out_bytes.0.to_constraint_field()?;
Ok(vec![out[0].clone()])
}
}
```

We can also define the circuit in Circom:
```circom
//
```

### Folding the circuit
Now we plug it into the library:
```rust
//
// The idea here is that eventually we could replace the next line chunk that defines the
// `type NOVA = Nova<...>` by using another folding scheme that fulfills the `FoldingScheme`
// trait, and the rest of our code would be working without needing to be updated.
type NOVA = Nova<
Projective,
GVar,
Projective2,
GVar2,
Sha256FCircuit<Fr>,
Pedersen<Projective>,
Pedersen<Projective2>,
>;

let num_steps = 10;
let initial_state = vec![Fr::from(1_u32)];

let F_circuit = Sha256FCircuit::<Fr>::new(());

println!("Prepare Nova ProverParams & VerifierParams");
let (prover_params, verifier_params) = nova_setup::<Sha256FCircuit<Fr>>(F_circuit);

println!("Initialize FoldingScheme");
let mut folding_scheme = NOVA::init(&prover_params, F_circuit, initial_state.clone()).unwrap();

// compute a step of the IVC
for i in 0..num_steps {
let start = Instant::now();
folding_scheme.prove_step().unwrap();
println!("Nova::prove_step {}: {:?}", i, start.elapsed());
}

let (running_instance, incomming_instance, cyclefold_instance) = folding_scheme.instances();

println!("Run the Nova's IVC verifier");
NOVA::verify(
verifier_params,
initial_state,
folding_scheme.state(), // latest state
Fr::from(num_steps as u32),
running_instance,
incomming_instance,
cyclefold_instance,
)
.unwrap();
```

### Final proof (decider proof)
Expand All @@ -56,18 +132,6 @@ Additionally, let's suppose that for the final proof (decider), instead of using
It just requires few line changes on our previous code [...]


## Development
Structure of the code:

[...]

In each of the implementations of the folding dir, there are mainly 3 blocks plus 'other':
- circuits
- folding/nifs/nimfs
- ivc/lib
- other


## License
https://github.com/privacy-scaling-explorations/folding-schemes/blob/main/LICENSE

Expand Down

0 comments on commit 3ec4ba1

Please sign in to comment.