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

feat: Implement batch operations in non_hiding_kzg module #269

Merged
merged 2 commits into from
Jan 23, 2024

Conversation

huitseeker
Copy link
Contributor

  • Added a batch_commit method to generate multiple commitments from a list of polynomials.
  • Introduced a batch_open functionality for evaluating multiple polynomials at different points.
  • Implemented batch_verify function for validation of polynomial evaluations in a multi-commitment setup.
  • Verified the correctness of the batch operations with a new unit test batch_check_test.

These basic variants of batch KZG were originally part of #145

@huitseeker huitseeker force-pushed the reintroduce_naive_batch_kzg branch 2 times, most recently from fab9b30 to ba408e4 Compare January 17, 2024 17:38
- Added a `batch_commit` method to generate multiple commitments from a list of polynomials.
- Introduced a `batch_open` functionality for evaluating multiple polynomials at different points.
- Implemented `batch_verify` function for validation of polynomial evaluations in a multi-commitment setup.
- Verified the correctness of the batch operations with a new unit test `batch_check_test`.
@huitseeker huitseeker force-pushed the reintroduce_naive_batch_kzg branch from de0c66b to d20c05e Compare January 17, 2024 21:20
huitseeker pushed a commit to huitseeker/arecibo that referenced this pull request Jan 22, 2024
* multilinear KZG PCS as a provider; builds

* fix two tests

* fix third test; cut duplicate code

* Tidy up source code comments

Signed-off-by: Greg Zaverucha <[email protected]>

* impl PairingGroup for bn256

* remove unneeded imports

* simplify CommitmentKey

* fix build; migrate G1Affine

* fmt

* checkpoint

* migrate G2Affine and pairing

* fix clippy; use unimplemented!

* switch to affine form for compressed commitments

* add a test with mlkzg

* cargo fmt

* cleanup

* go back to compressed group

* address clippy

* rename

* cleanup

* add an alias

* deduplicate

* Revert "add an alias"

This reverts commit 97cade6c8751deacbc8b5b0e0df1579e3baa1477.

* Use an alias for PreprocessedGroupElements

Signed-off-by: Greg Zaverucha <[email protected]>

* cargo fmt

* update README.md

---------

Signed-off-by: Greg Zaverucha <[email protected]>
Co-authored-by: Greg Zaverucha <[email protected]>
E::G1::batch_normalize(&[-total_w, total_c], &mut affine_points);
let (total_w, total_c) = (affine_points[0], affine_points[1]);

let result = E::multi_miller_loop(&[
Copy link
Contributor

Choose a reason for hiding this comment

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

As Adrian mentioned (and I then could also convince myself by observing the implementation), this form of pairings check is more optimal, comparing to:

let left = E::pairing(..., ...);
let right = E::pairing(..., ...);
assert_eq!(left, right);

as it saves one multi_miller_loop and one final_exponentiation call. However that requires some manipulating with input parameters, which differs from what is necessary to pass to pairing couple. For example, given vanilla KZG10 specification, described here, the final check is specified like:

e(C_q, a⋅G2−b⋅G2) == e(C_f−G1⋅c, G2) 

which has following Rust equivalent:

let g1 = srs.powers_of_g[0];
let g2 = srs.powers_of_h[0];

let left = pairing(
  &Cq.to_affine(),
  &(srs.powers_of_h[1] - (g2 * b)).to_affine(),
);
let right = pairing(&(Cf.to_affine() - (g1 * c).to_affine()).to_affine(), &g2);
assert_eq!(left, right);

Alternatively (more optimally), one can write this check as:

// Alternatively (more optimal as it doesn't require executing final_exponentiation twice)
let term1 = (
  &(srs.powers_of_g[0] * c - Cq * b - Cf).to_affine(),
  &G2Prepared::from_affine(srs.powers_of_h[0]),
);
let term2 = (
  &Cq.to_affine(),
  &G2Prepared::from_affine(srs.powers_of_h[1]),
);
let result = multi_miller_loop(&[term1, term2]).final_exponentiation();
assert_eq!(result.is_identity().unwrap_u8(), 0x01);

which I derived empirically.

I wonder if there is a systematic way that allows turning the e() == e() formula into more optimal one:

term1 = ...
term2 = ...
multi_miller_loop(term1, term2).final_exponentiation().is_identity()

Thanks in advance, for answering, @huitseeker !

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe the underpinnings of the speed of this API have been discussed elsewhere, but to summarize:

  1. the vectorized API allows us to perform less (a single) final exponentiation, which is an expensive operation,
  2. the initial part of the pairing computation, the Miller loop, is a fancy double-and-add algorithm that's easy(-ish) to mutualize in an SIMD fashion, giving the vectorized API a bit of an edge,

Hence the API you're remarking on above. The equivalent API in Arkworks is perhaps a bit simpler, but leads to the same idea:
https://github.com/arkworks-rs/algebra/blob/bf96a5b2873e69f3c378c7b25d0901a6701efcc4/ec/src/pairing.rs#L104-L109

@huitseeker huitseeker added this pull request to the merge queue Jan 23, 2024
Merged via the queue into lurk-lang:dev with commit db4375f Jan 23, 2024
9 checks passed
@huitseeker huitseeker deleted the reintroduce_naive_batch_kzg branch January 23, 2024 15:50
samuelburnham pushed a commit to samuelburnham/arecibo that referenced this pull request Jan 24, 2024
)

* feat: Implement batch operations in non_hiding_kzg module

- Added a `batch_commit` method to generate multiple commitments from a list of polynomials.
- Introduced a `batch_open` functionality for evaluating multiple polynomials at different points.
- Implemented `batch_verify` function for validation of polynomial evaluations in a multi-commitment setup.
- Verified the correctness of the batch operations with a new unit test `batch_check_test`.

* fix: convert to zip_with syntax
samuelburnham pushed a commit to samuelburnham/arecibo that referenced this pull request Jan 24, 2024
)

