From 0a72b8ec9de461356858aa4cd283cbbd8ad8ab66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Mon, 5 Feb 2024 19:58:27 +0100 Subject: [PATCH 01/12] Big optmizations to ecPairing and small refactor --- main/pairings/BN254/addPointBN254.zkasm | 245 -------------- main/pairings/BN254/addPointFP2BN254.zkasm | 277 ++++++++++++++++ main/pairings/BN254/doublePointFP2BN254.zkasm | 114 +++++++ main/pairings/BN254/doublePointFPBN254.zkasm | 93 ++++++ main/pairings/BN254/ecAdd.zkasm | 137 +++++--- main/pairings/BN254/ecMul.zkasm | 133 +++++--- main/pairings/BN254/escalarMulBN254.zkasm | 155 --------- main/pairings/BN254/lineDiffPointsBN254.zkasm | 9 +- main/pairings/BN254/lineSamePointsBN254.zkasm | 13 +- .../BN254/scalarMulPointBy6X2FP2BN254.zkasm | 158 +++++++++ main/pairings/BN254/sixX2.zkasm | 168 ++++++++++ .../CYCLOFP12BN254/compressFp12BN254.zkasm | 5 + .../CYCLOFP12BN254/decompressFp12BN254.zkasm | 28 +- .../expByXCompCycloFp12BN254.zkasm | 55 +++- .../squareCompCycloFp12BN254.zkasm | 22 +- .../CYCLOFP12BN254/squareCycloFp12BN254.zkasm | 29 +- main/pairings/FP12BN254/frob2Fp12BN254.zkasm | 15 +- main/pairings/FP12BN254/frob3Fp12BN254.zkasm | 5 + main/pairings/FP12BN254/frobFp12BN254.zkasm | 5 + .../pairings/FP12BN254/inverseFp12BN254.zkasm | 6 + main/pairings/FP12BN254/mulFp12BN254.zkasm | 5 + .../FP12BN254/sparseMulAFp12BN254.zkasm | 5 + .../FP12BN254/sparseMulBFp12BN254.zkasm | 5 + main/pairings/FP12BN254/squareFp12BN254.zkasm | 31 +- main/pairings/FP2BN254/addFp2BN254.zkasm | 9 +- main/pairings/FP2BN254/invFp2BN254.zkasm | 50 ++- main/pairings/FP2BN254/mulFp2BN254.zkasm | 5 + ...Fp2BN254.zkasm => scalarMulFp2BN254.zkasm} | 15 +- main/pairings/FP2BN254/squareFp2BN254.zkasm | 5 + main/pairings/FP2BN254/subFp2BN254.zkasm | 7 +- main/pairings/FP4BN254/squareFp4BN254.zkasm | 13 +- main/pairings/FP6BN254/addFp6BN254.zkasm | 5 + .../FP6BN254/escalarMulFp6BN254.zkasm | 51 --- main/pairings/FP6BN254/inverseFp6BN254.zkasm | 6 + main/pairings/FP6BN254/mulFp6BN254.zkasm | 5 + .../pairings/FP6BN254/scalarMulFp6BN254.zkasm | 56 ++++ .../FP6BN254/sparseMulAFp6BN254.zkasm | 5 + .../FP6BN254/sparseMulBFp6BN254.zkasm | 5 + .../FP6BN254/sparseMulCFp6BN254.zkasm | 5 + main/pairings/FP6BN254/squareFp6BN254.zkasm | 9 +- main/pairings/FP6BN254/subFp6BN254.zkasm | 5 + main/pairings/FPBN254/addFpBN254.zkasm | 5 + main/pairings/FPBN254/invFpBN254.zkasm | 22 +- main/pairings/FPBN254/mulFpBN254.zkasm | 5 + main/pairings/FPBN254/reduceFpBN254.zkasm | 5 + main/pairings/FPBN254/squareFpBN254.zkasm | 5 + main/pairings/FPBN254/subFpBN254.zkasm | 5 + main/pairings/FRBN254/reduceFrBN254.zkasm | 5 + main/pairings/constants.zkasm | 2 +- main/pairings/ecPairing.zkasm | 43 ++- main/pairings/finalExpBN254.zkasm | 14 +- main/pairings/halfPairingBN254.zkasm | 110 +++++-- main/pairings/millerLoopBN254.zkasm | 178 ++++++---- main/pairings/pairingBN254.zkasm | 110 +++++-- .../unused/scalarMulPointFP2BN254.zkasm | 191 +++++++++++ main/precompiled/selector.zkasm | 26 +- main/tables/bitwiseReconstruction.zkasm | 274 ++++++++++++++++ test/testCycloFp12ArithBN254.zkasm | 165 +++++----- test/testEcAdd.zkasm | 8 +- test/testEcMul.zkasm | 29 +- test/testFinalExpBn254.zkasm | 27 +- test/testFp12ArithBN254.zkasm | 6 +- test/testFp2ArithBN254.zkasm | 14 +- test/testFp6ArithBN254.zkasm | 29 +- test/testHalfPairingBN254.zkasm | 12 +- test/testPairingBN254.zkasm | 36 +- test/testPointArithBN254.zkasm | 309 ++++++++++-------- 67 files changed, 2580 insertions(+), 1029 deletions(-) delete mode 100644 main/pairings/BN254/addPointBN254.zkasm create mode 100644 main/pairings/BN254/addPointFP2BN254.zkasm create mode 100644 main/pairings/BN254/doublePointFP2BN254.zkasm create mode 100644 main/pairings/BN254/doublePointFPBN254.zkasm delete mode 100644 main/pairings/BN254/escalarMulBN254.zkasm create mode 100644 main/pairings/BN254/scalarMulPointBy6X2FP2BN254.zkasm create mode 100644 main/pairings/BN254/sixX2.zkasm rename main/pairings/FP2BN254/{escalarMulFp2BN254.zkasm => scalarMulFp2BN254.zkasm} (58%) delete mode 100644 main/pairings/FP6BN254/escalarMulFp6BN254.zkasm create mode 100644 main/pairings/FP6BN254/scalarMulFp6BN254.zkasm create mode 100644 main/pairings/unused/scalarMulPointFP2BN254.zkasm create mode 100644 main/tables/bitwiseReconstruction.zkasm diff --git a/main/pairings/BN254/addPointBN254.zkasm b/main/pairings/BN254/addPointBN254.zkasm deleted file mode 100644 index 8c2cf80b..00000000 --- a/main/pairings/BN254/addPointBN254.zkasm +++ /dev/null @@ -1,245 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; PRE: P1,P2 ∈ E'(Fp2) -;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to FP2 arithmetic -;; -;; addPointBN254: -;; in: P1 = (P1.x1 + P1.x2·u, P1.y1 + P1.y2·u), P2 = (P2.x1 + P2.x2·u, P2.y1 + P2.y2·u) ∈ E'(Fp2) -;; out: P1 + P2 = (P3.x1 + P3.x2·u, P3.y1 + P3.y2·u) ∈ E'(Fp2) -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; addPointBN254 assumes both P1 and P2 belong to E'(Fp2), since it is checked in the pairing. -; However, it must be implemented if addPointBN254 wants to be used independently. - -; Since the curve is E'/Fp2: y² = x³ + 3/(9+u), there is no issue in representing the point at infinity as (0, 0). - -VAR GLOBAL addPointBN254_P1_x1 -VAR GLOBAL addPointBN254_P1_x2 -VAR GLOBAL addPointBN254_P1_y1 -VAR GLOBAL addPointBN254_P1_y2 -VAR GLOBAL addPointBN254_P2_x1 -VAR GLOBAL addPointBN254_P2_x2 -VAR GLOBAL addPointBN254_P2_y1 -VAR GLOBAL addPointBN254_P2_y2 -VAR GLOBAL addPointBN254_P3_x1 -VAR GLOBAL addPointBN254_P3_x2 -VAR GLOBAL addPointBN254_P3_y1 -VAR GLOBAL addPointBN254_P3_y2 -VAR GLOBAL addPointBN254_lambda_x -VAR GLOBAL addPointBN254_lambda_y -VAR GLOBAL addPointBN254_RR - -addPointBN254: - RR :MSTORE(addPointBN254_RR) - - ; Is P1 = O? - 0n => B - $ => A :MLOAD(addPointBN254_P1_x1) - $ :EQ, JMPNC(__addPointBN254_P1_continue) - $ => A :MLOAD(addPointBN254_P1_x2) - $ :EQ, JMPNC(__addPointBN254_P1_continue) - $ => A :MLOAD(addPointBN254_P1_y1) - $ :EQ, JMPNC(__addPointBN254_P1_continue) - $ => A :MLOAD(addPointBN254_P1_y2) - $ :EQ, JMPC(addPointBN254_P1_is_zero) - __addPointBN254_P1_continue: - - ; Is P2 = 0? - 0n => B - $ => A :MLOAD(addPointBN254_P2_x1) - $ :EQ, JMPNC(__addPointBN254_P2_continue) - $ => A :MLOAD(addPointBN254_P2_x2) - $ :EQ, JMPNC(__addPointBN254_P2_continue) - $ => A :MLOAD(addPointBN254_P2_y1) - $ :EQ, JMPNC(__addPointBN254_P2_continue) - $ => A :MLOAD(addPointBN254_P2_y2) - $ :EQ, JMPC(addPointBN254_P2_is_zero) - __addPointBN254_P2_continue: - - ; P1 and P2 are not 0, let's check whether they are different points, the same point or inverses of each other - ; Is P1.x == P2.x? - $ => A :MLOAD(addPointBN254_P1_x1) - $ => B :MLOAD(addPointBN254_P2_x1) - $ :EQ, JMPNC(addPointBN254_different) - $ => A :MLOAD(addPointBN254_P1_x2) - $ => B :MLOAD(addPointBN254_P2_x2) - $ :EQ, JMPNC(addPointBN254_different) - - ; Is P1.y == P2.y? - $ => A :MLOAD(addPointBN254_P1_y1) - $ => B :MLOAD(addPointBN254_P2_y1) - $ :EQ, JMPNC(addPointBN254_P1_and_P2_are_inverted) - $ => A :MLOAD(addPointBN254_P1_y2) - $ => B :MLOAD(addPointBN254_P2_y2) - $ :EQ, JMPNC(addPointBN254_P1_and_P2_are_inverted) - - ; P1 == P2 - :JMP(addPointBN254_same) - -addPointBN254_P1_is_zero: - ; P3 = P2 - $ => A :MLOAD(addPointBN254_P2_x1) - $ => B :MLOAD(addPointBN254_P2_x2) - $ => C :MLOAD(addPointBN254_P2_y1) - $ => D :MLOAD(addPointBN254_P2_y2) - A :MSTORE(addPointBN254_P3_x1) - B :MSTORE(addPointBN254_P3_x2) - C :MSTORE(addPointBN254_P3_y1) - D :MSTORE(addPointBN254_P3_y2) - - :JMP(addPointBN254_end) - -addPointBN254_P2_is_zero: - ; P3 = P1 - $ => A :MLOAD(addPointBN254_P1_x1) - $ => B :MLOAD(addPointBN254_P1_x2) - $ => C :MLOAD(addPointBN254_P1_y1) - $ => D :MLOAD(addPointBN254_P1_y2) - A :MSTORE(addPointBN254_P3_x1) - B :MSTORE(addPointBN254_P3_x2) - C :MSTORE(addPointBN254_P3_y1) - D :MSTORE(addPointBN254_P3_y2) - - :JMP(addPointBN254_end) - -addPointBN254_P1_and_P2_are_inverted: - ; Check -P1.y == P2.y - %BN254_P => A - $ => B :MLOAD(addPointBN254_P1_y1) - $ => C :SUB - $ => B :MLOAD(addPointBN254_P1_y2) - $ => D :SUB - - $ => A :MLOAD(addPointBN254_P2_y1) - C :ASSERT - $ => A :MLOAD(addPointBN254_P2_y2) - D :ASSERT - - ; P3 = O - 0n :MSTORE(addPointBN254_P3_x1) - 0n :MSTORE(addPointBN254_P3_x2) - 0n :MSTORE(addPointBN254_P3_y1) - 0n :MSTORE(addPointBN254_P3_y2) - - :JMP(addPointBN254_end) - -addPointBN254_same: - $ => A :MLOAD(addPointBN254_P1_y1) - $ => B :MLOAD(addPointBN254_P1_y2) - $ => C :MLOAD(addPointBN254_P1_y1) - $ => D :MLOAD(addPointBN254_P1_y2), CALL(addFp2BN254) - ; E + C·u = 2y - - E => A - C => B :CALL(invFp2BN254) - ; C + D·u = 1 / 2y - - 3n => A :CALL(escalarMulFp2BN254) - ; E + C·u = 3/2y - - $ => A :MLOAD(addPointBN254_P1_x1) - $ => B :MLOAD(addPointBN254_P1_x2) - C => D - E => C :CALL(mulFp2BN254) - ; E + C·u = 3x/2y - - $ => A :MLOAD(addPointBN254_P1_x1) - $ => B :MLOAD(addPointBN254_P1_x2) - C => D - E => C :CALL(mulFp2BN254) - ; E + C·u = lambda = 3x²/2y - - E :MSTORE(addPointBN254_lambda_x) - C :MSTORE(addPointBN254_lambda_y) - ; E + C·u = lambda - - E => A - C => B :CALL(squareFp2BN254) - ; E + C·u = lambda² - - E => A - C => B - $ => C :MLOAD(addPointBN254_P1_x1) - $ => D :MLOAD(addPointBN254_P1_x2), CALL(subFp2BN254) - ; E + C·u = lambda² - x - - E => A - C => B - $ => C :MLOAD(addPointBN254_P1_x1) - $ => D :MLOAD(addPointBN254_P1_x2), CALL(subFp2BN254) - ; E + C·u = lambda² - x - x - - :JMP(addPointBN254_common_calculate) - -addPointBN254_different: - $ => A :MLOAD(addPointBN254_P2_x1) - $ => B :MLOAD(addPointBN254_P2_x2) - $ => C :MLOAD(addPointBN254_P1_x1) - $ => D :MLOAD(addPointBN254_P1_x2), CALL(subFp2BN254) - ; E + C·u = P2.x - P1.x - - E => A - C => B :CALL(invFp2BN254) - ; C + D·u = 1 / (P2_x - P1_x) - C :MSTORE(addPointBN254_lambda_x) - D :MSTORE(addPointBN254_lambda_y) - - $ => A :MLOAD(addPointBN254_P2_y1) - $ => B :MLOAD(addPointBN254_P2_y2) - $ => C :MLOAD(addPointBN254_P1_y1) - $ => D :MLOAD(addPointBN254_P1_y2), CALL(subFp2BN254) - ; E + C·u = P2.y - P1.y - - $ => A :MLOAD(addPointBN254_lambda_x) - $ => B :MLOAD(addPointBN254_lambda_y) - C => D - E => C :CALL(mulFp2BN254) - ; E + C·u = lambda = (P2_y - P1_y) / (P2_x - P1_x) - E :MSTORE(addPointBN254_lambda_x) - C :MSTORE(addPointBN254_lambda_y) - - E => A - C => B :CALL(squareFp2BN254) - ; E + C·u = lambda² - - E => A - C => B - $ => C :MLOAD(addPointBN254_P1_x1) - $ => D :MLOAD(addPointBN254_P1_x2), CALL(subFp2BN254) - ; E + C·u = lambda² - P1.x - - E => A - C => B - $ => C :MLOAD(addPointBN254_P2_x1) - $ => D :MLOAD(addPointBN254_P2_x2), CALL(subFp2BN254) - ; E + C·u = lambda² - P1.x - P2.x - -addPointBN254_common_calculate: - E :MSTORE(addPointBN254_P3_x1) - C :MSTORE(addPointBN254_P3_x2) - ; P3.x = lambda² - P1.x - P2.x - - $ => A :MLOAD(addPointBN254_P1_x1) - $ => B :MLOAD(addPointBN254_P1_x2) - C => D - E => C :CALL(subFp2BN254) - ; E + C·u = P1.x - P3.x - - $ => A :MLOAD(addPointBN254_lambda_x) - $ => B :MLOAD(addPointBN254_lambda_y) - C => D - E => C :CALL(mulFp2BN254) - ; E + C·u = lambda·(P1.x - P3.x) - - E => A - C => B - $ => C :MLOAD(addPointBN254_P1_y1) - $ => D :MLOAD(addPointBN254_P1_y2), CALL(subFp2BN254) - ; E + C·u = lambda·(P1.x - P3.x) - P1.y - - E :MSTORE(addPointBN254_P3_y1) - C :MSTORE(addPointBN254_P3_y2) - -addPointBN254_end: - $ => RR :MLOAD(addPointBN254_RR) - :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/addPointFP2BN254.zkasm b/main/pairings/BN254/addPointFP2BN254.zkasm new file mode 100644 index 00000000..4dbd00c1 --- /dev/null +++ b/main/pairings/BN254/addPointFP2BN254.zkasm @@ -0,0 +1,277 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: P1,P2 ∈ E'(Fp2) +;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to FP2 arithmetic +;; +;; addPointFP2BN254: +;; in: P1 = (P1.x1 + P1.x2·u, P1.y1 + P1.y2·u), P2 = (P2.x1 + P2.x2·u, P2.y1 + P2.y2·u) ∈ E'(Fp2) +;; out: P1 + P2 = (P3.x1 + P3.x2·u, P3.y1 + P3.y2·u) ∈ E'(Fp2) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; addPointFP2BN254 assumes both P1 and P2 belong to E'(Fp2), since it is checked in the pairing. +; However, it must be implemented if addPointFP2BN254 wants to be used independently. + +; Since the curve is E'/Fp2: y² = x³ + 3/(9+u), there is no issue in representing the point at infinity as (0, 0). + +VAR GLOBAL addPointFP2BN254_P1_x1 +VAR GLOBAL addPointFP2BN254_P1_x2 +VAR GLOBAL addPointFP2BN254_P1_y1 +VAR GLOBAL addPointFP2BN254_P1_y2 +VAR GLOBAL addPointFP2BN254_P2_x1 +VAR GLOBAL addPointFP2BN254_P2_x2 +VAR GLOBAL addPointFP2BN254_P2_y1 +VAR GLOBAL addPointFP2BN254_P2_y2 +VAR GLOBAL addPointFP2BN254_P3_x1 +VAR GLOBAL addPointFP2BN254_P3_x2 +VAR GLOBAL addPointFP2BN254_P3_y1 +VAR GLOBAL addPointFP2BN254_P3_y2 +VAR GLOBAL addPointFP2BN254_lambda_x +VAR GLOBAL addPointFP2BN254_lambda_y + +VAR GLOBAL addPointFP2BN254_diff ; 1 if one can assume that P1 != P2 and P1,P2 != 𝒪, 0 otherwise + +VAR GLOBAL addPointFP2BN254_RR + +; RESOURCES: +; ------------------------------------------- +; PATH 1 addPointFP2BN254_diff = 0: +; · PATH 1.1 P1 == 𝒪: [steps: 21, bin: 4] +; · PATH 1.2 P1 != 𝒪 and P2 == 𝒪: [steps: 30, bin: 8] +; · PATH 1.3 P1,P2 != 𝒪 and P1 == -P2: [steps: 47, bin: 14] +; · PATH 1.4 P1,P2 != 𝒪 and P1 == P2: [steps: 121, bin: 10, arith: 11]-[steps: 133, bin: 16, arith: 11] <--- w.c. +; · PATH 1.5 P1,P2 != 𝒪 and P1 != P2,-P2: [steps: 110, bin: 7, arith: 10]-[steps: 125, bin: 14, arith: 10] +; PATH 2 addPointFP2BN254_diff = 1: [steps: 101, bin: 4, arith: 10] +; ------------------------------------------- + +addPointFP2BN254: + RR :MSTORE(addPointFP2BN254_RR) + + $ :MLOAD(addPointFP2BN254_diff), JMPNZ(addPointFP2BN254_different) + + ; Is P1 = 𝒪? + 0n => B + $ => A :MLOAD(addPointFP2BN254_P1_x1) + $ :EQ, JMPNC(__addPointFP2BN254_P1_continue) + $ => A :MLOAD(addPointFP2BN254_P1_x2) + $ :EQ, JMPNC(__addPointFP2BN254_P1_continue) + $ => A :MLOAD(addPointFP2BN254_P1_y1) + $ :EQ, JMPNC(__addPointFP2BN254_P1_continue) + $ => A :MLOAD(addPointFP2BN254_P1_y2) + $ :EQ, JMPC(addPointFP2BN254_P1_is_zero) + __addPointFP2BN254_P1_continue: + ; [steps: 11, bin: 4] + + ; Is P2 = 𝒪? + 0n => B + $ => A :MLOAD(addPointFP2BN254_P2_x1) + $ :EQ, JMPNC(__addPointFP2BN254_P2_continue) + $ => A :MLOAD(addPointFP2BN254_P2_x2) + $ :EQ, JMPNC(__addPointFP2BN254_P2_continue) + $ => A :MLOAD(addPointFP2BN254_P2_y1) + $ :EQ, JMPNC(__addPointFP2BN254_P2_continue) + $ => A :MLOAD(addPointFP2BN254_P2_y2) + $ :EQ, JMPC(addPointFP2BN254_P2_is_zero) + __addPointFP2BN254_P2_continue: + ; [steps: 20, bin: 8] + + ; P1 and P2 are not 𝒪, let's check whether they are different points, the same point or inverses of each other + ; Is P1.x == P2.x? + $ => A :MLOAD(addPointFP2BN254_P1_x1) + $ => B :MLOAD(addPointFP2BN254_P2_x1) + $ :EQ, JMPNC(addPointFP2BN254_different) + $ => A :MLOAD(addPointFP2BN254_P1_x2) + $ => B :MLOAD(addPointFP2BN254_P2_x2) + $ :EQ, JMPNC(addPointFP2BN254_different) + ; [steps: 26, bin: 10] + + ; Is P1.y == P2.y? + $ => A :MLOAD(addPointFP2BN254_P1_y1) + $ => B :MLOAD(addPointFP2BN254_P2_y1) + $ :EQ, JMPNC(addPointFP2BN254_P1_and_P2_are_inverted) + $ => A :MLOAD(addPointFP2BN254_P1_y2) + $ => B :MLOAD(addPointFP2BN254_P2_y2) + $ :EQ, JMPC(addPointFP2BN254_same, addPointFP2BN254_P1_and_P2_are_inverted) + ; [steps: 32, bin: 12] + +; Begin of branching +addPointFP2BN254_P1_is_zero: + ; before (w.c.) -> [steps: 11, bin: 4] + + ; P3 = P2 + $ => A :MLOAD(addPointFP2BN254_P2_x1) + $ => B :MLOAD(addPointFP2BN254_P2_x2) + $ => C :MLOAD(addPointFP2BN254_P2_y1) + $ => D :MLOAD(addPointFP2BN254_P2_y2) + A :MSTORE(addPointFP2BN254_P3_x1) + B :MSTORE(addPointFP2BN254_P3_x2) + C :MSTORE(addPointFP2BN254_P3_y1) + D :MSTORE(addPointFP2BN254_P3_y2), JMP(addPointFP2BN254_end) + + ; till the end -> [steps: 21, bin: 4] + +addPointFP2BN254_P2_is_zero: + ; before (w.c.) -> [steps: 20, bin: 8] + + ; P3 = P1 + $ => A :MLOAD(addPointFP2BN254_P1_x1) + $ => B :MLOAD(addPointFP2BN254_P1_x2) + $ => C :MLOAD(addPointFP2BN254_P1_y1) + $ => D :MLOAD(addPointFP2BN254_P1_y2) + A :MSTORE(addPointFP2BN254_P3_x1) + B :MSTORE(addPointFP2BN254_P3_x2) + C :MSTORE(addPointFP2BN254_P3_y1) + D :MSTORE(addPointFP2BN254_P3_y2), JMP(addPointFP2BN254_end) + + ; till the end -> [steps: 30, bin: 8] + +addPointFP2BN254_P1_and_P2_are_inverted: + ; before (w.c.) -> [steps: 32, bin: 12] + + ; Check -P1.y == P2.y + %BN254_P => A + $ => B :MLOAD(addPointFP2BN254_P1_y1) + $ => C :SUB + $ => B :MLOAD(addPointFP2BN254_P1_y2) + $ => D :SUB + + $ => A :MLOAD(addPointFP2BN254_P2_y1) + C :ASSERT + $ => A :MLOAD(addPointFP2BN254_P2_y2) + D :ASSERT + + ; P3 = 𝒪 + 0n :MSTORE(addPointFP2BN254_P3_x1) + 0n :MSTORE(addPointFP2BN254_P3_x2) + 0n :MSTORE(addPointFP2BN254_P3_y1) + 0n :MSTORE(addPointFP2BN254_P3_y2), JMP(addPointFP2BN254_end) + + ; till the end -> [steps: 47, bin: 14] +; End of branching + +addPointFP2BN254_same: + ; before (w.c.) -> [steps: 32, bin: 12] + + $ => A :MLOAD(addPointFP2BN254_P1_y1) + $ => B :MLOAD(addPointFP2BN254_P1_y2) + $ => C :MLOAD(addPointFP2BN254_P1_y1) + $ => D :MLOAD(addPointFP2BN254_P1_y2), CALL(addFp2BN254) + ; E + C·u = 2y + ; [steps: 39, bin: 12, arith: 1] + + E => A + C => B :CALL(invFp2BN254) + ; C + D·u = 1 / 2y + ; [steps: 64, bin: 16, arith: 2] + + 3n => A :CALL(scalarMulFp2BN254) + ; E + C·u = 3/2y + ; [steps: 69, bin: 16, arith: 3] + + $ => A :MLOAD(addPointFP2BN254_P1_x1) + $ => B :MLOAD(addPointFP2BN254_P1_x2) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = 3x/2y + + $ => A :MLOAD(addPointFP2BN254_P1_x1) + $ => B :MLOAD(addPointFP2BN254_P1_x2) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = lambda = 3x²/2y + + E :MSTORE(addPointFP2BN254_lambda_x) + C :MSTORE(addPointFP2BN254_lambda_y), JMP(addPointFP2BN254_common_calculate) + ; E + C·u = lambda + ; [steps: 85, bin: 16, arith: 5] + +addPointFP2BN254_different: + ; block costs: [steps: 51, bin: 4, arith: 4] + + ; before (w.c.) -> [steps: 26, bin: 10] + + $ => A :MLOAD(addPointFP2BN254_P2_x1) + $ => B :MLOAD(addPointFP2BN254_P2_x2) + $ => C :MLOAD(addPointFP2BN254_P1_x1) + $ => D :MLOAD(addPointFP2BN254_P1_x2), CALL(subFp2BN254) + ; E + C·u = P2.x - P1.x + ; [steps: 33, bin: 10, arith: 1] + + E => A + C => B :CALL(invFp2BN254) + ; C + D·u = 1 / (P2_x - P1_x) + C :MSTORE(addPointFP2BN254_lambda_x) + D :MSTORE(addPointFP2BN254_lambda_y) + ; [steps: 60, bin: 14, arith: 2] + + $ => A :MLOAD(addPointFP2BN254_P2_y1) + $ => B :MLOAD(addPointFP2BN254_P2_y2) + $ => C :MLOAD(addPointFP2BN254_P1_y1) + $ => D :MLOAD(addPointFP2BN254_P1_y2), CALL(subFp2BN254) + ; E + C·u = P2.y - P1.y + ; [steps: 67, bin: 14, arith: 3] + + $ => A :MLOAD(addPointFP2BN254_lambda_x) + $ => B :MLOAD(addPointFP2BN254_lambda_y) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = lambda = (P2_y - P1_y) / (P2_x - P1_x) + + E :MSTORE(addPointFP2BN254_lambda_x) + C :MSTORE(addPointFP2BN254_lambda_y) + + 0 :MSTORE(addPointFP2BN254_diff) ; Reset the flag + ; [steps: 77, bin: 14, arith: 4] + +addPointFP2BN254_common_calculate: + ; block costs: [steps: 48, bin: 0, arith: 6] + + E => A + C => B :CALL(squareFp2BN254) + ; E + C·u = lambda² + ; [steps: 7, bin: 0, arith: 1] + + E => A + C => B + $ => C :MLOAD(addPointFP2BN254_P1_x1) + $ => D :MLOAD(addPointFP2BN254_P1_x2), CALL(subFp2BN254) + ; E + C·u = lambda² - P1.x + + E => A + C => B + $ => C :MLOAD(addPointFP2BN254_P2_x1) + $ => D :MLOAD(addPointFP2BN254_P2_x2), CALL(subFp2BN254) + ; E + C·u = lambda² - P1.x - P2.x + ; [steps: 21, bin: 0, arith: 3] + + E :MSTORE(addPointFP2BN254_P3_x1) + C :MSTORE(addPointFP2BN254_P3_x2) + ; P3.x = lambda² - P1.x - P2.x + + $ => A :MLOAD(addPointFP2BN254_P1_x1) + $ => B :MLOAD(addPointFP2BN254_P1_x2) + C => D + E => C :CALL(subFp2BN254) + ; E + C·u = P1.x - P3.x + ; [steps: 30, bin: 0, arith: 4] + + $ => A :MLOAD(addPointFP2BN254_lambda_x) + $ => B :MLOAD(addPointFP2BN254_lambda_y) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = lambda·(P1.x - P3.x) + ; [steps: 37, bin: 0, arith: 5] + + E => A + C => B + $ => C :MLOAD(addPointFP2BN254_P1_y1) + $ => D :MLOAD(addPointFP2BN254_P1_y2), CALL(subFp2BN254) + ; E + C·u = lambda·(P1.x - P3.x) - P1.y + + E :MSTORE(addPointFP2BN254_P3_y1) + C :MSTORE(addPointFP2BN254_P3_y2) + + ; till the end -> ; [steps: 48, bin: 0, arith: 6] + +addPointFP2BN254_end: + $ => RR :MLOAD(addPointFP2BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/doublePointFP2BN254.zkasm b/main/pairings/BN254/doublePointFP2BN254.zkasm new file mode 100644 index 00000000..1655e6b1 --- /dev/null +++ b/main/pairings/BN254/doublePointFP2BN254.zkasm @@ -0,0 +1,114 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: Both P and 2·P are in E'(Fp2)\{𝒪} and its coordinates are in the range [0,BN254_P) +;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to FP2 arithmetic +;; +;; doublePointFP2BN254: +;; in: P = (P.x1 + P.x2·u, P.y1 + P.y2·u) ∈ E'(Fp2) +;; out: 2·P = (Q.x1 + Q.x2·u, Q.y1 + Q.y2·u) ∈ E'(Fp2) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Since the curve is E'/Fp2: y² = x³ + 3/(9+u), there is no issue in representing the point at infinity as (0, 0). + +VAR GLOBAL doublePointFP2BN254_P_x1 +VAR GLOBAL doublePointFP2BN254_P_x2 +VAR GLOBAL doublePointFP2BN254_P_y1 +VAR GLOBAL doublePointFP2BN254_P_y2 +VAR GLOBAL doublePointFP2BN254_Q_x1 +VAR GLOBAL doublePointFP2BN254_Q_x2 +VAR GLOBAL doublePointFP2BN254_Q_y1 +VAR GLOBAL doublePointFP2BN254_Q_y2 +VAR GLOBAL doublePointFP2BN254_lambda_x +VAR GLOBAL doublePointFP2BN254_lambda_y +VAR GLOBAL doublePointFP2BN254_RR + +; RESOURCES: +; ----------------------------- +; [steps: 102, bin: 4, arith: 11] +; ----------------------------- + +doublePointFP2BN254: + RR :MSTORE(doublePointFP2BN254_RR) + + $ => A :MLOAD(doublePointFP2BN254_P_y1) + $ => B :MLOAD(doublePointFP2BN254_P_y2) + $ => C :MLOAD(doublePointFP2BN254_P_y1) + $ => D :MLOAD(doublePointFP2BN254_P_y2), CALL(addFp2BN254) + ; E + C·u = 2y + ; [steps: 8, bin: 0, arith: 1] + + E => A + C => B :CALL(invFp2BN254) + ; C + D·u = 1 / 2y + ; [steps: 33, bin: 4, arith: 2] + + 3n => A :CALL(scalarMulFp2BN254) + ; E + C·u = 3/2y + ; [steps: 38, bin: 4, arith: 3] + + $ => A :MLOAD(doublePointFP2BN254_P_x1) + $ => B :MLOAD(doublePointFP2BN254_P_x2) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = 3x/2y + + $ => A :MLOAD(doublePointFP2BN254_P_x1) + $ => B :MLOAD(doublePointFP2BN254_P_x2) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = lambda = 3x²/2y + ; [steps: 52, bin: 4, arith: 5] + + E :MSTORE(doublePointFP2BN254_lambda_x) + C :MSTORE(doublePointFP2BN254_lambda_y) + ; E + C·u = lambda + + E => A + C => B :CALL(squareFp2BN254) + ; E + C·u = lambda² + ; [steps: 61, bin: 4, arith: 6] + + E => A + C => B + $ => C :MLOAD(doublePointFP2BN254_P_x1) + $ => D :MLOAD(doublePointFP2BN254_P_x2), CALL(subFp2BN254) + ; E + C·u = lambda² - x + + E => A + C => B + $ => C :MLOAD(doublePointFP2BN254_P_x1) + $ => D :MLOAD(doublePointFP2BN254_P_x2), CALL(subFp2BN254) + ; E + C·u = lambda² - x - x + + E :MSTORE(doublePointFP2BN254_Q_x1) + C :MSTORE(doublePointFP2BN254_Q_x2) + ; Q.x = lambda² - P.x - P2.x + + $ => A :MLOAD(doublePointFP2BN254_P_x1) + $ => B :MLOAD(doublePointFP2BN254_P_x2) + C => D + E => C :CALL(subFp2BN254) + ; E + C·u = P.x - Q.x + ; [steps: 84, bin: 4, arith: 9] + + $ => A :MLOAD(doublePointFP2BN254_lambda_x) + $ => B :MLOAD(doublePointFP2BN254_lambda_y) + C => D + E => C :CALL(mulFp2BN254) + ; E + C·u = lambda·(P.x - Q.x) + ; [steps: 91, bin: 4, arith: 10] + + E => A + C => B + $ => C :MLOAD(doublePointFP2BN254_P_y1) + $ => D :MLOAD(doublePointFP2BN254_P_y2), CALL(subFp2BN254) + ; E + C·u = lambda·(P.x - Q.x) - P.y + + E :MSTORE(doublePointFP2BN254_Q_y1) + C :MSTORE(doublePointFP2BN254_Q_y2) + + ; till the end -> [steps: 102, bin: 4, arith: 11] + +doublePointFP2BN254_end: + $ => RR :MLOAD(doublePointFP2BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/doublePointFPBN254.zkasm b/main/pairings/BN254/doublePointFPBN254.zkasm new file mode 100644 index 00000000..e7bed49c --- /dev/null +++ b/main/pairings/BN254/doublePointFPBN254.zkasm @@ -0,0 +1,93 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: Both P and 2·P are in E(Fp)\{𝒪} and its coordinates are in the range [0,BN254_P) +;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to FP arithmetic +;; +;; doublePointFPBN254: +;; in: P = (P.x, P.y) ∈ E(Fp) +;; out: 2·P = (Q.x, Q.y) ∈ E(Fp) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Since the curve is E/Fp: y² = x³ + 3, there is no issue in representing the point at infinity as (0, 0). + +VAR GLOBAL doublePointFPBN254_P_x +VAR GLOBAL doublePointFPBN254_P_y +VAR GLOBAL doublePointFPBN254_P_y_inv +VAR GLOBAL doublePointFPBN254_Q_x +VAR GLOBAL doublePointFPBN254_Q_y +VAR GLOBAL doublePointFPBN254_lambda + +VAR GLOBAL doublePointFPBN254_RR + +; RESOURCES: +; ----------------------------- +; [steps: 174, bin: 14, arith: 24] +; ----------------------------- + +doublePointFPBN254: + RR :MSTORE(doublePointFPBN254_RR) + + $ => A :MLOAD(doublePointFPBN254_P_y) + $ => C :MLOAD(doublePointFPBN254_P_y), CALL(addFpBN254) + ; C = 2y + ; [steps: 14, bin: 1, arith: 2] + + C => A :CALL(invFpBN254) + ; B = 1 / 2y + B :MSTORE(doublePointFPBN254_P_y_inv) + ; [steps: 36, bin: 4, arith: 4] + + B => A,C :CALL(addFpBN254) + C => A + $ => C :MLOAD(doublePointFPBN254_P_y_inv), CALL(addFpBN254) + ; C = 3/2y + ; [steps: 61, bin: 6, arith: 8] + + C => A + $ => B :MLOAD(doublePointFPBN254_P_x), CALL(mulFpBN254) + ; C = 3x/2y + + C => A + $ => B :MLOAD(doublePointFPBN254_P_x), CALL(mulFpBN254) + ; C = lambda = 3x²/2y + ; [steps: 87, bin: 8, arith: 12] + + C :MSTORE(doublePointFPBN254_lambda) + ; C = lambda + + C => A :CALL(squareFpBN254) + ; B = lambda² + ; [steps: 102, bin: 9, arith: 14] + + B => A + $ => C :MLOAD(doublePointFPBN254_P_x), CALL(subFpBN254) + ; C = lambda² - P.x + + C => A + $ => C :MLOAD(doublePointFPBN254_P_x), CALL(subFpBN254) + ; C = lambda² - P.x - P.x + + C :MSTORE(doublePointFPBN254_Q_x) + ; Q.x = lambda² - P.x - P.x + + $ => A :MLOAD(doublePointFPBN254_P_x), CALL(subFpBN254) + ; C = P.x - Q.x + ; [steps: 144, bin: 12, arith: 20] + + $ => A :MLOAD(doublePointFPBN254_lambda) + C => B :CALL(mulFpBN254) + ; C = lambda·(P.x - Q.x) + ; [steps: 157, bin: 13, arith: 22] + + C => A + $ => C :MLOAD(doublePointFPBN254_P_y), CALL(subFpBN254) + ; C = lambda·(P.x - Q.x) - P.y + + C :MSTORE(doublePointFPBN254_Q_y) + ; Q.y = lambda·(P.x - Q.x) - P.y + +doublePointFPBN254_end: + $ => RR :MLOAD(doublePointFPBN254_RR) + :RETURN + + ; [steps: 174, bin: 14, arith: 24] \ No newline at end of file diff --git a/main/pairings/BN254/ecAdd.zkasm b/main/pairings/BN254/ecAdd.zkasm index 089116f7..784cc7e7 100644 --- a/main/pairings/BN254/ecAdd.zkasm +++ b/main/pairings/BN254/ecAdd.zkasm @@ -18,6 +18,8 @@ VAR GLOBAL ecAdd_P3_x VAR GLOBAL ecAdd_P3_y VAR GLOBAL ecAdd_lambda +VAR GLOBAL ecAdd_diff ; 1 if one can assume that P1 != P2 and P1,P2 != 𝒪, 0 otherwise + VAR GLOBAL ecAdd_RR ; ERROR CODES (B) @@ -29,9 +31,23 @@ VAR GLOBAL ecAdd_RR ; 5 - P1 is not in E(Fp) ; 6 - P2 is not in E(Fp) +; RESOURCES (not considering error paths): +; ------------------------------------------- +; PATH 1 ecAdd_diff = 0: +; · PATH 1.1 P1 == 𝒪 and P2 == 𝒪: [steps: 26, bin: 8] +; · PATH 1.2 P1 == 𝒪 and P2 != 𝒪: [steps: 84, bin: 13, arith: 8] +; · PATH 1.3 P1 != 𝒪 and P2 == 𝒪: [steps: 84, bin: 13, arith: 8] +; · PATH 1.4 P1,P2 != 𝒪 and P1 == P2: [steps: 323, bin: 33, arith: 40] <--- w.c. +; · PATH 1.5 P1,P2 != 𝒪 and P1 == -P2: [steps: 144, bin: 20, arith: 16] +; · PATH 1.6 P1,P2 != 𝒪 and P1 != P2,-P2: [steps: 298, bin: 31, arith: 36] +; PATH 2 ecAdd_diff = 1: [steps: 164, bin: 12, arith: 20] +; ------------------------------------------- ecAdd: RR :MSTORE(ecAdd_RR) + $ :MLOAD(ecAdd_diff), JMPNZ(ecAdd_different) + + ; Check whether the points coordinates are in the range [0, BN254_P) %BN254_P_MINUS_ONE => A $ => B :MLOAD(ecAdd_P1_x) $ :LT, JMPC(ecAdd_P1x_too_big) @@ -41,104 +57,125 @@ ecAdd: $ :LT, JMPC(ecAdd_P2x_too_big) $ => B :MLOAD(ecAdd_P2_y) $ :LT, JMPC(ecAdd_P2y_too_big) + ; [steps: 11, bin: 4] - ; Is P1 = O? + ; Is P1 = 𝒪? 0n => B $ => A :MLOAD(ecAdd_P1_x) $ :EQ, JMPNC(__ecAdd_P1_continue) $ => A :MLOAD(ecAdd_P1_y) $ :EQ, JMPC(ecAdd_P1_is_zero) __ecAdd_P1_continue: + ; [steps: 16, bin: 6] - ; Is P2 = O? + ; Is P2 = 𝒪? 0n => B $ => A :MLOAD(ecAdd_P2_x) $ :EQ, JMPNC(__ecAdd_P2_continue1) $ => A :MLOAD(ecAdd_P2_y) $ :EQ, JMPC(ecAdd_P2_is_zero) __ecAdd_P2_continue1: + ; [steps: 21, bin: 8] + ; P1 and P2 are not 𝒪 from here - ; 1] Check if P1 is in E(Fp) + ; 1] Check if P1 ∈ E(Fp) ; P1 in E iff (P1.y)² == (P1.x)³ + 3 (mod p) ; 1.1] Compute LHS and RHS $ => A :MLOAD(ecAdd_P1_x), CALL(squareFpBN254) ; B = (P1.x)² + ; [steps: 35, bin: 9, arith: 2] $ => A :MLOAD(ecAdd_P1_x), CALL(mulFpBN254) ; C = (P1.x)³ + ; [steps: 47, bin: 10, arith: 4] %BN254_E_B => A :CALL(addFpBN254) ; C = (P1.x)³ + 3 C :MSTORE(ecAdd_P3_x) + ; [steps: 60, bin: 11, arith: 6] $ => A :MLOAD(ecAdd_P1_y), CALL(squareFpBN254) ; B = (Py)² + ; [steps: 74, bin: 12, arith: 8] ; 1.2] Check if LHS == RHS B => A $ => B :MLOAD(ecAdd_P3_x) $ :EQ, JMPNC(ecAdd_P1_is_not_in_E) + ; [steps: 77, bin: 13, arith: 8] - ; 2] check if P2 is in E(Fp) + ; 2] check if P2 ∈ E(Fp) ; P2 in E iff (P2.y)² == (P2.x)³ + 3 (mod p) ; 2.1] Compute LHS and RHS $ => A :MLOAD(ecAdd_P2_x), CALL(squareFpBN254) ; B = (P2.x)² + ; [steps: 91, bin: 14, arith: 10] $ => A :MLOAD(ecAdd_P2_x), CALL(mulFpBN254) ; C = (P2.x)³ + ; [steps: 103, bin: 15, arith: 12] %BN254_E_B => A :CALL(addFpBN254) ; C = (P2.x)³ + 3 C :MSTORE(ecAdd_P3_x) + ; [steps: 116, bin: 16, arith: 14] $ => A :MLOAD(ecAdd_P2_y), CALL(squareFpBN254) ; B = (Py)² + ; [steps: 130, bin: 17, arith: 16] ; 2.2] Check if LHS == RHS B => A $ => B :MLOAD(ecAdd_P3_x) $ :EQ, JMPNC(ecAdd_P2_is_not_in_E) + ; P1,P2 ∈ E(Fp) from here - ; P1 and P2 are not 0, let's check whether they are different points, the same point or inverses of each other + ; P1 and P2 are not 𝒪, let's check whether they are different points, the same point or inverses of each other $ => A :MLOAD(ecAdd_P1_x) $ => B :MLOAD(ecAdd_P2_x) ; Is P1.x == P2.x? $ :EQ, JMPNC(ecAdd_different) + ; [steps: 136, bin: 19, arith: 16] $ => A :MLOAD(ecAdd_P1_y) $ => B :MLOAD(ecAdd_P2_y) ; Is P1.y == P2.y? - $ :EQ, JMPNC(ecAdd_P1_and_P2_are_inverted) - - ; P1 == P2 - :JMP(ecAdd_same) + $ :EQ, JMPC(ecAdd_same, ecAdd_P1_and_P2_are_inverted) + ; [steps: 139, bin: 20, arith: 16] +; Begin of branching ecAdd_P1_is_zero: - ; Is P2 = 0? + ; before (w.c.) -> [steps: 16, bin: 6] + + ; Is P2 = 𝒪? 0n => B $ => A :MLOAD(ecAdd_P2_x) $ :EQ, JMPNC(__ecAdd_P2_continue2) $ => A :MLOAD(ecAdd_P2_y) $ :EQ, JMPC(ecAdd_P1_and_P2_are_zero) __ecAdd_P2_continue2: + ; [steps: 21, bin: 8] ; P2 in E iff (P2.y)² == (P2.x)³ + 3 (mod p) ; 1] Compute LHS and RHS $ => A :MLOAD(ecAdd_P2_x), CALL(squareFpBN254) ; B = (P2.x)² + ; [steps: 35, bin: 9, arith: 2] $ => A :MLOAD(ecAdd_P2_x), CALL(mulFpBN254) ; C = (P2.x)³ + ; [steps: 47, bin: 10, arith: 4] %BN254_E_B => A :CALL(addFpBN254) ; C = (P2.x)³ + 3 C :MSTORE(ecAdd_P3_x) + ; [steps: 60, bin: 11, arith: 6] $ => A :MLOAD(ecAdd_P2_y), CALL(squareFpBN254) ; B = (Py)² + ; [steps: 74, bin: 12, arith: 8] ; 2] Check if LHS == RHS B => A @@ -149,25 +186,31 @@ ecAdd_P1_is_zero: $ => A :MLOAD(ecAdd_P2_x) $ => B :MLOAD(ecAdd_P2_y) A :MSTORE(ecAdd_P3_x) - B :MSTORE(ecAdd_P3_y) + B :MSTORE(ecAdd_P3_y), JMP(ecAdd_correct) - :JMP(ecAdd_correct) + ; till the end -> [steps: 84, bin: 13, arith: 8] ecAdd_P2_is_zero: + ; before (w.c.) -> [steps: 21, bin: 8] + ; P1 in E iff (P1.y)² == (P1.x)³ + 3 (mod p) ; 1] Compute LHS and RHS $ => A :MLOAD(ecAdd_P1_x), CALL(squareFpBN254) ; B = (P1.x)² + ; [steps: 35, bin: 9, arith: 2] $ => A :MLOAD(ecAdd_P1_x), CALL(mulFpBN254) ; C = (P1.x)³ + ; [steps: 47, bin: 10, arith: 4] %BN254_E_B => A :CALL(addFpBN254) ; C = (P1.x)³ + 3 C :MSTORE(ecAdd_P3_x) + ; [steps: 60, bin: 11, arith: 6] $ => A :MLOAD(ecAdd_P1_y), CALL(squareFpBN254) ; B = (Py)² + ; [steps: 74, bin: 12, arith: 8] ; 2] Check if LHS == RHS B => A @@ -178,109 +221,129 @@ ecAdd_P2_is_zero: $ => A :MLOAD(ecAdd_P1_x) $ => B :MLOAD(ecAdd_P1_y) A :MSTORE(ecAdd_P3_x) - B :MSTORE(ecAdd_P3_y) + B :MSTORE(ecAdd_P3_y), JMP(ecAdd_correct) - :JMP(ecAdd_correct) + ; till the end -> [steps: 84, bin: 13, arith: 8] ecAdd_P1_and_P2_are_zero: - ; P3 = 0 + ; before (w.c.) -> [steps: 21, bin: 8] + + ; P3 = 𝒪 0n :MSTORE(ecAdd_P3_x) - 0n :MSTORE(ecAdd_P3_y) + 0n :MSTORE(ecAdd_P3_y), JMP(ecAdd_correct) - :JMP(ecAdd_correct) + ; till the end -> [steps: 26, bin: 8] ecAdd_P1_and_P2_are_inverted: - ; P3 = 0 - 0n :MSTORE(ecAdd_P3_x) - 0n :MSTORE(ecAdd_P3_y) + ; before (w.c.) -> [steps: 139, bin: 20, arith: 16] - :JMP(ecAdd_correct) + ; P3 = 𝒪 + 0n :MSTORE(ecAdd_P3_x) + 0n :MSTORE(ecAdd_P3_y), JMP(ecAdd_correct) + + ; till the end -> [steps: 144, bin: 20, arith: 16] +; End of branching ecAdd_same: + ; before (w.c.) -> [steps: 139, bin: 20, arith: 16] + $ => A :MLOAD(ecAdd_P1_y) $ => C :MLOAD(ecAdd_P1_y), CALL(addFpBN254) ; C = 2y + ; [steps: 152, bin: 21, arith: 18] C => A :CALL(invFpBN254) ; B = 1 / 2y B :MSTORE(ecAdd_P1_y_inv) + ; [steps: 174, bin: 24, arith: 20] B => A,C :CALL(addFpBN254) C => A $ => C :MLOAD(ecAdd_P1_y_inv), CALL(addFpBN254) ; C = 3/2y + ; [steps: 199, bin: 25, arith: 24] C => A $ => B :MLOAD(ecAdd_P1_x), CALL(mulFpBN254) ; C = 3x/2y + ; [steps: 212, bin: 26, arith: 26] C => A $ => B :MLOAD(ecAdd_P1_x), CALL(mulFpBN254) ; C = lambda = 3x²/2y - C :MSTORE(ecAdd_lambda) + C :MSTORE(ecAdd_lambda), JMP(ecAdd_common_calculate) ; C = lambda + ; [steps: 226, bin: 27, arith: 28] - C => A :CALL(squareFpBN254) - ; B = lambda² - - B => A - $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) - ; C = lambda² - x - - C => A - $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) - ; C = lambda² - x - x +ecAdd_different: + ; block costs: [steps: 65, bin: 6, arith: 8] - :JMP(ecAdd_common_calculate) + ; before (w.c.) -> [steps: 136, bin: 19, arith: 16] -ecAdd_different: $ => A :MLOAD(ecAdd_P2_x) $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) ; C = P2.x - P1.x + ; [steps: 150, bin: 20, arith: 18] C => A :CALL(invFpBN254) ; B = 1 / (P2.x - P1.x) B :MSTORE(ecAdd_lambda) + ; [steps: 172, bin: 23, arith: 20] $ => A :MLOAD(ecAdd_P2_y) $ => C :MLOAD(ecAdd_P1_y), CALL(subFpBN254) ; C = P2.y - P1.y + ; [steps: 186, bin: 24, arith: 22] C => A $ => B :MLOAD(ecAdd_lambda), CALL(mulFpBN254) ; C = lambda = (P2.y - P1.y) / (P2.x - P1.x) + C :MSTORE(ecAdd_lambda) + ; C = lambda + + 0 :MSTORE(ecAdd_diff) ; Reset the flag + ; [steps: 201, bin: 25, arith: 24] + +ecAdd_common_calculate: + ; block costs: [steps: 97, bin: 6, arith: 12] C => A :CALL(squareFpBN254) ; B = lambda² + ; [steps: 14, bin: 1, arith: 2] B => A $ => C :MLOAD(ecAdd_P1_x), CALL(subFpBN254) ; C = lambda² - P1.x + ; [steps: 28, bin: 2, arith: 4] C => A $ => C :MLOAD(ecAdd_P2_x), CALL(subFpBN254) ; C = lambda² - P1.x - P2.x + ; [steps: 42, bin: 3, arith: 6] -ecAdd_common_calculate: C :MSTORE(ecAdd_P3_x) ; P3.x = lambda² - P1.x - P2.x $ => A :MLOAD(ecAdd_P1_x), CALL(subFpBN254) ; C = P1.x - P3.x + ; [steps: 66, bin: 4, arith: 8] $ => A :MLOAD(ecAdd_lambda) C => B :CALL(mulFpBN254) ; C = lambda·(P1.x - P3.x) + ; [steps: 79, bin: 5, arith: 10] C => A $ => C :MLOAD(ecAdd_P1_y), CALL(subFpBN254) ; C = lambda·(P1.x - P3.x) - P1.y + ; [steps: 93, bin: 6, arith: 12] - C :MSTORE(ecAdd_P3_y) + C :MSTORE(ecAdd_P3_y), JMP(ecAdd_correct) + ; P3.y = lambda·(P1.x - P3.x) - P1.y - :JMP(ecAdd_correct) + ; till the end -> [steps: 97, bin: 6, arith: 12] ; ERRORS ecAdd_P1x_too_big: diff --git a/main/pairings/BN254/ecMul.zkasm b/main/pairings/BN254/ecMul.zkasm index 1fecd4fc..e3db0ce5 100644 --- a/main/pairings/BN254/ecMul.zkasm +++ b/main/pairings/BN254/ecMul.zkasm @@ -15,6 +15,8 @@ VAR GLOBAL ecMul_P_y VAR GLOBAL ecMul_Q_x VAR GLOBAL ecMul_Q_y +VAR GLOBAL ecMul_acummulator + VAR GLOBAL ecMul_RR ; ERROR CODES (B) @@ -23,35 +25,56 @@ VAR GLOBAL ecMul_RR ; 2 - P_y is too big ; 3 - P is not in E(Fp) +; RESOURCES (not considering error paths): +; ------------------------------------------- +; PATH 1 P == 𝒪: [steps: 16, bin: 4] +; PATH 2 k == 0 and P != 𝒪: [steps: 85, bin: 12, arith: 13] +; PATH 3 k > r and P != 𝒪: <--- w.c. +; [steps: 90, bin: 13, arith: 13] // setup +; + max_bin_len(k) * [steps: 184, bin: 14, arith: 24] // doubles +; + number_of_bits_1(k) * [steps: 182, bin: 12, arith: 20] // additions +; + [steps: 7, bin: 1] // last iteration + k reconstruction check +; total (w.c.): [steps: 92513 bin: 6580, arith: 11125] // [90 + 253*184 + 252*182 + 7, +; 13 + 253*14 + 252*12 + 1, +; 13 + 253*24 + 252*20] +; ------------------------------------------- + ecMul: RR :MSTORE(ecMul_RR) + ; Check whether the point coordinates are in the range [0, BN254_P) %BN254_P_MINUS_ONE => A $ => B :MLOAD(ecMul_P_x) $ :LT, JMPC(ecMul_Px_too_big) $ => B :MLOAD(ecMul_P_y) $ :LT, JMPC(ecMul_Py_too_big) + ; [steps: 6, bin: 2] - ; Is P = O? + ; Is P = 𝒪? 0n => B $ => A :MLOAD(ecMul_P_x) $ :EQ, JMPNC(__ecMul_P_continue) $ => A :MLOAD(ecMul_P_y) $ :EQ, JMPC(ecMul_P_is_zero) __ecMul_P_continue: + ; [steps: 11, bin: 4] + ; P is not 𝒪 from here - ; 1] Check if P is in E(Fp) + ; 1] Check if P ∈ E(Fp) ; P in E iff (P.y)² == (P.x)³ + 3 (mod p) ; 1.1] Compute LHS and RHS $ => A :MLOAD(ecMul_P_x), CALL(squareFpBN254) ; B = (P.x)² + ; [steps: 25, bin: 6, arith: 2] $ => A :MLOAD(ecMul_P_x), CALL(mulFpBN254) ; C = (P.x)³ + ; [steps: 37, bin: 7, arith: 8] %BN254_E_B => A :CALL(addFpBN254) ; C = (P.x)³ + 3 C :MSTORE(ecMul_Q_x) + ; [steps: 50, bin: 8, arith: 10] $ => A :MLOAD(ecMul_P_y), CALL(squareFpBN254) ; B = (Py)² @@ -60,67 +83,77 @@ ecMul: B => A $ => B :MLOAD(ecMul_Q_x) $ :EQ, JMPNC(ecMul_P_is_not_in_E) - - ; Is k ∈ [1,r-1]? - $ => B :MLOAD(ecMul_k), CALL(reduceFrBN254) - A :MSTORE(ecMul_k) - 0n => B - $ :EQ, JMPC(ecMul_k_is_zero) - - 257 => RCX + ; [steps: 67, bin: 10, arith: 12] + ; P ∈ E(Fp) from here + + ; Is k ∈ [0,r-1]? + $ => A :MLOAD(ecMul_k) + %BN254_R => B + $ :LT, JMPC(__ecMul_continue) + A => B :CALL(reduceFrBN254) + __ecMul_continue: + 0 => B + $ :EQ, JMPC(ecMul_k_is_zero) + A :MSTORE(ecMul_k) + ; [steps: 83, bin: 13, arith: 13] + ; k ∈ [1,r-1] from here + + $0{receiveLen(mem.ecMul_k)} => RCX,E ; receive the length of the binary representation of k + + ; start the acummulator with the MSB of k + 0 => A :CALL(@bitwiseReconstruction + E) + A :MSTORE(ecMul_acummulator) $ => A :MLOAD(ecMul_P_x) $ => C :MLOAD(ecMul_P_y) A :MSTORE(ecMul_Q_x) - C :MSTORE(ecMul_Q_y) - - :JMP(ecMul_find_MSB_k) + C :MSTORE(ecMul_Q_y), JMP(ecMul_loop) + ; [steps: 90, bin: 13, arith: 13] +; Begin of branching ecMul_P_is_zero: - ; Q = O + ; before (w.c.) -> [steps: 11, bin: 4] + + ; Q = 𝒪 0n :MSTORE(ecMul_Q_x) - 0n :MSTORE(ecMul_Q_y) + 0n :MSTORE(ecMul_Q_y), JMP(ecMul_correct) - :JMP(ecMul_correct) + ; till the end -> [steps: 16, bin: 4] ecMul_k_is_zero: - ; Q = O - 0n :MSTORE(ecMul_Q_x) - 0n :MSTORE(ecMul_Q_y) - - :JMP(ecMul_correct) + ; before (w.c.) -> [steps: 80, bin: 12, arith: 13] -ecMul_find_MSB_k: - RCX - 1 => RCX - $ => A,B :MLOAD(ecMul_k) - ; E = 2A - $ => E :ADD,MSTORE(ecMul_k), JMPNC(ecMul_find_MSB_k) + ; Q = 𝒪 + 0n :MSTORE(ecMul_Q_x) + 0n :MSTORE(ecMul_Q_y), JMP(ecMul_correct) + ; till the end -> [steps: 85, bin: 12, arith: 13] +; End of branching ecMul_loop: - RCX - 1 => RCX :JMPZ(ecMul_correct) + ; block costs: + ; no_last: [steps: 184, bin: 14, arith: 24] + ; last: [steps: 1] + + RCX - 1 => RCX :JMPN(ecMul_check) ; We always double $ => A :MLOAD(ecMul_Q_x) $ => B :MLOAD(ecMul_Q_y) - A :MSTORE(ecAdd_P1_x) - B :MSTORE(ecAdd_P1_y) - A :MSTORE(ecAdd_P2_x) - B :MSTORE(ecAdd_P2_y), CALL(ecAdd) - ; Q = Q + Q - - $ => A :MLOAD(ecAdd_P3_x) - $ => B :MLOAD(ecAdd_P3_y) + A :MSTORE(doublePointFPBN254_P_x) + B :MSTORE(doublePointFPBN254_P_y), CALL(doublePointFPBN254) + $ => A :MLOAD(doublePointFPBN254_Q_x) + $ => B :MLOAD(doublePointFPBN254_Q_y) A :MSTORE(ecMul_Q_x) B :MSTORE(ecMul_Q_y) + ; Q = Q + Q - ; We check if the MSB b of k is either 1 or 0. If b==1, we should add P to Q. - ; Then, update the value of k. - $ => A,B :MLOAD(ecMul_k) - ; E = 2A - $ => E :ADD, MSTORE(ecMul_k), JMPNC(ecMul_loop) + ; Receive the next MSB b of k. If b == 1, we should add P to Q, otherwise start the next iteration + $0{(mem.ecMul_k) >> RCX & 0x1} :JMPZ(ecMul_loop) ecMul_add: + ; block costs: [steps: 182, bin: 12, arith: 20] + ; We add $ => A :MLOAD(ecMul_Q_x) $ => B :MLOAD(ecMul_Q_y) @@ -129,14 +162,19 @@ ecMul_add: A :MSTORE(ecAdd_P1_x) B :MSTORE(ecAdd_P1_y) C :MSTORE(ecAdd_P2_x) - D :MSTORE(ecAdd_P2_y), CALL(ecAdd) - ; Q = Q + P - + D :MSTORE(ecAdd_P2_y) + 1 :MSTORE(ecAdd_diff), CALL(ecAdd) $ => A :MLOAD(ecAdd_P3_x) $ => B :MLOAD(ecAdd_P3_y) A :MSTORE(ecMul_Q_x) - B :MSTORE(ecMul_Q_y), JMP(ecMul_loop) + B :MSTORE(ecMul_Q_y) + ; Q = Q + P + ; We keep reconstruction the scalar k + $ => A :MLOAD(ecMul_acummulator) + RCX => E + :CALL(@bitwiseReconstruction + E) + A :MSTORE(ecMul_acummulator), JMP(ecMul_loop) ; ERRORS ecMul_Px_too_big: @@ -148,6 +186,13 @@ ecMul_Py_too_big: ecMul_P_is_not_in_E: 3 => B :JMP(ecMul_error) +ecMul_check: + ; till the end -> [steps: 6, bin: 1] + + $ => A :MLOAD(ecMul_k) + $ => B :MLOAD(ecMul_acummulator) + 1 :EQ + ecMul_correct: 0 => B :JMP(ecMul_end) diff --git a/main/pairings/BN254/escalarMulBN254.zkasm b/main/pairings/BN254/escalarMulBN254.zkasm deleted file mode 100644 index c0e0764a..00000000 --- a/main/pairings/BN254/escalarMulBN254.zkasm +++ /dev/null @@ -1,155 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; PRE: P ∈ E'(Fp2) -;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to addPointBN254 -;; -;; -;; escalarMulBN254: -;; in: k, P = (P.x1 + P.x2·u, P.y1 + P.y2·u) ∈ E'(Fp2), where k ∈ [0,r-1] -;; out: k·P = (Q.x1 + Q.x2·u, Q.y1 + Q.y2·u) ∈ E'(Fp2) -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; escalarMulBN254 assumes P belong to E'(Fp2), since it is checked in the pairing. -; However, it must be implemented if escalarMulBN254 wants to be used independently. - -; Since the curve is E'/Fp2: y² = x³ + 3/(9+u), there is no issue in representing the point at infinity as (0, 0). - -VAR GLOBAL escalarMulBN254_k -VAR GLOBAL escalarMulBN254_P_x1 -VAR GLOBAL escalarMulBN254_P_x2 -VAR GLOBAL escalarMulBN254_P_y1 -VAR GLOBAL escalarMulBN254_P_y2 -VAR GLOBAL escalarMulBN254_Q_x1 -VAR GLOBAL escalarMulBN254_Q_x2 -VAR GLOBAL escalarMulBN254_Q_y1 -VAR GLOBAL escalarMulBN254_Q_y2 - -VAR GLOBAL escalarMulBN254_RR - - -escalarMulBN254: - RR :MSTORE(escalarMulBN254_RR) - - ; Is P = O? - 0n => B - $ => A :MLOAD(escalarMulBN254_P_x1) - $ :EQ, JMPNC(__escalarMulBN254_P_continue) - $ => A :MLOAD(escalarMulBN254_P_x2) - $ :EQ, JMPNC(__escalarMulBN254_P_continue) - $ => A :MLOAD(escalarMulBN254_P_y1) - $ :EQ, JMPNC(__escalarMulBN254_P_continue) - $ => A :MLOAD(escalarMulBN254_P_y2) - $ :EQ, JMPC(escalarMulBN254_P_is_zero) - __escalarMulBN254_P_continue: - - ; Is k = 0? - $ => B :MLOAD(escalarMulBN254_k), CALL(reduceFrBN254) - A :MSTORE(escalarMulBN254_k) - 0n => B - $ :EQ, JMPC(escalarMulBN254_k_is_zero) - - 257 => RCX - - $ => A :MLOAD(escalarMulBN254_P_x1) - $ => B :MLOAD(escalarMulBN254_P_x2) - $ => C :MLOAD(escalarMulBN254_P_y1) - $ => D :MLOAD(escalarMulBN254_P_y2) - A :MSTORE(escalarMulBN254_Q_x1) - B :MSTORE(escalarMulBN254_Q_x2) - C :MSTORE(escalarMulBN254_Q_y1) - D :MSTORE(escalarMulBN254_Q_y2) - - :JMP(escalarMulBN254_find_MSB_k) - -escalarMulBN254_P_is_zero: - ; Q = O - 0n :MSTORE(escalarMulBN254_Q_x1) - 0n :MSTORE(escalarMulBN254_Q_x2) - 0n :MSTORE(escalarMulBN254_Q_y1) - 0n :MSTORE(escalarMulBN254_Q_y2) - - :JMP(escalarMulBN254_end) - -escalarMulBN254_k_is_zero: - ; Q = O - 0n :MSTORE(escalarMulBN254_Q_x1) - 0n :MSTORE(escalarMulBN254_Q_x2) - 0n :MSTORE(escalarMulBN254_Q_y1) - 0n :MSTORE(escalarMulBN254_Q_y2) - - :JMP(escalarMulBN254_end) - -escalarMulBN254_find_MSB_k: - RCX - 1 => RCX - $ => A,B :MLOAD(escalarMulBN254_k) - ; E = 2A - $ => E :ADD,MSTORE(escalarMulBN254_k), JMPNC(escalarMulBN254_find_MSB_k) - - -escalarMulBN254_loop: - RCX - 1 => RCX :JMPZ(escalarMulBN254_end) - - ; We always double - $ => A :MLOAD(escalarMulBN254_Q_x1) - $ => B :MLOAD(escalarMulBN254_Q_x2) - $ => C :MLOAD(escalarMulBN254_Q_y1) - $ => D :MLOAD(escalarMulBN254_Q_y2) - A :MSTORE(addPointBN254_P1_x1) - B :MSTORE(addPointBN254_P1_x2) - C :MSTORE(addPointBN254_P1_y1) - D :MSTORE(addPointBN254_P1_y2) - A :MSTORE(addPointBN254_P2_x1) - B :MSTORE(addPointBN254_P2_x2) - C :MSTORE(addPointBN254_P2_y1) - D :MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) - ; Q = Q + Q - - $ => A :MLOAD(addPointBN254_P3_x1) - $ => B :MLOAD(addPointBN254_P3_x2) - $ => C :MLOAD(addPointBN254_P3_y1) - $ => D :MLOAD(addPointBN254_P3_y2) - A :MSTORE(escalarMulBN254_Q_x1) - B :MSTORE(escalarMulBN254_Q_x2) - C :MSTORE(escalarMulBN254_Q_y1) - D :MSTORE(escalarMulBN254_Q_y2) - - ; We check if the MSB b of k is either 1 or 0. If b==1, we should add P to Q. - ; Then, update the value of k. - $ => A,B :MLOAD(escalarMulBN254_k) - ; E = 2A - $ => E :ADD,MSTORE(escalarMulBN254_k), JMPNC(escalarMulBN254_loop) - -escalarMulBN254_add: - ; We add - $ => A :MLOAD(escalarMulBN254_Q_x1) - $ => B :MLOAD(escalarMulBN254_Q_x2) - $ => C :MLOAD(escalarMulBN254_Q_y1) - $ => D :MLOAD(escalarMulBN254_Q_y2) - A :MSTORE(addPointBN254_P1_x1) - B :MSTORE(addPointBN254_P1_x2) - C :MSTORE(addPointBN254_P1_y1) - D :MSTORE(addPointBN254_P1_y2) - - $ => A :MLOAD(escalarMulBN254_P_x1) - $ => B :MLOAD(escalarMulBN254_P_x2) - $ => C :MLOAD(escalarMulBN254_P_y1) - $ => D :MLOAD(escalarMulBN254_P_y2) - A :MSTORE(addPointBN254_P2_x1) - B :MSTORE(addPointBN254_P2_x2) - C :MSTORE(addPointBN254_P2_y1) - D :MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) - ; Q = Q + P - - $ => A :MLOAD(addPointBN254_P3_x1) - $ => B :MLOAD(addPointBN254_P3_x2) - $ => C :MLOAD(addPointBN254_P3_y1) - $ => D :MLOAD(addPointBN254_P3_y2) - A :MSTORE(escalarMulBN254_Q_x1) - B :MSTORE(escalarMulBN254_Q_x2) - C :MSTORE(escalarMulBN254_Q_y1) - D :MSTORE(escalarMulBN254_Q_y2), JMP(escalarMulBN254_loop) - - -escalarMulBN254_end: - $ => RR :MLOAD(escalarMulBN254_RR) - :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/lineDiffPointsBN254.zkasm b/main/pairings/BN254/lineDiffPointsBN254.zkasm index a0baac1b..6b6f91b0 100644 --- a/main/pairings/BN254/lineDiffPointsBN254.zkasm +++ b/main/pairings/BN254/lineDiffPointsBN254.zkasm @@ -35,6 +35,11 @@ VAR GLOBAL lineDiffPointsBN254_l23_y VAR GLOBAL lineDiffPointsBN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 60, bin: 0, arith: 7] +; ----------------------------- + lineDiffPointsBN254: RR :MSTORE(lineDiffPointsBN254_RR) @@ -45,7 +50,7 @@ lineDiffPointsBN254: $ => D :MLOAD(lineDiffPointsBN254_P1_x2), CALL(subFp2BN254) $ => A :MLOAD(lineDiffPointsBN254_Q_y) C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E :MSTORE(lineDiffPointsBN254_l12_x) C :MSTORE(lineDiffPointsBN254_l12_y) @@ -56,7 +61,7 @@ lineDiffPointsBN254: $ => D :MLOAD(lineDiffPointsBN254_P2_y2), CALL(subFp2BN254) $ => A :MLOAD(lineDiffPointsBN254_Q_x) C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E :MSTORE(lineDiffPointsBN254_l22_x) C :MSTORE(lineDiffPointsBN254_l22_y) diff --git a/main/pairings/BN254/lineSamePointsBN254.zkasm b/main/pairings/BN254/lineSamePointsBN254.zkasm index 5bdec945..b1065d2c 100644 --- a/main/pairings/BN254/lineSamePointsBN254.zkasm +++ b/main/pairings/BN254/lineSamePointsBN254.zkasm @@ -32,6 +32,11 @@ VAR GLOBAL lineSamePointsBN254_l22_y VAR GLOBAL lineSamePointsBN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 100, bin: 0, arith: 13] +; ----------------------------- + lineSamePointsBN254: RR :MSTORE(lineSamePointsBN254_RR) @@ -40,7 +45,7 @@ lineSamePointsBN254: $ => B :MLOAD(lineSamePointsBN254_P_y2), CALL(squareFp2BN254) C => D E => C - 2n => A :CALL(escalarMulFp2BN254) + 2n => A :CALL(scalarMulFp2BN254) E :MSTORE(lineSamePointsBN254_P_y1_square) C :MSTORE(lineSamePointsBN254_P_y2_square) @@ -55,7 +60,7 @@ lineSamePointsBN254: $ => D :MLOAD(lineSamePointsBN254_P_x2), CALL(mulFp2BN254) C => D E => C - 3n => A :CALL(escalarMulFp2BN254) + 3n => A :CALL(scalarMulFp2BN254) E => A C => B @@ -77,7 +82,7 @@ lineSamePointsBN254: C => A $ => C :MLOAD(lineSamePointsBN254_P_y1) - $ => D :MLOAD(lineSamePointsBN254_P_y2), CALL(escalarMulFp2BN254) + $ => D :MLOAD(lineSamePointsBN254_P_y2), CALL(scalarMulFp2BN254) E :MSTORE(lineSamePointsBN254_l22_x) C :MSTORE(lineSamePointsBN254_l22_y) @@ -87,7 +92,7 @@ lineSamePointsBN254: $ => B :MLOAD(lineSamePointsBN254_Q_x), CALL(mulFpBN254) C => A $ => C :MLOAD(lineSamePointsBN254_P_x1_square) - $ => D :MLOAD(lineSamePointsBN254_P_x2_square), CALL(escalarMulFp2BN254) + $ => D :MLOAD(lineSamePointsBN254_P_x2_square), CALL(scalarMulFp2BN254) E :MSTORE(lineSamePointsBN254_l13_x) C :MSTORE(lineSamePointsBN254_l13_y) diff --git a/main/pairings/BN254/scalarMulPointBy6X2FP2BN254.zkasm b/main/pairings/BN254/scalarMulPointBy6X2FP2BN254.zkasm new file mode 100644 index 00000000..a11da814 --- /dev/null +++ b/main/pairings/BN254/scalarMulPointBy6X2FP2BN254.zkasm @@ -0,0 +1,158 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: P ∈ E'(Fp2)\{𝒪} +;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to addPointFP2BN254 +;; +;; +;; scalarMulPointBy6X2FP2BN254: +;; in: P = (P.x1 + P.x2·u, P.y1 + P.y2·u) ∈ E'(Fp2) +;; out: [6x²]·P = (Q.x1 + Q.x2·u, Q.y1 + Q.y2·u) ∈ E'(Fp2), where 6x² == %BN254_SIX_TIMES_X_SQ +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Since the curve is E'/Fp2: y² = x³ + 3/(9+u), there is no issue in representing the point at infinity as (0, 0). + +VAR GLOBAL scalarMulPointBy6X2FP2BN254_P_x1 +VAR GLOBAL scalarMulPointBy6X2FP2BN254_P_x2 +VAR GLOBAL scalarMulPointBy6X2FP2BN254_P_y1 +VAR GLOBAL scalarMulPointBy6X2FP2BN254_P_y2 +VAR GLOBAL scalarMulPointBy6X2FP2BN254_Q_x1 +VAR GLOBAL scalarMulPointBy6X2FP2BN254_Q_x2 +VAR GLOBAL scalarMulPointBy6X2FP2BN254_Q_y1 +VAR GLOBAL scalarMulPointBy6X2FP2BN254_Q_y2 + +VAR GLOBAL scalarMulPointBy6X2FP2BN254_RR + +; RESOURCES: +; ------------------------------------------- +; [steps: 10] // setup +; + 128 * [steps: 124, bin: 3, arith: 11] // doubles +; + 19 * [steps: 126, bin: 3, arith: 10] // additions +; + 20 * [steps: 127, bin: 5, arith: 10] // subtractions +; + [steps: 3] // last iteration + end +; total (w.c.): [steps: 20819 bin: 541, arith: 1798] // [10 + 128*124 + 19*126 + 20*127 + 3, +; 128*3 + 19*3 + 20*5, +; 128*11 + 19*10 + 20*10] +; ------------------------------------------- + +scalarMulPointBy6X2FP2BN254: + RR :MSTORE(scalarMulPointBy6X2FP2BN254_RR) + + 128 => RCX + + $ => A :MLOAD(scalarMulPointBy6X2FP2BN254_P_x1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_P_x2) + $ => C :MLOAD(scalarMulPointBy6X2FP2BN254_P_y1) + $ => D :MLOAD(scalarMulPointBy6X2FP2BN254_P_y2) + A :MSTORE(scalarMulPointBy6X2FP2BN254_Q_x1) + B :MSTORE(scalarMulPointBy6X2FP2BN254_Q_x2) + C :MSTORE(scalarMulPointBy6X2FP2BN254_Q_y1) + D :MSTORE(scalarMulPointBy6X2FP2BN254_Q_y2) + ; [steps: 10, bin: 0, arith: 0] + +scalarMulPointBy6X2FP2BN254_loop: + ; block costs: + ; no_last: [steps: 124, bin: 3, arith: 11] + ; last: [steps: 1] + + RCX - 1 => RCX :JMPZ(scalarMulPointBy6X2FP2BN254_end) + + ; We always double + $ => A :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x2) + $ => C :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y1) + $ => D :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y2) + A :MSTORE(doublePointFP2BN254_P_x1) + B :MSTORE(doublePointFP2BN254_P_x2) + C :MSTORE(doublePointFP2BN254_P_y1) + D :MSTORE(doublePointFP2BN254_P_y2), CALL(doublePointFP2BN254) + ; Q = Q + Q + + $ => A :MLOAD(doublePointFP2BN254_Q_x1) + $ => B :MLOAD(doublePointFP2BN254_Q_x2) + $ => C :MLOAD(doublePointFP2BN254_Q_y1) + $ => D :MLOAD(doublePointFP2BN254_Q_y2) + A :MSTORE(scalarMulPointBy6X2FP2BN254_Q_x1) + B :MSTORE(scalarMulPointBy6X2FP2BN254_Q_x2) + C :MSTORE(scalarMulPointBy6X2FP2BN254_Q_y1) + D :MSTORE(scalarMulPointBy6X2FP2BN254_Q_y2) + + ; We check if the MSB b of x is either 1 or 0 + RCX - 1 => RR + :CALL(@sixX2 + RR) + + ; if bit = -1, then sub + B :JMPN(scalarMulPointBy6X2FP2BN254_sub) + ; if bit = 0, then repeat + B :JMPZ(scalarMulPointBy6X2FP2BN254_loop) + ; if bit = 1, then add + +scalarMulPointBy6X2FP2BN254_add: + ; block costs: [steps: 126, bin: 3, arith: 10] + + ; We add + $ => A :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x2) + $ => C :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y1) + $ => D :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y2) + A :MSTORE(addPointFP2BN254_P1_x1) + B :MSTORE(addPointFP2BN254_P1_x2) + C :MSTORE(addPointFP2BN254_P1_y1) + D :MSTORE(addPointFP2BN254_P1_y2) + + $ => A :MLOAD(scalarMulPointBy6X2FP2BN254_P_x1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_P_x2) + $ => C :MLOAD(scalarMulPointBy6X2FP2BN254_P_y1) + $ => D :MLOAD(scalarMulPointBy6X2FP2BN254_P_y2) + A :MSTORE(addPointFP2BN254_P2_x1) + B :MSTORE(addPointFP2BN254_P2_x2) + C :MSTORE(addPointFP2BN254_P2_y1) + D :MSTORE(addPointFP2BN254_P2_y2) + 1 :MSTORE(addPointFP2BN254_diff), CALL(addPointFP2BN254) + ; Q = Q + P + + $ => A :MLOAD(addPointFP2BN254_P3_x1) + $ => B :MLOAD(addPointFP2BN254_P3_x2) + $ => C :MLOAD(addPointFP2BN254_P3_y1) + $ => D :MLOAD(addPointFP2BN254_P3_y2) + A :MSTORE(scalarMulPointBy6X2FP2BN254_Q_x1) + B :MSTORE(scalarMulPointBy6X2FP2BN254_Q_x2) + C :MSTORE(scalarMulPointBy6X2FP2BN254_Q_y1) + D :MSTORE(scalarMulPointBy6X2FP2BN254_Q_y2), JMP(scalarMulPointBy6X2FP2BN254_loop) + +scalarMulPointBy6X2FP2BN254_sub: + ; block costs: [steps: 127, bin: 5, arith: 10] + + ; We subtract Q = Q - P + $ => A :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x2) + $ => C :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y1) + $ => D :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y2) + A :MSTORE(addPointFP2BN254_P1_x1) + B :MSTORE(addPointFP2BN254_P1_x2) + C :MSTORE(addPointFP2BN254_P1_y1) + D :MSTORE(addPointFP2BN254_P1_y2) + + $ => A :MLOAD(scalarMulPointBy6X2FP2BN254_P_x1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_P_x2) + A :MSTORE(addPointFP2BN254_P2_x1) + B :MSTORE(addPointFP2BN254_P2_x2) + %BN254_P => A + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_P_y1) + $ :SUB, MSTORE(addPointFP2BN254_P2_y1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_P_y2) + $ :SUB, MSTORE(addPointFP2BN254_P2_y2) + 1 :MSTORE(addPointFP2BN254_diff), CALL(addPointFP2BN254) + ; Q = Q - P + + $ => A :MLOAD(addPointFP2BN254_P3_x1) + $ => B :MLOAD(addPointFP2BN254_P3_x2) + $ => C :MLOAD(addPointFP2BN254_P3_y1) + $ => D :MLOAD(addPointFP2BN254_P3_y2) + A :MSTORE(scalarMulPointBy6X2FP2BN254_Q_x1) + B :MSTORE(scalarMulPointBy6X2FP2BN254_Q_x2) + C :MSTORE(scalarMulPointBy6X2FP2BN254_Q_y1) + D :MSTORE(scalarMulPointBy6X2FP2BN254_Q_y2), JMP(scalarMulPointBy6X2FP2BN254_loop) + +scalarMulPointBy6X2FP2BN254_end: + $ => RR :MLOAD(scalarMulPointBy6X2FP2BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/BN254/sixX2.zkasm b/main/pairings/BN254/sixX2.zkasm new file mode 100644 index 00000000..dbbebd8d --- /dev/null +++ b/main/pairings/BN254/sixX2.zkasm @@ -0,0 +1,168 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; sixX2: +;; output: A digit of the (little-endian) pseudobinary representation of 6x²: +;; 100-1000-1010100-10-1000001001001001000-1000-10-100-100010-10-101000000-1000000-1000010000-101010-10-101000010-100-10100010000-10100000-101010010-10 +;; that is, 6·%BN254_X² = 6·4965661367192848881² = 147946756881789318990833708069417712966 +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Sage code +; ---------------------------------------- +; def int2wNAF(k, w = 2): +; powOfw = 2 ** w +; +; NAF = [] +; while (k > 0): +; if (k & 1): +; kred = k % powOfw +; x = kred - powOfw if kred >= powOfw // 2 else kred +; NAF.append(x) +; k -= x +; else: +; NAF.append(0) +; +; k //= 2 +; +; return NAF +; +; x = 147946756881789318990833708069417712966 +; xNAF = int2wNAF(x) +; assert sum(bit * (2 ** index) for index, bit in enumerate(xNAF)) == x +; print(''.join(str(bit) for bit in xNAF[::-1])) +; +; for i in range(len(xNAF)): +; if (xNAF[i] == -1): +; print("\t {} => B \t\t\t\t\t\t\t\t :RETURN".format(xNAF[i])) +; else: +; print("\t\t{} => B \t\t\t\t\t\t\t\t :RETURN".format(xNAF[i])) +; ---------------------------------------- + +sixX2: + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + -1 => B :RETURN + 0 => B :RETURN + 0 => B :RETURN + 1 => B :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm index 4908a396..1fafe364 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/compressFp12BN254.zkasm @@ -29,6 +29,11 @@ VAR GLOBAL compressFp12BN254_Ca4_y VAR GLOBAL compressFp12BN254_Ca5_x VAR GLOBAL compressFp12BN254_Ca5_y +; RESOURCES: +; ----------------------------- +; [steps: 17, bin: 0, arith: 0] +; ----------------------------- + compressFp12BN254: $ => A :MLOAD(compressFp12BN254_a2_x) $ => B :MLOAD(compressFp12BN254_a2_y) diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm index 64cd2665..02cd4881 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm @@ -56,6 +56,14 @@ VAR GLOBAL decompressFp12BN254_sum_y VAR GLOBAL decompressFp12BN254_RR +; TODO: Add flags to avoid the a2 == 0 check + +; RESOURCES: +; ----------------------------- +; PATH 1 a2 == 0: [steps: 132, bin: 6, arith: 12] +; PATH 2 a2 != 0: [steps: 190, bin: 5, arith: 20] <--- w.c. +; ----------------------------- + decompressFp12BN254: RR :MSTORE(decompressFp12BN254_RR) @@ -85,7 +93,7 @@ decompressFp12BN254: $ :EQ, JMPC(decompressFp12BN254_Ca2_is_zero) __decompressFp12BN254_Ca2_continue: - :JMP(decompressFp12BN254_Ca2_is_not_zero) + :JMP(decompressFp12BN254_Ca2_is_not_zero) decompressFp12BN254_Ca2_is_zero: ; 1] Compute a1 = (2·a4·a5)/a3 @@ -96,7 +104,7 @@ decompressFp12BN254_Ca2_is_zero: 2n => A $ => C :MLOAD(decompressFp12BN254_Ca4_x) - $ => D :MLOAD(decompressFp12BN254_Ca4_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(decompressFp12BN254_Ca4_y), CALL(scalarMulFp2BN254) E => A C => B $ => C :MLOAD(decompressFp12BN254_Ca5_x) @@ -113,13 +121,13 @@ decompressFp12BN254_Ca2_is_zero: $ => B :MLOAD(decompressFp12BN254_a1_y), CALL(squareFp2BN254) 2n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E :MSTORE(decompressFp12BN254_twoCa1sq_x) C :MSTORE(decompressFp12BN254_twoCa1sq_y) 3n => A $ => C :MLOAD(decompressFp12BN254_Ca3_x) - $ => D :MLOAD(decompressFp12BN254_Ca3_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(decompressFp12BN254_Ca3_y), CALL(scalarMulFp2BN254) E => A C => B $ => C :MLOAD(decompressFp12BN254_Ca4_x) @@ -147,7 +155,7 @@ decompressFp12BN254_Ca2_is_not_zero: ; 1] Compute a1 = (a5²·(9+u) + 3·a4² - 2·a3)/(4·a2) 4n => A $ => C :MLOAD(decompressFp12BN254_Ca2_x) - $ => D :MLOAD(decompressFp12BN254_Ca2_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(decompressFp12BN254_Ca2_y), CALL(scalarMulFp2BN254) E => A C => B :CALL(invFp2BN254) C :MSTORE(decompressFp12BN254_fourCa2inv_x) @@ -166,13 +174,13 @@ decompressFp12BN254_Ca2_is_not_zero: $ => B :MLOAD(decompressFp12BN254_Ca4_y), CALL(squareFp2BN254) 3n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E :MSTORE(decompressFp12BN254_threeCa4sq_x) C :MSTORE(decompressFp12BN254_threeCa4sq_y) 2n => A $ => C :MLOAD(decompressFp12BN254_Ca3_x) - $ => D :MLOAD(decompressFp12BN254_Ca3_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(decompressFp12BN254_Ca3_y), CALL(scalarMulFp2BN254) $ => A :MLOAD(decompressFp12BN254_threeCa4sq_x) $ => B :MLOAD(decompressFp12BN254_threeCa4sq_y) C => D @@ -193,7 +201,7 @@ decompressFp12BN254_Ca2_is_not_zero: $ => B :MLOAD(decompressFp12BN254_a1_y), CALL(squareFp2BN254) 2n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E :MSTORE(decompressFp12BN254_twoCa1sq2_x) C :MSTORE(decompressFp12BN254_twoCa1sq2_y) @@ -215,7 +223,7 @@ decompressFp12BN254_Ca2_is_not_zero: $ => D :MLOAD(decompressFp12BN254_Ca4_y), CALL(mulFp2BN254) 3n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) $ => A :MLOAD(decompressFp12BN254_sum_x) $ => B :MLOAD(decompressFp12BN254_sum_y) C => D @@ -229,8 +237,6 @@ decompressFp12BN254_Ca2_is_not_zero: 1n => C :CALL(addFpBN254) C :MSTORE(decompressFp12BN254_a0_x) - :JMP(decompressFp12BN254_end) - decompressFp12BN254_end: $ => RR :MLOAD(decompressFp12BN254_RR) :RETURN \ No newline at end of file diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm index 4cfad725..e6c0a658 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm @@ -8,6 +8,10 @@ ;; NOTE: The output is not guaranteed to be in GΦ6(p²), if the input isn't. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO: unroll the loop +; TODO: Do not decompress!!! +; TODO: Multiply in compressed form + VAR GLOBAL expByXCompCycloFp12BN254_a0_x VAR GLOBAL expByXCompCycloFp12BN254_a0_y VAR GLOBAL expByXCompCycloFp12BN254_a2_x @@ -35,6 +39,22 @@ VAR GLOBAL expByXCompCycloFp12BN254_c5_y VAR GLOBAL expByXCompCycloFp12BN254_RR +; TODO: Add flags to avoid the a == 0,1 checks + +; RESOURCES: +; ------------------------------------------- +; PATH 1 a == 0: [steps: 40, bin: 12, arith: 0] +; PATH 2 a == 1: [steps: 66, bin: 13, arith: 0] +; PATH 3 a != 0: <--- w.c. +; [steps: 2338, bin: 29, arith: 216] // setup +; + 58 * [steps: 237, bin: 0, arith: 27] // squarings +; + 26 * [steps: 1305, bin: 5, arith: 108] // multiplications +; + [steps: 26] // last iteration + end +; total (w.c.): [steps: 50040 bin: 159, arith: 4590] // [2338 + 58*237 + 26*1305 + 26, +; 29 + 26*5, +; 216 + 58*27 + 26*108] +; ------------------------------------------- + expByXCompCycloFp12BN254: RR :MSTORE(expByXCompCycloFp12BN254_RR) @@ -65,6 +85,7 @@ expByXCompCycloFp12BN254: $ => A :MLOAD(expByXCompCycloFp12BN254_a5_y) $ :EQ, JMPC(expByXCompCycloFp12BN254_a_is_zero) __expByXCompCycloFp12BN254_a_continue1: + ; [steps: 26, bin: 12, arith: 0] ; Is a = 1? 1n => B @@ -94,6 +115,7 @@ expByXCompCycloFp12BN254: $ => A :MLOAD(expByXCompCycloFp12BN254_a5_y) $ :EQ, JMPC(expByXCompCycloFp12BN254_a_is_one) __expByXCompCycloFp12BN254_a_continue2: + ; [steps: 52, bin: 24, arith: 0] 59 => RCX @@ -137,6 +159,7 @@ expByXCompCycloFp12BN254: B :MSTORE(expByXCompCycloFp12BN254_c5_y) A :MSTORE(compressFp12BN254_a5_x) B :MSTORE(compressFp12BN254_a5_y), CALL(compressFp12BN254) + ; [steps: 106, bin: 24, arith: 0] $ => A :MLOAD(compressFp12BN254_Ca2_x) $ => B :MLOAD(compressFp12BN254_Ca2_y) @@ -154,6 +177,7 @@ expByXCompCycloFp12BN254: $ => B :MLOAD(compressFp12BN254_Ca5_y) A :MSTORE(squareCompCycloFp12BN254_Ca5_x) B :MSTORE(squareCompCycloFp12BN254_Ca5_y), CALL(squareCompCycloFp12BN254) + ; [steps: 338, bin: 24, arith: 27] ; 2] Third bit is 0, so compute C(c⁴) $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) @@ -172,6 +196,7 @@ expByXCompCycloFp12BN254: $ => B :MLOAD(squareCompCycloFp12BN254_Cb5_y) A :MSTORE(squareCompCycloFp12BN254_Ca5_x) B :MSTORE(squareCompCycloFp12BN254_Ca5_y), CALL(squareCompCycloFp12BN254) + ; [steps: 570, bin: 24, arith: 54] ; 3] Fourth bit is 0, so compute C(c⁸) $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) @@ -190,6 +215,7 @@ expByXCompCycloFp12BN254: $ => B :MLOAD(squareCompCycloFp12BN254_Cb5_y) A :MSTORE(squareCompCycloFp12BN254_Ca5_x) B :MSTORE(squareCompCycloFp12BN254_Ca5_y), CALL(squareCompCycloFp12BN254) + ; [steps: 802, bin: 24, arith: 81] ; 4] Fifth bit is 1, so compute C(c¹⁶), decompress to obtain c¹⁶ and multiply by a $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) @@ -208,6 +234,7 @@ expByXCompCycloFp12BN254: $ => B :MLOAD(squareCompCycloFp12BN254_Cb5_y) A :MSTORE(squareCompCycloFp12BN254_Ca5_x) B :MSTORE(squareCompCycloFp12BN254_Ca5_y), CALL(squareCompCycloFp12BN254) + ; [steps: 1034, bin: 24, arith: 108] $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) @@ -225,6 +252,7 @@ expByXCompCycloFp12BN254: $ => B :MLOAD(squareCompCycloFp12BN254_Cb5_y) A :MSTORE(decompressFp12BN254_Ca5_x) B :MSTORE(decompressFp12BN254_Ca5_y), CALL(decompressFp12BN254) + ; [steps: 1240, bin: 29, arith: 128] $ => A :MLOAD(expByXCompCycloFp12BN254_c0_x) $ => B :MLOAD(expByXCompCycloFp12BN254_c0_y) @@ -274,10 +302,12 @@ expByXCompCycloFp12BN254: $ => B :MLOAD(decompressFp12BN254_a5_y) A :MSTORE(mulFp12BN254_b23_x) B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) - :JMP(expByXCompCycloFp12BN254_loop) + ; [steps: 2339, bin: 29, arith: 216] +; Begin of branching expByXCompCycloFp12BN254_a_is_zero: + ; before (w.c.) -> [steps: 26, bin: 12, arith: 0] ; c = 0 0n :MSTORE(expByXCompCycloFp12BN254_c0_x) 0n :MSTORE(expByXCompCycloFp12BN254_c0_y) @@ -290,11 +320,13 @@ expByXCompCycloFp12BN254_a_is_zero: 0n :MSTORE(expByXCompCycloFp12BN254_c3_x) 0n :MSTORE(expByXCompCycloFp12BN254_c3_y) 0n :MSTORE(expByXCompCycloFp12BN254_c5_x) - 0n :MSTORE(expByXCompCycloFp12BN254_c5_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c5_y), JMP(expByXCompCycloFp12BN254_end) - :JMP(expByXCompCycloFp12BN254_end) + ; till the end -> [steps: 40, bin: 12, arith: 0] expByXCompCycloFp12BN254_a_is_one: + ; before (w.c.) -> [steps: 52, bin: 24, arith: 0] + ; c = 1 1n :MSTORE(expByXCompCycloFp12BN254_c0_x) 0n :MSTORE(expByXCompCycloFp12BN254_c0_y) @@ -307,11 +339,16 @@ expByXCompCycloFp12BN254_a_is_one: 0n :MSTORE(expByXCompCycloFp12BN254_c3_x) 0n :MSTORE(expByXCompCycloFp12BN254_c3_y) 0n :MSTORE(expByXCompCycloFp12BN254_c5_x) - 0n :MSTORE(expByXCompCycloFp12BN254_c5_y) + 0n :MSTORE(expByXCompCycloFp12BN254_c5_y), JMP(expByXCompCycloFp12BN254_end) - :JMP(expByXCompCycloFp12BN254_end) + ; till the end -> [steps: 66, bin: 24, arith: 0] +; End of branching expByXCompCycloFp12BN254_loop: + ; block costs: + ; no_last: [steps: 237, bin: 0, arith: 27] + ; last: [steps: 1] + RCX - 1 => RCX :JMPZ(expByXCompCycloFp12BN254_last) ; We always square (in compressed form): C(c²) @@ -334,7 +371,7 @@ expByXCompCycloFp12BN254_loop: B :MSTORE(squareCompCycloFp12BN254_Ca5_y), CALL(squareCompCycloFp12BN254) ; We check if the MSB b of x is either 1 or 0 - RCX-1 => RR + RCX - 1 => RR :CALL(@xBinDecompBN254 + RR) ; if bit = 0, then repeat @@ -343,6 +380,8 @@ expByXCompCycloFp12BN254_loop: ; else, multiply by the last result expByXCompCycloFp12BN254_multiply: + ; block costs: [steps: 1305, bin: 5, arith: 108] + $ => A :MLOAD(squareCompCycloFp12BN254_Cb2_x) $ => B :MLOAD(squareCompCycloFp12BN254_Cb2_y) A :MSTORE(decompressFp12BN254_Ca2_x) @@ -408,10 +447,11 @@ expByXCompCycloFp12BN254_multiply: $ => B :MLOAD(decompressFp12BN254_a5_y) A :MSTORE(mulFp12BN254_b23_x) B :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) - :JMP(expByXCompCycloFp12BN254_loop) expByXCompCycloFp12BN254_last: + ; block costs till end: [steps: 26, bin: 0, arith: 0] + ; Last asignments $ => A :MLOAD(mulFp12BN254_c11_x) $ => B :MLOAD(mulFp12BN254_c11_y) @@ -441,4 +481,3 @@ expByXCompCycloFp12BN254_last: expByXCompCycloFp12BN254_end: $ => RR :MLOAD(expByXCompCycloFp12BN254_RR) :RETURN - diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm index 63d576d5..c446f0b7 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm @@ -56,6 +56,11 @@ VAR GLOBAL squareCompCycloFp12BN254_twoCa4_y VAR GLOBAL squareCompCycloFp12BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 216, bin: 0, arith: 27] +; ----------------------------- + squareCompCycloFp12BN254: RR :MSTORE(squareCompCycloFp12BN254_RR) @@ -127,21 +132,21 @@ squareCompCycloFp12BN254: $ => D :MLOAD(squareCompCycloFp12BN254_B45_y), CALL(mulFp2BN254) 3n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E => A C => B $ => C :MLOAD(squareCompCycloFp12BN254_Ca2_x) $ => D :MLOAD(squareCompCycloFp12BN254_Ca2_y), CALL(addFp2BN254) 2n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E :MSTORE(squareCompCycloFp12BN254_Cb2_x) C :MSTORE(squareCompCycloFp12BN254_Cb2_y) ; 5] b3 = 3·(A45 - (10+u)·B45) - 2·a3 2n => A $ => C :MLOAD(squareCompCycloFp12BN254_Ca3_x) - $ => D :MLOAD(squareCompCycloFp12BN254_Ca3_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca3_y), CALL(scalarMulFp2BN254) E :MSTORE(squareCompCycloFp12BN254_twoCa3_x) C :MSTORE(squareCompCycloFp12BN254_twoCa3_y) @@ -156,7 +161,7 @@ squareCompCycloFp12BN254: 3n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E => A C => B @@ -168,7 +173,7 @@ squareCompCycloFp12BN254: ; 6] b4 = 3·(A23 - (10+u)·B23) - 2·a4 2n => A $ => C :MLOAD(squareCompCycloFp12BN254_Ca4_x) - $ => D :MLOAD(squareCompCycloFp12BN254_Ca4_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCompCycloFp12BN254_Ca4_y), CALL(scalarMulFp2BN254) E :MSTORE(squareCompCycloFp12BN254_twoCa4_x) C :MSTORE(squareCompCycloFp12BN254_twoCa4_y) @@ -183,7 +188,7 @@ squareCompCycloFp12BN254: 3n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E => A C => B @@ -195,18 +200,17 @@ squareCompCycloFp12BN254: ; 7] b5 = 2·(a5 + 3·B23) 3n => A $ => C :MLOAD(squareCompCycloFp12BN254_B23_x) - $ => D :MLOAD(squareCompCycloFp12BN254_B23_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCompCycloFp12BN254_B23_y), CALL(scalarMulFp2BN254) E => A C => B $ => C :MLOAD(squareCompCycloFp12BN254_Ca5_x) $ => D :MLOAD(squareCompCycloFp12BN254_Ca5_y), CALL(addFp2BN254) 2n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E :MSTORE(squareCompCycloFp12BN254_Cb5_x) C :MSTORE(squareCompCycloFp12BN254_Cb5_y) $ => RR :MLOAD(squareCompCycloFp12BN254_RR) :RETURN - diff --git a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm index 6b965120..95e7ecc8 100644 --- a/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm +++ b/main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm @@ -50,6 +50,11 @@ VAR GLOBAL squareCycloFp12BN254_t21_y VAR GLOBAL squareCycloFp12BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 411, bin: 0, arith: 43] +; ----------------------------- + squareCycloFp12BN254: RR :MSTORE(squareCycloFp12BN254_RR) @@ -118,13 +123,13 @@ squareCycloFp12BN254: ; 5] c11 = -2·a11 + 3·t11 %BN254_P - 2n => A $ => C :MLOAD(squareCycloFp12BN254_a11_x) - $ => D :MLOAD(squareCycloFp12BN254_a11_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_a11_y), CALL(scalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a11_x) C :MSTORE(squareCycloFp12BN254_a11_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t11_x) - $ => D :MLOAD(squareCycloFp12BN254_t11_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_t11_y), CALL(scalarMulFp2BN254) E => A C => B @@ -136,13 +141,13 @@ squareCycloFp12BN254: ; 6] c12 = -2·a12 + 3·t23 %BN254_P - 2n => A $ => C :MLOAD(squareCycloFp12BN254_a12_x) - $ => D :MLOAD(squareCycloFp12BN254_a12_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_a12_y), CALL(scalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a12_x) C :MSTORE(squareCycloFp12BN254_a12_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t23_x) - $ => D :MLOAD(squareCycloFp12BN254_t23_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_t23_y), CALL(scalarMulFp2BN254) E => A C => B @@ -154,13 +159,13 @@ squareCycloFp12BN254: ; 7] c13 = -2·a13 + 3·t13 %BN254_P - 2n => A $ => C :MLOAD(squareCycloFp12BN254_a13_x) - $ => D :MLOAD(squareCycloFp12BN254_a13_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_a13_y), CALL(scalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a13_x) C :MSTORE(squareCycloFp12BN254_a13_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t13_x) - $ => D :MLOAD(squareCycloFp12BN254_t13_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_t13_y), CALL(scalarMulFp2BN254) E => A C => B @@ -172,13 +177,13 @@ squareCycloFp12BN254: ; 8] c21 = 2·a21 + 3·t21 2n => A $ => C :MLOAD(squareCycloFp12BN254_a21_x) - $ => D :MLOAD(squareCycloFp12BN254_a21_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_a21_y), CALL(scalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a21_x) C :MSTORE(squareCycloFp12BN254_a21_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t21_x) - $ => D :MLOAD(squareCycloFp12BN254_t21_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_t21_y), CALL(scalarMulFp2BN254) E => A C => B @@ -190,13 +195,13 @@ squareCycloFp12BN254: ; 9] c22 = 2·a22 + 3·t22 2n => A $ => C :MLOAD(squareCycloFp12BN254_a22_x) - $ => D :MLOAD(squareCycloFp12BN254_a22_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_a22_y), CALL(scalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a22_x) C :MSTORE(squareCycloFp12BN254_a22_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t22_x) - $ => D :MLOAD(squareCycloFp12BN254_t22_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_t22_y), CALL(scalarMulFp2BN254) E => A C => B @@ -208,13 +213,13 @@ squareCycloFp12BN254: ; 9] c23 = 2·a23 + 3·t12 2n => A $ => C :MLOAD(squareCycloFp12BN254_a23_x) - $ => D :MLOAD(squareCycloFp12BN254_a23_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_a23_y), CALL(scalarMulFp2BN254) E :MSTORE(squareCycloFp12BN254_a23_x) C :MSTORE(squareCycloFp12BN254_a23_y) 3n => A $ => C :MLOAD(squareCycloFp12BN254_t12_x) - $ => D :MLOAD(squareCycloFp12BN254_t12_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(squareCycloFp12BN254_t12_y), CALL(scalarMulFp2BN254) E => A C => B diff --git a/main/pairings/FP12BN254/frob2Fp12BN254.zkasm b/main/pairings/FP12BN254/frob2Fp12BN254.zkasm index b09bcfec..52b84b63 100644 --- a/main/pairings/FP12BN254/frob2Fp12BN254.zkasm +++ b/main/pairings/FP12BN254/frob2Fp12BN254.zkasm @@ -36,6 +36,11 @@ VAR GLOBAL frob2Fp12BN254_c23_y VAR GLOBAL frob2Fp12BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 52, bin: 0, arith: 5] +; ----------------------------- + frob2Fp12BN254: RR :MSTORE(frob2Fp12BN254_RR) @@ -47,32 +52,32 @@ frob2Fp12BN254: %FROBENIUS_GAMMA22 => A $ => C :MLOAD(frob2Fp12BN254_a12_x) - $ => D :MLOAD(frob2Fp12BN254_a12_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(frob2Fp12BN254_a12_y), CALL(scalarMulFp2BN254) E :MSTORE(frob2Fp12BN254_c12_x) C :MSTORE(frob2Fp12BN254_c12_y) %FROBENIUS_GAMMA24 => A $ => C :MLOAD(frob2Fp12BN254_a13_x) - $ => D :MLOAD(frob2Fp12BN254_a13_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(frob2Fp12BN254_a13_y), CALL(scalarMulFp2BN254) E :MSTORE(frob2Fp12BN254_c13_x) C :MSTORE(frob2Fp12BN254_c13_y) ; 2] c2 = a21·γ21 + a22·γ23·v + a23·γ25·v² %FROBENIUS_GAMMA21 => A $ => C :MLOAD(frob2Fp12BN254_a21_x) - $ => D :MLOAD(frob2Fp12BN254_a21_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(frob2Fp12BN254_a21_y), CALL(scalarMulFp2BN254) E :MSTORE(frob2Fp12BN254_c21_x) C :MSTORE(frob2Fp12BN254_c21_y) %FROBENIUS_GAMMA23 => A $ => C :MLOAD(frob2Fp12BN254_a22_x) - $ => D :MLOAD(frob2Fp12BN254_a22_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(frob2Fp12BN254_a22_y), CALL(scalarMulFp2BN254) E :MSTORE(frob2Fp12BN254_c22_x) C :MSTORE(frob2Fp12BN254_c22_y) %FROBENIUS_GAMMA25 => A $ => C :MLOAD(frob2Fp12BN254_a23_x) - $ => D :MLOAD(frob2Fp12BN254_a23_y), CALL(escalarMulFp2BN254) + $ => D :MLOAD(frob2Fp12BN254_a23_y), CALL(scalarMulFp2BN254) E :MSTORE(frob2Fp12BN254_c23_x) C :MSTORE(frob2Fp12BN254_c23_y) diff --git a/main/pairings/FP12BN254/frob3Fp12BN254.zkasm b/main/pairings/FP12BN254/frob3Fp12BN254.zkasm index a1731e36..61340ca8 100644 --- a/main/pairings/FP12BN254/frob3Fp12BN254.zkasm +++ b/main/pairings/FP12BN254/frob3Fp12BN254.zkasm @@ -36,6 +36,11 @@ VAR GLOBAL frob3Fp12BN254_c23_y VAR GLOBAL frob3Fp12BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 63, bin: 6, arith: 5] +; ----------------------------- + frob3Fp12BN254: RR :MSTORE(frob3Fp12BN254_RR) diff --git a/main/pairings/FP12BN254/frobFp12BN254.zkasm b/main/pairings/FP12BN254/frobFp12BN254.zkasm index 8e951c64..6c1267d9 100644 --- a/main/pairings/FP12BN254/frobFp12BN254.zkasm +++ b/main/pairings/FP12BN254/frobFp12BN254.zkasm @@ -36,6 +36,11 @@ VAR GLOBAL frobFp12BN254_c23_y VAR GLOBAL frobFp12BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 63, bin: 6, arith: 5] +; ----------------------------- + frobFp12BN254: RR :MSTORE(frobFp12BN254_RR) diff --git a/main/pairings/FP12BN254/inverseFp12BN254.zkasm b/main/pairings/FP12BN254/inverseFp12BN254.zkasm index 6d9a1b09..323a5ab7 100644 --- a/main/pairings/FP12BN254/inverseFp12BN254.zkasm +++ b/main/pairings/FP12BN254/inverseFp12BN254.zkasm @@ -69,6 +69,12 @@ VAR GLOBAL inverseFp12BN254_final3_y VAR GLOBAL inverseFp12BN254_RR +; RESOURCES: +; ----------------------------- +; PATH 1 (a1² - a2²·v) == 0: [steps: 1129, bin: 10, arith: 108] +; PATH 2 (a1² - a2²·v) != 0: [steps: 1132, bin: 9, arith: 109] <--- w.c. +; ----------------------------- + inverseFp12BN254: RR :MSTORE(inverseFp12BN254_RR) diff --git a/main/pairings/FP12BN254/mulFp12BN254.zkasm b/main/pairings/FP12BN254/mulFp12BN254.zkasm index 6d721c1e..7243155e 100644 --- a/main/pairings/FP12BN254/mulFp12BN254.zkasm +++ b/main/pairings/FP12BN254/mulFp12BN254.zkasm @@ -80,6 +80,11 @@ VAR GLOBAL mulFp12BN254_b1b2sum3_y VAR GLOBAL mulFp12BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 1050, bin: 0, arith: 88] +; ----------------------------- + mulFp12BN254: RR :MSTORE(mulFp12BN254_RR) diff --git a/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm b/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm index 9646b0a3..2bb5698c 100644 --- a/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm +++ b/main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm @@ -60,6 +60,11 @@ VAR GLOBAL sparseMulAFp12BN254_aux2_y VAR GLOBAL sparseMulAFp12BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 664, bin: 0, arith: 51] +; ----------------------------- + sparseMulAFp12BN254: RR :MSTORE(sparseMulAFp12BN254_RR) diff --git a/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm b/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm index 535ca8dd..42a79325 100644 --- a/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm +++ b/main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm @@ -57,6 +57,11 @@ VAR GLOBAL sparseMulBFp12BN254_a2b2mul3_y VAR GLOBAL sparseMulBFp12BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 713, bin: 0, arith: 56] +; ----------------------------- + sparseMulBFp12BN254: RR :MSTORE(sparseMulBFp12BN254_RR) diff --git a/main/pairings/FP12BN254/squareFp12BN254.zkasm b/main/pairings/FP12BN254/squareFp12BN254.zkasm index b554b83d..143fe400 100644 --- a/main/pairings/FP12BN254/squareFp12BN254.zkasm +++ b/main/pairings/FP12BN254/squareFp12BN254.zkasm @@ -70,6 +70,11 @@ VAR GLOBAL squareFp12BN254_a1a2vsub3_y VAR GLOBAL squareFp12BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 876, bin: 0, arith: 69] +; ----------------------------- + squareFp12BN254: RR :MSTORE(squareFp12BN254_RR) @@ -173,28 +178,28 @@ squareFp12BN254: ; 3] c2 = 2·a1·a2 $ => A :MLOAD(squareFp12BN254_a1a2mul1_x) $ => B :MLOAD(squareFp12BN254_a1a2mul1_y) - A :MSTORE(escalarMulFp6BN254_a1_x) - B :MSTORE(escalarMulFp6BN254_a1_y) + A :MSTORE(scalarMulFp6BN254_a1_x) + B :MSTORE(scalarMulFp6BN254_a1_y) $ => A :MLOAD(squareFp12BN254_a1a2mul2_x) $ => B :MLOAD(squareFp12BN254_a1a2mul2_y) - A :MSTORE(escalarMulFp6BN254_a2_x) - B :MSTORE(escalarMulFp6BN254_a2_y) + A :MSTORE(scalarMulFp6BN254_a2_x) + B :MSTORE(scalarMulFp6BN254_a2_y) $ => A :MLOAD(squareFp12BN254_a1a2mul3_x) $ => B :MLOAD(squareFp12BN254_a1a2mul3_y) - A :MSTORE(escalarMulFp6BN254_a3_x) - B :MSTORE(escalarMulFp6BN254_a3_y) + A :MSTORE(scalarMulFp6BN254_a3_x) + B :MSTORE(scalarMulFp6BN254_a3_y) - 2n :MSTORE(escalarMulFp6BN254_b), CALL(escalarMulFp6BN254) - $ => A :MLOAD(escalarMulFp6BN254_c1_x) - $ => B :MLOAD(escalarMulFp6BN254_c1_y) + 2n :MSTORE(scalarMulFp6BN254_b), CALL(scalarMulFp6BN254) + $ => A :MLOAD(scalarMulFp6BN254_c1_x) + $ => B :MLOAD(scalarMulFp6BN254_c1_y) A :MSTORE(squareFp12BN254_c21_x) B :MSTORE(squareFp12BN254_c21_y) - $ => A :MLOAD(escalarMulFp6BN254_c2_x) - $ => B :MLOAD(escalarMulFp6BN254_c2_y) + $ => A :MLOAD(scalarMulFp6BN254_c2_x) + $ => B :MLOAD(scalarMulFp6BN254_c2_y) A :MSTORE(squareFp12BN254_c22_x) B :MSTORE(squareFp12BN254_c22_y) - $ => A :MLOAD(escalarMulFp6BN254_c3_x) - $ => B :MLOAD(escalarMulFp6BN254_c3_y) + $ => A :MLOAD(scalarMulFp6BN254_c3_x) + $ => B :MLOAD(scalarMulFp6BN254_c3_y) A :MSTORE(squareFp12BN254_c23_x) B :MSTORE(squareFp12BN254_c23_y) diff --git a/main/pairings/FP2BN254/addFp2BN254.zkasm b/main/pairings/FP2BN254/addFp2BN254.zkasm index a48b9a9e..f6a2b6f0 100644 --- a/main/pairings/FP2BN254/addFp2BN254.zkasm +++ b/main/pairings/FP2BN254/addFp2BN254.zkasm @@ -9,11 +9,16 @@ VAR GLOBAL addFp2BN254_i +; RESOURCES: +; ----------------------------- +; [steps: 3, bin: 0, arith: 1] +; ----------------------------- + addFp2BN254: ; Compute and check the mul ; A + C = [E] + (q0·BN254_P) ; B + D = [OP] + (q1·BN254_P) ${ARITH_BN254_ADDFP2(A,C)} => E - ${ARITH_BN254_ADDFP2(B,D)} :MSTORE(addFp2BN254_i), ARITH_BN254_ADDFP2 + ${ARITH_BN254_ADDFP2(B,D)} :MSTORE(addFp2BN254_i), ARITH_BN254_ADDFP2 - $ => C :MLOAD(addFp2BN254_i), RETURN + $ => C :MLOAD(addFp2BN254_i), RETURN \ No newline at end of file diff --git a/main/pairings/FP2BN254/invFp2BN254.zkasm b/main/pairings/FP2BN254/invFp2BN254.zkasm index 0635b151..075554a1 100644 --- a/main/pairings/FP2BN254/invFp2BN254.zkasm +++ b/main/pairings/FP2BN254/invFp2BN254.zkasm @@ -1,5 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; POST: The result is in the range [0,BN254_P) +;; POST: ARITH_BN254_MULFP2 ensures that the result is in the range [0,BN254_P) ;; ;; invFp2BN254 ;; in: (A + B·u) ∈ Fp2, where A,B ∈ Fp @@ -8,6 +8,43 @@ ;; NOTE: On input 0, it returns 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; RESOURCES: +; ------------------------------------------- +; PATH 1 A,B < p: [steps: 3, bin: 1] + [steps: 4, bin: 1] + +; PATH 1.1 A == 0 (p): [steps: 5, bin: 2] + +; PATH 1.1.1 B == 0 (p): [steps: 3] +; PATH 1.1.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] = [steps: 23, bin: 4, arith: 1] +; PATH 1.2 A != 0 (p): [steps: 3, bin: 1] + +; PATH 1.2.1 B == 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] +; PATH 1.2.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] + +; PATH 2 A < p, B > p: [steps: 3, bin: 1] + [steps: 14, bin: 2, arith: 1] + +; PATH 2.1 A == 0 (p): [steps: 5, bin: 2] + +; PATH 2.1.1 B == 0 (p): [steps: 3] +; PATH 2.1.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] +; PATH 2.2 A != 0 (p): [steps: 3, bin: 1] + +; PATH 2.2.1 B == 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] +; PATH 2.2.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] + +; PATH 3 A > p, B < p: [steps: 13, bin: 2, arith: 1] + [steps: 4, bin: 1] + +; PATH 3.1 A == 0 (p): [steps: 5, bin: 2] + +; PATH 3.1.1 B == 0 (p): [steps: 3] +; PATH 3.1.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] +; PATH 3.2 A != 0 (p): [steps: 3, bin: 1] + +; PATH 3.2.1 B == 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] +; PATH 3.2.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] + +; PATH 4 A,B > p: [steps: 13, bin: 2, arith: 1] + [steps: 14, bin: 2, arith: 1] + +; PATH 4.1 A == 0 (p): [steps: 5, bin: 2] + +; PATH 4.1.1 B == 0 (p): [steps: 3] +; PATH 4.1.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] = [steps: 43, bin: 6, arith: 3] <--- w.c. +; PATH 4.2 A != 0 (p): [steps: 3, bin: 1] + +; PATH 4.2.1 B == 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] +; PATH 4.2.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] +; ------------------------------------------- + +; TODO: Add flag in reduceFp to reduce that xiva if the result is 0 or not + VAR GLOBAL invFp2BN254_x VAR GLOBAL invFp2BN254_y @@ -16,19 +53,23 @@ VAR GLOBAL invFp2BN254_RR invFp2BN254: RR :MSTORE(invFp2BN254_RR) + A :MSTORE(invFp2BN254_x) B :MSTORE(invFp2BN254_y) - ; Normalization of A,B + + ; Normalization of A %BN254_P => B $ :LT, JMPC(__invFp2BN254_reduce_A_continue) :CALL(reduceFpBN254) - __invFp2BN254_reduce_A_continue: A :MSTORE(invFp2BN254_x) + __invFp2BN254_reduce_A_continue: + + ; Normalization of B $ => A :MLOAD(invFp2BN254_y) %BN254_P => B $ :LT, JMPC(__invFp2BN254_reduce_B_continue) :CALL(reduceFpBN254) - __invFp2BN254_reduce_B_continue: A :MSTORE(invFp2BN254_y) + __invFp2BN254_reduce_B_continue: ; From here, it is guaranteed that A,B ∈ [0,BN254_P) invFp2BN254_zero_check: @@ -38,6 +79,7 @@ invFp2BN254_zero_check: $ :EQ, JMPNC(invFp2BN254_normalized) $ => B :MLOAD(invFp2BN254_y) $ :EQ, JMPC(invFp2BN254_input_is_zero) + ; From here, either A != 0 or B != 0 invFp2BN254_normalized: $ => A :MLOAD(invFp2BN254_x) diff --git a/main/pairings/FP2BN254/mulFp2BN254.zkasm b/main/pairings/FP2BN254/mulFp2BN254.zkasm index 46c85799..09ba2f79 100644 --- a/main/pairings/FP2BN254/mulFp2BN254.zkasm +++ b/main/pairings/FP2BN254/mulFp2BN254.zkasm @@ -9,6 +9,11 @@ VAR GLOBAL mulFp2BN254_i +; RESOURCES: +; ----------------------------- +; [steps: 3, bin: 0, arith: 1] +; ----------------------------- + mulFp2BN254: ; Compute and check the mul ; A·C - B·D = [E] + (q0·BN254_P) diff --git a/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm b/main/pairings/FP2BN254/scalarMulFp2BN254.zkasm similarity index 58% rename from main/pairings/FP2BN254/escalarMulFp2BN254.zkasm rename to main/pairings/FP2BN254/scalarMulFp2BN254.zkasm index 1814aec3..c55c6f96 100644 --- a/main/pairings/FP2BN254/escalarMulFp2BN254.zkasm +++ b/main/pairings/FP2BN254/scalarMulFp2BN254.zkasm @@ -1,20 +1,25 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; POST: ARITH_BN254_MULFP2 ensures that the result is in the range [0,BN254_P) ;; -;; escalarMulFp2BN254: +;; scalarMulFp2BN254: ;; in: A ∈ Fp, (C + D·u) ∈ Fp2, where C,D ∈ Fp ;; out: E + C·u = (A·C) + (A·D)·u ∈ Fp2 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL escalarMulFp2BN254_i +VAR GLOBAL scalarMulFp2BN254_i -escalarMulFp2BN254: +; RESOURCES: +; ----------------------------- +; [steps: 4, bin: 0, arith: 1] +; ----------------------------- + +scalarMulFp2BN254: ; Compute and check the mul ; A·C - 0·D = [E] + (q0·BN254_P) ; A·D + 0·C = [OP] + (q1·BN254_P) 0n => B ${ARITH_BN254_MULFP2_X(A,B,C,D)} => E - ${ARITH_BN254_MULFP2_Y(A,B,C,D)} :MSTORE(escalarMulFp2BN254_i), ARITH_BN254_MULFP2 + ${ARITH_BN254_MULFP2_Y(A,B,C,D)} :MSTORE(scalarMulFp2BN254_i), ARITH_BN254_MULFP2 - $ => C :MLOAD(escalarMulFp2BN254_i), RETURN \ No newline at end of file + $ => C :MLOAD(scalarMulFp2BN254_i), RETURN \ No newline at end of file diff --git a/main/pairings/FP2BN254/squareFp2BN254.zkasm b/main/pairings/FP2BN254/squareFp2BN254.zkasm index e5d738e6..39d0693f 100644 --- a/main/pairings/FP2BN254/squareFp2BN254.zkasm +++ b/main/pairings/FP2BN254/squareFp2BN254.zkasm @@ -9,6 +9,11 @@ VAR GLOBAL squareFp2BN254_i +; RESOURCES: +; ----------------------------- +; [steps: 5, bin: 0, arith: 1] +; ----------------------------- + squareFp2BN254: ; Compute and check the squaring ; A·A - B·B = [E] + (q0·BN254_P) diff --git a/main/pairings/FP2BN254/subFp2BN254.zkasm b/main/pairings/FP2BN254/subFp2BN254.zkasm index 9dc84720..3f06ad30 100644 --- a/main/pairings/FP2BN254/subFp2BN254.zkasm +++ b/main/pairings/FP2BN254/subFp2BN254.zkasm @@ -9,6 +9,11 @@ VAR GLOBAL subFp2BN254_i +; RESOURCES: +; ----------------------------- +; [steps: 3, bin: 0, arith: 1] +; ----------------------------- + subFp2BN254: ; Compute and check the mul ; A - C = [E] + (q0·BN254_P) @@ -16,4 +21,4 @@ subFp2BN254: ${ARITH_BN254_SUBFP2(A,C)} => E ${ARITH_BN254_SUBFP2(B,D)} :MSTORE(subFp2BN254_i), ARITH_BN254_SUBFP2 - $ => C :MLOAD(subFp2BN254_i), RETURN + $ => C :MLOAD(subFp2BN254_i), RETURN \ No newline at end of file diff --git a/main/pairings/FP4BN254/squareFp4BN254.zkasm b/main/pairings/FP4BN254/squareFp4BN254.zkasm index ef064800..51f0efb3 100644 --- a/main/pairings/FP4BN254/squareFp4BN254.zkasm +++ b/main/pairings/FP4BN254/squareFp4BN254.zkasm @@ -25,6 +25,11 @@ VAR GLOBAL squareFp4BN254_a2square_y VAR GLOBAL squareFp4BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 67, bin: 0, arith: 8] +; ----------------------------- + squareFp4BN254: RR :MSTORE(squareFp4BN254_RR) @@ -33,18 +38,21 @@ squareFp4BN254: $ => B :MLOAD(squareFp4BN254_a1_y), CALL(squareFp2BN254) E :MSTORE(squareFp4BN254_a1square_x) C :MSTORE(squareFp4BN254_a1square_y) + ; [steps: 10, bin: 0, arith: 1] ; 2] a2² $ => A :MLOAD(squareFp4BN254_a2_x) $ => B :MLOAD(squareFp4BN254_a2_y), CALL(squareFp2BN254) E :MSTORE(squareFp4BN254_a2square_x) C :MSTORE(squareFp4BN254_a2square_y) + ; [steps: 19, bin: 0, arith: 2] ; 3] c1 = a2²·(9 + u) + a1² $ => A :MLOAD(squareFp4BN254_a2square_x) $ => B :MLOAD(squareFp4BN254_a2square_y) 9n => C 1n => D :CALL(mulFp2BN254) + ; [steps: 26, bin: 0, arith: 3] E => A C => B @@ -52,6 +60,7 @@ squareFp4BN254: $ => D :MLOAD(squareFp4BN254_a1square_y), CALL(addFp2BN254) E :MSTORE(squareFp4BN254_c1_x) C :MSTORE(squareFp4BN254_c1_y) + ; [steps: 35, bin: 0, arith: 4] ; 4] c2 = (a1 + a2)² - a1² - a2² $ => A :MLOAD(squareFp4BN254_a1_x) @@ -60,6 +69,7 @@ squareFp4BN254: $ => D :MLOAD(squareFp4BN254_a2_y), CALL(addFp2BN254) E => A C => B :CALL(squareFp2BN254) + ; [steps: 49, bin: 0, arith: 6] E => A C => B @@ -73,4 +83,5 @@ squareFp4BN254: C :MSTORE(squareFp4BN254_c2_y) $ => RR :MLOAD(squareFp4BN254_RR) - :RETURN \ No newline at end of file + :RETURN + ; [steps: 67, bin: 0, arith: 8] \ No newline at end of file diff --git a/main/pairings/FP6BN254/addFp6BN254.zkasm b/main/pairings/FP6BN254/addFp6BN254.zkasm index 8854b6bd..bbfabacf 100644 --- a/main/pairings/FP6BN254/addFp6BN254.zkasm +++ b/main/pairings/FP6BN254/addFp6BN254.zkasm @@ -28,6 +28,11 @@ VAR GLOBAL addFp6BN254_c3_y VAR GLOBAL addFp6BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 30, bin: 0, arith: 3] +; ----------------------------- + addFp6BN254: RR :MSTORE(addFp6BN254_RR) diff --git a/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm b/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm deleted file mode 100644 index 878abcd5..00000000 --- a/main/pairings/FP6BN254/escalarMulFp6BN254.zkasm +++ /dev/null @@ -1,51 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic -;; -;; escalarMulFp6BN254: -;; in: b ∈ Fp, (a1 + a2·v + a3·v²) ∈ Fp6, where ai ∈ Fp2 -;; out: (c1 + c2·v + c3·v²) = (a1·b) + (a2·b)·v + (a3·b)·v² ∈ Fp6 -;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -VAR GLOBAL escalarMulFp6BN254_a1_x -VAR GLOBAL escalarMulFp6BN254_a1_y -VAR GLOBAL escalarMulFp6BN254_a2_x -VAR GLOBAL escalarMulFp6BN254_a2_y -VAR GLOBAL escalarMulFp6BN254_a3_x -VAR GLOBAL escalarMulFp6BN254_a3_y -VAR GLOBAL escalarMulFp6BN254_b -VAR GLOBAL escalarMulFp6BN254_c1_x -VAR GLOBAL escalarMulFp6BN254_c1_y -VAR GLOBAL escalarMulFp6BN254_c2_x -VAR GLOBAL escalarMulFp6BN254_c2_y -VAR GLOBAL escalarMulFp6BN254_c3_x -VAR GLOBAL escalarMulFp6BN254_c3_y - -VAR GLOBAL escalarMulFp6BN254_RR - -escalarMulFp6BN254: - RR :MSTORE(escalarMulFp6BN254_RR) - - ; 1] c1 = a1·b - $ => A :MLOAD(escalarMulFp6BN254_b) - $ => C :MLOAD(escalarMulFp6BN254_a1_x) - $ => D :MLOAD(escalarMulFp6BN254_a1_y), CALL(escalarMulFp2BN254) - E :MSTORE(escalarMulFp6BN254_c1_x) - C :MSTORE(escalarMulFp6BN254_c1_y) - - ; 2] c2 = a2·b - $ => A :MLOAD(escalarMulFp6BN254_b) - $ => C :MLOAD(escalarMulFp6BN254_a2_x) - $ => D :MLOAD(escalarMulFp6BN254_a2_y), CALL(escalarMulFp2BN254) - E :MSTORE(escalarMulFp6BN254_c2_x) - C :MSTORE(escalarMulFp6BN254_c2_y) - - ; 3] c3 = a3·b - $ => A :MLOAD(escalarMulFp6BN254_b) - $ => C :MLOAD(escalarMulFp6BN254_a3_x) - $ => D :MLOAD(escalarMulFp6BN254_a3_y), CALL(escalarMulFp2BN254) - E :MSTORE(escalarMulFp6BN254_c3_x) - C :MSTORE(escalarMulFp6BN254_c3_y) - - $ => RR :MLOAD(escalarMulFp6BN254_RR) - :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/inverseFp6BN254.zkasm b/main/pairings/FP6BN254/inverseFp6BN254.zkasm index d43a0a7f..7ae8652a 100644 --- a/main/pairings/FP6BN254/inverseFp6BN254.zkasm +++ b/main/pairings/FP6BN254/inverseFp6BN254.zkasm @@ -58,6 +58,12 @@ VAR GLOBAL inverseFp6BN254_last_y VAR GLOBAL inverseFp6BN254_RR +; RESOURCES: +; ----------------------------- +; PATH 1 a1·c1mid + xi·(a3·c2mid + a2·c3mid)_x == 0: [steps: 199, bin: 4, arith: 21] +; PATH 2 a1·c1mid + xi·(a3·c2mid + a2·c3mid)_x != 0: [steps: 202, bin: 3, arith: 22] <--- w.c. +; ----------------------------- + inverseFp6BN254: RR :MSTORE(inverseFp6BN254_RR) diff --git a/main/pairings/FP6BN254/mulFp6BN254.zkasm b/main/pairings/FP6BN254/mulFp6BN254.zkasm index a907ab17..7693180c 100644 --- a/main/pairings/FP6BN254/mulFp6BN254.zkasm +++ b/main/pairings/FP6BN254/mulFp6BN254.zkasm @@ -53,6 +53,11 @@ VAR GLOBAL mulFp6BN254_b1b3sum_y VAR GLOBAL mulFp6BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 190, bin: 0, arith: 23] +; ----------------------------- + mulFp6BN254: RR :MSTORE(mulFp6BN254_RR) diff --git a/main/pairings/FP6BN254/scalarMulFp6BN254.zkasm b/main/pairings/FP6BN254/scalarMulFp6BN254.zkasm new file mode 100644 index 00000000..cac2e78e --- /dev/null +++ b/main/pairings/FP6BN254/scalarMulFp6BN254.zkasm @@ -0,0 +1,56 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; POST: The result is in the range [0,BN254_P) because if falls back to FP2 arithmetic +;; +;; scalarMulFp6BN254: +;; in: b ∈ Fp, (a1 + a2·v + a3·v²) ∈ Fp6, where ai ∈ Fp2 +;; out: (c1 + c2·v + c3·v²) = (a1·b) + (a2·b)·v + (a3·b)·v² ∈ Fp6 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +VAR GLOBAL scalarMulFp6BN254_a1_x +VAR GLOBAL scalarMulFp6BN254_a1_y +VAR GLOBAL scalarMulFp6BN254_a2_x +VAR GLOBAL scalarMulFp6BN254_a2_y +VAR GLOBAL scalarMulFp6BN254_a3_x +VAR GLOBAL scalarMulFp6BN254_a3_y +VAR GLOBAL scalarMulFp6BN254_b +VAR GLOBAL scalarMulFp6BN254_c1_x +VAR GLOBAL scalarMulFp6BN254_c1_y +VAR GLOBAL scalarMulFp6BN254_c2_x +VAR GLOBAL scalarMulFp6BN254_c2_y +VAR GLOBAL scalarMulFp6BN254_c3_x +VAR GLOBAL scalarMulFp6BN254_c3_y + +VAR GLOBAL scalarMulFp6BN254_RR + +; RESOURCES: +; ----------------------------- +; [steps: 30, bin: 0, arith: 3] +; ----------------------------- + +scalarMulFp6BN254: + RR :MSTORE(scalarMulFp6BN254_RR) + + ; 1] c1 = a1·b + $ => A :MLOAD(scalarMulFp6BN254_b) + $ => C :MLOAD(scalarMulFp6BN254_a1_x) + $ => D :MLOAD(scalarMulFp6BN254_a1_y), CALL(scalarMulFp2BN254) + E :MSTORE(scalarMulFp6BN254_c1_x) + C :MSTORE(scalarMulFp6BN254_c1_y) + + ; 2] c2 = a2·b + $ => A :MLOAD(scalarMulFp6BN254_b) + $ => C :MLOAD(scalarMulFp6BN254_a2_x) + $ => D :MLOAD(scalarMulFp6BN254_a2_y), CALL(scalarMulFp2BN254) + E :MSTORE(scalarMulFp6BN254_c2_x) + C :MSTORE(scalarMulFp6BN254_c2_y) + + ; 3] c3 = a3·b + $ => A :MLOAD(scalarMulFp6BN254_b) + $ => C :MLOAD(scalarMulFp6BN254_a3_x) + $ => D :MLOAD(scalarMulFp6BN254_a3_y), CALL(scalarMulFp2BN254) + E :MSTORE(scalarMulFp6BN254_c3_x) + C :MSTORE(scalarMulFp6BN254_c3_y) + + $ => RR :MLOAD(scalarMulFp6BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm b/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm index 76d33d26..072d8c69 100644 --- a/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm +++ b/main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm @@ -29,6 +29,11 @@ VAR GLOBAL sparseMulAFp6BN254_c3_y VAR GLOBAL sparseMulAFp6BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 37, bin: 0, arith: 4] +; ----------------------------- + sparseMulAFp6BN254: RR :MSTORE(sparseMulAFp6BN254_RR) diff --git a/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm b/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm index e5353ee5..30b7868d 100644 --- a/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm +++ b/main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm @@ -40,6 +40,11 @@ VAR GLOBAL sparseMulBFp6BN254_a1b2_y VAR GLOBAL sparseMulBFp6BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 122, bin: 0, arith: 16] +; ----------------------------- + sparseMulBFp6BN254: RR :MSTORE(sparseMulBFp6BN254_RR) diff --git a/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm b/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm index 6c07be82..5f4d3780 100644 --- a/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm +++ b/main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm @@ -40,6 +40,11 @@ VAR GLOBAL sparseMulCFp6BN254_a1a3sum_y VAR GLOBAL sparseMulCFp6BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 108, bin: 0, arith: 13] +; ----------------------------- + sparseMulCFp6BN254: RR :MSTORE(sparseMulCFp6BN254_RR) diff --git a/main/pairings/FP6BN254/squareFp6BN254.zkasm b/main/pairings/FP6BN254/squareFp6BN254.zkasm index fc9b62af..c7b94d04 100644 --- a/main/pairings/FP6BN254/squareFp6BN254.zkasm +++ b/main/pairings/FP6BN254/squareFp6BN254.zkasm @@ -38,6 +38,11 @@ VAR GLOBAL squareFp6BN254_2a2a3mul_y VAR GLOBAL squareFp6BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 140, bin: 0, arith: 17] +; ----------------------------- + squareFp6BN254: RR :MSTORE(squareFp6BN254_RR) @@ -48,7 +53,7 @@ squareFp6BN254: $ => D :MLOAD(squareFp6BN254_a2_y), CALL(mulFp2BN254) 2n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E :MSTORE(squareFp6BN254_2a1a2mul_x) C :MSTORE(squareFp6BN254_2a1a2mul_y) @@ -109,7 +114,7 @@ squareFp6BN254: $ => D :MLOAD(squareFp6BN254_a3_y), CALL(mulFp2BN254) 2n => A C => D - E => C :CALL(escalarMulFp2BN254) + E => C :CALL(scalarMulFp2BN254) E :MSTORE(squareFp6BN254_2a2a3mul_x) C :MSTORE(squareFp6BN254_2a2a3mul_y) diff --git a/main/pairings/FP6BN254/subFp6BN254.zkasm b/main/pairings/FP6BN254/subFp6BN254.zkasm index af0ab16f..6affec86 100644 --- a/main/pairings/FP6BN254/subFp6BN254.zkasm +++ b/main/pairings/FP6BN254/subFp6BN254.zkasm @@ -28,6 +28,11 @@ VAR GLOBAL subFp6BN254_c3_y VAR GLOBAL subFp6BN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 30, bin: 0, arith: 3] +; ----------------------------- + subFp6BN254: RR :MSTORE(subFp6BN254_RR) diff --git a/main/pairings/FPBN254/addFpBN254.zkasm b/main/pairings/FPBN254/addFpBN254.zkasm index 3c6043c7..6a7ce86e 100644 --- a/main/pairings/FPBN254/addFpBN254.zkasm +++ b/main/pairings/FPBN254/addFpBN254.zkasm @@ -7,6 +7,11 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; RESOURCES: +; ----------------------------- +; [steps: 11, bin: 1, arith: 2] +; ----------------------------- + addFpBN254: ; 1] Compute and check the sum over Z ; A·[1] + C = [D]·2²⁵⁶ + [E] diff --git a/main/pairings/FPBN254/invFpBN254.zkasm b/main/pairings/FPBN254/invFpBN254.zkasm index bf61486d..30657e99 100644 --- a/main/pairings/FPBN254/invFpBN254.zkasm +++ b/main/pairings/FPBN254/invFpBN254.zkasm @@ -8,24 +8,42 @@ ;; NOTE: On input 0, it returns 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO: Verify if alias check is necessary + VAR GLOBAL invFpBN254_tmp VAR GLOBAL invFpBN254_RR +; RESOURCES: +; ------------------------------------------- +; PATH 1 input_is_reduced_and_0: [steps: 8, bin: 2] +; PATH 2 input_is_not_reduced_and_0: [steps: 18, bin: 3, arith: 1] +; PATH 3 input_is_reduced: [steps: 20, bin: 3, arith: 2] +; PATH 4 input_is_not_reduced: [steps: 30, bin: 4, arith: 3] <--- w.c. +; ------------------------------------------- + invFpBN254: + ; block costs: + ; · input_is_reduced: [steps: 3, bin: 1] + ; · input_is_not_reduced: [steps: 13, bin: 2, arith: 1] + RR :MSTORE(invFpBN254_RR) - ; Normalization of A + ; Reduction of A %BN254_P => B $ :LT, JMPC(invFpBN254_zero_check) :CALL(reduceFpBN254) ; From here, it is guaranteed that A ∈ [0,BN254_P) invFpBN254_zero_check: + ; block costs: [steps: 2, bin: 1] + ; Check if A = 0, and if so, return 0 0 => B $ :EQ, JMPC(invFpBN254_A_is_zero) invFpBN254_normalized: + ; block costs: [steps: 13, bin: 1, arith: 2] + ; 1] Compute and check the inverse over Z ; A·A⁻¹ + [0] = [D]·2²⁵⁶ + [E] 0 => C @@ -48,6 +66,8 @@ invFpBN254_normalized: A => B :JMP(invFpBN254_end) invFpBN254_A_is_zero: + ; block costs: [steps: 1] + 0 => B invFpBN254_end: diff --git a/main/pairings/FPBN254/mulFpBN254.zkasm b/main/pairings/FPBN254/mulFpBN254.zkasm index b77ac02e..c5b7c552 100644 --- a/main/pairings/FPBN254/mulFpBN254.zkasm +++ b/main/pairings/FPBN254/mulFpBN254.zkasm @@ -7,6 +7,11 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; RESOURCES: +; ----------------------------- +; [steps: 11, bin: 1, arith: 2] +; ----------------------------- + mulFpBN254: ; 1] Compute and check the sum over Z ; A·B + [0] = [D]·2²⁵⁶ + [E] diff --git a/main/pairings/FPBN254/reduceFpBN254.zkasm b/main/pairings/FPBN254/reduceFpBN254.zkasm index 59929e79..44d08c1d 100644 --- a/main/pairings/FPBN254/reduceFpBN254.zkasm +++ b/main/pairings/FPBN254/reduceFpBN254.zkasm @@ -9,6 +9,11 @@ VAR GLOBAL reduceFpBN254_tmp +; RESOURCES: +; ----------------------------- +; [steps: 9, bin: 1, arith: 1] +; ----------------------------- + reduceFpBN254: ; 1] It must be satisfied that: ; [BN254_P]·[A / p] + [A % p] = [0]·2²⁵⁶ + A diff --git a/main/pairings/FPBN254/squareFpBN254.zkasm b/main/pairings/FPBN254/squareFpBN254.zkasm index 9b8ced1b..f876e5db 100644 --- a/main/pairings/FPBN254/squareFpBN254.zkasm +++ b/main/pairings/FPBN254/squareFpBN254.zkasm @@ -7,6 +7,11 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; RESOURCES: +; ----------------------------- +; [steps: 13, bin: 1, arith: 2] +; ----------------------------- + squareFpBN254: ; 1] Compute and check the inverse over Z ; A·A + [0] = [D]·2²⁵⁶ + [E] diff --git a/main/pairings/FPBN254/subFpBN254.zkasm b/main/pairings/FPBN254/subFpBN254.zkasm index 51a76959..fa106813 100644 --- a/main/pairings/FPBN254/subFpBN254.zkasm +++ b/main/pairings/FPBN254/subFpBN254.zkasm @@ -7,6 +7,11 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; RESOURCES: +; ----------------------------- +; [steps: 12, bin: 1, arith: 2] +; ----------------------------- + subFpBN254: ; 0] Negate C A => D diff --git a/main/pairings/FRBN254/reduceFrBN254.zkasm b/main/pairings/FRBN254/reduceFrBN254.zkasm index 927bf85b..1c83e2fc 100644 --- a/main/pairings/FRBN254/reduceFrBN254.zkasm +++ b/main/pairings/FRBN254/reduceFrBN254.zkasm @@ -9,6 +9,11 @@ VAR GLOBAL reduceFrBN254_tmp +; RESOURCES: +; ----------------------------- +; [steps: 9, bin: 1, arith: 1] +; ----------------------------- + reduceFrBN254: ; 1] It must be satisfied that: ; [BN254_R]·[B / r] + [B % r] = [0]·2²⁵⁶ + E diff --git a/main/pairings/constants.zkasm b/main/pairings/constants.zkasm index 9811197e..cb64efc7 100644 --- a/main/pairings/constants.zkasm +++ b/main/pairings/constants.zkasm @@ -2,7 +2,7 @@ ;; ;; Constants of the optimal Ate pairing over the BN254 curve ;; e: G1 x G2 --> GT -;; where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and GT = mu_r (the r-th roots of unity over Fp12* over the curves: +;; where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and GT = μ_r (the r-th roots of unity over Fp12* over the curves: ;; E/Fp: y² = x³ + 3, E'/Fp2: y² = x³ + 3/(9+u) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/main/pairings/ecPairing.zkasm b/main/pairings/ecPairing.zkasm index 16c235d2..a0487db2 100644 --- a/main/pairings/ecPairing.zkasm +++ b/main/pairings/ecPairing.zkasm @@ -5,10 +5,13 @@ ;; input: P1,...,Pn ∈ G1 and Q1,...,Qn ∈ G2, where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and ;; the curves are E/Fp: y² = x³ + 3 and E'/Fp2: y² = x³ + 3/(9+u) ;; output: 1 if e(P1,Q1)·...·e(Pn,Qn) = 1, 0 otherwise; where e: G1 x G2 -> GT is -;; the optimal Ate pairing over the BN254 curve and GT = mu_r (the r-th roots of unity over Fp12* +;; the optimal Ate pairing over the BN254 curve and GT = μ_r (the r-th roots of unity over Fp12* ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO: If nInputs = 1, output 1 iff P or Q are 0. Optimization +; TODO: If some Pi,Qi is 0, then set e(Pi,Qi)=1 and do not multiply by this naive element + VAR GLOBAL ecPairing_ninputs VAR GLOBAL ecPairing_mul_f11_x @@ -32,6 +35,21 @@ VAR GLOBAL ecPairing_RR ; 0 - no error ; 1 - error found in some input +; RESOURCES (not considering error or trivial paths): +; ------------------------------------------- +; [steps: 15] // setup +; + niputs * [steps: 173154, bin: 966, arith: 13415] // half_paring +; + [steps: 170762, bin: 498, arith: 15411] // final_exponentiation + end +; total (w.c.): [steps: 15 + niputs*173154 + 170762, +; bin: niputs*966 + 498, +; arith: niputs*13415 + 15411] +; +; Examples: +; · ninputs = 2: [517085, 2430, 42241] +; · ninputs = 3: [690239, 3396, 55656] +; · ninputs = 4: [863393, 4362, 69071] +; ------------------------------------------- + ecPairing: RR :MSTORE(ecPairing_RR) @@ -39,6 +57,7 @@ ecPairing: 0n :MSTORE(ecPairing_result) $ => A :MLOAD(ecPairing_ninputs), JMPZ(ecPairing_0_inputs) + ; [steps: 3, bin: 0, arith: 0] ; Initialize the multiplication with 1 1n :MSTORE(ecPairing_mul_f11_x) @@ -53,14 +72,11 @@ ecPairing: 0n :MSTORE(ecPairing_mul_f22_y) 0n :MSTORE(ecPairing_mul_f23_x) 0n :MSTORE(ecPairing_mul_f23_y) - - :JMP(ecPairing_Miller_loop) - -ecPairing_0_inputs: - 1 :MSTORE(ecPairing_result) - :JMP(ecPairing_correct) + ; [steps: 15, bin: 0, arith: 0] ecPairing_Miller_loop: + ; block costs: [steps: 173154, bin: 966, arith: 13415] + $ => E :MLOAD(readXFromCalldataOffset) 32 :MSTORE(readXFromCalldataLength) E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] @@ -81,6 +97,7 @@ ecPairing_Miller_loop: E + 32 => E :MSTORE(readXFromCalldataOffset), CALL(readFromCalldataOffset); in: [readXFromCalldataOffset: offset value, readXFromCalldataLength: length value], out: [readXFromCalldataResult: result value] $ => A :MLOAD(readXFromCalldataResult) A :MSTORE(halfPairingBN254_Q_y1), CALL(halfPairingBN254) + ; [steps: 172029, bin: 966, arith: 13327] ; Check if the error code (B) of halfPairingBN254 is not 0, meaning there is an error in some of the inputs B :JMPNZ(ecPairing_input_error) @@ -134,6 +151,7 @@ ecPairing_Miller_loop: B :MSTORE(mulFp12BN254_b22_y) C :MSTORE(mulFp12BN254_b23_x) D :MSTORE(mulFp12BN254_b23_y), CALL(mulFp12BN254) + ; [steps: 173127, bin: 966, arith: 13415] $ => A :MLOAD(mulFp12BN254_c11_x) $ => B :MLOAD(mulFp12BN254_c11_y) @@ -162,10 +180,12 @@ ecPairing_Miller_loop: $ => A :MLOAD(ecPairing_ninputs) A - 1 => A :JMPZ(ecPairing_final_exponentiation) - A :MSTORE(ecPairing_ninputs) - :JMP(ecPairing_Miller_loop) + A :MSTORE(ecPairing_ninputs), JMP(ecPairing_Miller_loop) + ; [steps: 173154, bin: 966, arith: 13415] ecPairing_final_exponentiation: + ; block costs: [steps: 170762, bin: 498, arith: 15411] + $ => A :MLOAD(mulFp12BN254_c11_x) $ => B :MLOAD(mulFp12BN254_c11_y) $ => C :MLOAD(mulFp12BN254_c12_x) @@ -190,6 +210,7 @@ ecPairing_final_exponentiation: B :MSTORE(finalExpBN254_f22_y) C :MSTORE(finalExpBN254_f23_x) D :MSTORE(finalExpBN254_f23_y), CALL(finalExpBN254) + ; [steps: 170731, bin: 486, arith: 15411] ; Check whether the result is 1 or not 1n => B @@ -219,6 +240,7 @@ ecPairing_final_exponentiation: $ => A :MLOAD(finalExpBN254_f23_y) $ :EQ, JMPC(ecPairing_equation_is_satisfied) __finalExpBN254_result_continue: + ; till end -> [steps: 170762, bin: 498, arith: 15411] ; the pairing equation is not satisfied, then output 0 0 :MSTORE(ecPairing_result) @@ -233,6 +255,9 @@ ecPairing_equation_is_satisfied: ecPairing_input_error: 1 => B :JMP(ecPairing_error) +ecPairing_0_inputs: + 1 :MSTORE(ecPairing_result) + ecPairing_correct: 0 => B :JMP(ecPairing_end) diff --git a/main/pairings/finalExpBN254.zkasm b/main/pairings/finalExpBN254.zkasm index 8dfae38a..546d6215 100644 --- a/main/pairings/finalExpBN254.zkasm +++ b/main/pairings/finalExpBN254.zkasm @@ -1,9 +1,10 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: f != 0,1 ;; POST: The result is in the range [0,BN254_P) because if falls back to FP12 arithmetic ;; ;; finalExpBN254: -;; input: f ∈ Fp12 -;; output: f^((p¹²-1)/r) +;; input: f ∈ Fp12* +;; output: f^((p¹²-1)/r) ∈ μ_r ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -278,6 +279,11 @@ VAR GLOBAL finalExpBN254_T24_23_y VAR GLOBAL finalExpBN254_RR +; RESOURCES: +; ----------------------------- +; [steps: 170707, bin: 486, arith: 15411] +; ----------------------------- + finalExpBN254: RR :MSTORE(finalExpBN254_RR) @@ -2091,5 +2097,5 @@ finalExpBN254: B :MSTORE(finalExpBN254_f23_y) finalExpBN254_end: - $ => RR :MLOAD(finalExpBN254_RR) - :RETURN \ No newline at end of file + $ => RR :MLOAD(finalExpBN254_RR) + :RETURN \ No newline at end of file diff --git a/main/pairings/halfPairingBN254.zkasm b/main/pairings/halfPairingBN254.zkasm index 98250839..3198b2c8 100644 --- a/main/pairings/halfPairingBN254.zkasm +++ b/main/pairings/halfPairingBN254.zkasm @@ -2,7 +2,7 @@ ;; ;; halfPairingBN254: ;; input: P ∈ G1 and Q ∈ G2 -;; output: It returns 1 if either P = 0 or Q = 0 and f_{r,Q}(P) ∈ Fp12 otherwise +;; output: It returns 1 if either P = 𝒪 or Q = 𝒪 and f_{r,Q}(P) ∈ FP2 otherwise ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -47,9 +47,18 @@ VAR GLOBAL halfPairingBN254_psi_y2 ; 7 - P is not in G1 ; 8 - Q is not in G2 +; RESOURCES (not considering error paths): +; ------------------------------------------- +; PATH 1 P == 𝒪 and Q == 𝒪: [steps: 40, bin: 12, arith: 0] +; PATH 2 P == 𝒪 and Q != 𝒪: [steps: 20939, bin: 561, arith: 1804] +; PATH 3 P != 𝒪 and Q == 𝒪: [steps: 96, bin: 17, arith: 8] +; PATH 4 P,Q != 𝒪: [steps: 172003, bin: 966, arith: 13327] <--- w.c. +; ------------------------------------------- + halfPairingBN254: RR :MSTORE(halfPairingBN254_RR) + ; Check whether the points coordinates are in the range [0, BN254_P) %BN254_P_MINUS_ONE => A $ => B :MLOAD(halfPairingBN254_P_x) $ :LT, JMPC(halfPairingBN254_Px_too_big) @@ -63,16 +72,18 @@ halfPairingBN254: $ :LT, JMPC(halfPairingBN254_Qy1_too_big) $ => B :MLOAD(halfPairingBN254_Q_y2) $ :LT, JMPC(halfPairingBN254_Qy2_too_big) + ; [steps: 14, bin: 6, arith: 0] - ; Is P = O? + ; Is P = 𝒪? 0n => B $ => A :MLOAD(halfPairingBN254_P_x) $ :EQ, JMPNC(__halfPairingBN254_P_continue) $ => A :MLOAD(halfPairingBN254_P_y) $ :EQ, JMPC(halfPairingBN254_P_is_zero) __halfPairingBN254_P_continue: + ; [steps: 19, bin: 8, arith: 0] - ; Is Q = O? + ; Is Q = 𝒪? $ => A :MLOAD(halfPairingBN254_Q_x1) $ :EQ, JMPNC(__halfPairingBN254_Q_continue1) $ => A :MLOAD(halfPairingBN254_Q_x2) @@ -82,11 +93,14 @@ halfPairingBN254: $ => A :MLOAD(halfPairingBN254_Q_y2) $ :EQ, JMPC(halfPairingBN254_Q_is_zero) __halfPairingBN254_Q_continue1: + :JMP(halfPairingBN254_P_subgroup_check) + ; [steps: 28, bin: 12, arith: 0] - :JMP(halfPairingBN254_P_subgroup_check) - +; Begin of branching halfPairingBN254_P_is_zero: - ; Is Q = O? + ; before (w.c.) -> [steps: 19, bin: 8, arith: 0] + + ; Is Q = 𝒪? $ => A :MLOAD(halfPairingBN254_Q_x1) $ :EQ, JMPNC(__halfPairingBN254_Q_continue2) $ => A :MLOAD(halfPairingBN254_Q_x2) @@ -96,34 +110,39 @@ halfPairingBN254_P_is_zero: $ => A :MLOAD(halfPairingBN254_Q_y2) $ :EQ, JMPC(halfPairingBN254_P_and_Q_are_zero) __halfPairingBN254_Q_continue2: + ; [steps: 27, bin: 12, arith: 0] - ; Check that Q is in G2 + ; Check that Q ∈ G2 ; Q in G2 iff Q in E' and psi(Q) == [6x²]Q as proven in Proposition 3 of 2022/352 - ; 1] Check if Q is in E'(Fp2) + ; 1] Check if Q ∈ E'(Fp2) ; Q in E' iff (Q.y1 + Q.y2·u)² == (Q.x1 + Q.x2·u)³ + 3/(9+u) ; 1.1] Compute LHS and RHS $ => A :MLOAD(halfPairingBN254_Q_x1) $ => B :MLOAD(halfPairingBN254_Q_x2), CALL(squareFp2BN254) ; E + C·u = (Q.x1 + Q.x2·u)² + ; [steps: 34, bin: 12, arith: 1] E => A C => B $ => C :MLOAD(halfPairingBN254_Q_x1) $ => D :MLOAD(halfPairingBN254_Q_x2), CALL(mulFp2BN254) ; E + C·u = (Q.x1 + Q.x2·u)³ + ; [steps: 41, bin: 12, arith: 2] E => A C => B %BN254_ETWISTED_B_X => C %BN254_ETWISTED_B_Y => D :CALL(addFp2BN254) ; E + C·u = (Q.x1 + Q.x2·u)³ + 3/(9+u) - E :MSTORE(halfPairingBN254_Q_RHS_x) - C :MSTORE(halfPairingBN254_Q_RHS_y) + E :MSTORE(halfPairingBN254_Q_RHS_x) + C :MSTORE(halfPairingBN254_Q_RHS_y) + ; [steps: 50, bin: 12, arith: 3] $ => A :MLOAD(halfPairingBN254_Q_y1) $ => B :MLOAD(halfPairingBN254_Q_y2), CALL(squareFp2BN254) ; E + C·u = (Q.y1 + Q.y2·u)² + ; [steps: 57, bin: 12, arith: 4] ; 1.2] Check if LHS == RHS E => A @@ -133,6 +152,7 @@ halfPairingBN254_P_is_zero: C => A $ => B :MLOAD(halfPairingBN254_Q_RHS_y) $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + ; [steps: 63, bin: 14, arith: 4] ; 2] Check if psi(Q) == [6x²]Q ; 2.1] Compute psi(Q) @@ -144,6 +164,7 @@ halfPairingBN254_P_is_zero: $ => C :MLOAD(halfPairingBN254_Q_x1), CALL(mulFp2BN254) E :MSTORE(halfPairingBN254_psi_x1) C :MSTORE(halfPairingBN254_psi_x2) + ; [steps: 74, bin: 15, arith: 5] %BN254_P => A $ => B :MLOAD(halfPairingBN254_Q_y2) @@ -153,35 +174,36 @@ halfPairingBN254_P_is_zero: $ => C :MLOAD(halfPairingBN254_Q_y1), CALL(mulFp2BN254) E :MSTORE(halfPairingBN254_psi_y1) C :MSTORE(halfPairingBN254_psi_y2) + ; [steps: 85, bin: 16, arith: 6] ; 2.2] Compute [6x²]Q $ => A :MLOAD(halfPairingBN254_Q_x1) $ => B :MLOAD(halfPairingBN254_Q_x2) $ => C :MLOAD(halfPairingBN254_Q_y1) $ => D :MLOAD(halfPairingBN254_Q_y2) - A :MSTORE(escalarMulBN254_P_x1) - B :MSTORE(escalarMulBN254_P_x2) - C :MSTORE(escalarMulBN254_P_y1) - D :MSTORE(escalarMulBN254_P_y2) - %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k), CALL(escalarMulBN254) - + A :MSTORE(scalarMulPointBy6X2FP2BN254_P_x1) + B :MSTORE(scalarMulPointBy6X2FP2BN254_P_x2) + C :MSTORE(scalarMulPointBy6X2FP2BN254_P_y1) + D :MSTORE(scalarMulPointBy6X2FP2BN254_P_y2), CALL(scalarMulPointBy6X2FP2BN254) + ; [steps: 20912, bin: 557, arith: 1804] ; 2.3] Check if psi(Q) == [6x²]Q $ => A :MLOAD(halfPairingBN254_psi_x1) - $ => B :MLOAD(escalarMulBN254_Q_x1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x1) $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) $ => A :MLOAD(halfPairingBN254_psi_x2) - $ => B :MLOAD(escalarMulBN254_Q_x2) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x2) $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) $ => A :MLOAD(halfPairingBN254_psi_y1) - $ => B :MLOAD(escalarMulBN254_Q_y1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y1) $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) $ => A :MLOAD(halfPairingBN254_psi_y2) - $ => B :MLOAD(escalarMulBN254_Q_y2) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y2) $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + ; [steps: 20924, bin: 561, arith: 1804] ; e(O,Q) = 1 1n :MSTORE(halfPairingBN254_f11_x) @@ -199,8 +221,12 @@ halfPairingBN254_P_is_zero: 0 => B :JMP(halfPairingBN254_end) + ; till the end -> [steps: 20939, bin: 561, arith: 1804] + halfPairingBN254_Q_is_zero: - ; Check that P is in G1 + ; before (w.c.) -> [steps: 28, bin: 12, arith: 0] + + ; Check that P ∈ G1 ; P in G1 iff (Py)² == (Px)³ + 3 (mod p) ; 1] Compute LHS and RHS $ => A,B :MLOAD(halfPairingBN254_P_x), CALL(mulFpBN254); C = (Px)² @@ -211,6 +237,7 @@ halfPairingBN254_Q_is_zero: C :MSTORE(halfPairingBN254_P_x3) ; halfPairingBN254_P_x3 = (Px)³ + 3 $ => A,B :MLOAD(halfPairingBN254_P_y), CALL(mulFpBN254); C = (Py)² + ; [steps: 78, bin: 16, arith: 8] ; 2] Check if LHS == RHS C => A @@ -233,7 +260,11 @@ halfPairingBN254_Q_is_zero: 0 => B :JMP(halfPairingBN254_end) + ; till the end -> [steps: 96, bin: 17, arith: 8] + halfPairingBN254_P_and_Q_are_zero: + ; before (w.c.) -> [steps: 27, bin: 12, arith: 0] + ; e(O,O) = 1 1n :MSTORE(halfPairingBN254_f11_x) 0n :MSTORE(halfPairingBN254_f11_y) @@ -250,8 +281,13 @@ halfPairingBN254_P_and_Q_are_zero: 0 => B :JMP(halfPairingBN254_end) + ; till the end -> [steps: 40, bin: 12, arith: 0] +; End of branching + halfPairingBN254_P_subgroup_check: - ; Check that P is in G1 + ; before (w.c.) -> [steps: 28, bin: 12, arith: 0] + + ; Check that P ∈ G1 ; P in G1 iff (Py)² == (Px)³ + 3 (mod p) ; 1] Compute LHS and RHS $ => A,B :MLOAD(halfPairingBN254_P_x), CALL(mulFpBN254); C = (Px)² @@ -262,17 +298,19 @@ halfPairingBN254_P_subgroup_check: C :MSTORE(halfPairingBN254_P_x3) ; halfPairingBN254_P_x3 = (Px)³ + 3 $ => A,B :MLOAD(halfPairingBN254_P_y), CALL(mulFpBN254); C = (Py)² + ; [steps: 78, bin: 16, arith: 8] ; 2] Check if LHS == RHS C => A $ => B :MLOAD(halfPairingBN254_P_x3) $ :EQ, JMPNC(halfPairingBN254_P_is_not_in_G1) + ; [steps: 81, bin: 17, arith: 8] halfPairingBN254_Q_subgroup_check: - ; Check that Q is in G2 + ; Check that Q ∈ G2 ; Q in G2 iff Q in E' and psi(Q) == [6x²]Q as proven in Proposition 3 of 2022/352 - ; 1] Check if Q is in E'(Fp2) + ; 1] Check if Q ∈ E'(Fp2) ; Q in E' iff (Q.y1 + Q.y2·u)² == (Q.x1 + Q.x2·u)³ + 3/(9+u) ; 1.1] Compute LHS and RHS $ => A :MLOAD(halfPairingBN254_Q_x1) @@ -331,29 +369,29 @@ halfPairingBN254_Q_subgroup_check: $ => B :MLOAD(halfPairingBN254_Q_x2) $ => C :MLOAD(halfPairingBN254_Q_y1) $ => D :MLOAD(halfPairingBN254_Q_y2) - A :MSTORE(escalarMulBN254_P_x1) - B :MSTORE(escalarMulBN254_P_x2) - C :MSTORE(escalarMulBN254_P_y1) - D :MSTORE(escalarMulBN254_P_y2) - %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k), CALL(escalarMulBN254) + A :MSTORE(scalarMulPointBy6X2FP2BN254_P_x1) + B :MSTORE(scalarMulPointBy6X2FP2BN254_P_x2) + C :MSTORE(scalarMulPointBy6X2FP2BN254_P_y1) + D :MSTORE(scalarMulPointBy6X2FP2BN254_P_y2), CALL(scalarMulPointBy6X2FP2BN254) ; 2.3] Check if psi(Q) == [6x²]Q $ => A :MLOAD(halfPairingBN254_psi_x1) - $ => B :MLOAD(escalarMulBN254_Q_x1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x1) $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) $ => A :MLOAD(halfPairingBN254_psi_x2) - $ => B :MLOAD(escalarMulBN254_Q_x2) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x2) $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) $ => A :MLOAD(halfPairingBN254_psi_y1) - $ => B :MLOAD(escalarMulBN254_Q_y1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y1) $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) $ => A :MLOAD(halfPairingBN254_psi_y2) - $ => B :MLOAD(escalarMulBN254_Q_y2) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y2) $ :EQ, JMPNC(halfPairingBN254_Q_is_not_in_G2) + ; [steps: 20978, bin: 566, arith: 1812] halfPairingBN254_Miller_loop: $ => A :MLOAD(halfPairingBN254_P_x) @@ -368,6 +406,8 @@ halfPairingBN254_Miller_loop: B :MSTORE(millerLoopBN254_Q_x2) C :MSTORE(millerLoopBN254_Q_y1) D :MSTORE(millerLoopBN254_Q_y2), CALL(millerLoopBN254) + ; [steps: 171976, bin: 966, arith: 13327] + $ => A :MLOAD(millerLoopBN254_f11_x) $ => B :MLOAD(millerLoopBN254_f11_y) A :MSTORE(halfPairingBN254_f11_x) @@ -395,6 +435,8 @@ halfPairingBN254_Miller_loop: 0 => B :JMP(halfPairingBN254_end) + ; till end -> [steps: 172003, bin: 966, arith: 13327] + ; ERRORS halfPairingBN254_Px_too_big: 1 => B :JMP(halfPairingBN254_error) @@ -425,4 +467,4 @@ halfPairingBN254_error: halfPairingBN254_end: $ => RR :MLOAD(halfPairingBN254_RR) - :RETURN \ No newline at end of file + :RETURN \ No newline at end of file diff --git a/main/pairings/millerLoopBN254.zkasm b/main/pairings/millerLoopBN254.zkasm index 2e339258..3c529c1d 100644 --- a/main/pairings/millerLoopBN254.zkasm +++ b/main/pairings/millerLoopBN254.zkasm @@ -1,12 +1,15 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: P ∈ G1\{𝒪} and Q ∈ G2\{𝒪} ;; POST: The result is in the range [0,BN254_P) because if falls back to FP12 arithmetic ;; ;; millerLoopBN254: ;; input: P ∈ G1 and Q ∈ G2 -;; output: f_{r,Q}(P) ∈ Fp12 +;; output: f_{6·x+2,Q}(P) ∈ Fp12 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; TODO: Precompute -Q + VAR GLOBAL millerLoopBN254_P_x VAR GLOBAL millerLoopBN254_P_y VAR GLOBAL millerLoopBN254_Q_x1 @@ -52,6 +55,18 @@ VAR GLOBAL millerLoopBN254_fsquare23_y VAR GLOBAL millerLoopBN254_RR +; RESOURCES: +; ------------------------------------------- +; [steps: 22, bin: 0, arith: 0] // setup +; + 65 * [steps: 1937, bin: 4, arith: 149] // doubles +; + 17 * [steps: 930, bin: 4, arith: 68] // additions +; + 8 * [steps: 934, bin: 8, arith: 68] // subtractions +; + [steps: 1777, bin: 8, arith: 130] // last iteration + last two lines +; total (w.c.): [steps: 150986 bin: 400, arith: 11515] // [22 + 65*1937 + 17*930 + 8*934 + 1777, +; 65*4 + 17*4 + 8*8 + 8, +; 65*149 + 17*68 + 8*68 + 130] +; ------------------------------------------- + millerLoopBN254: RR :MSTORE(millerLoopBN254_RR) @@ -78,13 +93,18 @@ millerLoopBN254: 0n :MSTORE(millerLoopBN254_f22_y) 0n :MSTORE(millerLoopBN254_f23_x) 0n :MSTORE(millerLoopBN254_f23_y) + ; [steps: 22, bin: 0, arith: 0] millerLoopBN254_loop: + ; block costs: + ; no_last: [steps: 1937, bin: 4, arith: 149] + ; last: [steps: 1] + RCX - 1 => RCX :JMPZ(millerLoopBN254_last_two_lines) ; 1] f = f² · line_{twist(R),twist(R)}(P) - ; f² + ; 1.1] f² $ => A :MLOAD(millerLoopBN254_f11_x) $ => B :MLOAD(millerLoopBN254_f11_y) A :MSTORE(squareFp12BN254_a11_x) @@ -109,6 +129,7 @@ millerLoopBN254_loop: $ => B :MLOAD(millerLoopBN254_f23_y) A :MSTORE(squareFp12BN254_a23_x) B :MSTORE(squareFp12BN254_a23_y), CALL(squareFp12BN254) + ; [steps: 901, bin: 0, arith: 69] $ => A :MLOAD(squareFp12BN254_c11_x) $ => B :MLOAD(squareFp12BN254_c11_y) @@ -135,7 +156,7 @@ millerLoopBN254_loop: A :MSTORE(millerLoopBN254_fsquare23_x) B :MSTORE(millerLoopBN254_fsquare23_y) - ; line_{twist(R),twist(R)}(P) + ; 1.2] line_{twist(R),twist(R)}(P) $ => A :MLOAD(millerLoopBN254_R_x1) $ => B :MLOAD(millerLoopBN254_R_x2) $ => C :MLOAD(millerLoopBN254_R_y1) @@ -148,6 +169,7 @@ millerLoopBN254_loop: $ => B :MLOAD(millerLoopBN254_P_y) A :MSTORE(lineSamePointsBN254_Q_x) B :MSTORE(lineSamePointsBN254_Q_y), CALL(lineSamePointsBN254) + ; [steps: 1037, bin: 0, arith: 82] $ => A :MLOAD(millerLoopBN254_fsquare11_x) $ => B :MLOAD(millerLoopBN254_fsquare11_y) @@ -174,7 +196,7 @@ millerLoopBN254_loop: A :MSTORE(sparseMulBFp12BN254_a23_x) B :MSTORE(sparseMulBFp12BN254_a23_y) - ; f² · line_{twist(R),twist(R)}(P) + ; 1.3] f² · line_{twist(R),twist(R)}(P) $ => A :MLOAD(lineSamePointsBN254_l11_x) $ => B :MLOAD(lineSamePointsBN254_l11_y) A :MSTORE(sparseMulBFp12BN254_b11_x) @@ -187,6 +209,7 @@ millerLoopBN254_loop: $ => B :MLOAD(lineSamePointsBN254_l22_y) A :MSTORE(sparseMulBFp12BN254_b22_x) B :MSTORE(sparseMulBFp12BN254_b22_y), CALL(sparseMulBFp12BN254) + ; [steps: 1786, bin: 0, arith: 138] $ => A :MLOAD(sparseMulBFp12BN254_c11_x) $ => B :MLOAD(sparseMulBFp12BN254_c11_y) @@ -218,19 +241,16 @@ millerLoopBN254_loop: $ => B :MLOAD(millerLoopBN254_R_x2) $ => C :MLOAD(millerLoopBN254_R_y1) $ => D :MLOAD(millerLoopBN254_R_y2) - A :MSTORE(addPointBN254_P1_x1) - A :MSTORE(addPointBN254_P2_x1) - B :MSTORE(addPointBN254_P1_x2) - B :MSTORE(addPointBN254_P2_x2) - C :MSTORE(addPointBN254_P1_y1) - C :MSTORE(addPointBN254_P2_y1) - D :MSTORE(addPointBN254_P1_y2) - D :MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) - - $ => A :MLOAD(addPointBN254_P3_x1) - $ => B :MLOAD(addPointBN254_P3_x2) - $ => C :MLOAD(addPointBN254_P3_y1) - $ => D :MLOAD(addPointBN254_P3_y2) + A :MSTORE(doublePointFP2BN254_P_x1) + B :MSTORE(doublePointFP2BN254_P_x2) + C :MSTORE(doublePointFP2BN254_P_y1) + D :MSTORE(doublePointFP2BN254_P_y2), CALL(doublePointFP2BN254) + ; [steps: 1924, bin: 4, arith: 149] + + $ => A :MLOAD(doublePointFP2BN254_Q_x1) + $ => B :MLOAD(doublePointFP2BN254_Q_x2) + $ => C :MLOAD(doublePointFP2BN254_Q_y1) + $ => D :MLOAD(doublePointFP2BN254_Q_y2) A :MSTORE(millerLoopBN254_R_x1) B :MSTORE(millerLoopBN254_R_x2) C :MSTORE(millerLoopBN254_R_y1) @@ -241,15 +261,19 @@ millerLoopBN254_loop: ; if bit = -1, then sub B :JMPN(millerLoopBN254_sub) + ; [steps: 1936, bin: 4, arith: 149] ; if bit = 0, then repeat B :JMPZ(millerLoopBN254_loop) + ; [steps: 1937, bin: 4, arith: 149] ; if bit = 1, then add millerLoopBN254_add: + ; block costs: [steps: 930, bin: 4, arith: 68] + ; 1] f = f · line_{twist(R),twist(Q)}(P) - ; line_{twist(R),twist(Q)}(P) + ; 1.1] line_{twist(R),twist(Q)}(P) $ => A :MLOAD(millerLoopBN254_R_x1) $ => B :MLOAD(millerLoopBN254_R_x2) $ => C :MLOAD(millerLoopBN254_R_y1) @@ -270,6 +294,7 @@ millerLoopBN254_add: $ => B :MLOAD(millerLoopBN254_P_y) A :MSTORE(lineDiffPointsBN254_Q_x) B :MSTORE(lineDiffPointsBN254_Q_y), CALL(lineDiffPointsBN254) + ; [steps: 80, bin: 0, arith: 7] $ => A :MLOAD(millerLoopBN254_f11_x) $ => B :MLOAD(millerLoopBN254_f11_y) @@ -296,7 +321,7 @@ millerLoopBN254_add: A :MSTORE(sparseMulAFp12BN254_a23_x) B :MSTORE(sparseMulAFp12BN254_a23_y) - ; f · line_{twist(R),twist(Q)}(P) + ; 1.2] f · line_{twist(R),twist(Q)}(P) $ => A :MLOAD(lineDiffPointsBN254_l12_x) $ => B :MLOAD(lineDiffPointsBN254_l12_y) A :MSTORE(sparseMulAFp12BN254_b12_x) @@ -309,6 +334,7 @@ millerLoopBN254_add: $ => B :MLOAD(lineDiffPointsBN254_l23_y) A :MSTORE(sparseMulAFp12BN254_b23_x) B :MSTORE(sparseMulAFp12BN254_b23_y), CALL(sparseMulAFp12BN254) + ; [steps: 780, bin: 0, arith: 58] $ => A :MLOAD(sparseMulAFp12BN254_c11_x) $ => B :MLOAD(sparseMulAFp12BN254_c11_y) @@ -340,34 +366,35 @@ millerLoopBN254_add: $ => B :MLOAD(millerLoopBN254_R_x2) $ => C :MLOAD(millerLoopBN254_R_y1) $ => D :MLOAD(millerLoopBN254_R_y2) - A :MSTORE(addPointBN254_P1_x1) - B :MSTORE(addPointBN254_P1_x2) - C :MSTORE(addPointBN254_P1_y1) - D :MSTORE(addPointBN254_P1_y2) + A :MSTORE(addPointFP2BN254_P1_x1) + B :MSTORE(addPointFP2BN254_P1_x2) + C :MSTORE(addPointFP2BN254_P1_y1) + D :MSTORE(addPointFP2BN254_P1_y2) $ => A :MLOAD(millerLoopBN254_Q_x1) $ => B :MLOAD(millerLoopBN254_Q_x2) $ => C :MLOAD(millerLoopBN254_Q_y1) $ => D :MLOAD(millerLoopBN254_Q_y2) - A :MSTORE(addPointBN254_P2_x1) - B :MSTORE(addPointBN254_P2_x2) - C :MSTORE(addPointBN254_P2_y1) - D :MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) - - $ => A :MLOAD(addPointBN254_P3_x1) - $ => B :MLOAD(addPointBN254_P3_x2) - $ => C :MLOAD(addPointBN254_P3_y1) - $ => D :MLOAD(addPointBN254_P3_y2) + A :MSTORE(addPointFP2BN254_P2_x1) + B :MSTORE(addPointFP2BN254_P2_x2) + C :MSTORE(addPointFP2BN254_P2_y1) + D :MSTORE(addPointFP2BN254_P2_y2) + 1 :MSTORE(addPointFP2BN254_diff), CALL(addPointFP2BN254) + + $ => A :MLOAD(addPointFP2BN254_P3_x1) + $ => B :MLOAD(addPointFP2BN254_P3_x2) + $ => C :MLOAD(addPointFP2BN254_P3_y1) + $ => D :MLOAD(addPointFP2BN254_P3_y2) A :MSTORE(millerLoopBN254_R_x1) B :MSTORE(millerLoopBN254_R_x2) C :MSTORE(millerLoopBN254_R_y1) - D :MSTORE(millerLoopBN254_R_y2) - - :JMP(millerLoopBN254_loop) - + D :MSTORE(millerLoopBN254_R_y2), JMP(millerLoopBN254_loop) + ; [steps: 930, bin: 4, arith: 68] millerLoopBN254_sub: + ; block costs: [steps: 934, bin: 8, arith: 68] + ; 1] f = f · line_{twist(R),twist(-Q)}(P) - ; line_{twist(R),twist(-Q)}(P) + ; 1.1] line_{twist(R),twist(-Q)}(P) $ => A :MLOAD(millerLoopBN254_R_x1) $ => B :MLOAD(millerLoopBN254_R_x2) $ => C :MLOAD(millerLoopBN254_R_y1) @@ -392,6 +419,7 @@ millerLoopBN254_sub: $ => B :MLOAD(millerLoopBN254_P_y) A :MSTORE(lineDiffPointsBN254_Q_x) B :MSTORE(lineDiffPointsBN254_Q_y), CALL(lineDiffPointsBN254) + ; [steps: 82, bin: 2, arith: 7] $ => A :MLOAD(millerLoopBN254_f11_x) $ => B :MLOAD(millerLoopBN254_f11_y) @@ -418,7 +446,7 @@ millerLoopBN254_sub: A :MSTORE(sparseMulAFp12BN254_a23_x) B :MSTORE(sparseMulAFp12BN254_a23_y) - ; ; f · line_{twist(R),twist(-Q)}(P) + ; 1.2] f · line_{twist(R),twist(-Q)}(P) $ => A :MLOAD(lineDiffPointsBN254_l12_x) $ => B :MLOAD(lineDiffPointsBN254_l12_y) A :MSTORE(sparseMulAFp12BN254_b12_x) @@ -431,6 +459,7 @@ millerLoopBN254_sub: $ => B :MLOAD(lineDiffPointsBN254_l23_y) A :MSTORE(sparseMulAFp12BN254_b23_x) B :MSTORE(sparseMulAFp12BN254_b23_y), CALL(sparseMulAFp12BN254) + ; [steps: 782, bin: 2, arith: 58] $ => A :MLOAD(sparseMulAFp12BN254_c11_x) $ => B :MLOAD(sparseMulAFp12BN254_c11_y) @@ -462,34 +491,35 @@ millerLoopBN254_sub: $ => B :MLOAD(millerLoopBN254_R_x2) $ => C :MLOAD(millerLoopBN254_R_y1) $ => D :MLOAD(millerLoopBN254_R_y2) - A :MSTORE(addPointBN254_P1_x1) - B :MSTORE(addPointBN254_P1_x2) - C :MSTORE(addPointBN254_P1_y1) - D :MSTORE(addPointBN254_P1_y2) + A :MSTORE(addPointFP2BN254_P1_x1) + B :MSTORE(addPointFP2BN254_P1_x2) + C :MSTORE(addPointFP2BN254_P1_y1) + D :MSTORE(addPointFP2BN254_P1_y2) $ => A :MLOAD(millerLoopBN254_Q_x1) $ => B :MLOAD(millerLoopBN254_Q_x2) - A :MSTORE(addPointBN254_P2_x1) - B :MSTORE(addPointBN254_P2_x2) + A :MSTORE(addPointFP2BN254_P2_x1) + B :MSTORE(addPointFP2BN254_P2_x2) %BN254_P => A $ => B :MLOAD(millerLoopBN254_Q_y1) - $ :SUB, MSTORE(addPointBN254_P2_y1) + $ :SUB, MSTORE(addPointFP2BN254_P2_y1) %BN254_P => A $ => B :MLOAD(millerLoopBN254_Q_y2) - $ :SUB, MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) + $ :SUB, MSTORE(addPointFP2BN254_P2_y2) + 1 :MSTORE(addPointFP2BN254_diff), CALL(addPointFP2BN254) - - $ => A :MLOAD(addPointBN254_P3_x1) - $ => B :MLOAD(addPointBN254_P3_x2) - $ => C :MLOAD(addPointBN254_P3_y1) - $ => D :MLOAD(addPointBN254_P3_y2) + $ => A :MLOAD(addPointFP2BN254_P3_x1) + $ => B :MLOAD(addPointFP2BN254_P3_x2) + $ => C :MLOAD(addPointFP2BN254_P3_y1) + $ => D :MLOAD(addPointFP2BN254_P3_y2) A :MSTORE(millerLoopBN254_R_x1) B :MSTORE(millerLoopBN254_R_x2) C :MSTORE(millerLoopBN254_R_y1) - D :MSTORE(millerLoopBN254_R_y2) - - :JMP(millerLoopBN254_loop) + D :MSTORE(millerLoopBN254_R_y2), JMP(millerLoopBN254_loop) + ; [steps: 934, bin: 8, arith: 68] millerLoopBN254_last_two_lines: + ; block costs till end: [steps: 1776, bin: 8, arith: 130] + ; 1] Given Q = (x,y) with x,y ∈ Fp2, compute Frobenius1(Q) = (\gamma12·x̄, \gamma13·ȳ) %BN254_P => A $ => B :MLOAD(millerLoopBN254_Q_x2) @@ -497,6 +527,7 @@ millerLoopBN254_last_two_lines: $ => A :MLOAD(millerLoopBN254_Q_x1) %FROBENIUS_GAMMA121 => C %FROBENIUS_GAMMA122 => D :CALL(mulFp2BN254) + ; [steps: 9, bin: 1, arith: 1] E :MSTORE(millerLoopBN254_Frobenius1_Q_x1) C :MSTORE(millerLoopBN254_Frobenius1_Q_x2) @@ -507,11 +538,11 @@ millerLoopBN254_last_two_lines: $ => A :MLOAD(millerLoopBN254_Q_y1) %FROBENIUS_GAMMA131 => C %FROBENIUS_GAMMA132 => D :CALL(mulFp2BN254) + ; [steps: 18, bin: 2, arith: 2] E :MSTORE(millerLoopBN254_Frobenius1_Q_y1) C :MSTORE(millerLoopBN254_Frobenius1_Q_y2) - ; 2] f = f · line_{twist(R),twist(Frobenius1(Q))}(P) ; line_{twist(R),twist(Frobenius1(Q))}(P) $ => A :MLOAD(millerLoopBN254_R_x1) @@ -535,6 +566,7 @@ millerLoopBN254_last_two_lines: $ => B :MLOAD(millerLoopBN254_P_y) A :MSTORE(lineDiffPointsBN254_Q_x) B :MSTORE(lineDiffPointsBN254_Q_y), CALL(lineDiffPointsBN254) + ; [steps: 100, bin: 2, arith: 9] $ => A :MLOAD(millerLoopBN254_f11_x) $ => B :MLOAD(millerLoopBN254_f11_y) @@ -574,6 +606,7 @@ millerLoopBN254_last_two_lines: $ => B :MLOAD(lineDiffPointsBN254_l23_y) A :MSTORE(sparseMulAFp12BN254_b23_x) B :MSTORE(sparseMulAFp12BN254_b23_y), CALL(sparseMulAFp12BN254) + ; [steps: 800, bin: 2, arith: 60] $ => A :MLOAD(sparseMulAFp12BN254_c11_x) $ => B :MLOAD(sparseMulAFp12BN254_c11_y) @@ -605,23 +638,25 @@ millerLoopBN254_last_two_lines: $ => B :MLOAD(millerLoopBN254_R_x2) $ => C :MLOAD(millerLoopBN254_R_y1) $ => D :MLOAD(millerLoopBN254_R_y2) - A :MSTORE(addPointBN254_P1_x1) - B :MSTORE(addPointBN254_P1_x2) - C :MSTORE(addPointBN254_P1_y1) - D :MSTORE(addPointBN254_P1_y2) + A :MSTORE(addPointFP2BN254_P1_x1) + B :MSTORE(addPointFP2BN254_P1_x2) + C :MSTORE(addPointFP2BN254_P1_y1) + D :MSTORE(addPointFP2BN254_P1_y2) $ => A :MLOAD(millerLoopBN254_Frobenius1_Q_x1) $ => B :MLOAD(millerLoopBN254_Frobenius1_Q_x2) $ => C :MLOAD(millerLoopBN254_Frobenius1_Q_y1) $ => D :MLOAD(millerLoopBN254_Frobenius1_Q_y2) - A :MSTORE(addPointBN254_P2_x1) - B :MSTORE(addPointBN254_P2_x2) - C :MSTORE(addPointBN254_P2_y1) - D :MSTORE(addPointBN254_P2_y2), CALL(addPointBN254) - - $ => A :MLOAD(addPointBN254_P3_x1) - $ => B :MLOAD(addPointBN254_P3_x2) - $ => C :MLOAD(addPointBN254_P3_y1) - $ => D :MLOAD(addPointBN254_P3_y2) + A :MSTORE(addPointFP2BN254_P2_x1) + B :MSTORE(addPointFP2BN254_P2_x2) + C :MSTORE(addPointFP2BN254_P2_y1) + D :MSTORE(addPointFP2BN254_P2_y2) + 1 :MSTORE(addPointFP2BN254_diff), CALL(addPointFP2BN254) + ; [steps: 942, bin: 6, arith: 70] + + $ => A :MLOAD(addPointFP2BN254_P3_x1) + $ => B :MLOAD(addPointFP2BN254_P3_x2) + $ => C :MLOAD(addPointFP2BN254_P3_y1) + $ => D :MLOAD(addPointFP2BN254_P3_y2) A :MSTORE(millerLoopBN254_R_x1) B :MSTORE(millerLoopBN254_R_x2) C :MSTORE(millerLoopBN254_R_y1) @@ -635,17 +670,18 @@ millerLoopBN254_last_two_lines: $ => A :MLOAD(millerLoopBN254_Frobenius1_Q_x1) %FROBENIUS_GAMMA121 => C %FROBENIUS_GAMMA122 => D :CALL(mulFp2BN254) + ; [steps: 959, bin: 7, arith: 71] E :MSTORE(millerLoopBN254_nFrobenius2_Q_x1) C :MSTORE(millerLoopBN254_nFrobenius2_Q_x2) - %BN254_P => A $ => B :MLOAD(millerLoopBN254_Frobenius1_Q_y2) $ => B :SUB $ => A :MLOAD(millerLoopBN254_Frobenius1_Q_y1) %FROBENIUS_GAMMA131_NEGATED => C %FROBENIUS_GAMMA132_NEGATED => D :CALL(mulFp2BN254) + ; [steps: 970, bin: 8, arith: 72] ; 5] f = f · line_{twist(R),twist(-Frobenius2(Q))}(P) @@ -671,6 +707,7 @@ millerLoopBN254_last_two_lines: $ => B :MLOAD(millerLoopBN254_P_y) A :MSTORE(lineDiffPointsBN254_Q_x) B :MSTORE(lineDiffPointsBN254_Q_y), CALL(lineDiffPointsBN254) + ; [steps: 1050, bin: 8, arith: 79] $ => A :MLOAD(millerLoopBN254_f11_x) $ => B :MLOAD(millerLoopBN254_f11_y) @@ -710,6 +747,7 @@ millerLoopBN254_last_two_lines: $ => B :MLOAD(lineDiffPointsBN254_l23_y) A :MSTORE(sparseMulAFp12BN254_b23_x) B :MSTORE(sparseMulAFp12BN254_b23_y), CALL(sparseMulAFp12BN254) + ; [steps: 1750, bin: 8, arith: 130] $ => A :MLOAD(sparseMulAFp12BN254_c11_x) $ => B :MLOAD(sparseMulAFp12BN254_c11_y) @@ -736,6 +774,8 @@ millerLoopBN254_last_two_lines: A :MSTORE(millerLoopBN254_f23_x) B :MSTORE(millerLoopBN254_f23_y) + ; till end -> [steps: 1776, bin: 8, arith: 130] + millerLoopBN254_end: $ => RR :MLOAD(millerLoopBN254_RR) :RETURN \ No newline at end of file diff --git a/main/pairings/pairingBN254.zkasm b/main/pairings/pairingBN254.zkasm index 4ab37b6f..955a4ec7 100644 --- a/main/pairings/pairingBN254.zkasm +++ b/main/pairings/pairingBN254.zkasm @@ -1,7 +1,7 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Optimal Ate Pairing e: G1 x G2 -> GT over the BN254 curve -;; where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and GT = mu_r (the r-th roots of unity over Fp12* +;; where G1 = E(Fp)[r] = E(Fp), G2 = E'(Fp2)[r] and GT = μ_r (the r-th roots of unity over Fp12* ;; the involved curves are E/Fp: y² = x³ + 3 and E'/Fp2: y² = x³ + 3/(9+u) ;; pairingBN254: ;; input: P ∈ G1 and Q ∈ G2 @@ -50,6 +50,14 @@ VAR GLOBAL pairingBN254_psi_y2 ; 7 - P is not in G1 ; 8 - Q is not in G2 +; RESOURCES (not considering error paths): +; ------------------------------------------- +; PATH 1 P == 𝒪 and Q == 𝒪: [steps: 40, bin: 12, arith: 0] +; PATH 2 P == 𝒪 and Q != 𝒪: [steps: 20939, bin: 561, arith: 1804] +; PATH 3 P != 𝒪 and Q == 𝒪: [steps: 96, bin: 17, arith: 8] +; PATH 4 P,Q != 𝒪: [steps: 342758, bin: 1452, arith: 28738] <--- w.c. +; ------------------------------------------- + pairingBN254: RR :MSTORE(pairingBN254_RR) @@ -66,16 +74,18 @@ pairingBN254: $ :LT, JMPC(pairingBN254_Qy1_too_big) $ => B :MLOAD(pairingBN254_Q_y2) $ :LT, JMPC(pairingBN254_Qy2_too_big) + ; [steps: 14, bin: 6, arith: 0] - ; Is P = O? + ; Is P = 𝒪? 0n => B $ => A :MLOAD(pairingBN254_P_x) $ :EQ, JMPNC(__pairingBN254_P_continue) $ => A :MLOAD(pairingBN254_P_y) $ :EQ, JMPC(pairingBN254_P_is_zero) __pairingBN254_P_continue: + ; [steps: 19, bin: 8, arith: 0] - ; Is Q = O? + ; Is Q = 𝒪? $ => A :MLOAD(pairingBN254_Q_x1) $ :EQ, JMPNC(__pairingBN254_Q_continue1) $ => A :MLOAD(pairingBN254_Q_x2) @@ -85,12 +95,14 @@ pairingBN254: $ => A :MLOAD(pairingBN254_Q_y2) $ :EQ, JMPC(pairingBN254_Q_is_zero) __pairingBN254_Q_continue1: + :JMP(pairingBN254_P_subgroup_check) + ; [steps: 28, bin: 12, arith: 0] - :JMP(pairingBN254_P_subgroup_check) - - +; Begin of branching pairingBN254_P_is_zero: - ; Is Q = O? + ; before (w.c.) -> [steps: 19, bin: 8, arith: 0] + + ; Is Q = 𝒪? $ => A :MLOAD(pairingBN254_Q_x1) $ :EQ, JMPNC(__pairingBN254_Q_continue2) $ => A :MLOAD(pairingBN254_Q_x2) @@ -100,22 +112,25 @@ pairingBN254_P_is_zero: $ => A :MLOAD(pairingBN254_Q_y2) $ :EQ, JMPC(pairingBN254_P_and_Q_are_zero) __pairingBN254_Q_continue2: + ; [steps: 27, bin: 12, arith: 0] - ; Check that Q is in G2 + ; Check that Q ∈ G2 ; Q in G2 iff Q in E' and psi(Q) == [6x²]Q as proven in Proposition 3 of 2022/352 - ; 1] Check if Q is in E'(Fp2) + ; 1] Check if Q ∈ E'(Fp2) ; Q in E' iff (Q.y1 + Q.y2·u)² == (Q.x1 + Q.x2·u)³ + 3/(9+u) ; 1.1] Compute LHS and RHS $ => A :MLOAD(pairingBN254_Q_x1) $ => B :MLOAD(pairingBN254_Q_x2), CALL(squareFp2BN254) ; E + C·u = (Q.x1 + Q.x2·u)² + ; [steps: 34, bin: 12, arith: 1] E => A C => B $ => C :MLOAD(pairingBN254_Q_x1) $ => D :MLOAD(pairingBN254_Q_x2), CALL(mulFp2BN254) ; E + C·u = (Q.x1 + Q.x2·u)³ + ; [steps: 41, bin: 12, arith: 2] E => A C => B @@ -124,10 +139,12 @@ pairingBN254_P_is_zero: ; E + C·u = (Q.x1 + Q.x2·u)³ + 3/(9+u) E :MSTORE(pairingBN254_Q_RHS_x) C :MSTORE(pairingBN254_Q_RHS_y) + ; [steps: 50, bin: 12, arith: 3] $ => A :MLOAD(pairingBN254_Q_y1) $ => B :MLOAD(pairingBN254_Q_y2), CALL(squareFp2BN254) ; E + C·u = (Q.y1 + Q.y2·u)² + ; [steps: 57, bin: 12, arith: 4] ; 1.2] Check if LHS == RHS E => A @@ -137,6 +154,7 @@ pairingBN254_P_is_zero: C => A $ => B :MLOAD(pairingBN254_Q_RHS_y) $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + ; [steps: 63, bin: 14, arith: 4] ; 2] Check if psi(Q) == [6x²]Q ; 2.1] Compute psi(Q) @@ -148,6 +166,7 @@ pairingBN254_P_is_zero: $ => C :MLOAD(pairingBN254_Q_x1), CALL(mulFp2BN254) E :MSTORE(pairingBN254_psi_x1) C :MSTORE(pairingBN254_psi_x2) + ; [steps: 74, bin: 15, arith: 5] %BN254_P => A $ => B :MLOAD(pairingBN254_Q_y2) @@ -157,35 +176,36 @@ pairingBN254_P_is_zero: $ => C :MLOAD(pairingBN254_Q_y1), CALL(mulFp2BN254) E :MSTORE(pairingBN254_psi_y1) C :MSTORE(pairingBN254_psi_y2) + ; [steps: 85, bin: 16, arith: 6] ; 2.2] Compute [6x²]Q $ => A :MLOAD(pairingBN254_Q_x1) $ => B :MLOAD(pairingBN254_Q_x2) $ => C :MLOAD(pairingBN254_Q_y1) $ => D :MLOAD(pairingBN254_Q_y2) - A :MSTORE(escalarMulBN254_P_x1) - B :MSTORE(escalarMulBN254_P_x2) - C :MSTORE(escalarMulBN254_P_y1) - D :MSTORE(escalarMulBN254_P_y2) - %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k), CALL(escalarMulBN254) - + A :MSTORE(scalarMulPointBy6X2FP2BN254_P_x1) + B :MSTORE(scalarMulPointBy6X2FP2BN254_P_x2) + C :MSTORE(scalarMulPointBy6X2FP2BN254_P_y1) + D :MSTORE(scalarMulPointBy6X2FP2BN254_P_y2), CALL(scalarMulPointBy6X2FP2BN254) + ; [steps: 20912, bin: 557, arith: 1804] ; 2.3] Check if psi(Q) == [6x²]Q $ => A :MLOAD(pairingBN254_psi_x1) - $ => B :MLOAD(escalarMulBN254_Q_x1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x1) $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) $ => A :MLOAD(pairingBN254_psi_x2) - $ => B :MLOAD(escalarMulBN254_Q_x2) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x2) $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) $ => A :MLOAD(pairingBN254_psi_y1) - $ => B :MLOAD(escalarMulBN254_Q_y1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y1) $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) $ => A :MLOAD(pairingBN254_psi_y2) - $ => B :MLOAD(escalarMulBN254_Q_y2) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y2) $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + ; [steps: 20924, bin: 561, arith: 1804] ; e(O,Q) = 1 1n :MSTORE(pairingBN254_f11_x) @@ -203,8 +223,12 @@ pairingBN254_P_is_zero: 0 => B :JMP(pairingBN254_end) + ; till the end -> [steps: 20939, bin: 561, arith: 1804] + pairingBN254_Q_is_zero: - ; Check that P is in G1 + ; before (w.c.) -> [steps: 28, bin: 12, arith: 0] + + ; Check that P ∈ G1 ; P in G1 iff (Py)² == (Px)³ + 3 (mod p) ; 1] Compute LHS and RHS $ => A,B :MLOAD(pairingBN254_P_x), CALL(mulFpBN254); C = (Px)² @@ -215,6 +239,7 @@ pairingBN254_Q_is_zero: C :MSTORE(pairingBN254_P_x3) ; pairingBN254_P_x3 = (Px)³ + 3 $ => A,B :MLOAD(pairingBN254_P_y), CALL(mulFpBN254); C = (Py)² + ; [steps: 78, bin: 16, arith: 8] ; 2] Check if LHS == RHS C => A @@ -237,7 +262,11 @@ pairingBN254_Q_is_zero: 0 => B :JMP(pairingBN254_end) + ; till the end -> [steps: 96, bin: 17, arith: 8] + pairingBN254_P_and_Q_are_zero: + ; before (w.c.) -> [steps: 27, bin: 12, arith: 0] + ; e(O,O) = 1 1n :MSTORE(pairingBN254_f11_x) 0n :MSTORE(pairingBN254_f11_y) @@ -252,8 +281,15 @@ pairingBN254_P_and_Q_are_zero: 0n :MSTORE(pairingBN254_f23_x) 0n :MSTORE(pairingBN254_f23_y) + 0 => B :JMP(pairingBN254_end) + + ; till the end -> [steps: 40, bin: 12, arith: 0] +; End of branching + pairingBN254_P_subgroup_check: - ; Check that P is in G1 + ; before (w.c.) -> [steps: 28, bin: 12, arith: 0] + + ; Check that P ∈ G1 ; P in G1 iff (Py)² == (Px)³ + 3 (mod p) ; 1] Compute LHS and RHS $ => A,B :MLOAD(pairingBN254_P_x), CALL(mulFpBN254); C = (Px)² @@ -264,17 +300,19 @@ pairingBN254_P_subgroup_check: C :MSTORE(pairingBN254_P_x3) ; pairingBN254_P_x3 = (Px)³ + 3 $ => A,B :MLOAD(pairingBN254_P_y), CALL(mulFpBN254); C = (Py)² + ; [steps: 78, bin: 16, arith: 8] ; 2] Check if LHS == RHS C => A $ => B :MLOAD(pairingBN254_P_x3) $ :EQ, JMPNC(pairingBN254_P_is_not_in_G1) + ; [steps: 81, bin: 17, arith: 8] pairingBN254_Q_subgroup_check: - ; Check that Q is in G2 + ; Check that Q ∈ G2 ; Q in G2 iff Q in E' and psi(Q) == [6x²]Q as proven in Proposition 3 of 2022/352 - ; 1] Check if Q is in E'(Fp2) + ; 1] Check if Q ∈ E'(Fp2) ; Q in E' iff (Q.y1 + Q.y2·u)² == (Q.x1 + Q.x2·u)³ + 3/(9+u) ; 1.1] Compute LHS and RHS $ => A :MLOAD(pairingBN254_Q_x1) @@ -333,29 +371,29 @@ pairingBN254_Q_subgroup_check: $ => B :MLOAD(pairingBN254_Q_x2) $ => C :MLOAD(pairingBN254_Q_y1) $ => D :MLOAD(pairingBN254_Q_y2) - A :MSTORE(escalarMulBN254_P_x1) - B :MSTORE(escalarMulBN254_P_x2) - C :MSTORE(escalarMulBN254_P_y1) - D :MSTORE(escalarMulBN254_P_y2) - %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k), CALL(escalarMulBN254) + A :MSTORE(scalarMulPointBy6X2FP2BN254_P_x1) + B :MSTORE(scalarMulPointBy6X2FP2BN254_P_x2) + C :MSTORE(scalarMulPointBy6X2FP2BN254_P_y1) + D :MSTORE(scalarMulPointBy6X2FP2BN254_P_y2), CALL(scalarMulPointBy6X2FP2BN254) ; 2.3] Check if psi(Q) == [6x²]Q $ => A :MLOAD(pairingBN254_psi_x1) - $ => B :MLOAD(escalarMulBN254_Q_x1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x1) $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) $ => A :MLOAD(pairingBN254_psi_x2) - $ => B :MLOAD(escalarMulBN254_Q_x2) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x2) $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) $ => A :MLOAD(pairingBN254_psi_y1) - $ => B :MLOAD(escalarMulBN254_Q_y1) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y1) $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) $ => A :MLOAD(pairingBN254_psi_y2) - $ => B :MLOAD(escalarMulBN254_Q_y2) + $ => B :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y2) $ :EQ, JMPNC(pairingBN254_Q_is_not_in_G2) + ; [steps: 20978, bin: 566, arith: 1812] pairingBN254_Miller_loop: $ => A :MLOAD(pairingBN254_P_x) @@ -370,6 +408,8 @@ pairingBN254_Miller_loop: B :MSTORE(millerLoopBN254_Q_x2) C :MSTORE(millerLoopBN254_Q_y1) D :MSTORE(millerLoopBN254_Q_y2), CALL(millerLoopBN254) + ; [steps: 171976, bin: 966, arith: 13327] + $ => A :MLOAD(millerLoopBN254_f11_x) $ => B :MLOAD(millerLoopBN254_f11_y) A :MSTORE(pairingBN254_f11_x) @@ -394,7 +434,7 @@ pairingBN254_Miller_loop: $ => B :MLOAD(millerLoopBN254_f23_y) A :MSTORE(pairingBN254_f23_x) B :MSTORE(pairingBN254_f23_y) - + ; [steps: 172002, bin: 966, arith: 13327] pairingBN254_final_exponentiation: $ => A :MLOAD(pairingBN254_f11_x) @@ -421,6 +461,8 @@ pairingBN254_final_exponentiation: $ => B :MLOAD(pairingBN254_f23_y) A :MSTORE(finalExpBN254_f23_x) B :MSTORE(finalExpBN254_f23_y), CALL(finalExpBN254) + ; [steps: 342733, bin: 1452, arith: 28738] + $ => A :MLOAD(finalExpBN254_f11_x) $ => B :MLOAD(finalExpBN254_f11_y) A :MSTORE(pairingBN254_f11_x) @@ -448,6 +490,8 @@ pairingBN254_final_exponentiation: 0 => B :JMP(pairingBN254_end) + ; till the end -> [steps: 342758, bin: 1452, arith: 28738] + ; ERRORS pairingBN254_Px_too_big: 1 => B :JMP(pairingBN254_error) diff --git a/main/pairings/unused/scalarMulPointFP2BN254.zkasm b/main/pairings/unused/scalarMulPointFP2BN254.zkasm new file mode 100644 index 00000000..09f42534 --- /dev/null +++ b/main/pairings/unused/scalarMulPointFP2BN254.zkasm @@ -0,0 +1,191 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: P ∈ E'(Fp2) +;; POST: The resulting coordinates are in the range [0,BN254_P) because if falls back to addPointFP2BN254 +;; +;; +;; scalarMulPointFP2BN254: +;; in: k, P = (P.x1 + P.x2·u, P.y1 + P.y2·u) ∈ E'(Fp2), where k ∈ [0,r-1] +;; out: k·P = (Q.x1 + Q.x2·u, Q.y1 + Q.y2·u) ∈ E'(Fp2) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; scalarMulPointFP2BN254 assumes P belong to E'(Fp2), since it is checked in the pairing. +; However, it must be implemented if scalarMulPointFP2BN254 wants to be used independently. + +; Since the curve is E'/Fp2: y² = x³ + 3/(9+u), there is no issue in representing the point at infinity as (0, 0). + +VAR GLOBAL scalarMulPointFP2BN254_k +VAR GLOBAL scalarMulPointFP2BN254_P_x1 +VAR GLOBAL scalarMulPointFP2BN254_P_x2 +VAR GLOBAL scalarMulPointFP2BN254_P_y1 +VAR GLOBAL scalarMulPointFP2BN254_P_y2 +VAR GLOBAL scalarMulPointFP2BN254_Q_x1 +VAR GLOBAL scalarMulPointFP2BN254_Q_x2 +VAR GLOBAL scalarMulPointFP2BN254_Q_y1 +VAR GLOBAL scalarMulPointFP2BN254_Q_y2 + +VAR GLOBAL scalarMulPointFP2BN254_acummulator + +VAR GLOBAL scalarMulPointFP2BN254_RR + +; RESOURCES: +; ------------------------------------------- +; PATH 1 P == 𝒪: [steps: 16, bin: 4] +; PATH 2 k == 0 and P != 𝒪: [steps: 32, bin: 7, arith: 1] +; PATH 3 k > r and P != 𝒪: <--- w.c. +; [steps: 38, bin: 7, arith: 1] // setup +; + max_bin_len(k) * [steps: 120, bin: 4, arith: 11] // doubles +; + number_of_bits_1(k) * [steps: 131, bin: 4, arith: 10] // additions +; + [steps: 6, bin: 1] // last iteration + k reconstruction check +; total (w.c.): [steps: 63416 bin: 2028, arith: 5304] // [38 + 253*120 + 252*131 + 6, +; 7 + 253*4 + 252*4 + 1, +; 1 + 253*11 + 252*10] +; ------------------------------------------- + +scalarMulPointFP2BN254: + RR :MSTORE(scalarMulPointFP2BN254_RR) + + ; Is P = 𝒪? + 0n => B + $ => A :MLOAD(scalarMulPointFP2BN254_P_x1) + $ :EQ, JMPNC(__scalarMulPointFP2BN254_P_continue) + $ => A :MLOAD(scalarMulPointFP2BN254_P_x2) + $ :EQ, JMPNC(__scalarMulPointFP2BN254_P_continue) + $ => A :MLOAD(scalarMulPointFP2BN254_P_y1) + $ :EQ, JMPNC(__scalarMulPointFP2BN254_P_continue) + $ => A :MLOAD(scalarMulPointFP2BN254_P_y2) + $ :EQ, JMPC(scalarMulPointFP2BN254_P_is_zero) + __scalarMulPointFP2BN254_P_continue: + ; [steps: 10, bin: 4] + + ; Is k ∈ [0,r-1]? + $ => A :MLOAD(scalarMulPointFP2BN254_k) + %BN254_R => B + $ :LT, JMPC(__scalarMulPointFP2BN254_continue) + A => B :CALL(reduceFrBN254) + __scalarMulPointFP2BN254_continue: + 0 => B + $ :EQ, JMPC(scalarMulPointFP2BN254_k_is_zero) + A :MSTORE(scalarMulPointFP2BN254_k) + ; [steps: 26, bin: 7, arith: 1] + ; k ∈ [1,r-1] from here + + $0{receiveLen(mem.scalarMulPointFP2BN254_k)} => RCX,E ; receive the length of the binary representation of k + + ; start the acummulator with the MSB of k + 0 => A :CALL(@bitwiseReconstruction + E) + A :MSTORE(scalarMulPointFP2BN254_acummulator) + + $ => A :MLOAD(scalarMulPointFP2BN254_P_x1) + $ => B :MLOAD(scalarMulPointFP2BN254_P_x2) + $ => C :MLOAD(scalarMulPointFP2BN254_P_y1) + $ => D :MLOAD(scalarMulPointFP2BN254_P_y2) + A :MSTORE(scalarMulPointFP2BN254_Q_x1) + B :MSTORE(scalarMulPointFP2BN254_Q_x2) + C :MSTORE(scalarMulPointFP2BN254_Q_y1) + D :MSTORE(scalarMulPointFP2BN254_Q_y2), JMP(scalarMulPointFP2BN254_loop) + ; [steps: 38, bin: 7, arith: 1] + +; Begin of branching +scalarMulPointFP2BN254_P_is_zero: + ; before (w.c.) -> [steps: 10, bin: 4] + + ; Q = 𝒪 + 0n :MSTORE(scalarMulPointFP2BN254_Q_x1) + 0n :MSTORE(scalarMulPointFP2BN254_Q_x2) + 0n :MSTORE(scalarMulPointFP2BN254_Q_y1) + 0n :MSTORE(scalarMulPointFP2BN254_Q_y2), JMP(scalarMulPointFP2BN254_end) + + ; till the end -> [steps: 16, bin: 4] + +scalarMulPointFP2BN254_k_is_zero: + ; before (w.c.) -> [steps: 26, bin: 7, arith: 1] + + ; Q = 𝒪 + 0n :MSTORE(scalarMulPointFP2BN254_Q_x1) + 0n :MSTORE(scalarMulPointFP2BN254_Q_x2) + 0n :MSTORE(scalarMulPointFP2BN254_Q_y1) + 0n :MSTORE(scalarMulPointFP2BN254_Q_y2), JMP(scalarMulPointFP2BN254_end) + + ; till the end -> [steps: 32, bin: 7, arith: 1] +; End of branching + +scalarMulPointFP2BN254_loop: + ; block costs: + ; no_last: [steps: 120, bin: 4, arith: 11] + ; last: [steps: 1] + + RCX - 1 => RCX :JMPN(scalarMulPointFP2BN254_check) + + ; We always double + $ => A :MLOAD(scalarMulPointFP2BN254_Q_x1) + $ => B :MLOAD(scalarMulPointFP2BN254_Q_x2) + $ => C :MLOAD(scalarMulPointFP2BN254_Q_y1) + $ => D :MLOAD(scalarMulPointFP2BN254_Q_y2) + A :MSTORE(doublePointFP2BN254_P_x1) + B :MSTORE(doublePointFP2BN254_P_x2) + C :MSTORE(doublePointFP2BN254_P_y1) + D :MSTORE(doublePointFP2BN254_P_y2), CALL(doublePointFP2BN254) + ; Q = Q + Q + + $ => A :MLOAD(doublePointFP2BN254_Q_x1) + $ => B :MLOAD(doublePointFP2BN254_Q_x2) + $ => C :MLOAD(doublePointFP2BN254_Q_y1) + $ => D :MLOAD(doublePointFP2BN254_Q_y2) + A :MSTORE(scalarMulPointFP2BN254_Q_x1) + B :MSTORE(scalarMulPointFP2BN254_Q_x2) + C :MSTORE(scalarMulPointFP2BN254_Q_y1) + D :MSTORE(scalarMulPointFP2BN254_Q_y2) + + ; Receive the next MSB b of k. If b == 1, we should add P to Q, otherwise start the next iteration + $0{(mem.scalarMulPointFP2BN254_k) >> RCX & 0x1} :JMPZ(scalarMulPointFP2BN254_loop) + +scalarMulPointFP2BN254_add: + ; block costs: [steps: 131, bin: 4, arith: 10] + + ; We add + $ => A :MLOAD(scalarMulPointFP2BN254_Q_x1) + $ => B :MLOAD(scalarMulPointFP2BN254_Q_x2) + $ => C :MLOAD(scalarMulPointFP2BN254_Q_y1) + $ => D :MLOAD(scalarMulPointFP2BN254_Q_y2) + A :MSTORE(addPointFP2BN254_P1_x1) + B :MSTORE(addPointFP2BN254_P1_x2) + C :MSTORE(addPointFP2BN254_P1_y1) + D :MSTORE(addPointFP2BN254_P1_y2) + + $ => A :MLOAD(scalarMulPointFP2BN254_P_x1) + $ => B :MLOAD(scalarMulPointFP2BN254_P_x2) + $ => C :MLOAD(scalarMulPointFP2BN254_P_y1) + $ => D :MLOAD(scalarMulPointFP2BN254_P_y2) + A :MSTORE(addPointFP2BN254_P2_x1) + B :MSTORE(addPointFP2BN254_P2_x2) + C :MSTORE(addPointFP2BN254_P2_y1) + D :MSTORE(addPointFP2BN254_P2_y2) + 1 :MSTORE(addPointFP2BN254_diff), CALL(addPointFP2BN254) + ; Q = Q + P + + $ => A :MLOAD(addPointFP2BN254_P3_x1) + $ => B :MLOAD(addPointFP2BN254_P3_x2) + $ => C :MLOAD(addPointFP2BN254_P3_y1) + $ => D :MLOAD(addPointFP2BN254_P3_y2) + A :MSTORE(scalarMulPointFP2BN254_Q_x1) + B :MSTORE(scalarMulPointFP2BN254_Q_x2) + C :MSTORE(scalarMulPointFP2BN254_Q_y1) + D :MSTORE(scalarMulPointFP2BN254_Q_y2) + + ; We keep reconstruction the scalar k + $ => A :MLOAD(scalarMulPointFP2BN254_acummulator) + RCX => E + :CALL(@bitwiseReconstruction + E) + A :MSTORE(scalarMulPointFP2BN254_acummulator), JMP(scalarMulPointFP2BN254_loop) + + +scalarMulPointFP2BN254_check: + ; till the end -> [steps: 5, bin: 1] + $ => A :MLOAD(scalarMulPointFP2BN254_k) + $ => B :MLOAD(scalarMulPointFP2BN254_acummulator) + 1 :EQ + +scalarMulPointFP2BN254_end: + $ => RR :MLOAD(scalarMulPointFP2BN254_RR) + :RETURN \ No newline at end of file diff --git a/main/precompiled/selector.zkasm b/main/precompiled/selector.zkasm index c81a55e0..57ff5c63 100644 --- a/main/precompiled/selector.zkasm +++ b/main/precompiled/selector.zkasm @@ -7,9 +7,21 @@ INCLUDE "pre-ecPairing.zkasm" INCLUDE "pre-modexp.zkasm" INCLUDE "pre-sha2-256.zkasm" INCLUDE "../pairings/constants.zkasm" +INCLUDE "../pairings/ecPairing.zkasm" +INCLUDE "../pairings/halfPairingBN254.zkasm" +INCLUDE "../pairings/millerLoopBN254.zkasm" +INCLUDE "../tables/bitwiseReconstruction.zkasm" +INCLUDE "../pairings/loopLengthBN254.zkasm" +INCLUDE "../pairings/finalExpBN254.zkasm" INCLUDE "../pairings/BN254/ecAdd.zkasm" INCLUDE "../pairings/BN254/ecMul.zkasm" -INCLUDE "../pairings/ecPairing.zkasm" +INCLUDE "../pairings/BN254/doublePointFPBN254.zkasm" +INCLUDE "../pairings/BN254/addPointFP2BN254.zkasm" +INCLUDE "../pairings/BN254/doublePointFP2BN254.zkasm" +INCLUDE "../pairings/BN254/scalarMulPointBy6X2FP2BN254.zkasm" +INCLUDE "../pairings/BN254/sixX2.zkasm" +INCLUDE "../pairings/BN254/lineSamePointsBN254.zkasm" +INCLUDE "../pairings/BN254/lineDiffPointsBN254.zkasm" INCLUDE "../pairings/FRBN254/reduceFrBN254.zkasm" INCLUDE "../pairings/FPBN254/addFpBN254.zkasm" INCLUDE "../pairings/FPBN254/subFpBN254.zkasm" @@ -21,13 +33,13 @@ INCLUDE "../pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../pairings/FP2BN254/mulFp2BN254.zkasm" INCLUDE "../pairings/FP2BN254/squareFp2BN254.zkasm" -INCLUDE "../pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../pairings/FP2BN254/scalarMulFp2BN254.zkasm" INCLUDE "../pairings/FP2BN254/invFp2BN254.zkasm" INCLUDE "../pairings/FP4BN254/squareFp4BN254.zkasm" INCLUDE "../pairings/FP6BN254/addFp6BN254.zkasm" INCLUDE "../pairings/FP6BN254/subFp6BN254.zkasm" INCLUDE "../pairings/FP6BN254/mulFp6BN254.zkasm" -INCLUDE "../pairings/FP6BN254/escalarMulFp6BN254.zkasm" +INCLUDE "../pairings/FP6BN254/scalarMulFp6BN254.zkasm" INCLUDE "../pairings/FP6BN254/sparseMulAFp6BN254.zkasm" INCLUDE "../pairings/FP6BN254/sparseMulBFp6BN254.zkasm" INCLUDE "../pairings/FP6BN254/sparseMulCFp6BN254.zkasm" @@ -47,14 +59,6 @@ INCLUDE "../pairings/FP12BN254/CYCLOFP12BN254/decompressFp12BN254.zkasm" INCLUDE "../pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkasm" INCLUDE "../pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm" INCLUDE "../pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm" -INCLUDE "../pairings/BN254/addPointBN254.zkasm" -INCLUDE "../pairings/BN254/escalarMulBN254.zkasm" -INCLUDE "../pairings/BN254/lineSamePointsBN254.zkasm" -INCLUDE "../pairings/BN254/lineDiffPointsBN254.zkasm" -INCLUDE "../pairings/halfPairingBN254.zkasm" -INCLUDE "../pairings/millerLoopBN254.zkasm" -INCLUDE "../pairings/loopLengthBN254.zkasm" -INCLUDE "../pairings/finalExpBN254.zkasm" INCLUDE "end.zkasm" /** diff --git a/main/tables/bitwiseReconstruction.zkasm b/main/tables/bitwiseReconstruction.zkasm new file mode 100644 index 00000000..b15b545d --- /dev/null +++ b/main/tables/bitwiseReconstruction.zkasm @@ -0,0 +1,274 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: bit i of A is 0 +;; +;; bitwiseReconstruction: +;; in: A ∈ [0, 2²⁵⁶ - 1] with bit i equal to 0 +;; out: bit i of A is set to 1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Sage code +; ---------------------------------------- +; for i in range(256): +; power = 2**i +; a = f"{power:#0{66}x}" +; print("\tA + {}n => A\t\t :RETURN".format(a)) +; ---------------------------------------- + +bitwiseReconstruction: + A + 0x0000000000000000000000000000000000000000000000000000000000000001n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000002n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000004n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000008n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000010n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000020n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000040n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000080n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000100n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000200n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000400n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000000800n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000001000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000002000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000004000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000008000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000010000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000020000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000040000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000080000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000100000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000200000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000400000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000000800000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000001000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000002000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000004000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000008000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000010000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000020000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000040000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000080000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000100000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000200000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000400000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000000800000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000001000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000002000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000004000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000008000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000010000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000020000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000040000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000080000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000100000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000200000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000400000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000000800000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000001000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000002000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000004000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000008000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000010000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000020000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000040000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000080000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000100000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000200000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000400000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000000800000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000001000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000002000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000004000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000008000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000010000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000020000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000040000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000080000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000100000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000200000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000400000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000000800000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000001000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000002000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000004000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000008000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000010000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000020000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000040000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000080000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000100000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000200000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000400000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000000800000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000001000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000002000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000004000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000008000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000010000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000020000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000040000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000080000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000100000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000200000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000400000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000000800000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000001000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000002000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000004000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000008000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000010000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000020000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000040000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000080000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000100000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000200000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000400000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000000800000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000001000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000002000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000004000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000008000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000010000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000020000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000040000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000080000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000100000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000200000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000400000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000000800000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000001000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000002000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000004000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000008000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000010000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000020000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000040000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000080000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000100000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000200000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000400000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000000800000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000001000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000002000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000004000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000008000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000010000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000020000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000040000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000080000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000100000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000200000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000400000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000000800000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000001000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000002000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000004000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000008000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000010000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000020000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000040000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000080000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000100000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000200000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000400000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000000800000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000001000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000002000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000004000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000008000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000010000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000020000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000040000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000080000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000100000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000200000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000400000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000000800000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000001000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000002000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000004000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000008000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000010000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000020000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000040000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000080000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000100000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000200000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000400000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000000800000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000001000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000002000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000004000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000008000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000010000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000020000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000040000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000080000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000100000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000200000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000400000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000000800000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000001000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000002000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000004000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000008000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000010000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000020000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000040000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000080000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000100000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000200000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000400000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000000800000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000001000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000002000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000004000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000008000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000010000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000020000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000040000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000080000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000100000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000200000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000400000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000000800000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000001000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000002000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000004000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000008000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000010000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000020000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000040000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000080000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000100000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000200000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000400000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000000800000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000001000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000002000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000004000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000008000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000010000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000020000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000040000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000080000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000100000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000200000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000400000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0000800000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0001000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0002000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0004000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0008000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0010000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0020000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0040000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0080000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0100000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0200000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0400000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x0800000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x1000000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x2000000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x4000000000000000000000000000000000000000000000000000000000000000n => A :RETURN + A + 0x8000000000000000000000000000000000000000000000000000000000000000n => A :RETURN \ No newline at end of file diff --git a/test/testCycloFp12ArithBN254.zkasm b/test/testCycloFp12ArithBN254.zkasm index 63872930..1e171955 100644 --- a/test/testCycloFp12ArithBN254.zkasm +++ b/test/testCycloFp12ArithBN254.zkasm @@ -331,87 +331,8 @@ start: 14005155248465440637906492674345786073382135452928153479559868247493919227266n :MLOAD(expCycloFp12BN254_c23_x) 20231158774990444129983338146063043702239109464764996510430767078543929636660n :MLOAD(expCycloFp12BN254_c23_y) - ; 5] Exponentiation by x - 0n :MSTORE(expByXCycloFp12BN254_a11_x) - 0n :MSTORE(expByXCycloFp12BN254_a11_y) - 0n :MSTORE(expByXCycloFp12BN254_a12_x) - 0n :MSTORE(expByXCycloFp12BN254_a12_y) - 0n :MSTORE(expByXCycloFp12BN254_a13_x) - 0n :MSTORE(expByXCycloFp12BN254_a13_y) - 0n :MSTORE(expByXCycloFp12BN254_a21_x) - 0n :MSTORE(expByXCycloFp12BN254_a21_y) - 0n :MSTORE(expByXCycloFp12BN254_a22_x) - 0n :MSTORE(expByXCycloFp12BN254_a22_y) - 0n :MSTORE(expByXCycloFp12BN254_a23_x) - 0n :MSTORE(expByXCycloFp12BN254_a23_y) - :CALL(expByXCycloFp12BN254) - 0n :MLOAD(expByXCycloFp12BN254_c11_x) - 0n :MLOAD(expByXCycloFp12BN254_c11_y) - 0n :MLOAD(expByXCycloFp12BN254_c12_x) - 0n :MLOAD(expByXCycloFp12BN254_c12_y) - 0n :MLOAD(expByXCycloFp12BN254_c13_x) - 0n :MLOAD(expByXCycloFp12BN254_c13_y) - 0n :MLOAD(expByXCycloFp12BN254_c21_x) - 0n :MLOAD(expByXCycloFp12BN254_c21_y) - 0n :MLOAD(expByXCycloFp12BN254_c22_x) - 0n :MLOAD(expByXCycloFp12BN254_c22_y) - 0n :MLOAD(expByXCycloFp12BN254_c23_x) - 0n :MLOAD(expByXCycloFp12BN254_c23_y) - - 1n :MSTORE(expByXCycloFp12BN254_a11_x) - 0n :MSTORE(expByXCycloFp12BN254_a11_y) - 0n :MSTORE(expByXCycloFp12BN254_a12_x) - 0n :MSTORE(expByXCycloFp12BN254_a12_y) - 0n :MSTORE(expByXCycloFp12BN254_a13_x) - 0n :MSTORE(expByXCycloFp12BN254_a13_y) - 0n :MSTORE(expByXCycloFp12BN254_a21_x) - 0n :MSTORE(expByXCycloFp12BN254_a21_y) - 0n :MSTORE(expByXCycloFp12BN254_a22_x) - 0n :MSTORE(expByXCycloFp12BN254_a22_y) - 0n :MSTORE(expByXCycloFp12BN254_a23_x) - 0n :MSTORE(expByXCycloFp12BN254_a23_y) - :CALL(expByXCycloFp12BN254) - 1n :MLOAD(expByXCycloFp12BN254_c11_x) - 0n :MLOAD(expByXCycloFp12BN254_c11_y) - 0n :MLOAD(expByXCycloFp12BN254_c12_x) - 0n :MLOAD(expByXCycloFp12BN254_c12_y) - 0n :MLOAD(expByXCycloFp12BN254_c13_x) - 0n :MLOAD(expByXCycloFp12BN254_c13_y) - 0n :MLOAD(expByXCycloFp12BN254_c21_x) - 0n :MLOAD(expByXCycloFp12BN254_c21_y) - 0n :MLOAD(expByXCycloFp12BN254_c22_x) - 0n :MLOAD(expByXCycloFp12BN254_c22_y) - 0n :MLOAD(expByXCycloFp12BN254_c23_x) - 0n :MLOAD(expByXCycloFp12BN254_c23_y) - - 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expByXCycloFp12BN254_a11_x) - 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(expByXCycloFp12BN254_a11_y) - 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(expByXCycloFp12BN254_a12_x) - 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(expByXCycloFp12BN254_a12_y) - 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(expByXCycloFp12BN254_a13_x) - 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(expByXCycloFp12BN254_a13_y) - 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(expByXCycloFp12BN254_a21_x) - 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(expByXCycloFp12BN254_a21_y) - 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(expByXCycloFp12BN254_a22_x) - 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(expByXCycloFp12BN254_a22_y) - 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(expByXCycloFp12BN254_a23_x) - 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(expByXCycloFp12BN254_a23_y) - :CALL(expByXCycloFp12BN254) - 8622123276929149313920900390800567957350463902034345693686819104151152922572n :MLOAD(expByXCycloFp12BN254_c11_x) - 8670626622362378075940101766943937502063808822022259182641087586661549444087n :MLOAD(expByXCycloFp12BN254_c11_y) - 17677799802795013101301829823610804881266875691488004414652375004895811278559n :MLOAD(expByXCycloFp12BN254_c12_x) - 8272841324134833464040573295664197017808088708485767794513847108589815911499n :MLOAD(expByXCycloFp12BN254_c12_y) - 9190911511691766859289188288177517604435774623843629661940012957026870785904n :MLOAD(expByXCycloFp12BN254_c13_x) - 18364099160954539591912436449937202384011431251285107932512938026494677069261n :MLOAD(expByXCycloFp12BN254_c13_y) - 19407988223605275774004312333801897121509906148567729782984282773586873391901n :MLOAD(expByXCycloFp12BN254_c21_x) - 15711652497826967457911333154250406880785527028595026050702704710166760791736n :MLOAD(expByXCycloFp12BN254_c21_y) - 16450402722786864781692733695027245893014266492802042336563706983420459072544n :MLOAD(expByXCycloFp12BN254_c22_x) - 11669304897933026204553226847848522415487901344170781144466032622467776938641n :MLOAD(expByXCycloFp12BN254_c22_y) - 14005155248465440637906492674345786073382135452928153479559868247493919227266n :MLOAD(expByXCycloFp12BN254_c23_x) - 20231158774990444129983338146063043702239109464764996510430767078543929636660n :MLOAD(expByXCycloFp12BN254_c23_y) - - ; 6] Exponentiation by x using the compression/decompression technique + ; 5] Exponentiation by x using the compression/decompression technique 0n :MSTORE(expByXCompCycloFp12BN254_a0_x) 0n :MSTORE(expByXCompCycloFp12BN254_a0_y) 0n :MSTORE(expByXCompCycloFp12BN254_a2_x) @@ -490,6 +411,88 @@ start: 14005155248465440637906492674345786073382135452928153479559868247493919227266n :MLOAD(expByXCompCycloFp12BN254_c5_x) 20231158774990444129983338146063043702239109464764996510430767078543929636660n :MLOAD(expByXCompCycloFp12BN254_c5_y) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; UNUSED + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; 6] Exponentiation by x + 0n :MSTORE(expByXCycloFp12BN254_a11_x) + 0n :MSTORE(expByXCycloFp12BN254_a11_y) + 0n :MSTORE(expByXCycloFp12BN254_a12_x) + 0n :MSTORE(expByXCycloFp12BN254_a12_y) + 0n :MSTORE(expByXCycloFp12BN254_a13_x) + 0n :MSTORE(expByXCycloFp12BN254_a13_y) + 0n :MSTORE(expByXCycloFp12BN254_a21_x) + 0n :MSTORE(expByXCycloFp12BN254_a21_y) + 0n :MSTORE(expByXCycloFp12BN254_a22_x) + 0n :MSTORE(expByXCycloFp12BN254_a22_y) + 0n :MSTORE(expByXCycloFp12BN254_a23_x) + 0n :MSTORE(expByXCycloFp12BN254_a23_y) + :CALL(expByXCycloFp12BN254) + 0n :MLOAD(expByXCycloFp12BN254_c11_x) + 0n :MLOAD(expByXCycloFp12BN254_c11_y) + 0n :MLOAD(expByXCycloFp12BN254_c12_x) + 0n :MLOAD(expByXCycloFp12BN254_c12_y) + 0n :MLOAD(expByXCycloFp12BN254_c13_x) + 0n :MLOAD(expByXCycloFp12BN254_c13_y) + 0n :MLOAD(expByXCycloFp12BN254_c21_x) + 0n :MLOAD(expByXCycloFp12BN254_c21_y) + 0n :MLOAD(expByXCycloFp12BN254_c22_x) + 0n :MLOAD(expByXCycloFp12BN254_c22_y) + 0n :MLOAD(expByXCycloFp12BN254_c23_x) + 0n :MLOAD(expByXCycloFp12BN254_c23_y) + + 1n :MSTORE(expByXCycloFp12BN254_a11_x) + 0n :MSTORE(expByXCycloFp12BN254_a11_y) + 0n :MSTORE(expByXCycloFp12BN254_a12_x) + 0n :MSTORE(expByXCycloFp12BN254_a12_y) + 0n :MSTORE(expByXCycloFp12BN254_a13_x) + 0n :MSTORE(expByXCycloFp12BN254_a13_y) + 0n :MSTORE(expByXCycloFp12BN254_a21_x) + 0n :MSTORE(expByXCycloFp12BN254_a21_y) + 0n :MSTORE(expByXCycloFp12BN254_a22_x) + 0n :MSTORE(expByXCycloFp12BN254_a22_y) + 0n :MSTORE(expByXCycloFp12BN254_a23_x) + 0n :MSTORE(expByXCycloFp12BN254_a23_y) + :CALL(expByXCycloFp12BN254) + 1n :MLOAD(expByXCycloFp12BN254_c11_x) + 0n :MLOAD(expByXCycloFp12BN254_c11_y) + 0n :MLOAD(expByXCycloFp12BN254_c12_x) + 0n :MLOAD(expByXCycloFp12BN254_c12_y) + 0n :MLOAD(expByXCycloFp12BN254_c13_x) + 0n :MLOAD(expByXCycloFp12BN254_c13_y) + 0n :MLOAD(expByXCycloFp12BN254_c21_x) + 0n :MLOAD(expByXCycloFp12BN254_c21_y) + 0n :MLOAD(expByXCycloFp12BN254_c22_x) + 0n :MLOAD(expByXCycloFp12BN254_c22_y) + 0n :MLOAD(expByXCycloFp12BN254_c23_x) + 0n :MLOAD(expByXCycloFp12BN254_c23_y) + + 12879671296228341798957541889042068293248913689212425431224938470232546313254n :MSTORE(expByXCycloFp12BN254_a11_x) + 3326450555199805883965490851796414254830144151329718176108864533289444035270n :MSTORE(expByXCycloFp12BN254_a11_y) + 20034916004680903865371475524544157810838259782601065778963371780592670397755n :MSTORE(expByXCycloFp12BN254_a12_x) + 18196221800554323016660057972017335112712278872243164622794778048181747904770n :MSTORE(expByXCycloFp12BN254_a12_y) + 2650685350723162073065693030364953757603657135232283880472468071129041178893n :MSTORE(expByXCycloFp12BN254_a13_x) + 1415534485628002925645978830263295545820817030311522411523977773123510463790n :MSTORE(expByXCycloFp12BN254_a13_y) + 11706129207700151979042100288958216850158405562525260961392090752318820540155n :MSTORE(expByXCycloFp12BN254_a21_x) + 13581688218243497693010389261307054804658398598414171976249347555990073884710n :MSTORE(expByXCycloFp12BN254_a21_y) + 865661210072615391091663782916883487315505694294592934212781713437127182959n :MSTORE(expByXCycloFp12BN254_a22_x) + 5364456672142552956341240304849409513108281743490635067211876654163672173225n :MSTORE(expByXCycloFp12BN254_a22_y) + 11182696274116283149832659131689911508224992839995672842130064887471806829782n :MSTORE(expByXCycloFp12BN254_a23_x) + 13862086431460254638576437312497952755826436162922426416336796129991391475329n :MSTORE(expByXCycloFp12BN254_a23_y) + :CALL(expByXCycloFp12BN254) + 8622123276929149313920900390800567957350463902034345693686819104151152922572n :MLOAD(expByXCycloFp12BN254_c11_x) + 8670626622362378075940101766943937502063808822022259182641087586661549444087n :MLOAD(expByXCycloFp12BN254_c11_y) + 17677799802795013101301829823610804881266875691488004414652375004895811278559n :MLOAD(expByXCycloFp12BN254_c12_x) + 8272841324134833464040573295664197017808088708485767794513847108589815911499n :MLOAD(expByXCycloFp12BN254_c12_y) + 9190911511691766859289188288177517604435774623843629661940012957026870785904n :MLOAD(expByXCycloFp12BN254_c13_x) + 18364099160954539591912436449937202384011431251285107932512938026494677069261n :MLOAD(expByXCycloFp12BN254_c13_y) + 19407988223605275774004312333801897121509906148567729782984282773586873391901n :MLOAD(expByXCycloFp12BN254_c21_x) + 15711652497826967457911333154250406880785527028595026050702704710166760791736n :MLOAD(expByXCycloFp12BN254_c21_y) + 16450402722786864781692733695027245893014266492802042336563706983420459072544n :MLOAD(expByXCycloFp12BN254_c22_x) + 11669304897933026204553226847848522415487901344170781144466032622467776938641n :MLOAD(expByXCycloFp12BN254_c22_y) + 14005155248465440637906492674345786073382135452928153479559868247493919227266n :MLOAD(expByXCycloFp12BN254_c23_x) + 20231158774990444129983338146063043702239109464764996510430767078543929636660n :MLOAD(expByXCycloFp12BN254_c23_y) + end: $ => A :MLOAD(initial_A) @@ -524,7 +527,7 @@ INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" -INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/scalarMulFp2BN254.zkasm" INCLUDE "../main/pairings/FP4BN254/squareFp4BN254.zkasm" diff --git a/test/testEcAdd.zkasm b/test/testEcAdd.zkasm index 20d75426..16c8a966 100644 --- a/test/testEcAdd.zkasm +++ b/test/testEcAdd.zkasm @@ -53,7 +53,7 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - ; 1] 0 + 0 = 0 + ; 1] 𝒪 + 𝒪 = 𝒪 0n :MSTORE(ecAdd_P1_x) 0n :MSTORE(ecAdd_P1_y) 0n :MSTORE(ecAdd_P2_x) @@ -63,7 +63,7 @@ start: 0n :MLOAD(ecAdd_P3_y) - ; 2] 0 + P = P + ; 2] 𝒪 + P = P 0n :MSTORE(ecAdd_P1_x) 0n :MSTORE(ecAdd_P1_y) 1n :MSTORE(ecAdd_P2_x) @@ -72,7 +72,7 @@ start: 1n :MLOAD(ecAdd_P3_x) 2n :MLOAD(ecAdd_P3_y) - ; 3] P + 0 = P + ; 3] P + 𝒪 = P 1n :MSTORE(ecAdd_P1_x) 2n :MSTORE(ecAdd_P1_y) 0n :MSTORE(ecAdd_P2_x) @@ -149,7 +149,7 @@ start: 6 => A 1 :EQ - ; 8] P + (-P) = 0 + ; 8] P + (-P) = 𝒪 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P1_x) 848677436511517736191562425154572367705380862894644942948681172815252343932n :MSTORE(ecAdd_P1_y) 10744596414106452074759370245733544594153395043370666422502510773307029471145n :MSTORE(ecAdd_P2_x) diff --git a/test/testEcMul.zkasm b/test/testEcMul.zkasm index 992b61fc..6cdd85dd 100644 --- a/test/testEcMul.zkasm +++ b/test/testEcMul.zkasm @@ -54,7 +54,7 @@ start: -1 :MSTORE(lastHashKId) -1 :MSTORE(lastHashPId) - ; 1] 0·O = O + ; 1] 0·𝒪 = 𝒪 0n :MSTORE(ecMul_k) 0n :MSTORE(ecMul_P_x) 0n :MSTORE(ecMul_P_y) @@ -62,7 +62,7 @@ start: 0n :MLOAD(ecMul_Q_x) 0n :MLOAD(ecMul_Q_y) - ; 2] k·O = O + ; 2] k·𝒪 = 𝒪 5n :MSTORE(ecMul_k) 0n :MSTORE(ecMul_P_x) 0n :MSTORE(ecMul_P_y) @@ -70,7 +70,7 @@ start: 0n :MLOAD(ecMul_Q_x) 0n :MLOAD(ecMul_Q_y) - ; 3] 0·P = O, where P != O + ; 3] 0·P = 𝒪, where P != 𝒪 0n :MSTORE(ecMul_k) 1n :MSTORE(ecMul_P_x) 2n :MSTORE(ecMul_P_y) @@ -122,30 +122,35 @@ start: :CALL(ecMul) 1368015179489954701390400359078579693043519447331113978918064868415326638035n :MLOAD(ecMul_Q_x) 9918110051302171585080402603319702774565515993150576347155970296011118125764n :MLOAD(ecMul_Q_y) + 65n :MSTORE(ecMul_k) 1n :MSTORE(ecMul_P_x) 2n :MSTORE(ecMul_P_y) :CALL(ecMul) 21184532036463169063041779836861514142873086093180850953095098556309204188255n :MLOAD(ecMul_Q_x) 16870949628445799017882714788639508275834535486794531840392367353784571921174n :MLOAD(ecMul_Q_y) + 10000000089n :MSTORE(ecMul_k) 1n :MSTORE(ecMul_P_x) 2n :MSTORE(ecMul_P_y) :CALL(ecMul) 4768044760451824005417871472283223457728569810854115125480649095031772328870n :MLOAD(ecMul_Q_x) 21389337952468851259287213083493638952853622949895525580347877121675081015727n :MLOAD(ecMul_Q_y) + 57n :MSTORE(ecMul_k) 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecMul_P_x) 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecMul_P_y) :CALL(ecMul) 21092868577100313210583214784627729175513062432513303686654820611840644382013n :MLOAD(ecMul_Q_x) 10293123368529248350591404721829100625076077203595282162629899903703630633665n :MLOAD(ecMul_Q_y) + 123456789n :MSTORE(ecMul_k) 1745860766704548035074878643814414425056208216948549237180537806484993001172n :MSTORE(ecMul_P_x) 10428992577810537311515619307712828512800028181521723820412159824785899508051n :MSTORE(ecMul_P_y) :CALL(ecMul) 9551410454255481932113938269904288675272239827491596157984458647610565008967n :MLOAD(ecMul_Q_x) 17781856861347070862134441477208204792978952663354273425763774350233183876915n :MLOAD(ecMul_Q_y) + 21888242871839275222246405745257275088548364400416034343698204186575808495617n :MSTORE(ecMul_k) 1n :MSTORE(ecMul_P_x) 2n :MSTORE(ecMul_P_y) @@ -173,6 +178,7 @@ start: :CALL(ecMul) 15886422571275617715400903250697722692198979607302343556925904858625057687404n :MLOAD(ecMul_Q_x) 9788557113822741943783365060165103517008620829146475047263378292709661309554n :MLOAD(ecMul_Q_y) + 115792089237316195423570985008687907853269984665640564039457584007913129639935n :MSTORE(ecMul_k) 1n :MSTORE(ecMul_P_x) 2n :MSTORE(ecMul_P_y) @@ -181,14 +187,18 @@ start: 8573070896319864868535933562264623076420652926303237982078693068147657243287n :MLOAD(ecMul_Q_y) ; 7] Worst case scenario in terms of ARITH calls and therefore in terms of number of steps. - ; In ecMul, this should be the scalar multiplication with scalar with higer Hamming weight - ; that is lower than r, which in this case is 2^253 - 1. - 14474011154664524427946373126085988481658748083205070504932198000989141204991n :MSTORE(ecMul_k) + ; In ecMul, this should be the scalar multiplication with the highest scalar with the + ; higher Hamming weight that is lower than r, which in this case is: + ; 0b101111111111111111111111111111111111111111111111111111111111111111111111111111111111111 + ; 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 + ; 11111111111111111111111111111111111111111111111111111111111111111111111111111111 + ; plus the alias r for extra steps. + 43599259603836061864165965434386257811036486525223640101096501188059520303104n :MSTORE(ecMul_k) 1n :MSTORE(ecMul_P_x) 2n :MSTORE(ecMul_P_y) :CALL(ecMul) - 3739418567393436576913511739065691570763034865122368432616000129799288055432n :MLOAD(ecMul_Q_x) - 18298856760603404171434473181920219106007178146585940397845192637485681860518n :MLOAD(ecMul_Q_y) + 8041448123897457278601593007848323813197856498612220939414281968624779383026n :MLOAD(ecMul_Q_x) + 19954199902209052547301623742734796126853744744756027752727888617225334710299n :MLOAD(ecMul_Q_y) end: @@ -218,6 +228,9 @@ checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/tables/bitwiseReconstruction.zkasm" + +INCLUDE "../main/pairings/BN254/doublePointFPBN254.zkasm" INCLUDE "../main/pairings/BN254/ecMul.zkasm" INCLUDE "../main/pairings/BN254/ecAdd.zkasm" diff --git a/test/testFinalExpBn254.zkasm b/test/testFinalExpBn254.zkasm index 6e182304..449f8242 100644 --- a/test/testFinalExpBn254.zkasm +++ b/test/testFinalExpBn254.zkasm @@ -75,6 +75,31 @@ start: 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(finalExpBN254_f23_x) 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(finalExpBN254_f23_y) + 4373180471897776675258309160655258716100668532239505928726075560119356030002n :MSTORE(finalExpBN254_f11_x) + 1998330412639707119754272620557145281813809980883950342297299979818528684154n :MSTORE(finalExpBN254_f11_y) + 18195156481784673240556983853217723353001088667319253095299836175016081692653n :MSTORE(finalExpBN254_f12_x) + 14416987383147396072613358222719907151645356863831412780374841605584347181537n :MSTORE(finalExpBN254_f12_y) + 13043331860922794250757689689044292794537063013289447519953992786299144640874n :MSTORE(finalExpBN254_f13_x) + 7998822704208929271799060800163633892021893672636774922339957381963568184335n :MSTORE(finalExpBN254_f13_y) + 11564170995253420243784236706220624235099028698811197560562608812904781569191n :MSTORE(finalExpBN254_f21_x) + 1561438582167048283732233548379207606975476164189711297629851900955098634579n :MSTORE(finalExpBN254_f21_y) + 6484979918970421531511710931913244277708494585657747727616767368177583870776n :MSTORE(finalExpBN254_f22_x) + 20613445875497535013958846315705228024956718707377978402415068145098513246407n :MSTORE(finalExpBN254_f22_y) + 138756767609839831937683255878181558527811811124453617774821196364866975362n :MSTORE(finalExpBN254_f23_x) + 5664414496761134021650100592655664221381485706767860975330303186756080468547n :MSTORE(finalExpBN254_f23_y) + :CALL(finalExpBN254) + 18376152097488863729411754051002103954297284193588700440955892969876269290212n :MLOAD(finalExpBN254_f11_x) + 10621257193499535812872442420676526729712802633301668776844575825415515291706n :MLOAD(finalExpBN254_f11_y) + 11633078801153629554817133551522435385231811573807701446913787691251259184784n :MLOAD(finalExpBN254_f12_x) + 1524260132424840981642464422216152736107774714882905588040921992015558050028n :MLOAD(finalExpBN254_f12_y) + 13420343631615804954746818284034553623986657939762003801605066035093420196426n :MLOAD(finalExpBN254_f13_x) + 21248541410826964104409380037646359020348991574668385986534894680205665925043n :MLOAD(finalExpBN254_f13_y) + 13187461668389015891472392065037907074391392568299301132940823459451095075224n :MLOAD(finalExpBN254_f21_x) + 370549011265327086992512937475900461760428010118224584269772725798245423758n :MLOAD(finalExpBN254_f21_y) + 12875992352119091280660051743521771761736469064351008729755940102932502650777n :MLOAD(finalExpBN254_f22_x) + 1659574700423039326204581620794343904398710545559593831226184365695657415833n :MLOAD(finalExpBN254_f22_y) + 12640187982786243062057108990058966774416170992161923454444647865801963113293n :MLOAD(finalExpBN254_f23_x) + 5859898564016854141716025149318506863354930253919386641282498067410796710392n :MLOAD(finalExpBN254_f23_y) end: @@ -113,7 +138,7 @@ INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" -INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/scalarMulFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" INCLUDE "../main/pairings/FP4BN254/squareFp4BN254.zkasm" diff --git a/test/testFp12ArithBN254.zkasm b/test/testFp12ArithBN254.zkasm index f387ba2b..7beedadb 100644 --- a/test/testFp12ArithBN254.zkasm +++ b/test/testFp12ArithBN254.zkasm @@ -666,12 +666,12 @@ INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" -INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/scalarMulFp2BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/addFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/subFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/mulFp6BN254.zkasm" -INCLUDE "../main/pairings/FP6BN254/escalarMulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/scalarMulFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm" @@ -689,4 +689,4 @@ INCLUDE "../main/pairings/FP12BN254/frob3Fp12BN254.zkasm" INCLUDE "../main/pairings/unused/addFp12BN254.zkasm" INCLUDE "../main/pairings/unused/subFp12BN254.zkasm" -INCLUDE "../main/pairings/unused/expFp12BN254.zkasm" +INCLUDE "../main/pairings/unused/expFp12BN254.zkasm" \ No newline at end of file diff --git a/test/testFp2ArithBN254.zkasm b/test/testFp2ArithBN254.zkasm index 0c51cd3d..7d2c83ec 100644 --- a/test/testFp2ArithBN254.zkasm +++ b/test/testFp2ArithBN254.zkasm @@ -130,6 +130,14 @@ start: D => A 0 :ASSERT + %BN254_P => A + %BN254_P + 67n => B + :CALL(invFp2BN254) + C => A + 0n :ASSERT + D => A + 326690192117004107794722473809810075950691211302952591980433401412615316546n :ASSERT + ; 4] Squaring 1n => A 4n => B @@ -139,11 +147,11 @@ start: C => A 8n :ASSERT - ; 5] Escalar Multiplication + ; 5] scalar Multiplication 3n => A 6n => C 4n => D - :CALL(escalarMulFp2BN254) + :CALL(scalarMulFp2BN254) E => A 18n :ASSERT C => A @@ -182,4 +190,4 @@ INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" -INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" \ No newline at end of file +INCLUDE "../main/pairings/FP2BN254/scalarMulFp2BN254.zkasm" \ No newline at end of file diff --git a/test/testFp6ArithBN254.zkasm b/test/testFp6ArithBN254.zkasm index 5259b73b..b280f08f 100644 --- a/test/testFp6ArithBN254.zkasm +++ b/test/testFp6ArithBN254.zkasm @@ -116,7 +116,23 @@ start: 173n :MLOAD(mulFp6BN254_c3_x) 123n :MLOAD(mulFp6BN254_c3_y) - ; 4] Square + ; 4] Scalar multiplication + 2n :MSTORE(scalarMulFp6BN254_b) + 10n :MSTORE(scalarMulFp6BN254_a1_x) + 2n :MSTORE(scalarMulFp6BN254_a1_y) + 5n :MSTORE(scalarMulFp6BN254_a2_x) + 13n :MSTORE(scalarMulFp6BN254_a2_y) + 7n :MSTORE(scalarMulFp6BN254_a3_x) + 5n :MSTORE(scalarMulFp6BN254_a3_y) + :CALL(scalarMulFp6BN254) + 20n :MLOAD(scalarMulFp6BN254_c1_x) + 4n :MLOAD(scalarMulFp6BN254_c1_y) + 10n :MLOAD(scalarMulFp6BN254_c2_x) + 26n :MLOAD(scalarMulFp6BN254_c2_y) + 14n :MLOAD(scalarMulFp6BN254_c3_x) + 10n :MLOAD(scalarMulFp6BN254_c3_y) + + ; 5] Square 10n :MSTORE(squareFp6BN254_a1_x) 2n :MSTORE(squareFp6BN254_a1_y) 5n :MSTORE(squareFp6BN254_a2_x) @@ -131,7 +147,7 @@ start: 21888242871839275222246405745257275088696311157297823662689037894645226208559n :MLOAD(squareFp6BN254_c3_x) 258n :MLOAD(squareFp6BN254_c3_y) - ; 5] Inverse + ; 6] Inverse 0n :MSTORE(inverseFp6BN254_a1_x) 0n :MSTORE(inverseFp6BN254_a1_y) 0n :MSTORE(inverseFp6BN254_a2_x) @@ -160,7 +176,7 @@ start: 14149695447230733832672344969363233706238986964811686150151922078523920094032n :MLOAD(inverseFp6BN254_c3_x) 8319081930844559069109603696113388970848243877139140810016204850690606105497n :MLOAD(inverseFp6BN254_c3_y) - ; 6] Sparse Multiplication A + ; 7] Sparse Multiplication A 10n :MSTORE(sparseMulAFp6BN254_a1_x) 2n :MSTORE(sparseMulAFp6BN254_a1_y) 5n :MSTORE(sparseMulAFp6BN254_a2_x) @@ -177,7 +193,7 @@ start: 21888242871839275222246405745257275088696311157297823662689037894645226207594n :MLOAD(sparseMulAFp6BN254_c3_x) 455n :MLOAD(sparseMulAFp6BN254_c3_y) - ; 7] Sparse Multiplication B + ; 8] Sparse Multiplication B 10n :MSTORE(sparseMulBFp6BN254_a1_x) 2n :MSTORE(sparseMulBFp6BN254_a1_y) 5n :MSTORE(sparseMulBFp6BN254_a2_x) @@ -196,7 +212,7 @@ start: 21888242871839275222246405745257275088696311157297823662689037894645226207452n :MLOAD(sparseMulBFp6BN254_c3_x) 653n :MLOAD(sparseMulBFp6BN254_c3_y) - ; 8] Sparse Multiplication C + ; 9] Sparse Multiplication C 10n :MSTORE(sparseMulCFp6BN254_a1_x) 2n :MSTORE(sparseMulCFp6BN254_a1_y) 5n :MSTORE(sparseMulCFp6BN254_a2_x) @@ -248,11 +264,12 @@ INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" -INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/scalarMulFp2BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/addFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/subFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/mulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/scalarMulFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/squareFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/inverseFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm" diff --git a/test/testHalfPairingBN254.zkasm b/test/testHalfPairingBN254.zkasm index a37ef1f0..0e1eff30 100644 --- a/test/testHalfPairingBN254.zkasm +++ b/test/testHalfPairingBN254.zkasm @@ -249,6 +249,8 @@ opINVALID: checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/tables/bitwiseReconstruction.zkasm" + INCLUDE "../main/pairings/halfPairingBN254.zkasm" INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" @@ -261,13 +263,13 @@ INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" -INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/scalarMulFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/addFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/subFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/mulFp6BN254.zkasm" -INCLUDE "../main/pairings/FP6BN254/escalarMulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/scalarMulFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm" @@ -276,8 +278,10 @@ INCLUDE "../main/pairings/FP12BN254/sparseMulAFp12BN254.zkasm" INCLUDE "../main/pairings/FP12BN254/sparseMulBFp12BN254.zkasm" INCLUDE "../main/pairings/FP12BN254/squareFp12BN254.zkasm" -INCLUDE "../main/pairings/BN254/addPointBN254.zkasm" -INCLUDE "../main/pairings/BN254/escalarMulBN254.zkasm" +INCLUDE "../main/pairings/BN254/addPointFP2BN254.zkasm" +INCLUDE "../main/pairings/BN254/doublePointFP2BN254.zkasm" +INCLUDE "../main/pairings/BN254/scalarMulPointBy6X2FP2BN254.zkasm" +INCLUDE "../main/pairings/BN254/sixX2.zkasm" INCLUDE "../main/pairings/BN254/lineSamePointsBN254.zkasm" INCLUDE "../main/pairings/BN254/lineDiffPointsBN254.zkasm" diff --git a/test/testPairingBN254.zkasm b/test/testPairingBN254.zkasm index 3a2ed975..7b581e5e 100644 --- a/test/testPairingBN254.zkasm +++ b/test/testPairingBN254.zkasm @@ -367,18 +367,18 @@ start: 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(pairingBN254_Q_y1) 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(pairingBN254_Q_y2) :CALL(pairingBN254) - 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(expCycloFp12BN254_c11_x) - 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(expCycloFp12BN254_c11_y) - 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(expCycloFp12BN254_c12_x) - 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(expCycloFp12BN254_c12_y) - 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(expCycloFp12BN254_c13_x) - 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(expCycloFp12BN254_c13_y) - 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(expCycloFp12BN254_c21_x) - 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(expCycloFp12BN254_c21_y) - 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(expCycloFp12BN254_c22_x) - 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(expCycloFp12BN254_c22_y) - 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(expCycloFp12BN254_c23_x) - 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(expCycloFp12BN254_c23_y) + 13413524510323321318921703539856938196252165859353070108808910520379565591578n :MLOAD(pairingBN254_f11_x) + 3548381829456735642031500506306367847474828769923557674325753657986253436214n :MLOAD(pairingBN254_f11_y) + 11258588180307399598255242775094467208478122055367286369273756816466078325984n :MLOAD(pairingBN254_f12_x) + 15692415863664227683780306499051704744181486071132299317385971936570963983778n :MLOAD(pairingBN254_f12_y) + 14331327121685823241734822812072572580994818894715351943735993854561590776973n :MLOAD(pairingBN254_f13_x) + 5829057651356763815288519037751619402051833008237861839412688801032331829766n :MLOAD(pairingBN254_f13_y) + 15475783993587934296880977452723101772140252350911606731569729596277613550216n :MLOAD(pairingBN254_f21_x) + 5097655688415311910623889733978393264040884000272175630800968927057028195666n :MLOAD(pairingBN254_f21_y) + 11451831001542370722617744987566735321553462342240810632153337322850540201855n :MLOAD(pairingBN254_f22_x) + 10214880648406402761779167726229820911960967566000435639888288131094179536430n :MLOAD(pairingBN254_f22_y) + 7513746461017094458199399930075345786758663515755635567834665490471393582925n :MLOAD(pairingBN254_f23_x) + 1522857835029638585907442329762418957365351568194442821861575097484378991036n :MLOAD(pairingBN254_f23_y) end: @@ -406,6 +406,8 @@ opINVALID: checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/tables/bitwiseReconstruction.zkasm" + INCLUDE "../main/pairings/constants.zkasm" INCLUDE "../main/pairings/pairingBN254.zkasm" @@ -420,7 +422,7 @@ INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" -INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/scalarMulFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" INCLUDE "../main/pairings/FP4BN254/squareFp4BN254.zkasm" @@ -428,7 +430,7 @@ INCLUDE "../main/pairings/FP4BN254/squareFp4BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/addFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/subFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/mulFp6BN254.zkasm" -INCLUDE "../main/pairings/FP6BN254/escalarMulFp6BN254.zkasm" +INCLUDE "../main/pairings/FP6BN254/scalarMulFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/sparseMulAFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/sparseMulBFp6BN254.zkasm" INCLUDE "../main/pairings/FP6BN254/sparseMulCFp6BN254.zkasm" @@ -451,8 +453,10 @@ INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/squareCompCycloFp12BN254.zkas INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/squareCycloFp12BN254.zkasm" INCLUDE "../main/pairings/FP12BN254/CYCLOFP12BN254/expByXCompCycloFp12BN254.zkasm" -INCLUDE "../main/pairings/BN254/addPointBN254.zkasm" -INCLUDE "../main/pairings/BN254/escalarMulBN254.zkasm" +INCLUDE "../main/pairings/BN254/addPointFP2BN254.zkasm" +INCLUDE "../main/pairings/BN254/doublePointFP2BN254.zkasm" +INCLUDE "../main/pairings/BN254/scalarMulPointBy6X2FP2BN254.zkasm" +INCLUDE "../main/pairings/BN254/sixX2.zkasm" INCLUDE "../main/pairings/BN254/lineSamePointsBN254.zkasm" INCLUDE "../main/pairings/BN254/lineDiffPointsBN254.zkasm" diff --git a/test/testPointArithBN254.zkasm b/test/testPointArithBN254.zkasm index 786e05ae..4cf015b4 100644 --- a/test/testPointArithBN254.zkasm +++ b/test/testPointArithBN254.zkasm @@ -54,141 +54,118 @@ start: ; 1] Point addition ; 0 + 0 = 0 - 0n :MSTORE(addPointBN254_P1_x1) - 0n :MSTORE(addPointBN254_P1_x2) - 0n :MSTORE(addPointBN254_P1_y1) - 0n :MSTORE(addPointBN254_P1_y2) - 0n :MSTORE(addPointBN254_P2_x1) - 0n :MSTORE(addPointBN254_P2_x2) - 0n :MSTORE(addPointBN254_P2_y1) - 0n :MSTORE(addPointBN254_P2_y2) - :CALL(addPointBN254) - 0n :MLOAD(addPointBN254_P3_x1) - 0n :MLOAD(addPointBN254_P3_x2) - 0n :MLOAD(addPointBN254_P3_y1) - 0n :MLOAD(addPointBN254_P3_y2) + 0n :MSTORE(addPointFP2BN254_P1_x1) + 0n :MSTORE(addPointFP2BN254_P1_x2) + 0n :MSTORE(addPointFP2BN254_P1_y1) + 0n :MSTORE(addPointFP2BN254_P1_y2) + 0n :MSTORE(addPointFP2BN254_P2_x1) + 0n :MSTORE(addPointFP2BN254_P2_x2) + 0n :MSTORE(addPointFP2BN254_P2_y1) + 0n :MSTORE(addPointFP2BN254_P2_y2) + :CALL(addPointFP2BN254) + 0n :MLOAD(addPointFP2BN254_P3_x1) + 0n :MLOAD(addPointFP2BN254_P3_x2) + 0n :MLOAD(addPointFP2BN254_P3_y1) + 0n :MLOAD(addPointFP2BN254_P3_y2) ; 0 + P2 = P2 - 0n :MSTORE(addPointBN254_P1_x1) - 0n :MSTORE(addPointBN254_P1_x2) - 0n :MSTORE(addPointBN254_P1_y1) - 0n :MSTORE(addPointBN254_P1_y2) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P2_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P2_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P2_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointBN254_P2_y2) - :CALL(addPointBN254) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MLOAD(addPointBN254_P3_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MLOAD(addPointBN254_P3_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MLOAD(addPointBN254_P3_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MLOAD(addPointBN254_P3_y2) + 0n :MSTORE(addPointFP2BN254_P1_x1) + 0n :MSTORE(addPointFP2BN254_P1_x2) + 0n :MSTORE(addPointFP2BN254_P1_y1) + 0n :MSTORE(addPointFP2BN254_P1_y2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointFP2BN254_P2_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointFP2BN254_P2_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointFP2BN254_P2_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointFP2BN254_P2_y2) + :CALL(addPointFP2BN254) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MLOAD(addPointFP2BN254_P3_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MLOAD(addPointFP2BN254_P3_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MLOAD(addPointFP2BN254_P3_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MLOAD(addPointFP2BN254_P3_y2) ; P1 + 0 = P1 - 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MSTORE(addPointBN254_P1_x1) - 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MSTORE(addPointBN254_P1_x2) - 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(addPointBN254_P1_y1) - 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(addPointBN254_P1_y2) - 0n :MSTORE(addPointBN254_P2_x1) - 0n :MSTORE(addPointBN254_P2_x2) - 0n :MSTORE(addPointBN254_P2_y1) - 0n :MSTORE(addPointBN254_P2_y2) - :CALL(addPointBN254) - 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MLOAD(addPointBN254_P3_x1) - 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MLOAD(addPointBN254_P3_x2) - 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MLOAD(addPointBN254_P3_y1) - 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MLOAD(addPointBN254_P3_y2) + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MSTORE(addPointFP2BN254_P1_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MSTORE(addPointFP2BN254_P1_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(addPointFP2BN254_P1_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(addPointFP2BN254_P1_y2) + 0n :MSTORE(addPointFP2BN254_P2_x1) + 0n :MSTORE(addPointFP2BN254_P2_x2) + 0n :MSTORE(addPointFP2BN254_P2_y1) + 0n :MSTORE(addPointFP2BN254_P2_y2) + :CALL(addPointFP2BN254) + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MLOAD(addPointFP2BN254_P3_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MLOAD(addPointFP2BN254_P3_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MLOAD(addPointFP2BN254_P3_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MLOAD(addPointFP2BN254_P3_y2) ; P1 + (-P1) = 0 - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P1_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P1_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P1_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointBN254_P1_y2) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P2_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P2_x2) - 13392588948715843804641432497768002650278120570034223513918757245338268106653n :MSTORE(addPointBN254_P2_y1) - 17805874995975841540914202342111839520379459829704422454583296818431106115052n :MSTORE(addPointBN254_P2_y2) - :CALL(addPointBN254) - 0n :MLOAD(addPointBN254_P3_x1) - 0n :MLOAD(addPointBN254_P3_x2) - 0n :MLOAD(addPointBN254_P3_y1) - 0n :MLOAD(addPointBN254_P3_y2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointFP2BN254_P1_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointFP2BN254_P1_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointFP2BN254_P1_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointFP2BN254_P1_y2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointFP2BN254_P2_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointFP2BN254_P2_x2) + 13392588948715843804641432497768002650278120570034223513918757245338268106653n :MSTORE(addPointFP2BN254_P2_y1) + 17805874995975841540914202342111839520379459829704422454583296818431106115052n :MSTORE(addPointFP2BN254_P2_y2) + :CALL(addPointFP2BN254) + 0n :MLOAD(addPointFP2BN254_P3_x1) + 0n :MLOAD(addPointFP2BN254_P3_x2) + 0n :MLOAD(addPointFP2BN254_P3_y1) + 0n :MLOAD(addPointFP2BN254_P3_y2) ; P1 + P1 = 2·P1 - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P1_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P1_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P1_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointBN254_P1_y2) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P2_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P2_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P2_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointBN254_P2_y2) - :CALL(addPointBN254) - 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MLOAD(addPointBN254_P3_x1) - 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MLOAD(addPointBN254_P3_x2) - 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MLOAD(addPointBN254_P3_y1) - 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MLOAD(addPointBN254_P3_y2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointFP2BN254_P1_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointFP2BN254_P1_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointFP2BN254_P1_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointFP2BN254_P1_y2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointFP2BN254_P2_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointFP2BN254_P2_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointFP2BN254_P2_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointFP2BN254_P2_y2) + :CALL(addPointFP2BN254) + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MLOAD(addPointFP2BN254_P3_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MLOAD(addPointFP2BN254_P3_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MLOAD(addPointFP2BN254_P3_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MLOAD(addPointFP2BN254_P3_y2) ; P1 + P2 = P3 - 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MSTORE(addPointBN254_P1_x1) - 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MSTORE(addPointBN254_P1_x2) - 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(addPointBN254_P1_y1) - 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(addPointBN254_P1_y2) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointBN254_P2_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointBN254_P2_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointBN254_P2_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointBN254_P2_y2) - :CALL(addPointBN254) - 2725019753478801796453339367788033689375851816420509565303521482350756874229n :MLOAD(addPointBN254_P3_x1) - 7273165102799931111715871471550377909735733521218303035754523677688038059653n :MLOAD(addPointBN254_P3_x2) - 2512659008974376214222774206987427162027254181373325676825515531566330959255n :MLOAD(addPointBN254_P3_y1) - 957874124722006818841961785324909313781880061366718538693995380805373202866n :MLOAD(addPointBN254_P3_y2) - - ; 2] Escalar multiplication - 0n :MSTORE(escalarMulBN254_k) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(escalarMulBN254_P_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(escalarMulBN254_P_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(escalarMulBN254_P_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(escalarMulBN254_P_y2) - :CALL(escalarMulBN254) - 0n :MLOAD(escalarMulBN254_Q_x1) - 0n :MLOAD(escalarMulBN254_Q_x2) - 0n :MLOAD(escalarMulBN254_Q_y1) - 0n :MLOAD(escalarMulBN254_Q_y2) - - %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k) - 0n :MSTORE(escalarMulBN254_P_x1) - 0n :MSTORE(escalarMulBN254_P_x2) - 0n :MSTORE(escalarMulBN254_P_y1) - 0n :MSTORE(escalarMulBN254_P_y2) - :CALL(escalarMulBN254) - 0n :MLOAD(escalarMulBN254_Q_x1) - 0n :MLOAD(escalarMulBN254_Q_x2) - 0n :MLOAD(escalarMulBN254_Q_y1) - 0n :MLOAD(escalarMulBN254_Q_y2) - - %BN254_SIX_TIMES_X_SQ :MSTORE(escalarMulBN254_k) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(escalarMulBN254_P_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(escalarMulBN254_P_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(escalarMulBN254_P_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(escalarMulBN254_P_y2) - :CALL(escalarMulBN254) - 13824868563399673693405984206252027284526901521624614945388441201916943098448n :MLOAD(escalarMulBN254_Q_x1) - 6070174842523651825461006324987645339257276059765462992338211551285097849152n :MLOAD(escalarMulBN254_Q_x2) - 4224873494559498571787136390356590572898009346319218613936276445484292886657n :MLOAD(escalarMulBN254_Q_y1) - 14979195929948718632567968180703131754953567972706796447883440492471033097811n :MLOAD(escalarMulBN254_Q_y2) - - %BN254_R :MSTORE(escalarMulBN254_k) - 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(escalarMulBN254_P_x1) - 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(escalarMulBN254_P_x2) - 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(escalarMulBN254_P_y1) - 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(escalarMulBN254_P_y2) - :CALL(escalarMulBN254) - 0n :MLOAD(escalarMulBN254_Q_x1) - 0n :MLOAD(escalarMulBN254_Q_x2) - 0n :MLOAD(escalarMulBN254_Q_y1) - 0n :MLOAD(escalarMulBN254_Q_y2) - - ; 3] Tangent line to a point + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MSTORE(addPointFP2BN254_P1_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MSTORE(addPointFP2BN254_P1_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MSTORE(addPointFP2BN254_P1_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MSTORE(addPointFP2BN254_P1_y2) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(addPointFP2BN254_P2_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(addPointFP2BN254_P2_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(addPointFP2BN254_P2_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(addPointFP2BN254_P2_y2) + :CALL(addPointFP2BN254) + 2725019753478801796453339367788033689375851816420509565303521482350756874229n :MLOAD(addPointFP2BN254_P3_x1) + 7273165102799931111715871471550377909735733521218303035754523677688038059653n :MLOAD(addPointFP2BN254_P3_x2) + 2512659008974376214222774206987427162027254181373325676825515531566330959255n :MLOAD(addPointFP2BN254_P3_y1) + 957874124722006818841961785324909313781880061366718538693995380805373202866n :MLOAD(addPointFP2BN254_P3_y2) + + ; 2] point doubling + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(doublePointFP2BN254_P_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(doublePointFP2BN254_P_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(doublePointFP2BN254_P_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(doublePointFP2BN254_P_y2) + :CALL(doublePointFP2BN254) + 18029695676650738226693292988307914797657423701064905010927197838374790804409n :MLOAD(doublePointFP2BN254_Q_x1) + 14583779054894525174450323658765874724019480979794335525732096752006891875705n :MLOAD(doublePointFP2BN254_Q_x2) + 2140229616977736810657479771656733941598412651537078903776637920509952744750n :MLOAD(doublePointFP2BN254_Q_y1) + 11474861747383700316476719153975578001603231366361248090558603872215261634898n :MLOAD(doublePointFP2BN254_Q_y2) + + ; 3] scalar multiplication by 6x² + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(scalarMulPointBy6X2FP2BN254_P_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(scalarMulPointBy6X2FP2BN254_P_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(scalarMulPointBy6X2FP2BN254_P_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(scalarMulPointBy6X2FP2BN254_P_y2) + :CALL(scalarMulPointBy6X2FP2BN254) + 13824868563399673693405984206252027284526901521624614945388441201916943098448n :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x1) + 6070174842523651825461006324987645339257276059765462992338211551285097849152n :MLOAD(scalarMulPointBy6X2FP2BN254_Q_x2) + 4224873494559498571787136390356590572898009346319218613936276445484292886657n :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y1) + 14979195929948718632567968180703131754953567972706796447883440492471033097811n :MLOAD(scalarMulPointBy6X2FP2BN254_Q_y2) + + ; 4] Tangent line to a point 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(lineSamePointsBN254_P_x1) 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(lineSamePointsBN254_P_x2) 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(lineSamePointsBN254_P_y1) @@ -203,7 +180,7 @@ start: 12094372820654450448173487244699814664976451191756576932392084702582606199137n :MLOAD(lineSamePointsBN254_l22_x) 16329471503453734725328813612581742273267405310373604832422964304856480374124n :MLOAD(lineSamePointsBN254_l22_y) - ; 4] Line passing through two different points + ; 5] Line passing through two different points 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(lineDiffPointsBN254_P1_x1) 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(lineDiffPointsBN254_P1_x2) 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(lineDiffPointsBN254_P1_y1) @@ -223,6 +200,72 @@ start: 18535807517613687025007129469892030737201813557688282181535107728189048279364n :MLOAD(lineDiffPointsBN254_l23_y) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; UNUSED + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; 6] scalar multiplication + 0n :MSTORE(scalarMulPointFP2BN254_k) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(scalarMulPointFP2BN254_P_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(scalarMulPointFP2BN254_P_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(scalarMulPointFP2BN254_P_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(scalarMulPointFP2BN254_P_y2) + :CALL(scalarMulPointFP2BN254) + 0n :MLOAD(scalarMulPointFP2BN254_Q_x1) + 0n :MLOAD(scalarMulPointFP2BN254_Q_x2) + 0n :MLOAD(scalarMulPointFP2BN254_Q_y1) + 0n :MLOAD(scalarMulPointFP2BN254_Q_y2) + + %BN254_SIX_TIMES_X_SQ :MSTORE(scalarMulPointFP2BN254_k) + 0n :MSTORE(scalarMulPointFP2BN254_P_x1) + 0n :MSTORE(scalarMulPointFP2BN254_P_x2) + 0n :MSTORE(scalarMulPointFP2BN254_P_y1) + 0n :MSTORE(scalarMulPointFP2BN254_P_y2) + :CALL(scalarMulPointFP2BN254) + 0n :MLOAD(scalarMulPointFP2BN254_Q_x1) + 0n :MLOAD(scalarMulPointFP2BN254_Q_x2) + 0n :MLOAD(scalarMulPointFP2BN254_Q_y1) + 0n :MLOAD(scalarMulPointFP2BN254_Q_y2) + + %BN254_SIX_TIMES_X_SQ :MSTORE(scalarMulPointFP2BN254_k) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(scalarMulPointFP2BN254_P_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(scalarMulPointFP2BN254_P_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(scalarMulPointFP2BN254_P_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(scalarMulPointFP2BN254_P_y2) + :CALL(scalarMulPointFP2BN254) + 13824868563399673693405984206252027284526901521624614945388441201916943098448n :MLOAD(scalarMulPointFP2BN254_Q_x1) + 6070174842523651825461006324987645339257276059765462992338211551285097849152n :MLOAD(scalarMulPointFP2BN254_Q_x2) + 4224873494559498571787136390356590572898009346319218613936276445484292886657n :MLOAD(scalarMulPointFP2BN254_Q_y1) + 14979195929948718632567968180703131754953567972706796447883440492471033097811n :MLOAD(scalarMulPointFP2BN254_Q_y2) + + %BN254_R :MSTORE(scalarMulPointFP2BN254_k) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(scalarMulPointFP2BN254_P_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(scalarMulPointFP2BN254_P_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(scalarMulPointFP2BN254_P_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(scalarMulPointFP2BN254_P_y2) + :CALL(scalarMulPointFP2BN254) + 0n :MLOAD(scalarMulPointFP2BN254_Q_x1) + 0n :MLOAD(scalarMulPointFP2BN254_Q_x2) + 0n :MLOAD(scalarMulPointFP2BN254_Q_y1) + 0n :MLOAD(scalarMulPointFP2BN254_Q_y2) + + ; Worst case scenario in terms of ARITH calls and therefore in terms of number of steps. + ; In ecMul, this should be the scalar multiplication with the highest scalar with the + ; higher Hamming weight that is lower than r, which in this case is: + ; 0b101111111111111111111111111111111111111111111111111111111111111111111111111111111111111 + ; 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 + ; 11111111111111111111111111111111111111111111111111111111111111111111111111111111 + ; plus the alias r for extra steps. + 43599259603836061864165965434386257811036486525223640101096501188059520303104n :MSTORE(scalarMulPointFP2BN254_k) + 10857046999023057135944570762232829481370756359578518086990519993285655852781n :MSTORE(scalarMulPointFP2BN254_P_x1) + 11559732032986387107991004021392285783925812861821192530917403151452391805634n :MSTORE(scalarMulPointFP2BN254_P_x2) + 8495653923123431417604973247489272438418190587263600148770280649306958101930n :MSTORE(scalarMulPointFP2BN254_P_y1) + 4082367875863433681332203403145435568316851327593401208105741076214120093531n :MSTORE(scalarMulPointFP2BN254_P_y2) + :CALL(scalarMulPointFP2BN254) + 12536589405695890042778074166090729450510624702468576267854249385036853744632n :MLOAD(scalarMulPointFP2BN254_Q_x1) + 15713017434790825075818519312689945017347770064641346153472788652535544155080n :MLOAD(scalarMulPointFP2BN254_Q_x2) + 6079700360548984165981052260641857743840171518032336121585542327686267531649n :MLOAD(scalarMulPointFP2BN254_Q_y1) + 19755047999007266693074280518870820367977150819477065517222387947884818210996n :MLOAD(scalarMulPointFP2BN254_Q_y2) + end: $ => A :MLOAD(initial_A) @@ -250,6 +293,8 @@ checkAndSaveFrom: :JMP(opINVALID) +INCLUDE "../main/tables/bitwiseReconstruction.zkasm" + INCLUDE "../main/pairings/FRBN254/reduceFrBN254.zkasm" INCLUDE "../main/pairings/FPBN254/reduceFpBN254.zkasm" @@ -259,12 +304,16 @@ INCLUDE "../main/pairings/FPBN254/mulFpBN254.zkasm" INCLUDE "../main/pairings/FP2BN254/addFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/subFp2BN254.zkasm" -INCLUDE "../main/pairings/FP2BN254/escalarMulFp2BN254.zkasm" +INCLUDE "../main/pairings/FP2BN254/scalarMulFP2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/mulFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/squareFp2BN254.zkasm" INCLUDE "../main/pairings/FP2BN254/invFp2BN254.zkasm" -INCLUDE "../main/pairings/BN254/addPointBN254.zkasm" -INCLUDE "../main/pairings/BN254/escalarMulBN254.zkasm" +INCLUDE "../main/pairings/BN254/addPointFP2BN254.zkasm" +INCLUDE "../main/pairings/BN254/doublePointFP2BN254.zkasm" +INCLUDE "../main/pairings/BN254/scalarMulPointBy6X2FP2BN254.zkasm" +INCLUDE "../main/pairings/BN254/sixX2.zkasm" INCLUDE "../main/pairings/BN254/lineSamePointsBN254.zkasm" -INCLUDE "../main/pairings/BN254/lineDiffPointsBN254.zkasm" \ No newline at end of file +INCLUDE "../main/pairings/BN254/lineDiffPointsBN254.zkasm" + +INCLUDE "../main/pairings/unused/scalarMulPointFP2BN254.zkasm" \ No newline at end of file From fa4e7ea5c0182ccc1640e6b4e4816ec37e374492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Tue, 6 Feb 2024 18:43:29 +0100 Subject: [PATCH 02/12] Fp subtraction over BN254 optimized --- main/pairings/FPBN254/subFpBN254.zkasm | 32 ++++++++------------------ 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/main/pairings/FPBN254/subFpBN254.zkasm b/main/pairings/FPBN254/subFpBN254.zkasm index fa106813..d86549f6 100644 --- a/main/pairings/FPBN254/subFpBN254.zkasm +++ b/main/pairings/FPBN254/subFpBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: A,C are assumed to be in the range [0,BN254_P) ;; POST: The result is in the range [0,BN254_P) ;; ;; subFpBN254: @@ -13,29 +14,16 @@ ; ----------------------------- subFpBN254: - ; 0] Negate C - A => D - %BN254_P => A C => B - $ => C :SUB - D => A + $ => C :SUB, JMPC(subFpBN254_addp) + :RETURN +subFpBN254_addp: + ; NOTE: 5·BN254_P < 2²⁵⁶ < 6·BN254_P - ; 1] Compute and check the sub over Z - ; A·[1] + [BN254_P-C] = [D]·2²⁵⁶ + [E] - 1 => B - $${var _subFpBN254_AC = A + C} - ${_subFpBN254_AC >> 256} => D - ${_subFpBN254_AC} => E :ARITH + B => C ; save for later use - ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[(A - C) / p] + [(A - C) % p] = D·2²⁵⁶ + E - ; where C < BN254_P - %BN254_P => A - ${_subFpBN254_AC / const.BN254_P} => B ; quotient (256 bits) - ${_subFpBN254_AC % const.BN254_P} => C ; residue (256 bits) - E :ARITH + %BN254_P => B + $ => A :ADD ; It cannot overflow under the PRE condition - ; 3] Check that the result is lower than BN254_P - A => B - C => A - 1 :LT, RETURN \ No newline at end of file + C => B + $ => C :SUB, RETURN \ No newline at end of file From 8cdadf928e5943527f61fd0ccaa8aa6ab1f73de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Tue, 20 Feb 2024 16:08:36 +0100 Subject: [PATCH 03/12] Adding the modular arithmetic --- main/pairings/FP2BN254/invFp2BN254.zkasm | 74 ++++------------------- main/pairings/FPBN254/addFpBN254.zkasm | 25 ++------ main/pairings/FPBN254/invFpBN254.zkasm | 67 +++++--------------- main/pairings/FPBN254/mulFpBN254.zkasm | 24 ++------ main/pairings/FPBN254/reduceFpBN254.zkasm | 21 +++---- main/pairings/FPBN254/squareFpBN254.zkasm | 25 ++------ main/pairings/FPBN254/subFpBN254.zkasm | 9 ++- main/pairings/FRBN254/reduceFrBN254.zkasm | 23 +++---- package.json | 8 +-- test/testFp2ArithBN254.zkasm | 24 -------- test/testFpArithBN254.zkasm | 20 ------ test/testFrArithBN254.zkasm | 18 ++---- 12 files changed, 74 insertions(+), 264 deletions(-) diff --git a/main/pairings/FP2BN254/invFp2BN254.zkasm b/main/pairings/FP2BN254/invFp2BN254.zkasm index 075554a1..055ef036 100644 --- a/main/pairings/FP2BN254/invFp2BN254.zkasm +++ b/main/pairings/FP2BN254/invFp2BN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: A,B are assumed to be in the range [0,BN254_P) ;; POST: ARITH_BN254_MULFP2 ensures that the result is in the range [0,BN254_P) ;; ;; invFp2BN254 @@ -10,75 +11,27 @@ ; RESOURCES: ; ------------------------------------------- -; PATH 1 A,B < p: [steps: 3, bin: 1] + [steps: 4, bin: 1] + -; PATH 1.1 A == 0 (p): [steps: 5, bin: 2] + -; PATH 1.1.1 B == 0 (p): [steps: 3] -; PATH 1.1.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] = [steps: 23, bin: 4, arith: 1] -; PATH 1.2 A != 0 (p): [steps: 3, bin: 1] + -; PATH 1.2.1 B == 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] -; PATH 1.2.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] - -; PATH 2 A < p, B > p: [steps: 3, bin: 1] + [steps: 14, bin: 2, arith: 1] + -; PATH 2.1 A == 0 (p): [steps: 5, bin: 2] + -; PATH 2.1.1 B == 0 (p): [steps: 3] -; PATH 2.1.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] -; PATH 2.2 A != 0 (p): [steps: 3, bin: 1] + -; PATH 2.2.1 B == 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] -; PATH 2.2.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] - -; PATH 3 A > p, B < p: [steps: 13, bin: 2, arith: 1] + [steps: 4, bin: 1] + -; PATH 3.1 A == 0 (p): [steps: 5, bin: 2] + -; PATH 3.1.1 B == 0 (p): [steps: 3] -; PATH 3.1.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] -; PATH 3.2 A != 0 (p): [steps: 3, bin: 1] + -; PATH 3.2.1 B == 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] -; PATH 3.2.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] - -; PATH 4 A,B > p: [steps: 13, bin: 2, arith: 1] + [steps: 14, bin: 2, arith: 1] + -; PATH 4.1 A == 0 (p): [steps: 5, bin: 2] + -; PATH 4.1.1 B == 0 (p): [steps: 3] -; PATH 4.1.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] = [steps: 43, bin: 6, arith: 3] <--- w.c. -; PATH 4.2 A != 0 (p): [steps: 3, bin: 1] + -; PATH 4.2.1 B == 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] -; PATH 4.2.2 B != 0 (p): [steps: 8, bin: 0, arith: 1] + [steps: 3] +; PATH 1 A,B == 0: [steps: 3, bin: 0, arith: 0] +; PATH 2 A != 0, B == 0: [steps: 16, bin: 3, arith: 1] +; PATH 3 A,B != 0: [steps: 18, bin: 4, arith: 1] <-- w.c. ; ------------------------------------------- -; TODO: Add flag in reduceFp to reduce that xiva if the result is 0 or not - VAR GLOBAL invFp2BN254_x VAR GLOBAL invFp2BN254_y -VAR GLOBAL invFp2BN254_RR - invFp2BN254: - RR :MSTORE(invFp2BN254_RR) + ; Check if A = B = 0, and if so, return 0 + ${checkIfZero(A,B)} :JMPNZ(invFp2BN254_input_is_zero) A :MSTORE(invFp2BN254_x) B :MSTORE(invFp2BN254_y) - ; Normalization of A - %BN254_P => B - $ :LT, JMPC(__invFp2BN254_reduce_A_continue) - :CALL(reduceFpBN254) - A :MSTORE(invFp2BN254_x) - __invFp2BN254_reduce_A_continue: - - ; Normalization of B - $ => A :MLOAD(invFp2BN254_y) - %BN254_P => B - $ :LT, JMPC(__invFp2BN254_reduce_B_continue) - :CALL(reduceFpBN254) - A :MSTORE(invFp2BN254_y) - __invFp2BN254_reduce_B_continue: - ; From here, it is guaranteed that A,B ∈ [0,BN254_P) - invFp2BN254_zero_check: - ; Check if A = B = 0, and if so, return 0 - $ => B :MLOAD(invFp2BN254_x) + 0 => A $ :EQ, JMPNC(invFp2BN254_normalized) - $ => B :MLOAD(invFp2BN254_y) - $ :EQ, JMPC(invFp2BN254_input_is_zero) + $ => B :MLOAD(invFp2BN254_x) + 0 :EQ ; From here, either A != 0 or B != 0 invFp2BN254_normalized: @@ -98,11 +51,8 @@ invFp2BN254_normalized: C => A 1 :LT D => A - 1 :LT, JMP(invFp2BN254_end) + 1 :LT, RETURN invFp2BN254_input_is_zero: - 0 => C,D - -invFp2BN254_end: - $ => RR :MLOAD(invFp2BN254_RR) - :RETURN \ No newline at end of file + 0 => C,D :ASSERT + B :ASSERT, RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/addFpBN254.zkasm b/main/pairings/FPBN254/addFpBN254.zkasm index 6a7ce86e..0bcba33d 100644 --- a/main/pairings/FPBN254/addFpBN254.zkasm +++ b/main/pairings/FPBN254/addFpBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: A,C are assumed to be in the range [0,BN254_P) ;; POST: The result is in the range [0,BN254_P) ;; ;; addFpBN254: @@ -9,26 +10,12 @@ ; RESOURCES: ; ----------------------------- -; [steps: 11, bin: 1, arith: 2] +; [steps: 4, bin: 0, arith: 1] ; ----------------------------- addFpBN254: - ; 1] Compute and check the sum over Z - ; A·[1] + C = [D]·2²⁵⁶ + [E] + ; A·1 + C = op (mod BN254_P) 1 => B - $${var _addFpBN254_AC = A + C} - ${_addFpBN254_AC >> 256} => D - ${_addFpBN254_AC} => E :ARITH - - ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[(A+C) / p] + [(A+C) % p] = D·2²⁵⁶ + E - ; where C < BN254_P - %BN254_P => A - ${_addFpBN254_AC / const.BN254_P} => B ; quotient (256 bits) - ${_addFpBN254_AC % const.BN254_P} => C ; residue (256 bits) - E :ARITH - - ; 3] Check that the result is lower than BN254_P - A => B - C => A - 1 :LT, RETURN \ No newline at end of file + %BN254_P => D + ${(A + C) % D} => E :ARITH_MOD + E => C :RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/invFpBN254.zkasm b/main/pairings/FPBN254/invFpBN254.zkasm index 30657e99..39f9ed1a 100644 --- a/main/pairings/FPBN254/invFpBN254.zkasm +++ b/main/pairings/FPBN254/invFpBN254.zkasm @@ -1,4 +1,5 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: A is assumed to be in the range [0,BN254_P) ;; POST: The result is in the range [0,BN254_P) ;; ;; invFpBN254: @@ -8,68 +9,32 @@ ;; NOTE: On input 0, it returns 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; TODO: Verify if alias check is necessary - -VAR GLOBAL invFpBN254_tmp -VAR GLOBAL invFpBN254_RR - ; RESOURCES: ; ------------------------------------------- -; PATH 1 input_is_reduced_and_0: [steps: 8, bin: 2] -; PATH 2 input_is_not_reduced_and_0: [steps: 18, bin: 3, arith: 1] -; PATH 3 input_is_reduced: [steps: 20, bin: 3, arith: 2] -; PATH 4 input_is_not_reduced: [steps: 30, bin: 4, arith: 3] <--- w.c. +; PATH 1 input_is_0: [steps: 2, bin: 0] +; PATH 2 input_is_not_0: [steps: 11, bin: 2, arith: 1] <-- w.c. ; ------------------------------------------- invFpBN254: - ; block costs: - ; · input_is_reduced: [steps: 3, bin: 1] - ; · input_is_not_reduced: [steps: 13, bin: 2, arith: 1] - - RR :MSTORE(invFpBN254_RR) - - ; Reduction of A - %BN254_P => B - $ :LT, JMPC(invFpBN254_zero_check) - :CALL(reduceFpBN254) - ; From here, it is guaranteed that A ∈ [0,BN254_P) - -invFpBN254_zero_check: - ; block costs: [steps: 2, bin: 1] - ; Check if A = 0, and if so, return 0 + ${A == 0} :JMPNZ(invFpBN254_A_is_zero) + 0 => B - $ :EQ, JMPC(invFpBN254_A_is_zero) + 0 :EQ invFpBN254_normalized: - ; block costs: [steps: 13, bin: 1, arith: 2] - - ; 1] Compute and check the inverse over Z - ; A·A⁻¹ + [0] = [D]·2²⁵⁶ + [E] + ; A·A⁻¹ + 0 = 1 (mod BN254_P) + ${var _invFpBN254_A = fpBN254inv(A)} => B 0 => C - ${var _invFpBN254_A = fpBN254inv(A)} => B :MSTORE(invFpBN254_tmp); - $${var _invFpBN254_AB = A * _invFpBN254_A} - ${_invFpBN254_AB >> 256} => D - ${_invFpBN254_AB} => E :ARITH + %BN254_P => D + 1n :ARITH_MOD - ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[(A·A⁻¹) / BN254_P] + [1] = D·2²⁵⁶ + E - %BN254_P => A - ${_invFpBN254_AB / const.BN254_P} => B ; quotient (256 bits) - 1n => C ; residue (1 bit) - E :ARITH + ; Check that the resulting inverse is alias-free + B => A + %BN254_P => B + 1 :LT - ; 3] Check that the result is lower than BN254_P - A => B - $ => A :MLOAD(invFpBN254_tmp) - 1 :LT - A => B :JMP(invFpBN254_end) + A => B :RETURN invFpBN254_A_is_zero: - ; block costs: [steps: 1] - - 0 => B - -invFpBN254_end: - $ => RR :MLOAD(invFpBN254_RR) - :RETURN \ No newline at end of file + 0 => B :ASSERT, RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/mulFpBN254.zkasm b/main/pairings/FPBN254/mulFpBN254.zkasm index c5b7c552..74de72e0 100644 --- a/main/pairings/FPBN254/mulFpBN254.zkasm +++ b/main/pairings/FPBN254/mulFpBN254.zkasm @@ -9,26 +9,12 @@ ; RESOURCES: ; ----------------------------- -; [steps: 11, bin: 1, arith: 2] +; [steps: 4, bin: 0, arith: 1] ; ----------------------------- mulFpBN254: - ; 1] Compute and check the sum over Z - ; A·B + [0] = [D]·2²⁵⁶ + [E] + ; A·B + 0 = op (mod BN254_P) 0 => C - $${var _mulFpBN254_AB = A*B} - ${_mulFpBN254_AB >> 256} => D - ${_mulFpBN254_AB} => E :ARITH - - ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[(A·B) / p] + [C / p] = D·2²⁵⁶ + E - ; where C < BN254_P - %BN254_P => A - ${_mulFpBN254_AB / const.BN254_P} => B ; quotient (256 bits) - ${_mulFpBN254_AB % const.BN254_P} => C ; residue (256 bits) - E :ARITH - - ; 3] Check that the result is lower than BN254_P - A => B - C => A - 1 :LT, RETURN \ No newline at end of file + %BN254_P => D + ${(A*B) % D} => E :ARITH_MOD + E => C :RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/reduceFpBN254.zkasm b/main/pairings/FPBN254/reduceFpBN254.zkasm index 44d08c1d..7b84dfdb 100644 --- a/main/pairings/FPBN254/reduceFpBN254.zkasm +++ b/main/pairings/FPBN254/reduceFpBN254.zkasm @@ -11,20 +11,13 @@ VAR GLOBAL reduceFpBN254_tmp ; RESOURCES: ; ----------------------------- -; [steps: 9, bin: 1, arith: 1] +; [steps: 5, bin: 0, arith: 1] ; ----------------------------- reduceFpBN254: - ; 1] It must be satisfied that: - ; [BN254_P]·[A / p] + [A % p] = [0]·2²⁵⁶ + A - A :MSTORE(reduceFpBN254_tmp) - ${A / const.BN254_P} => B ; quotient (256 bits) - ${A % const.BN254_P} => C ; residue (256 bits) - %BN254_P => A - 0n => D - $ :MLOAD(reduceFpBN254_tmp), ARITH - - ; 2] Check the the residue is less than p - A => B - C => A - 1 :LT, RETURN \ No newline at end of file + ; A·1 + 0 = op (mod BN254_P) + 1 => B + 0 => C + %BN254_P => D + ${A % D} => E :ARITH_MOD + E => A :RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/squareFpBN254.zkasm b/main/pairings/FPBN254/squareFpBN254.zkasm index f876e5db..fb7cce0a 100644 --- a/main/pairings/FPBN254/squareFpBN254.zkasm +++ b/main/pairings/FPBN254/squareFpBN254.zkasm @@ -9,28 +9,13 @@ ; RESOURCES: ; ----------------------------- -; [steps: 13, bin: 1, arith: 2] +; [steps: 5, bin: 0, arith: 1] ; ----------------------------- squareFpBN254: - ; 1] Compute and check the inverse over Z - ; A·A + [0] = [D]·2²⁵⁶ + [E] + ; A·A + 0 = op (mod BN254_P) A => B 0 => C - $${var _squareFpBN254_AA = A * A} - ${_squareFpBN254_AA >> 256} => D - ${_squareFpBN254_AA} => E :ARITH - - ; 2] Check it over Fp, that is, it must be satisfied that: - ; [BN254_P]·[A² / p] + [A² % p] = D·2²⁵⁶ + E - ; where C < BN254_P - %BN254_P => A - ${_squareFpBN254_AA / const.BN254_P} => B ; quotient (256 bits) - ${_squareFpBN254_AA % const.BN254_P} => C ; residue (256 bits) - E :ARITH - - ; 3] Check that the result is lower than BN254_P - A => B - C => A - 1 :LT - A => B :RETURN \ No newline at end of file + %BN254_P => D + ${(A*A) % D} => E :ARITH_MOD + E => B :RETURN \ No newline at end of file diff --git a/main/pairings/FPBN254/subFpBN254.zkasm b/main/pairings/FPBN254/subFpBN254.zkasm index d86549f6..361e53a4 100644 --- a/main/pairings/FPBN254/subFpBN254.zkasm +++ b/main/pairings/FPBN254/subFpBN254.zkasm @@ -10,14 +10,17 @@ ; RESOURCES: ; ----------------------------- -; [steps: 12, bin: 1, arith: 2] +; PATH A >= C: [steps: 3, bin: 1, arith: 0] +; PATH A < C: [steps: 7, bin: 3, arith: 0] <-- w.c. ; ----------------------------- subFpBN254: C => B - $ => C :SUB, JMPC(subFpBN254_addp) + $ => C :SUB, JMPC(subFpBN254_add_alias) :RETURN -subFpBN254_addp: +subFpBN254_add_alias: + ; if A < C, then we must compute A + BN254_P - C + ; NOTE: 5·BN254_P < 2²⁵⁶ < 6·BN254_P B => C ; save for later use diff --git a/main/pairings/FRBN254/reduceFrBN254.zkasm b/main/pairings/FRBN254/reduceFrBN254.zkasm index 1c83e2fc..dcb1d4dd 100644 --- a/main/pairings/FRBN254/reduceFrBN254.zkasm +++ b/main/pairings/FRBN254/reduceFrBN254.zkasm @@ -7,24 +7,15 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -VAR GLOBAL reduceFrBN254_tmp - ; RESOURCES: ; ----------------------------- -; [steps: 9, bin: 1, arith: 1] +; [steps: 5, bin: 0, arith: 1] ; ----------------------------- reduceFrBN254: - ; 1] It must be satisfied that: - ; [BN254_R]·[B / r] + [B % r] = [0]·2²⁵⁶ + E - B :MSTORE(reduceFrBN254_tmp) - ${B % const.BN254_R} => C ; residue (256 bits) - ${B / const.BN254_R} => B ; quotient (256 bits) - %BN254_R => A - 0n => D - $ :MLOAD(reduceFrBN254_tmp), ARITH - - ; 2] Check the the residue is less than r - A => B - C => A - 1 :LT, RETURN \ No newline at end of file + ; 1·B + 0 = op (mod BN254_R) + 1 => A + 0 => C + %BN254_R => D + ${B % D} => E :ARITH_MOD + E => A :RETURN \ No newline at end of file diff --git a/package.json b/package.json index 024df269..cb8c02d6 100644 --- a/package.json +++ b/package.json @@ -39,13 +39,13 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#develop-feijoa", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/arith-mod", "yargs": "^17.5.1" }, "devDependencies": { - "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#develop-feijoa", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#develop-feijoa", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#develop-feijoa", + "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-fork.7", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#feature/modular-arith", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#v4.0.0-fork.7", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0", diff --git a/test/testFp2ArithBN254.zkasm b/test/testFp2ArithBN254.zkasm index 7d2c83ec..d4d3d4be 100644 --- a/test/testFp2ArithBN254.zkasm +++ b/test/testFp2ArithBN254.zkasm @@ -114,30 +114,6 @@ start: D => A 1287543698343486777779200337956310299335077126899871980158178699685013306387n :ASSERT - %BN254_P => A - 0n => B - :CALL(invFp2BN254) - C => A - 0 :ASSERT - D => A - 0 :ASSERT - - 0n => A - %BN254_P => B - :CALL(invFp2BN254) - C => A - 0 :ASSERT - D => A - 0 :ASSERT - - %BN254_P => A - %BN254_P + 67n => B - :CALL(invFp2BN254) - C => A - 0n :ASSERT - D => A - 326690192117004107794722473809810075950691211302952591980433401412615316546n :ASSERT - ; 4] Squaring 1n => A 4n => B diff --git a/test/testFpArithBN254.zkasm b/test/testFpArithBN254.zkasm index 3b2bc356..b00d8a5c 100644 --- a/test/testFpArithBN254.zkasm +++ b/test/testFpArithBN254.zkasm @@ -79,26 +79,6 @@ start: B => A 0n :ASSERT - %BN254_P + %BN254_P => A - :CALL(invFpBN254) - B => A - 0n :ASSERT - - %BN254_P + %BN254_P + %BN254_P => A - :CALL(invFpBN254) - B => A - 0n :ASSERT - - %BN254_P + %BN254_P + %BN254_P + %BN254_P => A - :CALL(invFpBN254) - B => A - 0n :ASSERT - - %BN254_P + %BN254_P + %BN254_P + %BN254_P + %BN254_P => A - :CALL(invFpBN254) - B => A - 0n :ASSERT - 2n => A :CALL(invFpBN254) B => A diff --git a/test/testFrArithBN254.zkasm b/test/testFrArithBN254.zkasm index 0ae8cfa7..a2f5b9e5 100644 --- a/test/testFrArithBN254.zkasm +++ b/test/testFrArithBN254.zkasm @@ -54,33 +54,27 @@ start: ; 1] Reduction 3n => B :CALL(reduceFrBN254) - C => A - 3n => B :ASSERT + 3n :ASSERT %BN254_R => B :CALL(reduceFrBN254) - C => A - 0n => B :ASSERT + 0n :ASSERT 21888242871839275222246405745257275088548364400416034343698204186575808495618n => B :CALL(reduceFrBN254) - C => A - 1n => B :ASSERT + 1n :ASSERT %BN254_P => B :CALL(reduceFrBN254) - C => A - %BN254_SIX_TIMES_X_SQ => B :ASSERT + 147946756881789318990833708069417712966n :ASSERT 21888242871839275222246405745257275088696311157297823662689037894645226208584n => B :CALL(reduceFrBN254) - C => A - 147946756881789318990833708069417712967n => B :ASSERT + 147946756881789318990833708069417712967n :ASSERT 115792089237316195423570985008687907853269984665640564039457584007913129639935n => B :CALL(reduceFrBN254) - C => A - 6350874878119819312338956282401532410528162663560392320966563075034087161850n => B :ASSERT + 6350874878119819312338956282401532410528162663560392320966563075034087161850n :ASSERT end: From 9fb12a480605083ef07729d24cd5746f68dc49e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 7 Feb 2024 14:25:13 +0100 Subject: [PATCH 04/12] Upadte package and GHA --- .github/workflows/main.yaml | 2 +- package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index b29465e8..b13303f1 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -37,4 +37,4 @@ jobs: run: | export NUM_CPUS=31 npm run test:start - sh tools/parallel-testing/checker.sh + sh tools/parallel-testing/checker.sh \ No newline at end of file diff --git a/package.json b/package.json index cb8c02d6..80e540e6 100644 --- a/package.json +++ b/package.json @@ -39,12 +39,12 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#feature/arith-mod", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#v4.0.0-fork.7", "yargs": "^17.5.1" }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-fork.7", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#feature/modular-arith", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#develop-feijoa", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#v4.0.0-fork.7", "chai": "^4.3.6", "chalk": "^3.0.0", From 99c2d42f6d29cae70c20b116b4cd1a8b54bdfaf8 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Sun, 31 Dec 2023 01:53:27 +0100 Subject: [PATCH 05/12] readPush optimization --- main/opcodes/stack-operations.zkasm | 2 +- main/utils.zkasm | 256 +++++++++++++++++++---- test/read-push-ed.zkasm | 304 ++++++++++++++++++++++++++++ 3 files changed, 526 insertions(+), 36 deletions(-) create mode 100644 test/read-push-ed.zkasm diff --git a/main/opcodes/stack-operations.zkasm b/main/opcodes/stack-operations.zkasm index ef669de5..d0cc3913 100644 --- a/main/opcodes/stack-operations.zkasm +++ b/main/opcodes/stack-operations.zkasm @@ -135,7 +135,7 @@ opAuxPUSHA2: ; check out-of-gas GAS - %GAS_FASTEST_STEP => GAS :JMPN(outOfGas) ; read bytes from calldata - D => E :CALL(readPush); in: [D,E: bytes to read] out: [E: value read] + D => E :CALL(readPushTable); in: [D,E: bytes to read] out: [E: value read] ; store stack output E :MSTORE(SP++); [pushed_value(E) => SP] ; check stack overflow diff --git a/main/utils.zkasm b/main/utils.zkasm index 48d25adf..73a61a53 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -771,11 +771,16 @@ VAR GLOBAL pushBytes_RR ; @info Read bytes opcode PUSHX ; @internalParam {numBlocks} 4 bytes blocks to read ; @internalParam {leftBytes} remaining bytes -; @in D,E => bytes to read (1..32) +; @in D => bytes to read (1..32) ; @out E => value read readPush: :JMP(@readPush+E) ;0 +; readPush: +; D => E +; readPushTable: +; :JMP(@readPushTable+E) ;0 + readPush1: PC => HASHPOS :JMP(_readPush1) ;1 readPush2: @@ -842,92 +847,273 @@ readPush32: PC => HASHPOS :JMP(_readPush32) ;32 _readPush1: + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + $ => E :MLOAD(contractHashId) $ => E :HASHP1(E),RETURN _readPush2: + %MAX_CNT_STEPS - STEP - 7 :JMPN(outOfCountersStep) + $ => E :MLOAD(contractHashId) - $ => C :HASHP1(E) - C * 256 + $ => E :F_HASHP1(E), RETURN + $ => D :HASHP1(E) + $ => E :HASHP1(E) + D * 256 + E => E + 2 => D :RETURN _readPush3: + %MAX_CNT_STEPS - STEP - 8 :JMPN(outOfCountersStep) + $ => E :MLOAD(contractHashId) $ => A :HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => E :F_HASHP1(E), RETURN + $ => D :HASHP1(E) + $ => E :HASHP1(E) + A * 2**16 + D * 2**8 + E => E + 3 => D :RETURN _readPush4: + %MAX_CNT_STEPS - STEP - 8 :JMPN(outOfCountersStep) + $ => E :MLOAD(contractHashId) $ => A :HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => E :F_HASHP1(E), RETURN + $ => D :HASHP1(E) + A * 2**8 + D => A + $ => D :HASHP1(E) + $ => E :HASHP1(E) + A * 2**16 + D * 2**8 + E => E + 4 => D :RETURN + _readPush32: + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + $ => E :MLOAD(contractHashId) + $ => B :HASHP1(E) + $ => RCX :HASHP1(E) + $ => D :HASHP1(E) $ => A :HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => C :F_HASHP1(E) + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C ; 28 bytes + $ => B :HASHP1(E) + $ => RCX :HASHP1(E) + $ => D :HASHP1(E) $ => A :HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - ROTL_C + A * 256 + $ => C :F_HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C ; 24 bytes + $ => B :HASHP1(E) + $ => RCX :HASHP1(E) + $ => D :HASHP1(E) $ => A :HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - ROTL_C + A * 256 + $ => C :F_HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C ; 20 bytes + $ => B :HASHP1(E) + $ => RCX :HASHP1(E) + $ => D :HASHP1(E) $ => A :HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - ROTL_C + A * 256 + $ => C :F_HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C ; 16 bytes + $ => B :HASHP1(E) + $ => RCX :HASHP1(E) + $ => D :HASHP1(E) $ => A :HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - ROTL_C + A * 256 + $ => C :F_HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C ; 12 bytes + $ => B :HASHP1(E) + $ => RCX :HASHP1(E) + $ => D :HASHP1(E) $ => A :HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - ROTL_C + A * 256 + $ => C :F_HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C ; 8 bytes + $ => B :HASHP1(E) + $ => RCX :HASHP1(E) + $ => D :HASHP1(E) $ => A :HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - ROTL_C + A * 256 + $ => C :F_HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C ; 4 bytes + $ => B :HASHP1(E) + $ => RCX :HASHP1(E) + $ => D :HASHP1(E) $ => A :HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - A * 256 + $ => A :F_HASHP1(E) - ROTL_C + A * 256 + $ => E :F_HASHP1(E),RETURN + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => E -_readPushBaseTable: + $ => RCX :MLOAD(pushBytes_RR) + 32 => D :RETURN _readPushX: + %MAX_CNT_STEPS - STEP - 20 - D :JMPN(outOfCountersStep) + D => A,E :MSTORE(pushBytes) + $ => B :MLOAD(contractHashId) readPushBytes: - 0 => A, C - B => E :JMP(@_readPushBaseTable - E) + B => E :JMP(@readPushBytes + E) + + 0 => RCX, B, D, A, C :JMP(readPushBytes_1) + 0 => RCX, B, D, A, C :JMP(readPushBytes_2) + 0 => RCX, B, D, A, C :JMP(readPushBytes_3) + 0 => RCX, B, D, A, C :JMP(readPushBytes_4) + 0 => RCX, B, D, A, C :JMP(readPushBytes_5) + 0 => RCX, B, D, A, C :JMP(readPushBytes_6) + 0 => RCX, B, D, A, C :JMP(readPushBytes_7) + 0 => RCX, B, D, A, C :JMP(readPushBytes_8) + 0 => RCX, B, D, A, C :JMP(readPushBytes_9) + 0 => RCX, B, D, A, C :JMP(readPushBytes_10) + 0 => RCX, B, D, A, C :JMP(readPushBytes_11) + 0 => RCX, B, D, A, C :JMP(readPushBytes_12) + 0 => RCX, B, D, A, C :JMP(readPushBytes_13) + 0 => RCX, B, D, A, C :JMP(readPushBytes_14) + 0 => RCX, B, D, A, C :JMP(readPushBytes_15) + 0 => RCX, B, D, A, C :JMP(readPushBytes_16) + 0 => RCX, B, D, A, C :JMP(readPushBytes_17) + 0 => RCX, B, D, A, C :JMP(readPushBytes_18) + 0 => RCX, B, D, A, C :JMP(readPushBytes_19) + 0 => RCX, B, D, A, C :JMP(readPushBytes_20) + 0 => RCX, B, D, A, C :JMP(readPushBytes_21) + 0 => RCX, B, D, A, C :JMP(readPushBytes_22) + 0 => RCX, B, D, A, C :JMP(readPushBytes_23) + 0 => RCX, B, D, A, C :JMP(readPushBytes_24) + 0 => RCX, B, D, A, C :JMP(readPushBytes_25) + 0 => RCX, B, D, A, C :JMP(readPushBytes_26) + 0 => RCX, B, D, A, C :JMP(readPushBytes_27) + 0 => RCX, B, D, A, C :JMP(readPushBytes_28) + 0 => RCX, B, D, A, C :JMP(readPushBytes_29) + 0 => RCX, B, D, A, C :JMP(readPushBytes_30) + 0 => RCX, B, D, A, C :JMP(readPushBytes_31) + 0 => RCX, B, D, A, C :JMP(readPushBytes_32) + +readPushBytes_32: + $ => B :HASHP1(E) +readPushBytes_31: + $ => RCX :HASHP1(E) +readPushBytes_30: + $ => D :HASHP1(E) +readPushBytes_29: + $ => A :HASHP1(E) + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C + +readPushBytes_28: + $ => B :HASHP1(E) +readPushBytes_27: + $ => RCX :HASHP1(E) +readPushBytes_26: + $ => D :HASHP1(E) +readPushBytes_25: + $ => A :HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C + +readPushBytes_24: + $ => B :HASHP1(E) +readPushBytes_23: + $ => RCX :HASHP1(E) +readPushBytes_22: + $ => D :HASHP1(E) +readPushBytes_21: + $ => A :HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C + +readPushBytes_20: + $ => B :HASHP1(E) +readPushBytes_19: + $ => RCX :HASHP1(E) +readPushBytes_18: + $ => D :HASHP1(E) +readPushBytes_17: + $ => A :HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C + +readPushBytes_16: + $ => B :HASHP1(E) +readPushBytes_15: + $ => RCX :HASHP1(E) +readPushBytes_14: + $ => D :HASHP1(E) +readPushBytes_13: + $ => A :HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C + +readPushBytes_12: + $ => B :HASHP1(E) +readPushBytes_11: + $ => RCX :HASHP1(E) +readPushBytes_10: + $ => D :HASHP1(E) +readPushBytes_9: + $ => A :HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C + +readPushBytes_8: + $ => B :HASHP1(E) +readPushBytes_7: + $ => RCX :HASHP1(E) +readPushBytes_6: + $ => D :HASHP1(E) +readPushBytes_5: + $ => A :HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => C + +readPushBytes_4: + $ => B :HASHP1(E) +readPushBytes_3: + $ => RCX :HASHP1(E) +readPushBytes_2: + $ => D :HASHP1(E) +readPushBytes_1: + $ => A :HASHP1(E) + ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => E + + $ => D :MLOAD(pushBytes), RETURN + +VAR GLOBAL tmpVarDaddB +VAR GLOBAL tmpVarBaddB +VAR GLOBAL tmpZkPCaddB +VAR GLOBAL auxBytes + +;@info: adds data to batchHashdata byte by byte +;@in: A: bytes to add +;@in D: bytes length +addBatchHashByteByByte: + %MAX_CNT_STEPS - STEP - 10 :JMPN(outOfCountersStep) + RR :MSTORE(tmpZkPCaddB) + A :MSTORE(auxBytes) + D :MSTORE(tmpVarDaddB) + B :MSTORE(tmpVarBaddB) + 1 => D + +utilsAddBatchHashBytebyByteLoop: + %MAX_CNT_STEPS - STEP - 50 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 1 :JMPN(outOfCountersBinary) + 32 - D => D + $ => A :MLOAD(auxBytes), CALL(SHRarith); in: [A: value, D: #bytes to right shift] out: [A: shifted result] + ; get last byte in A + 0xFFn => B + $ => A :AND + D => B + ; add last byte to batchHashData + 1 => D :CALL(addBatchHashData); in:[D: length of the hash] + ; check loop + B => D + ; D + 1 => D, we set 33 instead of 32 to earn 1 step + 33 - D => D + $ => B :MLOAD(tmpVarDaddB) + D - B - 1 :JMPN(utilsAddBatchHashBytebyByteLoop) + $ => B :MLOAD(tmpVarBaddB) + $ => RR :MLOAD(tmpZkPCaddB) + :RETURN VAR GLOBAL startsWithEF ; @info check bytecode first byte != 0xEF as defined in EIP-3541 (https://eips.ethereum.org/EIPS/eip-3541) diff --git a/test/read-push-ed.zkasm b/test/read-push-ed.zkasm new file mode 100644 index 00000000..32358b8f --- /dev/null +++ b/test/read-push-ed.zkasm @@ -0,0 +1,304 @@ +VAR GLOBAL test + +;; Comments 'readPush' function +; @info Read bytes opcode PUSHX +; @internalParam {numBlocks} 4 bytes blocks to read +; @internalParam {leftBytes} remaining bytes +; @in D => bytes to read +; @out E => value read + +start: + ; init vars + 0 => HASHPOS + 1 => D + $${var rounds} + + ; add bytes one by one + 0x0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20n => A :CALL(initLoop) + 0x2122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F40n => A :CALL(initLoop) + 0x4142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60n => A :CALL(initLoop) + + ; close hash + HASHPOS :HASHPLEN(0) + $ :HASHPDIGEST(0) + 0 :MSTORE(contractHashId) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;;;; INIT TESTS ;;;;; + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ; log init counters + CNT_BINARY => A + ; ${log(A, binaryCouners)} ; result: 1 + STEP => A + ; ${log(A, stepCounter)} ; result: 202 + + ;; Start test PUSH1 + ; PUSH1 reading 1 byte at position 0 in the bytecode + 0 => PC + 1 => D,E :CALL(readPush) + 0x01 => A + E :ASSERT + + ; PUSH1 reading 1 byte at position 20 in the bytecode + 20 => PC + 1 => D,E :CALL(readPush) + 0x15 => A + E :ASSERT + + ; PUSH1 reading 1 byte at position 31 in the bytecode + 31 => PC + 1 => D,E :CALL(readPush) + 0x20 => A + E :ASSERT + + ; PUSH1 reading 1 byte at position 32 in the bytecode + 32 => PC + 1 => D,E :CALL(readPush) + 0x21 => A + E :ASSERT + + ; PUSH1 reading 1 byte at position 33 in the bytecode + 33 => PC + 1 => D,E :CALL(readPush) + 0x22 => A + E :ASSERT + + ;; Start test PUSH2 + ; PUSH2 reading 2 byte at position 4 in the bytecode + 4 => PC + 2 => D,E :CALL(readPush) + 0x0506 => A + E :ASSERT + + ; PUSH2 reading 2 byte at position 34 in the bytecode + 34 => PC + 2 => D,E :CALL(readPush) + 0x2324 => A + E :ASSERT + + ;; Start test PUSH3 + ; PUSH3 reading 3 byte at position 60 in the bytecode + 60 => PC + 3 => D,E :CALL(readPush) + 0x3d3e3f => A + E :ASSERT + + ;; Start test PUSH4 + ; PUSH4 reading 4 byte at position 72 in the bytecode + 72 => PC + 4 => D,E :CALL(readPush) + 0x494a4b4c => A + E :ASSERT + + ;; Start test PUSH5 + ; PUSH5 reading 5 byte at position 42 in the bytecode + 42 => PC + 5 => D,E :CALL(readPush) + 0x2B2C2D2E2Fn => A + E :ASSERT + + ;; Start test PUSH6 + ; PUSH6 reading 6 byte at position 42 in the bytecode + 42 => PC + 6 => D,E :CALL(readPush) + 0x2B2C2D2E2F30n => A + E :ASSERT + + ;; Start test PUSH7 + ; PUSH7 reading 7 byte at position 42 in the bytecode + 42 => PC + 7 => D,E :CALL(readPush) + 0x2B2C2D2E2F3031n => A + E :ASSERT + + ;; Start test PUSH8 + ; PUSH8 reading 8 byte at position 42 in the bytecode + 42 => PC + 8 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132n => A + E :ASSERT + + ;; Start test PUSH9 + ; PUSH9 reading 9 byte at position 42 in the bytecode + 42 => PC + 9 => D,E :CALL(readPush) + 0x2B2C2D2E2F30313233n => A + E :ASSERT + + ;; Start test PUSH10 + ; PUSH10 reading 10 byte at position 42 in the bytecode + 42 => PC + 10 => D,E :CALL(readPush) + 0x2B2C2D2E2F3031323334n => A + E :ASSERT + + ;; Start test PUSH11 + ; PUSH11 reading 11 byte at position 42 in the bytecode + 42 => PC + 11 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435n => A + E :ASSERT + + ;; Start test PUSH12 + ; PUSH12 reading 12 byte at position 42 in the bytecode + 42 => PC + 12 => D,E :CALL(readPush) + 0x2B2C2D2E2F30313233343536n => A + E :ASSERT + + ;; Start test PUSH13 + ; PUSH13 reading 13 byte at position 42 in the bytecode + 42 => PC + 13 => D,E :CALL(readPush) + 0x2B2C2D2E2F3031323334353637n => A + E :ASSERT + + ;; Start test PUSH14 + ; PUSH14 reading 14 byte at position 42 in the bytecode + 42 => PC + 14 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738n => A + E :ASSERT + + ;; Start test PUSH15 + ; PUSH15 reading 15 byte at position 42 in the bytecode + 42 => PC + 15 => D,E :CALL(readPush) + 0x2B2C2D2E2F30313233343536373839n => A + E :ASSERT + + ;; Start test PUSH16 + ; PUSH16 reading 16 byte at position 42 in the bytecode + 42 => PC + 16 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393An => A + E :ASSERT + + ;; Start test PUSH17 + ; PUSH17 reading 17 byte at position 42 in the bytecode + 42 => PC + 17 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3Bn => A + E :ASSERT + + ;; Start test PUSH18 + ; PUSH18 reading 18 byte at position 42 in the bytecode + 42 => PC + 18 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3Cn => A + E :ASSERT + + ;; Start test PUSH19 + ; PUSH19 reading 19 byte at position 42 in the bytecode + 42 => PC + 19 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3Dn => A + E :ASSERT + + ;; Start test PUSH20 + ; PUSH20 reading 20 byte at position 42 in the bytecode + 42 => PC + 20 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3En => A + E :ASSERT + + ;; Start test PUSH21 + ; PUSH21 reading 21 byte at position 42 in the bytecode + 42 => PC + 21 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3Fn => A + E :ASSERT + + ;; Start test PUSH22 + ; PUSH22 reading 22 byte at position 42 in the bytecode + 42 => PC + 22 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F40n => A + E :ASSERT + + ;; Start test PUSH23 + ; PUSH23 reading 23 byte at position 42 in the bytecode + 42 => PC + 23 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F4041n => A + E :ASSERT + + ;; Start test PUSH24 + ; PUSH24 reading 24 byte at position 42 in the bytecode + 42 => PC + 24 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142n => A + E :ASSERT + + ;; Start test PUSH25 + ; PUSH25 reading 25 byte at position 42 in the bytecode + 42 => PC + 25 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F40414243n => A + E :ASSERT + + ;; Start test PUSH26 + ; PUSH26 reading 26 byte at position 42 in the bytecode + 42 => PC + 26 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F4041424344n => A + E :ASSERT + + ;; Start test PUSH27 + ; PUSH27 reading 27 byte at position 42 in the bytecode + 42 => PC + 27 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445n => A + E :ASSERT + + ;; Start test PUSH28 + ; PUSH28 reading 28 byte at position 42 in the bytecode + 42 => PC + 28 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F40414243444546n => A + E :ASSERT + + ;; Start test PUSH29 + ; PUSH29 reading 29 byte at position 42 in the bytecode + 42 => PC + 29 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F4041424344454647n => A + E :ASSERT + + ;; Start test PUSH30 + ; PUSH30 reading 30 byte at position 42 in the bytecode + 42 => PC + 30 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748n => A + E :ASSERT + + ;; Start test PUSH31 + ; PUSH31 reading 31 byte at position 42 in the bytecode + 42 => PC + 31 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F40414243444546474849n => A + E :ASSERT + + ;; Start test PUSH32 + ; PUSH32 reading 32 byte at position 42 in the bytecode + 42 => PC + 32 => D,E :CALL(readPush) + 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494An => A + E :ASSERT + + 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, HASHPOS, RR ; Set all registers to 0 + :JMP(finalizeExecution) + +initLoop: + $${rounds = 32} + 0 => B ; to allow $$ + +loopAdd32Byte: + $${rounds = rounds - 1} + ${(A >> (rounds * 8)) & 0xFF} => E :HASHP1(0) + ${rounds} :JMPZ(endLoop, loopAdd32Byte) + +endLoop: + :RETURN + +INCLUDE "../main/main.zkasm" From 8b99d572a4b58ed9ca3d0670a54729d157aada59 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Mon, 8 Jan 2024 14:07:54 +0100 Subject: [PATCH 06/12] update counters read push --- main/utils.zkasm | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/main/utils.zkasm b/main/utils.zkasm index 73a61a53..4c17d6a7 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -847,7 +847,7 @@ readPush32: PC => HASHPOS :JMP(_readPush32) ;32 _readPush1: - %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 2 :JMPN(outOfCountersStep) $ => E :MLOAD(contractHashId) $ => E :HASHP1(E),RETURN @@ -856,32 +856,28 @@ _readPush2: %MAX_CNT_STEPS - STEP - 7 :JMPN(outOfCountersStep) $ => E :MLOAD(contractHashId) - $ => D :HASHP1(E) + $ => C :HASHP1(E) $ => E :HASHP1(E) - D * 256 + E => E - 2 => D :RETURN + C * 256 + E => E :RETURN _readPush3: - %MAX_CNT_STEPS - STEP - 8 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 5 :JMPN(outOfCountersStep) $ => E :MLOAD(contractHashId) $ => A :HASHP1(E) - $ => D :HASHP1(E) + $ => C :HASHP1(E) $ => E :HASHP1(E) - A * 2**16 + D * 2**8 + E => E - 3 => D :RETURN + A * 2**16 + C * 2**8 + E => E :RETURN _readPush4: - %MAX_CNT_STEPS - STEP - 8 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 6 :JMPN(outOfCountersStep) $ => E :MLOAD(contractHashId) $ => A :HASHP1(E) - $ => D :HASHP1(E) - A * 2**8 + D => A - $ => D :HASHP1(E) + $ => B :HASHP1(E) + $ => C :HASHP1(E) $ => E :HASHP1(E) - A * 2**16 + D * 2**8 + E => E - 4 => D :RETURN + A * 2**24 + B * 2**16 + C * 2**8 + E => E :RETURN _readPush32: @@ -961,7 +957,7 @@ _readPushX: $ => B :MLOAD(contractHashId) readPushBytes: - B => E :JMP(@readPushBytes + E) + B => E :JMP(@readPushBytes + E) 0 => RCX, B, D, A, C :JMP(readPushBytes_1) 0 => RCX, B, D, A, C :JMP(readPushBytes_2) From 7b262287648be1907de5a1270379194a7468ace4 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Mon, 8 Jan 2024 15:41:27 +0100 Subject: [PATCH 07/12] fix readPush call --- main/opcodes/stack-operations.zkasm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/opcodes/stack-operations.zkasm b/main/opcodes/stack-operations.zkasm index d0cc3913..ef669de5 100644 --- a/main/opcodes/stack-operations.zkasm +++ b/main/opcodes/stack-operations.zkasm @@ -135,7 +135,7 @@ opAuxPUSHA2: ; check out-of-gas GAS - %GAS_FASTEST_STEP => GAS :JMPN(outOfGas) ; read bytes from calldata - D => E :CALL(readPushTable); in: [D,E: bytes to read] out: [E: value read] + D => E :CALL(readPush); in: [D,E: bytes to read] out: [E: value read] ; store stack output E :MSTORE(SP++); [pushed_value(E) => SP] ; check stack overflow From 245a557e44bdc8162e36c600de810d8dd9a66ec6 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Tue, 9 Jan 2024 06:59:49 +0100 Subject: [PATCH 08/12] update readPush test to use D,E for bytes --- main/utils.zkasm | 9 +- test/read-push-ed.zkasm | 304 ---------------------------------------- 2 files changed, 2 insertions(+), 311 deletions(-) delete mode 100644 test/read-push-ed.zkasm diff --git a/main/utils.zkasm b/main/utils.zkasm index 4c17d6a7..be7cec9b 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -771,16 +771,11 @@ VAR GLOBAL pushBytes_RR ; @info Read bytes opcode PUSHX ; @internalParam {numBlocks} 4 bytes blocks to read ; @internalParam {leftBytes} remaining bytes -; @in D => bytes to read (1..32) +; @in D,E => bytes to read (1..32) ; @out E => value read readPush: :JMP(@readPush+E) ;0 -; readPush: -; D => E -; readPushTable: -; :JMP(@readPushTable+E) ;0 - readPush1: PC => HASHPOS :JMP(_readPush1) ;1 readPush2: @@ -947,7 +942,6 @@ _readPush32: $ => A :HASHP1(E) ROTL_C + 2**24 * B + 2**16 * RCX + 2**8 * D + A => E - $ => RCX :MLOAD(pushBytes_RR) 32 => D :RETURN _readPushX: @@ -992,6 +986,7 @@ readPushBytes: 0 => RCX, B, D, A, C :JMP(readPushBytes_31) 0 => RCX, B, D, A, C :JMP(readPushBytes_32) + readPushBytes_32: $ => B :HASHP1(E) readPushBytes_31: diff --git a/test/read-push-ed.zkasm b/test/read-push-ed.zkasm deleted file mode 100644 index 32358b8f..00000000 --- a/test/read-push-ed.zkasm +++ /dev/null @@ -1,304 +0,0 @@ -VAR GLOBAL test - -;; Comments 'readPush' function -; @info Read bytes opcode PUSHX -; @internalParam {numBlocks} 4 bytes blocks to read -; @internalParam {leftBytes} remaining bytes -; @in D => bytes to read -; @out E => value read - -start: - ; init vars - 0 => HASHPOS - 1 => D - $${var rounds} - - ; add bytes one by one - 0x0102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20n => A :CALL(initLoop) - 0x2122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F40n => A :CALL(initLoop) - 0x4142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F60n => A :CALL(initLoop) - - ; close hash - HASHPOS :HASHPLEN(0) - $ :HASHPDIGEST(0) - 0 :MSTORE(contractHashId) - - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;;;;; INIT TESTS ;;;;; - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ; log init counters - CNT_BINARY => A - ; ${log(A, binaryCouners)} ; result: 1 - STEP => A - ; ${log(A, stepCounter)} ; result: 202 - - ;; Start test PUSH1 - ; PUSH1 reading 1 byte at position 0 in the bytecode - 0 => PC - 1 => D,E :CALL(readPush) - 0x01 => A - E :ASSERT - - ; PUSH1 reading 1 byte at position 20 in the bytecode - 20 => PC - 1 => D,E :CALL(readPush) - 0x15 => A - E :ASSERT - - ; PUSH1 reading 1 byte at position 31 in the bytecode - 31 => PC - 1 => D,E :CALL(readPush) - 0x20 => A - E :ASSERT - - ; PUSH1 reading 1 byte at position 32 in the bytecode - 32 => PC - 1 => D,E :CALL(readPush) - 0x21 => A - E :ASSERT - - ; PUSH1 reading 1 byte at position 33 in the bytecode - 33 => PC - 1 => D,E :CALL(readPush) - 0x22 => A - E :ASSERT - - ;; Start test PUSH2 - ; PUSH2 reading 2 byte at position 4 in the bytecode - 4 => PC - 2 => D,E :CALL(readPush) - 0x0506 => A - E :ASSERT - - ; PUSH2 reading 2 byte at position 34 in the bytecode - 34 => PC - 2 => D,E :CALL(readPush) - 0x2324 => A - E :ASSERT - - ;; Start test PUSH3 - ; PUSH3 reading 3 byte at position 60 in the bytecode - 60 => PC - 3 => D,E :CALL(readPush) - 0x3d3e3f => A - E :ASSERT - - ;; Start test PUSH4 - ; PUSH4 reading 4 byte at position 72 in the bytecode - 72 => PC - 4 => D,E :CALL(readPush) - 0x494a4b4c => A - E :ASSERT - - ;; Start test PUSH5 - ; PUSH5 reading 5 byte at position 42 in the bytecode - 42 => PC - 5 => D,E :CALL(readPush) - 0x2B2C2D2E2Fn => A - E :ASSERT - - ;; Start test PUSH6 - ; PUSH6 reading 6 byte at position 42 in the bytecode - 42 => PC - 6 => D,E :CALL(readPush) - 0x2B2C2D2E2F30n => A - E :ASSERT - - ;; Start test PUSH7 - ; PUSH7 reading 7 byte at position 42 in the bytecode - 42 => PC - 7 => D,E :CALL(readPush) - 0x2B2C2D2E2F3031n => A - E :ASSERT - - ;; Start test PUSH8 - ; PUSH8 reading 8 byte at position 42 in the bytecode - 42 => PC - 8 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132n => A - E :ASSERT - - ;; Start test PUSH9 - ; PUSH9 reading 9 byte at position 42 in the bytecode - 42 => PC - 9 => D,E :CALL(readPush) - 0x2B2C2D2E2F30313233n => A - E :ASSERT - - ;; Start test PUSH10 - ; PUSH10 reading 10 byte at position 42 in the bytecode - 42 => PC - 10 => D,E :CALL(readPush) - 0x2B2C2D2E2F3031323334n => A - E :ASSERT - - ;; Start test PUSH11 - ; PUSH11 reading 11 byte at position 42 in the bytecode - 42 => PC - 11 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435n => A - E :ASSERT - - ;; Start test PUSH12 - ; PUSH12 reading 12 byte at position 42 in the bytecode - 42 => PC - 12 => D,E :CALL(readPush) - 0x2B2C2D2E2F30313233343536n => A - E :ASSERT - - ;; Start test PUSH13 - ; PUSH13 reading 13 byte at position 42 in the bytecode - 42 => PC - 13 => D,E :CALL(readPush) - 0x2B2C2D2E2F3031323334353637n => A - E :ASSERT - - ;; Start test PUSH14 - ; PUSH14 reading 14 byte at position 42 in the bytecode - 42 => PC - 14 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738n => A - E :ASSERT - - ;; Start test PUSH15 - ; PUSH15 reading 15 byte at position 42 in the bytecode - 42 => PC - 15 => D,E :CALL(readPush) - 0x2B2C2D2E2F30313233343536373839n => A - E :ASSERT - - ;; Start test PUSH16 - ; PUSH16 reading 16 byte at position 42 in the bytecode - 42 => PC - 16 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393An => A - E :ASSERT - - ;; Start test PUSH17 - ; PUSH17 reading 17 byte at position 42 in the bytecode - 42 => PC - 17 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3Bn => A - E :ASSERT - - ;; Start test PUSH18 - ; PUSH18 reading 18 byte at position 42 in the bytecode - 42 => PC - 18 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3Cn => A - E :ASSERT - - ;; Start test PUSH19 - ; PUSH19 reading 19 byte at position 42 in the bytecode - 42 => PC - 19 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3Dn => A - E :ASSERT - - ;; Start test PUSH20 - ; PUSH20 reading 20 byte at position 42 in the bytecode - 42 => PC - 20 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3En => A - E :ASSERT - - ;; Start test PUSH21 - ; PUSH21 reading 21 byte at position 42 in the bytecode - 42 => PC - 21 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3Fn => A - E :ASSERT - - ;; Start test PUSH22 - ; PUSH22 reading 22 byte at position 42 in the bytecode - 42 => PC - 22 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F40n => A - E :ASSERT - - ;; Start test PUSH23 - ; PUSH23 reading 23 byte at position 42 in the bytecode - 42 => PC - 23 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F4041n => A - E :ASSERT - - ;; Start test PUSH24 - ; PUSH24 reading 24 byte at position 42 in the bytecode - 42 => PC - 24 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142n => A - E :ASSERT - - ;; Start test PUSH25 - ; PUSH25 reading 25 byte at position 42 in the bytecode - 42 => PC - 25 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F40414243n => A - E :ASSERT - - ;; Start test PUSH26 - ; PUSH26 reading 26 byte at position 42 in the bytecode - 42 => PC - 26 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F4041424344n => A - E :ASSERT - - ;; Start test PUSH27 - ; PUSH27 reading 27 byte at position 42 in the bytecode - 42 => PC - 27 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445n => A - E :ASSERT - - ;; Start test PUSH28 - ; PUSH28 reading 28 byte at position 42 in the bytecode - 42 => PC - 28 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F40414243444546n => A - E :ASSERT - - ;; Start test PUSH29 - ; PUSH29 reading 29 byte at position 42 in the bytecode - 42 => PC - 29 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F4041424344454647n => A - E :ASSERT - - ;; Start test PUSH30 - ; PUSH30 reading 30 byte at position 42 in the bytecode - 42 => PC - 30 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748n => A - E :ASSERT - - ;; Start test PUSH31 - ; PUSH31 reading 31 byte at position 42 in the bytecode - 42 => PC - 31 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F40414243444546474849n => A - E :ASSERT - - ;; Start test PUSH32 - ; PUSH32 reading 32 byte at position 42 in the bytecode - 42 => PC - 32 => D,E :CALL(readPush) - 0x2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494An => A - E :ASSERT - - 0 => A,B,C,D,E,CTX, SP, PC, GAS, SR, HASHPOS, RR ; Set all registers to 0 - :JMP(finalizeExecution) - -initLoop: - $${rounds = 32} - 0 => B ; to allow $$ - -loopAdd32Byte: - $${rounds = rounds - 1} - ${(A >> (rounds * 8)) & 0xFF} => E :HASHP1(0) - ${rounds} :JMPZ(endLoop, loopAdd32Byte) - -endLoop: - :RETURN - -INCLUDE "../main/main.zkasm" From e6450fe7b2bac55e1f61d654b361c015c8a28153 Mon Sep 17 00:00:00 2001 From: zkronos73 Date: Wed, 7 Feb 2024 12:50:37 +0100 Subject: [PATCH 09/12] adjust steps on counter verification --- main/utils.zkasm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/utils.zkasm b/main/utils.zkasm index be7cec9b..ef48efba 100644 --- a/main/utils.zkasm +++ b/main/utils.zkasm @@ -848,7 +848,7 @@ _readPush1: $ => E :HASHP1(E),RETURN _readPush2: - %MAX_CNT_STEPS - STEP - 7 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 4 :JMPN(outOfCountersStep) $ => E :MLOAD(contractHashId) $ => C :HASHP1(E) From d99f8c16104ed431b74cb92ce5439e64b3d2cb5e Mon Sep 17 00:00:00 2001 From: krlosMata Date: Mon, 5 Feb 2024 22:20:37 +0100 Subject: [PATCH 10/12] allow gha on develop-feijoa --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 80e540e6..322fb025 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-fork.7", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#develop-feijoa", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#feature/precompiled-optz", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#v4.0.0-fork.7", "chai": "^4.3.6", "chalk": "^3.0.0", From 77a655e99a88e571f8e7ce2d98555b4fa67e745c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Wed, 7 Feb 2024 13:32:34 +0100 Subject: [PATCH 11/12] Upadte package --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 322fb025..80e540e6 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-fork.7", - "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#feature/precompiled-optz", + "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#develop-feijoa", "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#v4.0.0-fork.7", "chai": "^4.3.6", "chalk": "^3.0.0", From d8011e4c4b393b454b2886aab6375c12b833fabb Mon Sep 17 00:00:00 2001 From: krlosMata Date: Wed, 7 Feb 2024 22:56:59 +0100 Subject: [PATCH 12/12] update to fork.8 --- main/constants.zkasm | 2 +- package.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/main/constants.zkasm b/main/constants.zkasm index a8224fb5..b84eb7da 100644 --- a/main/constants.zkasm +++ b/main/constants.zkasm @@ -6,7 +6,7 @@ CONST %BATCH_DIFFICULTY = 0 CONST %TX_GAS_LIMIT = 30000000 CONSTL %BLOCK_GAS_LIMIT = 2**50 CONST %MAX_MEM_EXPANSION_BYTES = 0x3fffe0 -CONST %FORK_ID = 10 +CONST %FORK_ID = 8 CONST %L1INFO_TREE_LEVELS = 32 CONST %CALLDATA_RESERVED_CTX = 1 CONSTL %FOUR_GOLDILOCKS = 0xffffffff00000001ffffffff00000001ffffffff00000001ffffffff00000001n diff --git a/package.json b/package.json index 80e540e6..c38335ef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@0xpolygonhermez/zkevm-rom", - "version": "7.0.0", + "version": "5.0.0", "description": "zkROM source code", "main": "index.js", "scripts": { @@ -39,13 +39,13 @@ "url": "https://github.com/0xPolygonHermez/zkevm-rom.git" }, "dependencies": { - "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#v4.0.0-fork.7", + "@0xpolygonhermez/zkasmcom": "https://github.com/0xPolygonHermez/zkasmcom.git#develop", "yargs": "^17.5.1" }, "devDependencies": { "@0xpolygonhermez/zkevm-commonjs": "github:0xPolygonHermez/zkevm-commonjs#v4.0.0-fork.7", "@0xpolygonhermez/zkevm-proverjs": "github:0xPolygonHermez/zkevm-proverjs#develop-feijoa", - "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#v4.0.0-fork.7", + "@0xpolygonhermez/zkevm-testvectors": "github:0xPolygonHermez/zkevm-testvectors#feature/update-forkid-8", "chai": "^4.3.6", "chalk": "^3.0.0", "eslint": "^8.25.0",