-
Notifications
You must be signed in to change notification settings - Fork 132
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 ParamsVerifierKZG
#301
Conversation
f1bc892
to
b11077b
Compare
- remove `get_g` from ParamsProver - modify `verifier_params` -> `into_verifier_params` - Adjust to function calls to use verifier parameters when needed, instead of the full parameters.
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.
Where's all this read/write impls comming from??
halo2_backend/src/poly/commitment.rs
Outdated
fn verifier_params(&'params self) -> &'params Self::ParamsVerifier; | ||
fn into_verifier_params(self) -> Self::ParamsVerifier; |
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.
Why removimg the return of the ref? You can always clone later if you need to own the data.
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.
Thanks for bringing this up! This is the change I'm the least happy with.
Before this PR, the verfier params and the prover params where the same struct. As a result, this function could just return self without issue.
The problem is that now, the verifier and prover params are different. Moreover, the prover parameters do not contain the verifier parameters directly. As a result, the ParamsVerifier
struct must be created here, and we cannot return a reference.
I reasoned that in most cases, when you create the verifier params you are done with all the proving, so it is acceptable to consume the prover parameters. ( I removed an unnecessary clone
in the From
implementation 3b5b8a5). So in most cases, the user can generate the verifier parameters without cloning.
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.
Can we at least get &self
as input?
I say it as usually, when we test, we do both prove and verify within the same scope. And this will force a clone of a quite big struct most likely.
In any case, not strongly against this change though. Just wanted to explore the options.
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 also would have liked to keep the &self
as input, but it run into a big issue: A lot of cloning.
For example, in IPA, where the verifier parameters are the same as the input parameters, this forced to clone the whole struct (with its n
sized vectors and all...).
I found that by getting self
, the user could decide to clone
in advance to keep the parameters, or just consume them to create the verifier params, which is the most usual case.
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.
Here is an attempt to go back to the original function: 4e2f44e
The g
and g_lagrange
fields of ParmamsIPA
have been changed from Vec<C>
to Arc<[C]>
( as suggested by @ed255). As a result, the clone that that would happen in verifier_params
is very cheap.
Despite this, I'm not sure if this is the right choice. There are a couple of points where I've been forced to initialize a vector first, and then convert it to Arc
. I'd like to avoid these re-allocations, but I'm not sure if it is possible.
These are adaptations from the implementations of |
We should consider this as related to #176 |
// Domain size. | ||
pub(crate) n: u64, | ||
// This is the maximum size of PI supported. | ||
pub(crate) trimed_size: u32, |
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.
What is the point of storing trimed_size
here if AFIS it's just g_lagrange.len()
?
Makes sense to store it serialized, but maybe it's not necessary to be kept in memory.
@@ -186,6 +204,8 @@ where | |||
where | |||
E::G2Affine: SerdeCurveAffine, | |||
{ | |||
// TODO: 4 bytes is too much for k, this is the log-size of the params. |
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.
Maybe it's just enough with the check you added later.
// This is a generous bound on the size of the domain.
debug_assert!(k < 32);
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.
Yes, I think that check is definitely necessary, even with just 1 byte for storing k
. This check was already added in the verifier keys, as it could lead to the attempt of allocating a 2 ^ (2 ^ 32)
len vector. ( #244 ). In this PR, we also reduced the number of bytes from 4 to 1, so I think it would be good to reduce it here to keep things coherent. WDYT?
} | ||
|
||
/// Reads verifier parameters from a buffer. | ||
pub fn read_custom<R: io::Read>(reader: &mut R, format: SerdeFormat) -> io::Result<Self> |
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.
There's some code that is repeated in ParamsKZG::read_custom
, maybe it can be reused via shared functions.
Go back to `verifier_params` method in `ParamsProver`. To avoid duplciating the IPA parameters when calling this function, `g`, `g_lagrange` has been change from `Vec<C>` to `Arc<[C]>`.
Overridden by #318 |
Description
The aim of this PR is to allow the verification of a KZG proof without having to deal with the complete KZG parameters.
ParamsKZG
contains 2 G2 elements and 2 vectors ofn
-sized vectors of G1 elements, wheren
is the size of the circuit.The verifier only needs the 2 G2 elements, and as many G1 elements as public inputs in the circuit.
Changes
ParamsVerifierKZG
.This struct contains the bare minimum info needed to verify a proof.
get_g
from ParamsProver.verifier_params
->into_verifier_params
.I'm not 100% convinced how this ended up, so any suggestion is greatly appreciated.
Closes #280