The frontend interface allows to define the circuit to be folded.
The recommended frontend is to directly use [arkworks](https://github.com/arkworks-rs) to define the FCircuit, just following the [`FCircuit` trait](https://github.com/privacy-scaling-explorations/sonobe/blob/main/folding-schemes/src/frontend/mod.rs).
Alternatively, experimental frontends for [Circom](https://github.com/iden3/circom), [Noir](https://noir-lang.org/), and [Noname](https://github.com/zksecurity/noname) can be found at [sonobe/frontends](https://github.com/privacy-scaling-explorations/sonobe/tree/main/frontends), which have some computational (and time) overhead.
Defining a circuit to be folded is as simple as fulfilling the `FCircuit` trait interface. Henceforth, integrating a new zk circuits language into Sonobe, can be done by building a wrapper on top of it that satisfies the `FCircuit` trait.
# Side note: adhoc frontend dependencies for the experimental frontends
> Note: this affects only to the experimental frontends in the [sonobe/frontends](https://github.com/privacy-scaling-explorations/sonobe/tree/main/frontends) directory.
There are many ad hoc dependencies for each of the frontends integrated with Sonobe. Here are a few reasons why this is the case.
@ -64,4 +65,3 @@ First, any frontend different from Arkworks needs a "bridge"—a way to "transla
Second, R1CS bridge libraries are often developed by teams assuming that public and private witness values will be assigned simultaneously. This is typically the standard approach. However, folding schemes differ, as they redirect the public outputs of one computation to the public inputs of the next step. This means that public inputs are already assigned when calling the "bridge" to port whatever frontend constraints to Sonobe.
Consequently, we had to make a few ad hoc changes to each of these bridges to make them compatible with Sonobe. We are aware that this significantly increases dependencies, which also raises maintenance requirements. The topic of how to reduce our reliance on such ad hoc changes in the future is being actively [discussed](https://github.com/privacy-scaling-explorations/sonobe/issues/146).
In its seminal paper, [Nova](https://eprint.iacr.org/2021/370) detailed how to achieve zero-knowledge using an ad-hoc zk-SNARK ([Spartan]()). This involved compressing and hiding a proof of knowledge of a valid IVC proof. Indeed, an IVC proof is not zero-knowledge by default: the prover must provide an IVC verifier with witness values to verify the correctness of their IVC computation.
[Nova](https://eprint.iacr.org/2021/370) shows how to achieve zero-knowledge at the Decider level using an ad-hoc zk-SNARK ([Spartan](https://eprint.iacr.org/2019/550) in the original Nova paper). This involves compressing and hiding a proof of knowledge of a valid IVC proof. Indeed, an IVC proof is not zero-knowledge by default: the prover must provide an IVC verifier with witness values to verify the correctness of their IVC computation.
However, having to modify and use a special-purpose zk-SNARK for hiding and compressing a Nova IVC proof was somewhat inefficient. Fortunately, a subsequent [update](https://eprint.iacr.org/2023/573) (section D.4) to the [Nova](https://eprint.iacr.org/2021/370) paper specified a design for generating zk-IVC proofs. This allows an IVC prover to send an IVC verifier a zero-knowledge proof that hides the values attesting to the correctness of an IVC computation.
The updated version of the [HyperNova](https://eprint.iacr.org/2023/573) paper (section D.4), specifies a design for generating zk-IVC proofs which also applies to the Nova IVC. This allows an IVC prover to send an IVC verifier a zero-knowledge proof that hides the values attesting to the correctness of an IVC computation.
# Use Cases
Nova's zk-IVC proof generation is quite efficient, as it simply involves blinding private field elements with randomly sampled values. It can be applied to a variety of use cases.
Nova's zk-IVC proof generation is quite efficient, as it simply involves blinding private field elements with randomly sampled values and folding the instances with randomized instances. It can be applied to a variety of use cases.
Firstly, Nova's zero-knowledge layer allows users to compute folds and send a zk-IVC proof to any IVC verifier while blinding witness values. This is useful in itself; however, the proof will not be succinct. This is the sole usecase that can be supported by sonobe *today*.
We identify 3 main interesting places to use the nova zk-layer: one before all the folding pipeline (Use-case-1), one at the end of the folding pipeline right before the final Decider SNARK proof (Use-case-2), and a third one for cases where compressed SNARK proofs are not needed, and just IVC proofs (bigger than SNARK proofs) suffice (Use-case-3):
We can still envision additional applications for Nova's zero-knowledge layer. It could also be used to delegate the compression of an IVC proof to a more powerful but untrusted server. With this approach, a user could blind witness values attesting to the correctness of their computation and send a zk-IVC proof, which a server will "compress" using the SNARK of its choice.
- Use-case-1: at the beginning of the folding pipeline, right when the user has their original instance prior to be folded into the running instance, the user can fold it with the random-satisfying-instance to then have a blinded instance that can be sent to a server that will fold it with the running instance.
- In this one, the user could externalize all the IVC folding and also the Decider final proof generation to a server.
- Use-case-2: at the end of all the IVC folding steps (after n iterations of nova.prove_step), to 'blind' the IVC proof so then it can be sent to a server that will generate the final Decider SNARK proof.
- In this one, the user could externalize the Decider final proof generation to a server.
- Use-case-3: the user does not care about the Decider (final compressed SNARK proof), and wants to generate a zk-proof of the last IVC state to an IVC verifier (without any SNARK proof involved). In this use-case, the zk is only added at the last IVCProof. Note that this proof will be much bigger and expensive to verify than a Decider SNARK proof.
Finally, users could leverage Nova's zero-knowledge layer to delegate both folding and compression to an untrusted server. This is an interesting use case, as it could enable an efficient, tree-like folding version of Nova. See [this issue](https://github.com/privacy-scaling-explorations/sonobe/issues/136) on the Sonobe repository. Again, this usecase is not supported by sonobe as of now, come talk to us if you are working on it!
The current implementation available in Sonobe covers the Use-case-3.
Use-case-1 can be achieved directly by a simpler version of the zk IVC scheme skipping steps and implemented directly at the app level by folding the original instance with a randomized instance (steps 2,3,4 from section D.4 of the [HyperNova](https://eprint.iacr.org/2023/573.pdf)
paper). And the Use-case-2 would require a modified version of the Decider circuits.
# Example
It is straightforward to obtain a zk IVC proof from the nova computation you just performed:
# Example (use case 3)
It is straightforward to obtain a zk IVC proof from the nova computation by:
```rust
// where `&nova` is of type `Nova<...>`
@ -24,4 +31,4 @@ It is straightforward to obtain a zk IVC proof from the nova computation you jus
let proof = RandomizedIVCProof::new(&nova, &mut rng);
```
See [here](https://github.com/privacy-scaling-explorations/sonobe/blob/7097c001fc876578be2229d3590d506858bc0069/folding-schemes/src/folding/nova/zk.rs#L285) for a small demo on how to generate and verify a zk IVC nova proof.
See [here](https://github.com/privacy-scaling-explorations/sonobe/blob/7097c001fc876578be2229d3590d506858bc0069/folding-schemes/src/folding/nova/zk.rs#L285) for a small demo on how to generate and verify a zk IVC nova proof for the described use-case 3.