Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement nova's zk layer #127

Merged
merged 14 commits into from
Aug 17, 2024
Merged

feat: implement nova's zk layer #127

merged 14 commits into from
Aug 17, 2024

Conversation

dmpierre
Copy link
Collaborator

@dmpierre dmpierre commented Jul 16, 2024

This PR implements nova's zero-knowledge layer, as specified in Appendix D.4 of Kothapalli, Setty (2023).

Edit: we initially were blinding the cyclefold instance. However, after discussing, it appears that blinding the cyclefold instance should not be necessary, while keeping zk for the IVC proof.

@dmpierre dmpierre linked an issue Jul 16, 2024 that may be closed by this pull request
@dmpierre dmpierre changed the title Feat/zk nova Implement Nova's IVC proof zero-knowledge layer Jul 16, 2024
@dmpierre dmpierre force-pushed the feat/zk-nova branch 2 times, most recently from 25b3318 to ffe4e62 Compare July 16, 2024 17:06
@arnaucube arnaucube added the Nova label Jul 31, 2024
@dmpierre dmpierre changed the title Implement Nova's IVC proof zero-knowledge layer feat: implement nova's zk layer Aug 2, 2024
@dmpierre dmpierre requested review from han0110 and arnaucube and removed request for han0110 August 2, 2024 14:09
@dmpierre dmpierre marked this pull request as ready for review August 2, 2024 14:11
@dmpierre dmpierre requested a review from CPerezz August 2, 2024 14:11
Copy link
Member

@CPerezz CPerezz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass.

folding-schemes/src/arith/r1cs.rs Show resolved Hide resolved
folding-schemes/src/arith/r1cs.rs Show resolved Hide resolved
folding-schemes/src/arith/r1cs.rs Outdated Show resolved Hide resolved
folding-schemes/src/folding/nova/zk.rs Show resolved Hide resolved
folding-schemes/src/folding/nova/zk.rs Outdated Show resolved Hide resolved
folding-schemes/src/folding/nova/zk.rs Show resolved Hide resolved
folding-schemes/src/folding/nova/zk.rs Show resolved Hide resolved
folding-schemes/src/folding/nova/zk.rs Outdated Show resolved Hide resolved
folding-schemes/src/folding/nova/zk.rs Show resolved Hide resolved
folding-schemes/src/folding/nova/zk.rs Show resolved Hide resolved
@CPerezz
Copy link
Member

CPerezz commented Aug 6, 2024

Currently discussing why is it required to add ZK to CycleFold instance.

DIscussed in Zulip with @dmpierre and Srinath.

Hey Srinath
I was reviewing the PR from Pierre where ZK is included for Nova.
And I saw that the CycleFold instance was also getting folded with a randomized sample to produce ZK on that side too.
I'm curious on why is needed to add ZK to the CycleFold instance. AFAIK, it doesn't leak any info of the operations in the Primary Curve. And that means no relevant data is leaked at all.

In short, the main important operations related to circuit logic and ZK happen in the PrimaryCurve. CycleFold works on the secondary proving correct folding only.
Therefore, I wonder why does it need to be ZK if in reality is not giving any sensitive info.

Thanks. And sorry if the answer is trivial. I just did not see why while reviewing the PR.

@dmpierre
Copy link
Collaborator Author

dmpierre commented Aug 7, 2024

Currently discussing why is it required to add ZK to CycleFold instance.

DIscussed in Zulip with @dmpierre and Srinath.

Hey Srinath
I was reviewing the PR from Pierre where ZK is included for Nova.
And I saw that the CycleFold instance was also getting folded with a randomized sample to produce ZK on that side too.
I'm curious on why is needed to add ZK to the CycleFold instance. AFAIK, it doesn't leak any info of the operations in the Primary Curve. And that means no relevant data is leaked at all.
In short, the main important operations related to circuit logic and ZK happen in the PrimaryCurve. CycleFold works on the secondary proving correct folding only.
Therefore, I wonder why does it need to be ZK if in reality is not giving any sensitive info.
Thanks. And sorry if the answer is trivial. I just did not see why while reviewing the PR.

Answer from Srinath:

Hi! Good question, we are writing up a more general ZK compiler with proofs, which will clarify more details. Yes, you are right that we could avoid blinding U_EC instance. Btw, if you are using Groth16 for wrapping IVC proofs, then there is no need to do this blinding step as long as Groth16 provides zk (which is easier than this blinding approach, for Groth16).

Nice, this should simplify this PR, will take this into account and remove the blinding of the cyclefold instances!

@CPerezz
Copy link
Member

CPerezz commented Aug 7, 2024

Hi! Good question, we are writing up a more general ZK compiler with proofs, which will clarify more details. Yes, you are right that we could avoid blinding U_EC instance. Btw, if you are using Groth16 for wrapping IVC proofs, then there is no need to do this blinding step as long as Groth16 provides zk (which is easier than this blinding approach, for Groth16).

Thanks for the quick reply @srinath Setty !!

In regards of your reply, I think there is a need no?
Mainly because if we want to have a distributed folding setting then the intermediate blinding is required such that future folders don't get witness nor commitment info from previous ones.

I agree, that otherwise, ZK is not needed at all as G16 can provide us with it, thus saving us 1 extra blinding at the very least (so 1 fold with a randomized instance) for each previous fold verification.

So to sum-up.
Does it make sense @srinath Setty to just keep the folding with randomized instances in the primary curve? (For the distributed prover setting I mean ofc) and simply don't do any ZK at all if we own all the provers and allow G16 to take care of it?

Thanks,
Carlos.

Last transcription. After we get an answer for this, I think we are good to go.

