-
Notifications
You must be signed in to change notification settings - Fork 36
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
feat: Implement batch operations in non_hiding_kzg module #269
Conversation
fab9b30
to
ba408e4
Compare
- 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`.
de0c66b
to
d20c05e
Compare
* 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(&[ |
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.
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 !
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 believe the underpinnings of the speed of this API have been discussed elsewhere, but to summarize:
- the vectorized API allows us to perform less (a single) final exponentiation, which is an expensive operation,
- 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
) * 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
) * 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
* 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]>
…rk-lang#269)" This reverts commit db4375f.
…rk-lang#269)" This reverts commit db4375f.
* 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.
batch_commit
method to generate multiple commitments from a list of polynomials.batch_open
functionality for evaluating multiple polynomials at different points.batch_verify
function for validation of polynomial evaluations in a multi-commitment setup.batch_check_test
.These basic variants of batch KZG were originally part of #145