-
Notifications
You must be signed in to change notification settings - Fork 408
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
perf(bn254): include G2 membership check in ML #1387
Conversation
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 {
|
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)
|
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.
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.
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
computeLines
the 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₀+2
and enforces G2 membership check systematically in pairing calls, simplifying probably the Wizard glue.* since
x₀ ≠ 4 mod 13 and x₀ ≠ 92 mod 97
for 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-lint
does not output errors locally