Copy link
Collaborator

@arnaucube arnaucube left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Great work! And thanks for writting in-line comments specifying each step related to the paper, made things more easy to follow! ^^

I guess that we're pending on the answer regarding the need to 'zk-fold' also the cyclefold instances or not, but otherwise LGTM!

I'm not sure how the structs and methods in the nova/zk.rs file are expected to be used:

I identify 2 interesting places to use the nova zk-layer (not specifically this PR, but the concept of the zk-layer), one before all the folding pipeline (point 2), and the other at the end of the folding pipeline right before the final Decider snark proof (point 1)):

  • Use-case-1: 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 is externalizing the Decider final proof generation to a server.
  • Use-case-2: 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 is externalizing all the IVC folding and also the Decider final proof generation to a server.

From what I'm understanding (please correct me if I'm wrong), this PR allows to do part of the Use-case-1. 'part' because the new structs in nova/zk.rs can not be plugged into the existing decider to generate the final snark proof, since it has extra parameters that would require extra checks in a modified Decider circuit.

Regarding Use-case-2, which would be adding the zk layer at the initial instances, where the use case would be the user initializes their instance, folds it with the randomly sampled instance, and then sends this folded instance (blinded) to a server which will fold it with the rest of instances and also will generate the final compressed Decider snark proof.
If I understand correctly this PR does not cover this case, and in fact this case could be done without the code in the nova/zk.rs file, by just sampling a satisfying random instance and folding it with the user's original instance. (ie. in the current impl and paper there are more steps because we fold $U_i$ with $u_i$ obtaining $U_f$, and then $U_f$ with $U_r$ obtaining $U'_i$; but in the described usecase, the user would just fold their initial $u_i$ with $U_r$ obtaining $u'_i$ ('blinded' instance).
This last description of Use-case-1, applied to the paper D.4 construction would be doing directly the steps 2,3,4:

  • (2.) sample random satisfying instance $(U_r, W_r)$
  • (3.) fold user original fresh instance $(u_i, w_i)$ with $(U_r, W_r)$, obtaining $(u'_i, w'_i), \overline{T}'$
  • (4.) the randomized proof then is: $\pi' = (U_r, u_i, u_i', \overline{T}', w'_i)$
    (notice that there is no $U_f, W_f, \overline{T}$)
    The output of this process can be then the instance to be folded into the next iteration of the folding steps. This is related to Allow tree-like folding #136 , since then we would be folding 'non-fresh' instances in the folding step (the original running instance with the new blinded folded instance), which to enable this it has similar requirements as the tree-like folding described on that issue.

Is the overview described in this message correct? if that's the case, then I understand that this PR is targeting the Use-case-1, and this PR by itself is partially implementing it right?
ie. This PR allows to generate the blinded IVC proof (not a snark proof) out of the final folded instance, but this is not compatible with the current Decider to then generate the final snark proof, right? I imagine that the idea is that at some point we would have a modified Decider that takes these kind of zkIVC instances and verifies them in-circuit to produce the final snark proof), so that the work done in this PR can be connected with the rest of the flow. Is that correct?

folding-schemes/src/arith/r1cs.rs Outdated Show resolved Hide resolved
folding-schemes/src/folding/nova/zk.rs Show resolved Hide resolved
@dmpierre
Copy link
Collaborator Author

cc @arnaucube (quote replying breaks latex code)

Thanks for the thoughtful comment and questions!

Yes, this PR is only focused on implementing the zk layer for nova. In fact, there is a third use case, where the user computes folds and sends the zk IVC proof to any IVC verifier, without any decider circuit involved anywhere.

Regarding use case 1: this is correct. Using the nova zk layer, a user can blind his running and incoming instances and send a zk IVC proof that can be groth16'ed by an untrusted server. This PR is not modifying sonobe's decider circuit to make this possible. In fact, I think the decider circuit would be a tad different? Notably to accommodate for the random instances. Hence, this might require its own PR.

Regarding use case 2: this is correct. This PR does not aim to cover this use case, but you can do what you are describing with what this PR introduces, since you only need sampling relaxed r1cs instances. I see the connection with doing tree-like folding, nice! This is tangential, but here as well, I guess that obtaining a final compressed snark would require another modified final decider.

@CPerezz
Copy link
Member

CPerezz commented Aug 12, 2024

As per discussion with @srinathtv I think we can simply remove the Cyclefold blinding for now and merge this.
Once he releases a more formal version of it, we can stick to it much better.

But was clearly stated in the Folding implementers call that the Cyclefold Instance blinders indeed aren't useful as "a priori" CycleFold shouldn't leak anything relevant from the IVC. ie. doesn't break ZK.

Copy link
Collaborator Author

@dmpierre dmpierre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed blinding the cyclefold instance. However, the verifier still performs the following checks on the cyclefold instance:

  1. The hash of the running cyclefold instance points to the same hash as u_i.x[1]
  2. The prover-provided cyclefold instance satisfies the cyclefold R1CS

Also, rebased on main!

@dmpierre dmpierre requested review from CPerezz and arnaucube August 12, 2024 15:20
Copy link
Member

@CPerezz CPerezz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add some of this explanation to the docs.

Mainly because it really gives a good intuition on how is the ZK introduced here useful (in which scenarios, and how does it work).

For the rest, LGTM, awesome job!!!!

@dmpierre dmpierre added this pull request to the merge queue Aug 17, 2024
Merged via the queue into main with commit c09c52f Aug 17, 2024
5 checks passed
@dmpierre dmpierre deleted the feat/zk-nova branch August 17, 2024 22:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement Nova's IVC proof zero-knowledge layer
3 participants