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

Fast amortized KZG commitments #79

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

joebebel
Copy link

@joebebel joebebel commented May 4, 2021

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.

joebebel and others added 2 commits May 3, 2021 23:24
Fix MarlinPC's CommitterKey to return the correct supported_degree (arkworks-rs#78)
/// 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}
Copy link
Member

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?

Copy link
Author

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 Show resolved Hide resolved
src/kzg10/fastpoly.rs Outdated Show resolved Hide resolved
Comment on lines 6 to 8
use ark_poly::polynomial::univariate::DensePolynomial;

type P<E: PairingEngine> = DensePolynomial<E::Fr>;
Copy link
Member

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.

Copy link
Author

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

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, that seems reasonable!

Copy link
Member

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/fastpoly.rs Outdated Show resolved Hide resolved
src/kzg10/mod.rs Outdated Show resolved Hide resolved
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(
Copy link
Member

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.

Suggested change
pub fn G2_commit(
pub fn commit_g2(

Copy link
Author

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)

Copy link
Member

@Pratyush Pratyush May 28, 2021

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.

src/kzg10/mod.rs Outdated Show resolved Hide resolved
src/kzg10/mod.rs Outdated Show resolved Hide resolved
src/kzg10/mod.rs Outdated Show resolved Hide resolved
@Pratyush
Copy link
Member

Pratyush commented May 4, 2021

Thanks for the PR! Left some comments

@joebebel joebebel changed the title Merge pull request #1 from arkworks-rs/master Fast amortized KZG commitments May 4, 2021
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..]);
Copy link
Author

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)

Copy link
Member

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?

Copy link
Author

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.

@joebebel
Copy link
Author

I added more comments to the SubproductDomain algorithms

src/error.rs Outdated Show resolved Hide resolved
Comment on lines +23 to +24
mod subproductdomain;
pub use subproductdomain::*;
Copy link
Member

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

Suggested change
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?
Copy link
Member

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.

Copy link
Author

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

joebebel and others added 2 commits May 28, 2021 14:52
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
@Pratyush
Copy link
Member

this looks great, modulo the nits and the bug fix!

joebebel and others added 2 commits June 10, 2021 14:18
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
@alxiong
Copy link
Contributor

alxiong commented May 25, 2023

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),
we have an implementation in Jellyfish library.
(relevant PR: initial work, follow-up refactor)

Essentially, you can go to: jellyfish/primitives/pcs/univariate_kzg/mod.rs::UnivariateKzgPCS::multi_open() for general multi-points opening, and the multi_open_rou_*() APIs in the same file that are specialized for roots of unity (faster)

Of independent interest, you can find

(we are open-sourced under permissive license, so feel free to grab whichever subcomponent you find useful.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants