perf(bn254): include G2 membership check in ML#1387
Merged
Conversation
Collaborator
|
Suggested edit: diff --git a/std/algebra/emulated/sw_bn254/pairing.go b/std/algebra/emulated/sw_bn254/pairing.go
index 4798876a..6d9d170c 100644
--- a/std/algebra/emulated/sw_bn254/pairing.go
+++ b/std/algebra/emulated/sw_bn254/pairing.go
@@ -81,10 +81,10 @@ func NewPairing(api frontend.API) (*Pairing, error) {
}, nil
}
-// Pair calculates the reduced pairing for a set of points
-// ∏ᵢ e(Pᵢ, Qᵢ).
+// Pair calculates the reduced pairing for a set of points ∏ᵢ e(Pᵢ, Qᵢ).
//
-// This function checks that the Qᵢ are in the correct subgroupsi, but does not check Pᵢ. See AssertIsOnG1.
+// This function checks that the Qᵢ are in the correct subgroup, but does not
+// check Pᵢ. See AssertIsOnG1.
func (pr Pairing) Pair(P []*G1Affine, Q []*G2Affine) (*GTEl, error) {
res, err := pr.MillerLoop(P, Q)
if err != nil {
@@ -206,10 +206,13 @@ func (pr Pairing) AssertFinalExponentiationIsOne(a *GTEl) {
pr.AssertIsEqual(t0, t2)
}
-// PairingCheck calculates the reduced pairing for a set of points and asserts if the result is One
-// ∏ᵢ e(Pᵢ, Qᵢ) =? 1
+// PairingCheck calculates the reduced pairing for a set of points and asserts
+// if the result is one:
//
-// This function checks that the Qᵢ are in the correct subgroupsi, but does not check Pᵢ. See AssertIsOnG1.
+// ∏ᵢ e(Pᵢ, Qᵢ) =? 1
+//
+// This function checks that the Qᵢ are in the correct subgroup, but does not
+// check Pᵢ. See AssertIsOnG1.
func (pr Pairing) PairingCheck(P []*G1Affine, Q []*G2Affine) error {
f, err := pr.MillerLoop(P, Q)
if err != nil {
|
Collaborator
|
Suggested edit: diff --git a/std/evmprecompiles/08-bnpairing.go b/std/evmprecompiles/08-bnpairing.go
index b5bd7a54..f4ff6b1b 100644
--- a/std/evmprecompiles/08-bnpairing.go
+++ b/std/evmprecompiles/08-bnpairing.go
@@ -76,7 +76,6 @@ func ECPairMillerLoopAndMul(api frontend.API, accumulator *sw_bn254.GTEl, P *sw_
if err != nil {
return fmt.Errorf("new pairing: %w", err)
}
- pairing.AssertIsOnG2(Q)
ml, err := pairing.MillerLoopAndMul(P, Q, accumulator)
if err != nil {
return fmt.Errorf("miller loop and mul: %w", err)
@@ -94,7 +93,6 @@ func ECPairMillerLoopAndFinalExpCheck(api frontend.API, accumulator *sw_bn254.GT
if err != nil {
return fmt.Errorf("new pairing: %w", err)
}
- pairing.AssertIsOnG2(Q)
isSuccess := pairing.IsMillerLoopAndFinalExpOne(P, Q, accumulator)
api.AssertIsEqual(expectedIsSuccess, isSuccess)
|
ivokub
reviewed
Jan 15, 2025
ivokub
approved these changes
Jan 15, 2025
Collaborator
ivokub
left a comment
There was a problem hiding this comment.
Looks very good. However, in the context of Linea we also need to remove the G2 subgroup checks from the ECPairMillerLoopAndMul and ECPairMillerLoopAndFinalExpCheck methods. These are the ones called from the precompile glue.
I created suggested edits for that and also for some method comments. If you can include them then good to merge from my side.
This was referenced Jan 16, 2025
lucasmenendez
pushed a commit
to lucasmenendez/gnark
that referenced
this pull request
Jan 31, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Including G2 subgroup membership in the pairing computations saves a lot of constraints. For Linea zkEVM, gnark circuit has only to check G2 membership as the arithemtization does the check for G1.
In
computeLinesthe accumulated point is[6x₀+2]Q(x₀being the curve seed). We can tweak* the subgroup membership to check[6x₀+2]Q + ψ(Q) + ψ³(Q) == ψ²(Q)instead ofψ³([2x₀]Q) - ψ²([x₀]Q) - ψ([x₀]Q) - [x₀]Q == Q. This saves the multiplication by6x₀+2and enforces G2 membership check systematically in pairing calls, simplifying probably the Wizard glue.* since
x₀ ≠ 4 mod 13 and x₀ ≠ 92 mod 97for BN254,V=(6x₀+ 2,1,−1,1)is also a valid short vector.TL;DR: G2 subgroup membership becomes ~2 point additions instead of ~81 point additions.
Type of change
How has this been tested?
All current tests pass.
How has this been benchmarked?
On one hand a product of 2 pairings check increases by 18,857 scs but on the other hand the G2 membership which costs (for 2 points) 407,729 scs is removed.
Checklist:
golangci-lintdoes not output errors locally