-
Notifications
You must be signed in to change notification settings - Fork 116
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
Fast amortized KZG commitments #79
base: master
Are you sure you want to change the base?
Conversation
Fix MarlinPC's CommitterKey to return the correct supported_degree (arkworks-rs#78)
src/kzg10/data_structures.rs
Outdated
/// Combine opening proofs onto a subset of the domain | ||
pub fn combine_at_evals( | ||
&self, | ||
range: &std::ops::Range<usize>, // Domain is omega^{start}, ..., omega^{end-1} |
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 just replacing this with start: usize, end: usize
would work better? Or do we need it to be a Range
?
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.
Sure, I think that makes sense. Ideally it seems more rustic to use something like Range
but it has it's own issues.
src/kzg10/fastpoly.rs
Outdated
use ark_poly::polynomial::univariate::DensePolynomial; | ||
|
||
type P<E: PairingEngine> = DensePolynomial<E::Fr>; |
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 just import this is as ark_poly::polynomial::univariate::DensePolynomial as Poly
? Also, not sure if it's more ergonomic to make it generic over a pairing engine, instead of directly over the scalar field.
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.
That sounds good, and also it may be better to merge the polynomial operations into algebra
rather than poly-commit
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.
Yeah, that seems reasonable!
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.
Let's merge the polynomial operations here for the time being, and then in a follow up PR we can move them to ark-poly
?
src/kzg10/mod.rs
Outdated
@@ -191,6 +218,30 @@ where | |||
Ok((Commitment(commitment.into()), randomness)) | |||
} | |||
|
|||
/// Outputs a commitment to `polynomial` in G2 | |||
pub fn G2_commit( |
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.
We should also rename commit
to commit_g1
.
pub fn G2_commit( | |
pub fn commit_g2( |
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.
This part is also a little awkward, because to check
a KZG proof you have to commit the witness/evaluation polynomial in G1 and the subproduct domain polynomial in G2, both of which in the case of a single reveal can happen implicitly, but with a multi reveal should probably call commit_g1
and commit_g2
which requires the UniversalParams
.
Or, the VerifierKey
needs to include a lot more, and actually might need to include more powers than the committer key (in the case where the multi reveal domain is larger than the degree of the committed polynomial)
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.
Or, the VerifierKey needs to include a lot more, and actually might need to include more powers than the committer key (in the case where the multi reveal domain is larger than the degree of the committed polynomial)
That's fine, as long as we make it parameterized, so that when produce_g2_powers
(or whatever the appropriate flag is) is false
, we don't produce the powers in the verifier key.
Thanks for the PR! Left some comments |
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
circulant[size + 1..size + 1 + coeffs.len() - 2] | ||
.copy_from_slice(&coeffs[1..coeffs.len() - 1]); | ||
} else { | ||
circulant[size + 1..size + 1 + coeffs.len() - 1].copy_from_slice(&coeffs[1..]); |
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.
Unfortunately there is a bug somewhere in here which prevents arbitrary circulant matrices/toeplitz matrices from being constructed (it is not triggered by the KZG opening, but is triggered by other tests where the diagonal of the toeplitz matrix is all zeros)
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's the bug that you face?
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.
it doesn't give the correct result for circulant
in the "else" case (e.g. zeros on the diagonal of the Toeplitz matrix). The "else" is never triggered by the fast KZG open so all of those tests pass.
I suspect it's just some indexing error, off by one or something, but I haven't debugged it yet.
I added more comments to the SubproductDomain algorithms |
mod subproductdomain; | ||
pub use subproductdomain::*; |
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.
Stylistic nit, but usually Rust uses snake-case for module names, which means this should be something like
mod subproductdomain; | |
pub use subproductdomain::*; | |
mod subproduct_domain; | |
pub use subproduct_domain::*; |
let mut i = 2usize; | ||
// Use Newton iteration which converges to the inverse mod x^l | ||
for _ in 0..r { | ||
g = &(&g + &g) - &(f * &(&g * &g)); //TODO: is g*2 better than g+g? |
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.
You can do something like g.double()
and g.square()
. These should be slightly faster than computing the addition and multiplication 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.
Oh, that makes sense, I hadn't realized there were API calls for this
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
this looks great, modulo the nits and the bug fix! |
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
I stumble onto this stale PR yesterday, for those who want to use this FK23 today(Fast amortized KZG https://eprint.iacr.org/2023/033.pdf), Essentially, you can go to: Of independent interest, you can find
(we are open-sourced under permissive license, so feel free to grab whichever subcomponent you find useful.) |
Description
This is an implementation of fast amortized KZG commitments with additional details from here and here and here
Definitely a "work in progress" but early-stage review, feedback, critique is appreciated.