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

Final exponentiation should only be applied to the accumulator #250

Closed
IAvecilla opened this issue Apr 12, 2024 · 0 comments · Fixed by #256
Closed

Final exponentiation should only be applied to the accumulator #250

IAvecilla opened this issue Apr 12, 2024 · 0 comments · Fixed by #256
Assignees

Comments

@IAvecilla
Copy link
Contributor

Context: EcPairing.yul#L1558

Description:

In the current implementation the finalExponentiation() is applied to each pair. This is unnecessary because it is enough to apply it only to the value r accumulated by the fp12Mul() after the millerLoop().

This significantly reduces the gas cost: processing each pair after the first one is cheaper by ~36%. E.g. for 10-pair input the cost is reduced to ~66%.

Recommendation:

Apply the following modification to the implementation.

Note: in case all pairs contain a point-at-infinity (zero point) the cost will be higher because the finalExponentiation(1) will be computed needlessly. However, such inputs don't happen in practice and we believe it is not worth to handle them separately.

diff --git a/precompiles/EcPairing.yul b/precompiles/EcPairing.yul
index 2be2efe..4e2b597 100644
--- a/precompiles/EcPairing.yul
+++ b/precompiles/EcPairing.yul
@@ -1547,17 +1547,6 @@ object "EcPairing" {
                 f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51)
             }

-            /// @notice Computes the Pairing between two points P and Q.
-            /// @dev Applies the Millers Loop and the final exponentiation to return the result of the pairing.
-            /// @params g1x, g1y The coordinates of the point P of the curve G1.
-            /// @params g2_x0, g2_x1 The coefficients of the X coordinate of point Q on the twisted curve G2.
-            /// @params g2_y0, g2_y1 The coefficients of the Y coordinate of point Q on the twisted curve G2.
-            /// @return f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 The Fp12 element result of the pairing e(P,Q)
-            function pair(g1_x, g1_y, g2_x0, g2_x1, g2_y0, g2_y1) -f000, f001, f010, f011, f100, f101, f110, f111, f200, f201, f210, f211 {
-                f000, f001, f010, f011, f100, f101, f110, f111, f200, f201, f210, f211 := millerLoop(g2_x0, g2_x1, g2_y0, g2_y1, g1_x, g1_y)
-                f000, f001, f010, f011, f100, f101, f110, f111, f200, f201, f210, f211 := finalExponentiation(f000, f001, f010, f011, f100, f101, f110, f111, f200, f201, f210, f211)
-            }
-
             // FALLBACK

                        let inputSize := calldatasize()
@@ -1645,11 +1634,13 @@ object "EcPairing" {
                     continue
                 }

-                let f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := pair(g1_x, g1_y, g2_x0, g2_x1, g2_y0, g2_y1)
+                let f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := millerLoop(g2_x0, g2_x1, g2_y0, g2_y1, g1_x, g1_y)

                 r000, r001, r010, r011, r020, r021, r100, r101, r110, r111, r120, r121 := fp12Mul(r000, r001, r010, r011, r020, r021, r100, r101, r110, r111, r120, r121, f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121)
                        }

+            r000, r001, r010, r011, r020, r021, r100, r101, r110, r111, r120, r121 := finalExponentiation(r000, r001, r010, r011, r020, r021, r100, r101, r110, r111, r120, r121)
+
             // Pair check
             if and(eq(r000, MONTGOMERY_ONE()), iszero(or(r001, or(r010, r011)))) {
                 if iszero(or(or(r020, r021), or(r100, r101))) {

zkSync:

Spearbit:

@fkrause98 fkrause98 self-assigned this Apr 12, 2024
IAvecilla added a commit that referenced this issue Apr 18, 2024
* Apply diff patch from issue

* Remove artifacts

* Add script to check git ignore

* Add check to CI

* Update CI, update makefile

* Fix CI

* Fix path in copy-precompiles

* Add missing cross dependency

* Add missing cargo-cross

* Update ci, makefile

* Fix clean target on makefile

* Fix pairing suggestion

* Update solc install step in CI

---------

Co-authored-by: Francisco Krause Arnim <fran@MBPdeFrancisco.fibertel.com.ar>
Co-authored-by: IAvecilla <ignacio.avecilla@lambdaclass.com>
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 a pull request may close this issue.

2 participants