diff --git a/src/README.md b/src/README.md index 306325b..0cc31ad 100644 --- a/src/README.md +++ b/src/README.md @@ -1,4 +1,4 @@ -# sonobe docs +# sonobe Experimental folding schemes library implemented in a joint effort by [0xPARC](https://0xparc.org/) and [PSE](https://pse.dev). diff --git a/src/SUMMARY.md b/src/SUMMARY.md index e89c3b7..16d3140 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -1,3 +1,9 @@ # sonobe docs [Introduction](README.md) +- [Usage](usage/overview.md) + - [Frontend](usage/frontend.md) + - [Fold](usage/fold.md) + - [Decider prove](usage/decider-prove.md) + - [Solidity verifier](usage/solidity-verifier.md) + - [Modularity](usage/modularity.md) diff --git a/src/imgs/decider-onchain-flow-diagram.png b/src/imgs/decider-onchain-flow-diagram.png new file mode 100644 index 0000000..71c4f06 Binary files /dev/null and b/src/imgs/decider-onchain-flow-diagram.png differ diff --git a/src/imgs/folding-main-idea-diagram.png b/src/imgs/folding-main-idea-diagram.png new file mode 100644 index 0000000..0374dc2 Binary files /dev/null and b/src/imgs/folding-main-idea-diagram.png differ diff --git a/src/imgs/sonobe-lib-pipeline.png b/src/imgs/sonobe-lib-pipeline.png new file mode 100644 index 0000000..544ba25 Binary files /dev/null and b/src/imgs/sonobe-lib-pipeline.png differ diff --git a/src/usage/decider-prove.md b/src/usage/decider-prove.md new file mode 100644 index 0000000..7796929 --- /dev/null +++ b/src/usage/decider-prove.md @@ -0,0 +1,57 @@ +# Decider prove + +Two options: + +- onchain (Ethereum's EVM) mode +- offchain mode + +Once we have been folding our circuit instances, we can generate the *"final proof"*, the Decider proof. + + +#### Onchain Decider + +![](../imgs/decider-onchain-flow-diagram.png) + +Generating the final proof (decider), to be able to verify it in Ethereum's EVM: + +```rust +type DECIDER = Decider< + Projective, + GVar, + Projective2, + GVar2, + CubicFCircuit, + KZG<'static, Bn254>, + Pedersen, + Groth16, // here we define the Snark to use in the decider + NOVA, // here we define the FoldingScheme to use +>; + +// generate Groth16 setup +let circuit = DeciderEthCircuit::< + Projective, + GVar, + Projective2, + GVar2, + Pedersen, + Pedersen, +>::from_nova::>(nova.clone()); +let mut rng = rand::rngs::OsRng; + +let start = Instant::now(); +let (pk, vk) = + Groth16::::circuit_specific_setup(circuit.clone(), &mut rng).unwrap(); +println!("Groth16 setup, {:?}", start.elapsed()); + +// decider proof generation +let decider_pp = (poseidon_config.clone(), g16_pk, kzg_pk); +let proof = DECIDER::prove(decider_pp, rng, nova.clone()).unwrap(); + +// decider proof verification +let decider_vp = (poseidon_config, g16_vk, kzg_vk); +let verified = DECIDER::verify(decider_vp, nova.i, nova.z_0, nova.z_i, &nova.U_i, &nova.u_i, proof).unwrap(); +assert!(verified); +``` + +As mentioned above, complete examples can be found at [sonobe/folding-schemes/examples](https://github.com/privacy-scaling-explorations/sonobe/tree/main/folding-schemes/examples) + diff --git a/src/usage/fold.md b/src/usage/fold.md new file mode 100644 index 0000000..0c55461 --- /dev/null +++ b/src/usage/fold.md @@ -0,0 +1,50 @@ +# Fold + +We plug our `FCircuit` 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, + KZG<'static, Bn254>, + Pedersen, +>; + +let num_steps = 10; +let initial_state = vec![Fr::from(1_u32)]; + +let F_circuit = Sha256FCircuit::::new(()); + +println!("Prepare Nova ProverParams & VerifierParams"); +let (prover_params, verifier_params) = nova_setup::>(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, incoming_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, + incoming_instance, + cyclefold_instance, +) +.unwrap(); +``` diff --git a/src/usage/frontend.md b/src/usage/frontend.md new file mode 100644 index 0000000..be127e8 --- /dev/null +++ b/src/usage/frontend.md @@ -0,0 +1,43 @@ +# Frontend + +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](https://github.com/privacy-scaling-explorations/sonobe/blob/main/sonobe/src/frontend/mod.rs): + +```rust +/// 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: 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, + ) -> Result, 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, + i: usize, + z_i: Vec>, + ) -> Result>, SynthesisError>; +} +``` + diff --git a/src/usage/modularity.md b/src/usage/modularity.md new file mode 100644 index 0000000..8a400a4 --- /dev/null +++ b/src/usage/modularity.md @@ -0,0 +1,5 @@ +# Modularity +## Swapping curves and proving schemes +Thanks to the modularity of arkworks, we can swap between curves and proving systems. +Suppose that for the final proof (decider), instead of using Groth16 over the BN254 curve, we want to use Marlin+IPA over the Pasta curves, so we can enjoy of not needing a trusted setup. +It just requires few line changes on our previous code [...] diff --git a/src/usage/overview.md b/src/usage/overview.md new file mode 100644 index 0000000..1db9e87 --- /dev/null +++ b/src/usage/overview.md @@ -0,0 +1,20 @@ +# Usage + +## Folding schemes overview +(wip) + + + + +[...] [this presentation](https://youtu.be/IzLTpKWt-yg?t=6367), where [Carlos Pérez](https://twitter.com/CPerezz19) overviews the features of folding schemes and what can be build with them. + + +## Sonobe overview + +Suppose that the user inputs a circuit that follows the IVC structure, chooses which Folding Scheme to use (eg. Nova), and which Decider (eg. Spartan over Pasta curve). + +Later the user can for example change with few code changes the Folding Scheme being used (eg. switch to ProtoGalaxy) and also the Decider (eg. Groth16 over bn254), so the final proof can be verified in an Ethereum smart contract. + +![](../imgs/sonobe-lib-pipeline.png) + +Complete examples can be found at [sonobe/folding-schemes/examples](https://github.com/privacy-scaling-explorations/sonobe/tree/main/folding-schemes/examples) diff --git a/src/usage/solidity-verifier.md b/src/usage/solidity-verifier.md new file mode 100644 index 0000000..2829c7b --- /dev/null +++ b/src/usage/solidity-verifier.md @@ -0,0 +1,8 @@ +# Solidity verifier + +Having used the `DeciderEth` (see [Onchain Decider](#Onchain-Decider) section), we can now verify it in Ethereum's EVM. + +First we need to generate the Solidity contracts that verify the Decider proofs. Use the [solidity-verifiers-cli](cli) tool +``` +> solidity-verifier-cli -p nova-cyclefold -d ./folding-verifier-solidity/assets/G16_test_vk_data +```