Nova's Zero-Knowledge Layer
Nova shows how to achieve zero-knowledge at the Decider level using an ad-hoc zk-SNARK (Spartan 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.
The updated version of the HyperNova 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 and folding the instances with randomized instances. It can be applied to a variety of use cases.
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):
- 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.
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 paper). And the Use-case-2 would require a modified version of the Decider circuits.
Example (use case 3)
It is straightforward to obtain a zk IVC proof from the nova computation by:
#![allow(unused)] fn main() { // where `&nova` is of type `Nova<...>` // returns a `Result`, containing a zk IVC nova proof if successful let proof = RandomizedIVCProof::new(&nova, &mut rng); }
See here for a small demo on how to generate and verify a zk IVC nova proof for the described use-case 3.