* feat: Implement batch operations in non_hiding_kzg module

- Added a `batch_commit` method to generate multiple commitments from a list of polynomials.
- Introduced a `batch_open` functionality for evaluating multiple polynomials at different points.
- Implemented `batch_verify` function for validation of polynomial evaluations in a multi-commitment setup.
- Verified the correctness of the batch operations with a new unit test `batch_check_test`.

* fix: convert to zip_with syntax
gabriel-barrett pushed a commit to gabriel-barrett/arecibo that referenced this pull request Feb 9, 2024
* Support for multilinear KZG commitments (lurk-lang#269)

* multilinear KZG PCS as a provider; builds

* fix two tests

* fix third test; cut duplicate code

* Tidy up source code comments

Signed-off-by: Greg Zaverucha <[email protected]>

* impl PairingGroup for bn256

* remove unneeded imports

* simplify CommitmentKey

* fix build; migrate G1Affine

* fmt

* checkpoint

* migrate G2Affine and pairing

* fix clippy; use unimplemented!

* switch to affine form for compressed commitments

* add a test with mlkzg

* cargo fmt

* cleanup

* go back to compressed group

* address clippy

* rename

* cleanup

* add an alias

* deduplicate

* Revert "add an alias"

This reverts commit 97cade6c8751deacbc8b5b0e0df1579e3baa1477.

* Use an alias for PreprocessedGroupElements

Signed-off-by: Greg Zaverucha <[email protected]>

* cargo fmt

* update README.md

---------

Signed-off-by: Greg Zaverucha <[email protected]>
Co-authored-by: Greg Zaverucha <[email protected]>

* refactor: clean up the needed scaffolding in MLKZG

Summary:

- THe MLKZG implementation re-implements some group traits, so as to give it maximum generality and depende maximally on the Nova traits.
- However, the way in which it imports a pairing (using pairing::Engine) already implicitly constrains perfrectly usable group implementations to be available on the same types.  This commit therefore removes the boilerplate and uses those external traits.
- Finally, so as to mutualize part of the pairing implementation, this commit also leverages the MultiMillerLoop trait, a subtrait of `pairing::Engine`.
- In sum, this commit only moves types - no actual data was harmed in its making.

In detail:

- Removed the `PairingGroup` trait and its related implementations from the `traits.rs` and `bn256_grumpkin.rs` files.
- Simplified the imports from `halo2curves::bn256` in `bn256_grumpkin.rs` and removed unused types such as `pairing`, `G2Affine`, `G2Compressed`, `Gt`, and `G2`.
- Deleted substantial amount of code associated with `G2` from `bn256_grumpkin.rs`.

* make Minroot example generic over the supported curve cycles (lurk-lang#272)

* make Minroot example generic over the supported curve cycles

* upgrade version

* refactor: Refactor and enhance point infinity handling in `to_transcript_bytes`

- Enhanced the functionality of `to_transcript_bytes` method in `TranscriptReprTrait` for `Affine` in both `pasta.rs` and `traits.rs`.
- Combined the x and y coordinates with the `is_infinity_byte` into a single byte stream for ease of handling.
- Integrated additional checks for 'infinity' conditions to ensure accurate extractions of coordinate values.

* refactor: Relocate multi-scalar multiplication module

- Restructure the `provider` module by moving `msm` to the `util` subdirectory.

* chore: Rename UV(KZG{ProverKey, VerifierKey}|UniversalKZGParam) -> \1

* refactor: Apply univariate polynomial evaluation

- chore: move comment
- fix: standardize power sequences computation
- fix: parallelize several poly computations

refactor: Refactor `EvaluationArgument` struct in mlkzg.rs

- Renamed several fields in `EvaluationArgument` struct within `src/provider/mlkzg.rs` for increased clarity.
- Adjusted the `prove` and `verify` methods in `src/provider/mlkzg.rs` to reflect these name changes.
- Modified test code to align with the updates in the `EvaluationArgument` structure.

---------

Signed-off-by: Greg Zaverucha <[email protected]>
Co-authored-by: Srinath Setty <[email protected]>
Co-authored-by: Greg Zaverucha <[email protected]>
huitseeker added a commit to huitseeker/arecibo that referenced this pull request Feb 17, 2024
huitseeker added a commit to huitseeker/arecibo that referenced this pull request Feb 17, 2024
github-merge-queue bot pushed a commit that referenced this pull request Feb 19, 2024
* Revert "feat: Implement batch operations in non_hiding_kzg module (#269)"

This reverts commit db4375f.

* refactor: remove non_hiding_kzg module, split code where dependents need it

- Moved `UniversalParams` and several dependent structures for the KZG10 scheme in the `kzg_commitment.rs` file.
- Deleted the `non_hiding_kzg.rs` file,
- Consolidated KZG related structs under the `kzg_commitment` module,
- Updated `mod.rs` to reflect the removal of the `non_hiding_kzg` module.
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.

2 participants