-
Notifications
You must be signed in to change notification settings - Fork 77
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
Refactor Public Inputs and add them to the transcript #134
Conversation
Update `construct_dense_pi_vec` so it returns the evaluation representation of the PI polynomial over the used domain. This means that the result vector will always have a power of two length.
Co-authored-by: Joshua Fitzgerald <joshuabfitzgerald@gmail.com>
This method may not be best way of solving the issue so discussions on alternative solutions are welcome! |
Halo 2 also includes the circuit description in the transcript, which I think is another good level of defense in depth. In general, my understanding of the Trail of Bits recommendation is that pretty much everything the verifier has access to should go in the transcript. |
Per Alistair's suggestion on ZK study club telegram, it's not a bad idea to add the first element of the KZG SRS to the transcript as well. This is a bit tricky as it's not generic over the poly commit scheme |
Update `construct_dense_pi_vec` so it returns the evaluation representation of the PI polynomial over the used domain. This means that the result vector will always have a power of two length.
Co-authored-by: Joshua Fitzgerald <joshuabfitzgerald@gmail.com>
…o add-pi-transcript
The new implmenentation uses BTreeMap to ensure no duplicates are introduced and to easily get an ordered representation. This is particualrly helpuful to get a unique representation to add to the transcript.
cbc7e97
to
b7bc1a4
Compare
@joebebel makes sense. Note that for the ordering, the hash will take care too. As we store the PI in a |
The only issue I see with serializing the sparse form of the PI is that we would need to provide a spec for the serialization so that other implementations of the Verifier serialize PI in the same way. Instead, why don't we just use the SRS to get a binding commitment the PI polynomial and add it to the transcript using the existing Merlin API wrapper? It may not be the most efficient solution as it requires doing another MSM, but we can still take advantage of the sparseness of the PI by skipping all the zeros. And since all we need is a binding commitment we won't need to use an FFT before MSM. This method would use our existing tools without modification and is consistent with the rest of the protocol. |
Why is prefixing an issue? The documentation on |
In the verifier (Usually a Smart Contract) will probably be much more expensive to do the MSM than the hash. That's why I suggested that @lopeetall. For now, we could start with something easy that solves the bug. And then move on into a better design. Something like this as purposed by @davidnevadoc in private. // For each PI != 0
transcript.append(b"pi_pos", &F::from(*pos));
transcript.append(b"pi_val", &F::from(val)); This is not the most optimal. But works for now. And we can discuss the approach we want to go for in a follow-up issue. |
Can we reuse those labels From the Merlin website:
|
The absolute requirement is that the transcript is binding to the messages in it, that is, it is not feasible to find a different transcript with different labels/messages that gives the same challenges. The property that It could be that the transcript is message binding even if the labels are not prefix-free, but this requires an additional argument and can't be assumed from the guarantees that
Or, just serialize the PI polynomial? Though I think your original suggestion of serializing the PI directly is probably fine as well. I think the MSM is expensive. |
If this is the case then why are we letting the user specify any labeling scheme at all, just choose a prefix-free sequence of labels and use each one in turn. From an engineering perspective, I don't want to have to think about these safety requirements if there exists a protocol that takes care of it for me, especially when these labels don't actually help me accomplish anything inside of my application (in this case PLONK). This is the API I actually care about: trait Transcript {
fn append<M>(&mut self, message: M);
fn challenge<C>(&mut self) -> C;
} In which scenarios is knowing or specifying the labels manually an important feature to have? |
Yeah, you are absolutely correct that from an implementation perspective, it is entirely possible to do without labels, or without The reason it's important, though, is because "Frozen Heart" is just the latest in a long history of Fiat-Shamir implementation mistakes (mostly of the "omit data" kind). The idea is that we should write down - very explicitly - the exact Plonk interactive protocol being used, and then duplicate it exactly with |
Public Inputs are serialized and added to the transcript under the label "pi". The struct PI is responsible of guaranteeing a unique representation of each possible public input vector.
After reading the discussion and learning about the correct usage of labels in Having the |
The docs on Transcript Protocols might be helpful; the recommended way to use the library is for each protocol to define a protocol-specific extension trait that maps the protocol-level transcript actions ("do a domain separation", "append a public key", "append a commitment to whatever", etc) operating on higher-level types into the underlying calls to the byte-oriented Merlin API. So in this case, for instance, it might make sense to have a transcript protocol that handled the serialization and labeling, and presented higher-level methods to the rest of the crate. |
92e8557
to
2ed6f87
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few points, and a possible bug, otherwise LGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
I like that refactor of the Public Inputs TBH. Although I think we can do more in the future with that and improve them much more.
As for the concerns of @bhgomes , they're legit. But at the same time, panicking due to a PI re-assignation is not something crazy. As it means you're not building a correct circuit. Which is not worth then compiling or making proofs for.
Would like the approval of @bhgomes and maybe one more before we merge TBH as this topic lead to a broad discussion and lots of members were involved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Feel free to merge
In this PR we have added the Public Inputs to the transcript as the first step of the
prove
andverify
algorithms. They have been added as the evaluations of the PI polynomial over the used domain (n
field elements).Close #133