-
Notifications
You must be signed in to change notification settings - Fork 131
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
Add verifying key and proving key serialization #103
Add verifying key and proving key serialization #103
Conversation
zcash#661 that allows for vkey serialization/deserialization and fixes the previous selector optimization issue
of fixed columns, post selector compression, are read
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.
Overall look good to me! Just with some more proper error propagation I think it's good to merge.
I feel like next we can try to serialize the ConstraintSystem
with selector compressed in VerifyingKey
, then we don't need to store selector values in vk and the verifier doesn't even need to know the concrete circuit but can still verify the proof.
* add `plonk::Error::Serde` to pass through serialization errors
Implemented @han0110 's suggestions. |
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.
I'm a bit concerned about introducing all of the serde
stack here. Why do we go for serde rather than a simpler to/from_bytes
and maybe also a side read/write
in case you prefer it??
Serde comes with A BUNCH of dependencies and it forces anything that is using this as a dependency to also use serde
.
I would say that since the entire crate is done without using it, I'd follow the same rationale and structure for these structs. read/write
and to/from_bytes
might suit better.
I say that because it's annoying to use a lib as dependency (as halo2) and need to use serde just for 2 structures in it.
halo2_proofs/src/plonk.rs
Outdated
fixed_cosets: self.fixed_cosets.clone(), | ||
permutation: self.permutation.clone(), | ||
}; | ||
bincode::serialize_into(writer, &partial_pkey).map_err(Error::Serde) |
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.
Hardcoding bincode
directly here is a bit tough TBH. But I understand that you can't use serde traits because that could allow yaml or anything esentially.
As said in my review comment, I'm a bit hessitant over the serde
.
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.
Previously because of evaluation there was too much to implement write
for directly, but since Han pointed out that we can recompute evaluation directly, it seems the only primitive necessary is to implement write for Polynomial<F, _> = Vec<F>
and Vec<Polynomial<F, _>>
, which seems doable.
So if you want to limit dependencies, I think it is possible to just implement some write
and read
directly.
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.
I'd prefer it and avoid serde. Unless it is extremely painful.
If any of Han or Onur agree with me, I'd suggest to change it.
Hey @jonathanpwang any news with that?? |
Ah sorry I've been a bit busy. It may take a little longer (a week or two) before I get around to this, but just confirming I will try to do the serialization without |
`serde` or `bincode`
write on "simple-example"
Okay I think I implemented the direct implementation of read/write by just serializing vectors in the obvious way. Also added an example for basic testing. |
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.
Thank you so much for the work on refactoring a bit this @jonathanpwang !
Just some comments and also 2 points I want to consider.
- Could you also provide a
to/from_bytes
fn for ProverKey & VerifierKey?? - The example you added feels extremely large for what we need to show which is how to use serde. I'm not even unsure if an example is needed TBH. But if we want it, I think we should use the smallest possible circuit and not have any comments for it. As at the end, we want to focus the example on the serialisation, not the circuit.
* add `pack`/`unpack` helper functions between `&[bool]` and `u8` * made serialization example use smaller example of standard plonk for less code bloat
I added Added Moved helper functions to Made the example smaller using a standard plonk example. I think it's still good to have the example just to have basic skeleton code for people to copy. Also it's helpful for testing. |
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!!!! Running the workflows now!
Thanks for the work and the corrections @jonathanpwang 😄
I realized why reading the pkey was still kind of slow for >1GB proving keys: currently the Additionally, the I would prefer to just print out both |
I see, now I understand why some zkp library encodes field element in montgomery form and curve element in uncompressed form. I think it will be cool to have such feature implemented as trait in As for halo2 pk/vk serialization, using |
OK I will try to implement functions like |
I completelly agree with the idea @jonathanpwang @han0110 . Filled privacy-scaling-explorations/halo2curves#9 to track this! |
Note that zcash/zcash#661 has been updated to use a leading version byte; little-endian byte order; and extra length fields for the selectors and permutation commitments. It's therefore no longer compatible with the format in this PR. However, the leading version byte is 0x01 which will make the two formats distinguishable, whenever the number of fixed column commitments is less than |
Thanks @daira for the ping! <3 |
This PR adds features for reading and writing the verifying key and proving key of any circuit from/to file.
For verifying key, this uses zcash#661 which fixes the issue with vkey write not working after selector compression.
For proving key, this uses serde derive macros and
bincode
.Both vkey and pkey serializations have been tested on very large circuits (up to
K = 23
), including circuits created fromplonk-verifier
. There have been no problems even up to pkey of sizes> 100GB
.