From 72cd72d9200917a566c54d4a090273df2b044c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Mon, 5 Feb 2024 17:59:02 +0100 Subject: [PATCH 1/4] Refactor and huge optmization of the ecrecover --- .../FNSECP256K1/invFnSecp256k1.zkasm | 42 + .../FNSECP256K1/mulFnSecp256k1.zkasm | 28 + .../FPSECP256K1/addFpSecp256k1.zkasm | 29 + .../FPSECP256K1/checkSqrtFpSecp256k1.zkasm | 1564 +++++++++++++++ .../FPSECP256K1/invFpSecp256k1.zkasm | 42 + .../FPSECP256K1/mulFpSecp256k1.zkasm | 28 + .../FPSECP256K1/sqrtFpSecp256k1.zkasm | 58 + .../FPSECP256K1/squareFpSecp256k1.zkasm | 30 + main/ecrecover/addFpEc.zkasm | 31 - main/ecrecover/checkSqrtFpEc.zkasm | 1558 --------------- main/ecrecover/constEc.zkasm | 13 - main/ecrecover/constSecp256k1.zkasm | 16 + main/ecrecover/dblScalarMulSecp256k1.zkasm | 1695 +++++++++++++++++ main/ecrecover/ecrecover.zkasm | 197 +- main/ecrecover/invFnEc.zkasm | 44 - main/ecrecover/invFpEc.zkasm | 45 - main/ecrecover/mulFnEc.zkasm | 36 - main/ecrecover/mulFpEc.zkasm | 36 - main/ecrecover/mulPointEc.zkasm | 311 --- main/ecrecover/sqFpEc.zkasm | 38 - main/ecrecover/sqrtFpEc.zkasm | 70 - test/ecrecover.zkasm | 47 +- 22 files changed, 3656 insertions(+), 2302 deletions(-) create mode 100644 main/ecrecover/FNSECP256K1/invFnSecp256k1.zkasm create mode 100644 main/ecrecover/FNSECP256K1/mulFnSecp256k1.zkasm create mode 100644 main/ecrecover/FPSECP256K1/addFpSecp256k1.zkasm create mode 100644 main/ecrecover/FPSECP256K1/checkSqrtFpSecp256k1.zkasm create mode 100644 main/ecrecover/FPSECP256K1/invFpSecp256k1.zkasm create mode 100644 main/ecrecover/FPSECP256K1/mulFpSecp256k1.zkasm create mode 100644 main/ecrecover/FPSECP256K1/sqrtFpSecp256k1.zkasm create mode 100644 main/ecrecover/FPSECP256K1/squareFpSecp256k1.zkasm delete mode 100644 main/ecrecover/addFpEc.zkasm delete mode 100644 main/ecrecover/checkSqrtFpEc.zkasm delete mode 100644 main/ecrecover/constEc.zkasm create mode 100644 main/ecrecover/constSecp256k1.zkasm create mode 100644 main/ecrecover/dblScalarMulSecp256k1.zkasm delete mode 100644 main/ecrecover/invFnEc.zkasm delete mode 100644 main/ecrecover/invFpEc.zkasm delete mode 100644 main/ecrecover/mulFnEc.zkasm delete mode 100644 main/ecrecover/mulFpEc.zkasm delete mode 100644 main/ecrecover/mulPointEc.zkasm delete mode 100644 main/ecrecover/sqFpEc.zkasm delete mode 100644 main/ecrecover/sqrtFpEc.zkasm diff --git a/main/ecrecover/FNSECP256K1/invFnSecp256k1.zkasm b/main/ecrecover/FNSECP256K1/invFnSecp256k1.zkasm new file mode 100644 index 00000000..0a29a41c --- /dev/null +++ b/main/ecrecover/FNSECP256K1/invFnSecp256k1.zkasm @@ -0,0 +1,42 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: A is not alias-free +;; POST: The result B is not alias-free (on MAP) +;; +;; invFnSecp256k1: +;; in: A +;; out: B = A⁻¹ (mod n) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; RESOURCES: +; non-normalized: 2 ariths + 2 binaries + 13 steps +; normalized: 2 ariths + 1 binaries + 12 steps +; TOTAL (worst case): 2 ariths + 2 binaries + 13 steps + +VAR GLOBAL invFnSecp256k1_tmp + +invFnSecp256k1: + + ; Reduction of A + %SECP256K1_N => B + $ :LT, JMPC(invFnSecp256k1_normalized) + $ => A :SUB + +invFnSecp256k1_normalized: + + ; 1] Compute and check the inverse over Z + ; A·A⁻¹ + 0 = [D]·2²⁵⁶ + [E] + 0 => C + ${var _invFnSecp256k1_A = inverseFnEc(A)} => B :MSTORE(invFnSecp256k1_tmp) + $${var _invFnSecp256k1_AB = A * _invFnSecp256k1_A} + ${_invFnSecp256k1_AB >> 256} => D + ${_invFnSecp256k1_AB} => E :ARITH + + ; 2] Check it over Fn, that is, it must be satisfied that: + ; n·[(A·A⁻¹) / n] + 1 = D·2²⁵⁶ + E + %SECP256K1_N => A + ${_invFnSecp256k1_AB / const.SECP256K1_N} => B + 1 => C + E :ARITH + + $ => B :MLOAD(invFnSecp256k1_tmp), RETURN \ No newline at end of file diff --git a/main/ecrecover/FNSECP256K1/mulFnSecp256k1.zkasm b/main/ecrecover/FNSECP256K1/mulFnSecp256k1.zkasm new file mode 100644 index 00000000..7023d30c --- /dev/null +++ b/main/ecrecover/FNSECP256K1/mulFnSecp256k1.zkasm @@ -0,0 +1,28 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: A,B are not alias-free +;; POST: The result C is not alias-free (on MAP) +;; +;; mulFnSecp256k1: +;; in: A,B +;; out: C = A·B (mod n) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; RESOURCES: +; 2 arith + 8 steps + +mulFnSecp256k1: + + ; 1] Compute and check the multiplication over Z + ; A·B + 0 = [D]·2²⁵⁶ + [E] + 0 => C + $${var _mulFnSecp256k1_AB = A * B} + ${_mulFnSecp256k1_AB >> 256} => D + ${_mulFnSecp256k1_AB} => E :ARITH + + ; 2] Check it over Fn, that is, it must be satisfied that: + ; n·[(A·B) / n] + [(A·B) % n] = D·2²⁵⁶ + E + %SECP256K1_N => A + ${_mulFnSecp256k1_AB / const.SECP256K1_N} => B ; quotient (256 bits) + ${_mulFnSecp256k1_AB % const.SECP256K1_N} => C ; residue (256 bits) + E :ARITH, RETURN \ No newline at end of file diff --git a/main/ecrecover/FPSECP256K1/addFpSecp256k1.zkasm b/main/ecrecover/FPSECP256K1/addFpSecp256k1.zkasm new file mode 100644 index 00000000..444ef522 --- /dev/null +++ b/main/ecrecover/FPSECP256K1/addFpSecp256k1.zkasm @@ -0,0 +1,29 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: A,C are not alias-free +;; POST: The result C is not alias-free (on MAP) +;; +;; addFpSecp256k1: +;; in: A,C +;; out: C = A + C (mod p) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; RESOURCES: +; 2 ariths + 8 steps + +addFpSecp256k1: + + ; 1] Compute and check the sum over Z + ; A·[1] + C = [D]·2²⁵⁶ + [E] + 1 => B + $${var _addFpSecp256k1_AC = A + C} + ${_addFpSecp256k1_AC >> 256} => D + ${_addFpSecp256k1_AC} => E :ARITH + + ; 2] Check it over Fp, that is, it must be satisfied that: + ; p·[(A+C) / p] + [(A+C) % p] = D·2²⁵⁶ + E + %SECP256K1_P => A + ${_addFpSecp256k1_AC / const.SECP256K1_P} => B ; quotient (256 bits) + ${_addFpSecp256k1_AC % const.SECP256K1_P} => C ; residue (256 bits) + + E :ARITH, RETURN \ No newline at end of file diff --git a/main/ecrecover/FPSECP256K1/checkSqrtFpSecp256k1.zkasm b/main/ecrecover/FPSECP256K1/checkSqrtFpSecp256k1.zkasm new file mode 100644 index 00000000..4c0b80cc --- /dev/null +++ b/main/ecrecover/FPSECP256K1/checkSqrtFpSecp256k1.zkasm @@ -0,0 +1,1564 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: C is not alias free +;; POST: A ∈ {0,1} +;; +;; checkSqrtFpSecp256k1: +;; in: C +;; out: +;; · C = pow(C, (p-1)/2) ∈ {-1,0,1} +;; · A ∈ {0,1}: +;; * C == -1 ==> C hasn't root ==> A = 1 +;; * C ∈ {0,1} ==> C has root or C = 0 (mod p) ==> A = 0 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; This function is using Euler's criterion to determine if a given number is a quadratic residue modulo p + +; Efficiency of the exponentiation: +; (p-1)/2 = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffe17 +; (*) 222 x 1, 1 x 0, 22 x 1, 4 x 0, 1 x 1, 1 x 0, 3 x 1 +; (*) 222 x SM, S, 22 x SM, 4 x S, 1 x SM, 1 x S, 3 x SM (S=square M=multiplication) +; BLOCK: 1 2 3 4 5 6 7 +; (*) 222 + initial initialization + +VAR GLOBAL checkSqrtFpSecp256k1_base +VAR GLOBAL checkSqrtFpSecp256k1_RR + +checkSqrtFpSecp256k1: + ; RESOURCES: + ; 248 x (3 steps + 2 arith + 8 steps + 2 arith + 7 steps) = 992 ariths + 4464 steps + ; 6 x (1 step + 2 arith + 8 steps) = 12 ariths + 54 steps + ; 6 steps + 1 binary + ; TOTAL = 1004 ariths + 1 binary + 4524 steps + + RR :MSTORE(checkSqrtFpSecp256k1_RR) + C :MSTORE(checkSqrtFpSecp256k1_base) + + ; === BLOCK1: 1/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 2/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 3/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 4/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 5/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 6/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 7/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 8/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 9/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 10/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 11/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 12/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 13/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 14/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 15/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 16/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 17/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 18/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 19/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 20/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 21/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 22/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 23/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 24/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 25/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 26/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 27/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 28/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 29/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 30/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 31/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 32/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 33/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 34/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 35/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 36/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 37/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 38/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 39/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 40/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 41/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 42/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 43/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 44/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 45/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 46/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 47/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 48/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 49/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 50/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 51/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 52/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 53/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 54/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 55/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 56/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 57/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 58/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 59/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 60/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 61/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 62/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 63/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 64/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 65/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 66/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 67/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 68/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 69/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 70/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 71/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 72/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 73/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 74/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 75/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 76/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 77/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 78/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 79/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 80/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 81/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 82/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 83/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 84/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 85/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 86/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 87/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 88/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 89/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 90/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 91/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 92/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 93/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 94/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 95/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 96/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 97/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 98/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 99/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 100/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 101/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 102/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 103/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 104/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 105/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 106/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 107/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 108/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 109/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 110/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 111/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 112/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 113/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 114/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 115/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 116/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 117/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 118/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 119/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 120/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 121/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 122/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 123/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 124/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 125/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 126/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 127/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 128/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 129/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 130/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 131/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 132/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 133/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 134/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 135/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 136/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 137/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 138/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 139/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 140/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 141/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 142/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 143/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 144/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 145/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 146/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 147/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 148/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 149/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 150/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 151/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 152/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 153/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 154/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 155/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 156/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 157/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 158/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 159/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 160/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 161/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 162/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 163/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 164/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 165/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 166/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 167/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 168/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 169/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 170/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 171/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 172/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 173/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 174/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 175/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 176/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 177/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 178/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 179/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 180/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 181/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 182/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 183/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 184/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 185/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 186/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 187/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 188/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 189/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 190/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 191/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 192/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 193/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 194/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 195/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 196/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 197/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 198/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 199/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 200/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 201/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 202/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 203/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 204/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 205/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 206/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 207/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 208/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 209/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 210/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 211/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 212/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 213/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 214/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 215/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 216/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 217/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 218/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 219/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 220/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 221/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK1: 222/222 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + + + ; === BLOCK2: 1/1 SM === + + :CALL(squareFpSecp256k1) + + + + ; === BLOCK3: 1/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 2/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 3/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 4/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 5/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 6/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 7/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 8/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 9/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 10/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 11/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 12/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 13/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 14/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 15/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 16/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 17/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 18/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 19/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 20/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 21/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK3: 22/22 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + + ; === BLOCK4: 1/4 S === + + :CALL(squareFpSecp256k1) + + ; === BLOCK4: 2/4 S === + + :CALL(squareFpSecp256k1) + + ; === BLOCK4: 3/4 S === + + :CALL(squareFpSecp256k1) + + ; === BLOCK4: 4/4 S === + + :CALL(squareFpSecp256k1) + + + ; === BLOCK5: 1/1 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + + ; === BLOCK6: 1 SM === + + :CALL(squareFpSecp256k1) + + ; === BLOCK7: 1/3 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK7: 2/3 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; === BLOCK7: 3/3 SM === + + :CALL(squareFpSecp256k1) + $ => A :MLOAD(checkSqrtFpSecp256k1_base) + C => B :CALL(mulFpSecp256k1) + + ; Check if the result C = -1 (mod p) = p - 1 + %SECP256K1_P_MINUS_ONE => A + C => B + $ => RR :MLOAD(checkSqrtFpSecp256k1_RR) + + ; C == -1 ==> C hasn't root ==> A = 1 + ; C ∈ {0,1} ==> C has root or C = 0 (mod p) ==> A = 0 + + $ => A :EQ, RETURN \ No newline at end of file diff --git a/main/ecrecover/FPSECP256K1/invFpSecp256k1.zkasm b/main/ecrecover/FPSECP256K1/invFpSecp256k1.zkasm new file mode 100644 index 00000000..d41b564c --- /dev/null +++ b/main/ecrecover/FPSECP256K1/invFpSecp256k1.zkasm @@ -0,0 +1,42 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: A is not alias-free +;; POST: The result B is not alias-free (on MAP) +;; +;; invFpSecp256k1: +;; in: A +;; out: B = A⁻¹ (mod p) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; RESOURCES: +; non-normalized: 2 ariths + 2 binaries + 13 steps +; normalized: 2 ariths + 1 binaries + 12 steps +; TOTAL (worst case): 2 ariths + 2 binaries + 13 steps + +VAR GLOBAL invFpSecp256k1_tmp + +invFpSecp256k1: + + ; Reduction of A + %SECP256K1_P => B + $ :LT, JMPC(invFpSecp256k1_normalized) + $ => A :SUB + +invFpSecp256k1_normalized: + + ; 1] Compute and check the inverse over Z + ; A·A⁻¹ + 0 = [D]·2²⁵⁶ + [E] + 0 => C + ${var _invFpSecp256k1_A = inverseFpEc(A)} => B :MSTORE(invFpSecp256k1_tmp); + $${var _invFpSecp256k1_AB = A * _invFpSecp256k1_A} + ${_invFpSecp256k1_AB >> 256} => D + ${_invFpSecp256k1_AB} => E :ARITH + + ; 2] Check it over Fp, that is, it must be satisfied that: + ; p·[(A·A⁻¹) / p] + 1 = D·2²⁵⁶ + E + %SECP256K1_P => A + ${_invFpSecp256k1_AB / const.SECP256K1_P} => B ; quotient (256 bits) + 1 => C ; residue (1 bit) + E :ARITH + + $ => B :MLOAD(invFpSecp256k1_tmp), RETURN \ No newline at end of file diff --git a/main/ecrecover/FPSECP256K1/mulFpSecp256k1.zkasm b/main/ecrecover/FPSECP256K1/mulFpSecp256k1.zkasm new file mode 100644 index 00000000..f36e2068 --- /dev/null +++ b/main/ecrecover/FPSECP256K1/mulFpSecp256k1.zkasm @@ -0,0 +1,28 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: A,B are not alias-free +;; POST: The result C is not alias-free (on MAP) +;; +;; mulFpSecp256k1: +;; in: A,B +;; out: C = A·B (mod p) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; RESOURCES: +; 2 arith + 8 steps + +mulFpSecp256k1: + + ; 1] Compute and check the multiplication over Z + ; A·B + 0 = [D]·2²⁵⁶ + [E] + 0 => C + $${var _mulFpSecp256k1_AB = A * B} + ${_mulFpSecp256k1_AB >> 256} => D + ${_mulFpSecp256k1_AB} => E :ARITH + + ; 2] Check it over Fp, that is, it must be satisfied that: + ; p·[(A·B) / p] + [(A·B) % p] = D·2²⁵⁶ + E + %SECP256K1_P => A + ${_mulFpSecp256k1_AB / const.SECP256K1_P} => B ; quotient (256 bits) + ${_mulFpSecp256k1_AB % const.SECP256K1_P} => C ; residue (256 bits) + E :ARITH, RETURN \ No newline at end of file diff --git a/main/ecrecover/FPSECP256K1/sqrtFpSecp256k1.zkasm b/main/ecrecover/FPSECP256K1/sqrtFpSecp256k1.zkasm new file mode 100644 index 00000000..5420564d --- /dev/null +++ b/main/ecrecover/FPSECP256K1/sqrtFpSecp256k1.zkasm @@ -0,0 +1,58 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: A = [0,1] and C is not alias-free +;; POST: The result C is alias-free +;; +;; mulFpSecp256k1: +;; in: A,C, where A indicates the parity of the result +;; out: +;; · B = 1 or 0, depending on whether C has square root or not +;; · C = √C or -√C (mod p), if B = 1 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; RESOURCES: +; with sqrt: 2 arith + 1 binary + 15 steps +; without sqrt: 1 binary + 5 steps +; TOTAL (worst case): 2 arith + 1 binary + 15 steps + +VAR GLOBAL sqrtFpSecp256k1_tmp +VAR GLOBAL sqrtFpSecp256k1_res + +sqrtFpSecp256k1: + C :MSTORE(sqrtFpSecp256k1_tmp) + + ; start by free-inputing the square root of the input C + ; taking the positive one if A = 1, and the negative one if A = 0 + ${var _sqrtFpSecp256k1_sqrt = sqrtFpEcParity(C,A)} => A,C :MSTORE(sqrtFpSecp256k1_res) + + ; In this point we check whether A is LT than SECP256K1_P since, otherwise, either: + ; a) A doesn't have square root. 0 is returned in B. + ; b) A contains an alias, it's a MAP. 0 is returned in B. In this case, the proof cannot + ; be generated because we check in checkSqrtFpSecp256k1 if the root actually exists. + %SECP256K1_P => B + $ => B :LT, JMPNC(sqrtFpSecp256k1_NoRoot) + ; From here, A,C < SECP256K1_P + + ; 1] Compute and check the square over Z + ; √C·√C + 0 = [D]·2²⁵⁶ + [E] + A => B + 0 => C + $${var _sqrtFpSecp256k1_sq = _sqrtFpSecp256k1_sqrt * _sqrtFpSecp256k1_sqrt } + ${_sqrtFpSecp256k1_sq >> 256} => D + ${_sqrtFpSecp256k1_sq} => E :ARITH + + + ; 2] Check it over Fp, that is, it must be satisfied that: + ; p·[(√C·√C) / p] + C = D·2²⁵⁶ + E + %SECP256K1_P => A + ${_sqrtFpSecp256k1_sq / const.SECP256K1_P} => B ; quotient (256 bits) + $ => C :MLOAD(sqrtFpSecp256k1_tmp) ; residue (256 bits) + E :ARITH + + ; the result is guaranteed to be < SECP256K1_P, so we can skip the check + + 1 => B + $ => C :MLOAD(sqrtFpSecp256k1_res), RETURN + +sqrtFpSecp256k1_NoRoot: + :RETURN \ No newline at end of file diff --git a/main/ecrecover/FPSECP256K1/squareFpSecp256k1.zkasm b/main/ecrecover/FPSECP256K1/squareFpSecp256k1.zkasm new file mode 100644 index 00000000..9b835fda --- /dev/null +++ b/main/ecrecover/FPSECP256K1/squareFpSecp256k1.zkasm @@ -0,0 +1,30 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: C is not alias-free +;; POST: The result C is not alias-free (on MAP) +;; +;; squareFpSecp256k1: +;; in: C +;; out: C = C·C (mod p) +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; RESOURCES: +; 2 arith + 9 steps + +squareFpSecp256k1: + + ; 1] Compute and check the square over Z + ; A·A + 0 = [D]·2²⁵⁶ + [E] + C => A,B + 0n => C + $${var _squareFpSecp256k1_AA = A * A} + ${_squareFpSecp256k1_AA >> 256} => D + ${_squareFpSecp256k1_AA} => E :ARITH + + ; 2] Check it over Fp, that is, it must be satisfied that: + ; p·[A² / p] + [A² % p] = D·2²⁵⁶ + E + ${_squareFpSecp256k1_AA / const.SECP256K1_P} => B ; quotient (256 bits) + ${_squareFpSecp256k1_AA % const.SECP256K1_P} => C ; residue (256 bits) + %SECP256K1_P => A + + E :ARITH, RETURN \ No newline at end of file diff --git a/main/ecrecover/addFpEc.zkasm b/main/ecrecover/addFpEc.zkasm deleted file mode 100644 index 96986f10..00000000 --- a/main/ecrecover/addFpEc.zkasm +++ /dev/null @@ -1,31 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; addFpEc C = (A + C) % FpEc -;; -;; PRE: A,C no alias-free -;; POST: C no alias-free (on MAP) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; RESOURCES: -; 2 ariths + 7 steps - -addFpEc: - 1 => B - - ; A + C = [D] * 2 ** 256 + [E] - - $${var _addFpEc_AC = A + C} - - ${_addFpEc_AC >> 256} => D - ${_addFpEc_AC} => E :ARITH - - ; - ; with committed E,D - ; FpEc * [k] + [C] = D * 2 ** 256 + E - ; - - ${_addFpEc_AC / const.FPEC} => B ; times p - ${_addFpEc_AC % const.FPEC} => C ; A + C (256 bits) - %FPEC => A - - E :ARITH,RETURN \ No newline at end of file diff --git a/main/ecrecover/checkSqrtFpEc.zkasm b/main/ecrecover/checkSqrtFpEc.zkasm deleted file mode 100644 index 6f2440c1..00000000 --- a/main/ecrecover/checkSqrtFpEc.zkasm +++ /dev/null @@ -1,1558 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; checkSqrtFpEc (C = pow(C,(FpEc-1)/2)) -;; -;; (FpEc-1)/2 = 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff 7ffffe17 -;; (*) 222 x 1, 1 x 0, 22 x 1, 4 x 0, 1 x 1, 1 x 0, 3 x 1 -;; (*) 222 x SM, S, 22 x SM, 4 x S, 1 x SM, 1 x S, 3 x SM (S=square M=multiplication) -;; BLOCK: 1 2 3 4 5 6 7 -;; (*) 222 + initial initialization -;; -;; PRE: C no alias-free -;; POST: A in [0,1] -;; return A: A = 1 ==> C = -1 ==> hasn't root -;; A = 0 ==> C != -1 ==> has root or MAP, proof fails. -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -VAR GLOBAL checkSqrtFpEc_base -VAR GLOBAL checkSqrtFpEc_RR - -checkSqrtFpEc: - ; RESOURCES: - ; 248 x (3 steps + 2 arith + 8 steps + 2 arith + 7 steps) = 992 ariths + 4464 steps - ; 6 x (1 step + 2 arith + 8 steps) = 12 ariths + 54 steps - ; 6 steps + 1 binary - ; TOTAL = 1004 ariths + 1 binary + 4524 steps - - RR :MSTORE(checkSqrtFpEc_RR) - C :MSTORE(checkSqrtFpEc_base) - - ; === BLOCK1: 1/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 2/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 3/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 4/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 5/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 6/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 7/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 8/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 9/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 10/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 11/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 12/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 13/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 14/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 15/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 16/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 17/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 18/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 19/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 20/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 21/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 22/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 23/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 24/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 25/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 26/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 27/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 28/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 29/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 30/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 31/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 32/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 33/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 34/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 35/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 36/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 37/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 38/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 39/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 40/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 41/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 42/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 43/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 44/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 45/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 46/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 47/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 48/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 49/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 50/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 51/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 52/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 53/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 54/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 55/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 56/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 57/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 58/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 59/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 60/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 61/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 62/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 63/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 64/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 65/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 66/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 67/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 68/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 69/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 70/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 71/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 72/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 73/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 74/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 75/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 76/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 77/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 78/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 79/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 80/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 81/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 82/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 83/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 84/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 85/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 86/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 87/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 88/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 89/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 90/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 91/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 92/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 93/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 94/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 95/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 96/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 97/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 98/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 99/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 100/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 101/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 102/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 103/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 104/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 105/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 106/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 107/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 108/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 109/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 110/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 111/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 112/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 113/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 114/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 115/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 116/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 117/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 118/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 119/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 120/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 121/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 122/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 123/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 124/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 125/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 126/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 127/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 128/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 129/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 130/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 131/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 132/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 133/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 134/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 135/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 136/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 137/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 138/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 139/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 140/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 141/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 142/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 143/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 144/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 145/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 146/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 147/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 148/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 149/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 150/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 151/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 152/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 153/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 154/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 155/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 156/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 157/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 158/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 159/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 160/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 161/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 162/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 163/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 164/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 165/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 166/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 167/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 168/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 169/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 170/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 171/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 172/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 173/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 174/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 175/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 176/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 177/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 178/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 179/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 180/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 181/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 182/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 183/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 184/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 185/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 186/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 187/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 188/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 189/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 190/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 191/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 192/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 193/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 194/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 195/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 196/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 197/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 198/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 199/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 200/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 201/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 202/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 203/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 204/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 205/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 206/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 207/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 208/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 209/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 210/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 211/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 212/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 213/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 214/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 215/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 216/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 217/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 218/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 219/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 220/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 221/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK1: 222/222 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - - - ; === BLOCK2: 1/1 S === - - :CALL(sqFpEc) - - - - ; === BLOCK3: 1/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 2/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 3/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 4/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 5/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 6/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 7/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 8/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 9/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 10/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 11/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 12/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 13/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 14/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 15/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 16/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 17/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 18/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 19/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 20/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 21/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK3: 22/22 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - - ; === BLOCK4: 1/4 S === - - :CALL(sqFpEc) - - ; === BLOCK4: 2/4 S === - - :CALL(sqFpEc) - - ; === BLOCK4: 3/4 S === - - :CALL(sqFpEc) - - ; === BLOCK4: 4/4 S === - - :CALL(sqFpEc) - - - ; === BLOCK5: 1/1 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - - ; === BLOCK6: 1 SM === - - :CALL(sqFpEc) - - ; === BLOCK7: 1/3 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK7: 2/3 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - ; === BLOCK7: 3/3 SM === - - :CALL(sqFpEc) - $ => A :MLOAD(checkSqrtFpEc_base) - C => B :CALL(mulFpEc) - - - ; FPEC_MINUS_ONE hasn't alias of 256 bits - C => B - %FPEC_MINUS_ONE => A - $ => RR :MLOAD(checkSqrtFpEc_RR) - - ; A = 1 ==> C = -1 ==> hasn't root - ; A = 0 ==> C != -1 ==> has root or MAP, proof fails. - - $ => A :EQ,RETURN diff --git a/main/ecrecover/constEc.zkasm b/main/ecrecover/constEc.zkasm deleted file mode 100644 index b858190e..00000000 --- a/main/ecrecover/constEc.zkasm +++ /dev/null @@ -1,13 +0,0 @@ -CONSTL %FPEC = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2Fn -CONSTL %FPEC_MINUS_ONE = %FPEC - 1 -CONSTL %FNEC_DIV_TWO = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0n -CONSTL %FPEC_C2_256 = 0x1000003D1n -CONSTL %FPEC_NON_SQRT = (1n << 256n) - 1n - -CONSTL %FNEC = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141n -CONSTL %FNEC_MINUS_ONE = %FNEC - 1 - -CONSTL %ECGX = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798n -CONSTL %ECGY = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8n -CONSTL %P2_160 = 2n ** 160n -CONSTL %P2_96 = 2n ** 96n \ No newline at end of file diff --git a/main/ecrecover/constSecp256k1.zkasm b/main/ecrecover/constSecp256k1.zkasm new file mode 100644 index 00000000..5c6effb9 --- /dev/null +++ b/main/ecrecover/constSecp256k1.zkasm @@ -0,0 +1,16 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Constants of the Secp256k1 curve E: y² = x³ + 7 +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Basic constants: P = "base field order", N = "scalar field order" +CONSTL %SECP256K1_P = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2Fn +CONSTL %SECP256K1_P_MINUS_ONE = %SECP256K1_P - 1 +CONSTL %SECP256K1_N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141n +CONSTL %SECP256K1_N_MINUS_ONE = %SECP256K1_N - 1 +CONSTL %SECP256K1_N_DIV_TWO = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0n + +; Coordinates of the generator of the entire group E(Fp) +CONSTL %SECP256K1_GX = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798n +CONSTL %SECP256K1_GY = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8n \ No newline at end of file diff --git a/main/ecrecover/dblScalarMulSecp256k1.zkasm b/main/ecrecover/dblScalarMulSecp256k1.zkasm new file mode 100644 index 00000000..f5846ce7 --- /dev/null +++ b/main/ecrecover/dblScalarMulSecp256k1.zkasm @@ -0,0 +1,1695 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; PRE: p1 = (p1_x, p1_y), p2 = (p2_x, p2_y) are in E(Fp)\{𝒪} and p1_x,p1_y,p2_x,p2_y,k1,k2 are alias-free +;; POST: The resulting coordinates p3_x,p3_y are alias-free and variable p3_is_zero ∈ {0,1} +;; +;; dblScalarMulSecp256k1: +;; in: Points p1 = (p1_x, p1_y), p2 = (p2_x, p2_y) and scalars k1, k2 +;; out: +;; · p3 = (p3_x, p3_y) ∈ E(Fp) +;; · Variable p3_is_zero = 0 or 1, to indicate whether p3 is the point at infinity or not +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +; Since the curve is E: y² = x³ + 7, there is no issue in representing the point at infinity as (0, 0). + +VAR GLOBAL dblScalarMulSecp256k1_p1_x +VAR GLOBAL dblScalarMulSecp256k1_p1_y +VAR GLOBAL dblScalarMulSecp256k1_p2_x +VAR GLOBAL dblScalarMulSecp256k1_p2_y +VAR GLOBAL dblScalarMulSecp256k1_k1 +VAR GLOBAL dblScalarMulSecp256k1_k2 + +; p3 output point +VAR GLOBAL dblScalarMulSecp256k1_p3_x +VAR GLOBAL dblScalarMulSecp256k1_p3_y + +; point p12 = p1 + p2 +VAR GLOBAL dblScalarMulSecp256k1_p12_x +VAR GLOBAL dblScalarMulSecp256k1_p12_y + +; flag to indicate whether the resulting point p3 is the point at infinity +VAR GLOBAL dblScalarMulSecp256k1_p3_is_zero + +; dblScalarMulSecp256k1_p12_zero = 1 ==> p12 is the point at infinity +; dblScalarMulSecp256k1_p12_zero = 0 ==> p12 isn't the point at infinity +VAR GLOBAL dblScalarMulSecp256k1_p12_zero + +; acummulators +VAR GLOBAL dblScalarMulSecp256k1_acum_k1 +VAR GLOBAL dblScalarMulSecp256k1_acum_k2 + +; backups +VAR GLOBAL dblScalarMulSecp256k1_RR +VAR GLOBAL dblScalarMulSecp256k1_RCX + +; RESOURCES (k1,k2): +; 1 arith + 23 steps // setup, calculation p12 +; + number_of_bits_1(k1|k2) * arith // additions +; + max_bin_len(k1,k2) * arith // doubles +; + 29 * max_bin_len(k1,k2) // additions + doubles (steps, worst case) +; + (8 - 5) steps // last part - last part double no done +; - 1 arith // first assignation +; +; +; RESOURCES (worst case): 512 arith + 2 binaries + 7451 steps // 23 + 256 * 29 + 3 = 7451 + +dblScalarMulSecp256k1: + RR :MSTORE(dblScalarMulSecp256k1_RR) + + RCX :MSTORE(dblScalarMulSecp256k1_RCX) + + $0{receiveLen(mem.dblScalarMulSecp256k1_k1, mem.dblScalarMulSecp256k1_k2)} => RR ; receive the maximum length between the binary + ; representations of k1 and k2 + + ; start the acummulator of k1 and k2 + 0 => RCX :MSTORE(dblScalarMulSecp256k1_acum_k1) + 0 => HASHPOS :MSTORE(dblScalarMulSecp256k1_acum_k2) + + ; Initialize p3 = 𝒪 (it is symbolic, so we use a variable) + 1n :MSTORE(dblScalarMulSecp256k1_p3_is_zero) + + ; Start by precomputing P1 + P2 + $ => A :MLOAD(dblScalarMulSecp256k1_p1_x) + $ => B :MLOAD(dblScalarMulSecp256k1_p1_y) + $ => C :MLOAD(dblScalarMulSecp256k1_p2_x) + $ => D :MLOAD(dblScalarMulSecp256k1_p2_y) + + ; check p1_x == p2_x + ; [steps: 14] + ${A == C} :JMPZ(dblScalarMulSecp256k1DiffInitialPoints) + + ; verify path p1_x == p2_x + C :ASSERT + + ; check p1_y == p2_y + ; [steps: 16] + ${B == D} :JMPNZ(dblScalarMulSecp256k1SameInitialPoints) + + ; verify path p1_y != p2_y <==> p1_y = -p2_y or p1_y + p2_y = 0 + ; use arith because in this path save a lot of arith, + ; because when add p12 do nothing. + + ; x must be distinct from 0, because the square root of 7 doesn't exist (y² = x³ + 7) + ; y must be distinct from 0, because the cubic root of -7 doesn't exist (y² = x³ + 7) + + B => A ; A = p1_y + 1 => B + D => C ; C = p2_y + 0 => D ; check p1_y * 1 + p2_y = 0 * 2^256 * 0 + SECP256K1_P + %SECP256K1_P :ARITH + ; We have p2 == -p1 + + ; p12 = p1 - p1 = 𝒪, therefore is the point at infinity + ; [steps: 23] + 1n :MSTORE(dblScalarMulSecp256k1_p12_zero), JMP(dblScalarMulSecp256k1_loop) + +dblScalarMulSecp256k1SameInitialPoints: + ; [steps.before: 16] + ; verify path p1_y (B) == p2_y (D) + ; as an ASSERT(B == mulPointEc_p2_y) + B :MLOAD(dblScalarMulSecp256k1_p2_y) + + ; p12 = p1 + p1, therefore isn't the point at infinity + 0n :MSTORE(dblScalarMulSecp256k1_p12_zero) + + ; Compute and check the doubling p1 + p1 + ; A == p1_x + ; B == p1_y + ; (A,B) * 2 = (E, op) + ${xDblPointEc(A,B)} => E :MSTORE(dblScalarMulSecp256k1_p12_x) + ${yDblPointEc(A,B)} :ARITH_ECADD_SAME, MSTORE(dblScalarMulSecp256k1_p12_y), JMP(dblScalarMulSecp256k1_loop) + +dblScalarMulSecp256k1DiffInitialPoints: + ; [steps.before: 14] + ; verify path p1_x != p2_x + ; p2_x != p1_x ==> p2 != p1 + ; [MAP] if p1 == p2 => arith fails because p1 = p2 + + ; p12 = p1 + p2, therefore isn't the point at infinity + 0n :MSTORE(dblScalarMulSecp256k1_p12_zero) + + ; Compute and check the addition p1 + p2 + ; (A, B) + (C, D) = (E, op) + ${xAddPointEc(A,B,C,D)} => E :MSTORE(dblScalarMulSecp256k1_p12_x) + ${yAddPointEc(A,B,C,D)} :ARITH_ECADD_DIFFERENT, MSTORE(dblScalarMulSecp256k1_p12_y) + + +; [steps.before (worst case): 23] + +; Goes forward in different branches of code depending on the values of the +; most significant bits of k1 and k2. + +; [steps.byloop (worst case): 12 + 17 = 29] + +; [steps.byloop (p3initialempty.nolast): 12] +; [steps.byloop (bit.k1 || bit.k2 == 1): 8] +; [steps.byloop (bit.k1 && bit.k2 == 1): 12] + +dblScalarMulSecp256k1_loop: + ; Receive the next MSB bit of k1 + $0{(mem.dblScalarMulSecp256k1_k1 >> RR) & 0x1} :JMPNZ(dblScalarMulSecp256k1_k11) + +; high_bit(k1) == 0 high_bit(k2) == ?? +dblScalarMulSecp256k1_k10: + ; Receive the next MSB bit of k2 + $0{(mem.dblScalarMulSecp256k1_k2) >> RR & 0x1} :JMPZ(@dblScalarMulSecp256k1_scalar_table_k10_k20 + RR) + +; high_bit(k1) == 0 high_bit(k2) == 1 +dblScalarMulSecp256k1_k10_k21: + :JMP(@dblScalarMulSecp256k1_scalar_table_k10_k21 + RR) +dblScalarMulSecp256k1_k10_k21_continue: + $ => C :MLOAD(dblScalarMulSecp256k1_p2_x) + $ => D :MLOAD(dblScalarMulSecp256k1_p2_y), JMP(dblScalarMulSecp256k1_add) + +; high_bit(k1) == 1 high_bit(k2) == ?? +dblScalarMulSecp256k1_k11: + ; Receive the next MSB b of k2. + $0{(mem.dblScalarMulSecp256k1_k2) >> RR & 0x1} :JMPZ(@dblScalarMulSecp256k1_scalar_table_k11_k20 + RR) + +; high_bit(k1) == 1 high_bit(k2) == 1 +dblScalarMulSecp256k1_k11_k21: + :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part1 + RR) +dblScalarMulSecp256k1_k11_k21_continue: + ; if (dblScalarMulSecp256k1_p12_zero) k11_k21 is the same as k10_k20 + ; because adding the point at infinity to a point is the point itself + $ :MLOAD(dblScalarMulSecp256k1_p12_zero), JMPNZ(dblScalarMulSecp256k1_double) + + $ => C :MLOAD(dblScalarMulSecp256k1_p12_x) + $ => D :MLOAD(dblScalarMulSecp256k1_p12_y), JMP(dblScalarMulSecp256k1_add) + +; high_bit(k1) == 1 high_bit(k2) == 0 +dblScalarMulSecp256k1_k11_k20: + $ => C :MLOAD(dblScalarMulSecp256k1_p1_x) + $ => D :MLOAD(dblScalarMulSecp256k1_p1_y), JMP(dblScalarMulSecp256k1_add) +; [steps.loadp2 (worst case): 7 (regular case 6) + +; in this point C,D have point to be add +dblScalarMulSecp256k1_add: + ; [steps.p3empty.nolast: 10] + ; [steps.p3empty.last: 5] + ; [steps.xeq.yeq: 9 + steps.double = 15] + ; [steps.xeq.yneq: 11 + steps.double = 17] + ; [steps.xneq.nolast: 7 + steps.double = 13] + ; [steps.xneq.last: 7 + steps.double = 13] + ; [steps.block: 17] + + ; if p3 is the point at infinity do not add, just assign, since 𝒪 + P = P + $ :MLOAD(dblScalarMulSecp256k1_p3_is_zero), JMPNZ(dblScalarMulSecp256k1_p3_assignment) + + ; check whether p.x == p3.x + ${ C == mem.dblScalarMulSecp256k1_p3_x } :JMPNZ(dblScalarMulSecp256k1_x_equals_before_add) + + ; [MAP] if C == mem.dblScalarMulSecp256k1_p3_x ==> fails arithmetic because check + ; points are different + + ; p3 = (A,B) + $ => A :MLOAD(dblScalarMulSecp256k1_p3_x) + $ => B :MLOAD(dblScalarMulSecp256k1_p3_y) + + ; p3 = p3 + (C,D) + ; (C, D) is point to add (p1 or p2 or p12) + ; (A, B) + (C, D) = (E, op) + ${xAddPointEc(A,B,C,D)} => E :MSTORE(dblScalarMulSecp256k1_p3_x) + ${yAddPointEc(A,B,C,D)} => B :ARITH_ECADD_DIFFERENT, MSTORE(dblScalarMulSecp256k1_p3_y) + +dblScalarMulSecp256k1_after_add: + E => A :JMP(dblScalarMulSecp256k1_double) + +dblScalarMulSecp256k1_p3_assignment: + ; p3 = (C,D) + 0 :MSTORE(dblScalarMulSecp256k1_p3_is_zero) ; flag, dblScalarMulSecp256k1_p3 has a value, no-empty + C => A :MSTORE(dblScalarMulSecp256k1_p3_x) + D => B :MSTORE(dblScalarMulSecp256k1_p3_y) + +dblScalarMulSecp256k1_double: + ; [steps.last: 1] + ; [steps.nolast.p3empty: 2] + ; [steps.nolast.p3: 6] + ; [steps.block: 6] + + ; E,A = p3_x B = p3_y + RR - 1 => RR :JMPN(dblScalarMulSecp256k1_end_loop) + + ; if p3 is the point at infinity do not double, since 𝒪 + 𝒪 = 𝒪 + $ :MLOAD(dblScalarMulSecp256k1_p3_is_zero), JMPNZ(dblScalarMulSecp256k1_loop) + + $ => A :MLOAD(dblScalarMulSecp256k1_p3_x) + $ => B :MLOAD(dblScalarMulSecp256k1_p3_y) + + ; (A, B) * 2 = (E, op) + ${xDblPointEc(A,B)} => E :MSTORE(dblScalarMulSecp256k1_p3_x) + ${yDblPointEc(A,B)} :ARITH_ECADD_SAME, MSTORE(dblScalarMulSecp256k1_p3_y), JMP(dblScalarMulSecp256k1_loop) + +dblScalarMulSecp256k1_x_equals_before_add: + ; [steps.same.point: 7] + ; [steps.opposite.point: 9] + ; [steps.block: 9] + + ; [MAP] if C != mem.dblScalarMulSecp256k1_p3_x ==> fails, MLOAD fails because read something different + ; for memory. It verifies C and dblScalarMulSecp256k1_p3_x are same value, as an ASSERT. + C :MLOAD(dblScalarMulSecp256k1_p3_x) + + ; points to add: point1 (p3) + point2 (C,D) + + ; C: point2.x + ; D: point2.y + + ; p3_x == C, check if points are same or a point was opposite point + + ${ D == mem.dblScalarMulSecp256k1_p3_y } :JMPNZ(dblScalarMulSecp256k1_same_point_to_add) + + ; In this path must be verified that D != dblScalarMulSecp256k1_p3_y to + ; how p2_y and p3_y are different for same x, it implies that + ; p2_y == -p3_y. In this case next operation with p3 doesn't + ; spend arithmetics, for this reason is used an arithmetic + ; instead of binary to use similar resources on different paths. + + ; if p2_y == -p3_y, and them are alias free ==> p2_y + p3_y === SECP256K1_P + + 1 => B + D => A + 0 => D + $ => C :MLOAD(dblScalarMulSecp256k1_p3_y) + + ; p2_y * 1 + p3_y = 2^256 * 0 + SECP256K1_P + %SECP256K1_P :ARITH + + ; NOTE: all points are free of alias because arithmetic guarantees it + + ; dblScalarMulSecp256k1_p3_is_zero flag = 0, dblScalarMulSecp256k1_p3 was empty, need addition must be an assignation + 1n :MSTORE(dblScalarMulSecp256k1_p3_is_zero), JMP(dblScalarMulSecp256k1_double) + +dblScalarMulSecp256k1_same_point_to_add: + ; [steps.block: 5] + ; must check really are equals, use MLOAD as ASSERT + ; ASSERT(D == dblScalarMulSecp256k1_p3_y) + + D :MLOAD(dblScalarMulSecp256k1_p3_y) + C => A + D => B + + ; (A,B) * 2 = (E, op) + ${xDblPointEc(A,B)} => E :MSTORE(dblScalarMulSecp256k1_p3_x) + ${yDblPointEc(A,B)} => B :ARITH_ECADD_SAME, MSTORE(dblScalarMulSecp256k1_p3_y), JMP(dblScalarMulSecp256k1_after_add) + +dblScalarMulSecp256k1_end_loop: + ; [steps.block: 8] + + ; Check that the accumulated scalars coincide with the original ones + $ => A :MLOAD(dblScalarMulSecp256k1_k1) + $ => B :MLOAD(dblScalarMulSecp256k1_acum_k1) + 1 :EQ + $ => A :MLOAD(dblScalarMulSecp256k1_k2) + $ => B :MLOAD(dblScalarMulSecp256k1_acum_k2) + 1 :EQ + + $ => RR :MLOAD(dblScalarMulSecp256k1_RR) + $ => RCX :MLOAD(dblScalarMulSecp256k1_RCX), RETURN + +; Begin of table +dblScalarMulSecp256k1_save_k10_k20: + ROTL_C + RCX :MSTORE(dblScalarMulSecp256k1_acum_k1) + + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k2) + ROTL_C + HASHPOS :MSTORE(dblScalarMulSecp256k1_acum_k2) + + 0n => RCX,HASHPOS :JMP(dblScalarMulSecp256k1_double) + +dblScalarMulSecp256k1_save_k11_k20: + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1) + ROTL_C + RCX :MSTORE(dblScalarMulSecp256k1_acum_k1) + + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k2) + ROTL_C + HASHPOS :MSTORE(dblScalarMulSecp256k1_acum_k2) + + 0n => RCX,HASHPOS :JMP(dblScalarMulSecp256k1_k11_k20) + +dblScalarMulSecp256k1_save_k11_k21: + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1) + ROTL_C + RCX :MSTORE(dblScalarMulSecp256k1_acum_k1) + + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k2) + ROTL_C + HASHPOS :MSTORE(dblScalarMulSecp256k1_acum_k2) + + 0n => RCX,HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) + +dblScalarMulSecp256k1_save_k10_k21: + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1) + ROTL_C + RCX :MSTORE(dblScalarMulSecp256k1_acum_k1) + + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k2) + ROTL_C + HASHPOS :MSTORE(dblScalarMulSecp256k1_acum_k2) + + 0n => RCX,HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) + +; Sage code +; ---------------------------------------- +; binLen = 256 +; clock = 32 +; for i in range(binLen): +; latch = i % clock +; power = 2**latch +; a = f"{power:#0{10}x}" +; if (latch == 0): +; print("\t:JMP(dblScalarMulSecp256k1_save_k10_k20)\t; RR = {}".format(i)) +; else: +; print("\t:JMP(dblScalarMulSecp256k1_double)\t\t\t; RR = {}".format(i)) +; ---------------------------------------- +dblScalarMulSecp256k1_scalar_table_k10_k20: + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1), JMP(dblScalarMulSecp256k1_save_k10_k20) ; RR = 0 + :JMP(dblScalarMulSecp256k1_double) ; RR = 1 + :JMP(dblScalarMulSecp256k1_double) ; RR = 2 + :JMP(dblScalarMulSecp256k1_double) ; RR = 3 + :JMP(dblScalarMulSecp256k1_double) ; RR = 4 + :JMP(dblScalarMulSecp256k1_double) ; RR = 5 + :JMP(dblScalarMulSecp256k1_double) ; RR = 6 + :JMP(dblScalarMulSecp256k1_double) ; RR = 7 + :JMP(dblScalarMulSecp256k1_double) ; RR = 8 + :JMP(dblScalarMulSecp256k1_double) ; RR = 9 + :JMP(dblScalarMulSecp256k1_double) ; RR = 10 + :JMP(dblScalarMulSecp256k1_double) ; RR = 11 + :JMP(dblScalarMulSecp256k1_double) ; RR = 12 + :JMP(dblScalarMulSecp256k1_double) ; RR = 13 + :JMP(dblScalarMulSecp256k1_double) ; RR = 14 + :JMP(dblScalarMulSecp256k1_double) ; RR = 15 + :JMP(dblScalarMulSecp256k1_double) ; RR = 16 + :JMP(dblScalarMulSecp256k1_double) ; RR = 17 + :JMP(dblScalarMulSecp256k1_double) ; RR = 18 + :JMP(dblScalarMulSecp256k1_double) ; RR = 19 + :JMP(dblScalarMulSecp256k1_double) ; RR = 20 + :JMP(dblScalarMulSecp256k1_double) ; RR = 21 + :JMP(dblScalarMulSecp256k1_double) ; RR = 22 + :JMP(dblScalarMulSecp256k1_double) ; RR = 23 + :JMP(dblScalarMulSecp256k1_double) ; RR = 24 + :JMP(dblScalarMulSecp256k1_double) ; RR = 25 + :JMP(dblScalarMulSecp256k1_double) ; RR = 26 + :JMP(dblScalarMulSecp256k1_double) ; RR = 27 + :JMP(dblScalarMulSecp256k1_double) ; RR = 28 + :JMP(dblScalarMulSecp256k1_double) ; RR = 29 + :JMP(dblScalarMulSecp256k1_double) ; RR = 30 + :JMP(dblScalarMulSecp256k1_double) ; RR = 31 + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1), JMP(dblScalarMulSecp256k1_save_k10_k20) ; RR = 32 + :JMP(dblScalarMulSecp256k1_double) ; RR = 33 + :JMP(dblScalarMulSecp256k1_double) ; RR = 34 + :JMP(dblScalarMulSecp256k1_double) ; RR = 35 + :JMP(dblScalarMulSecp256k1_double) ; RR = 36 + :JMP(dblScalarMulSecp256k1_double) ; RR = 37 + :JMP(dblScalarMulSecp256k1_double) ; RR = 38 + :JMP(dblScalarMulSecp256k1_double) ; RR = 39 + :JMP(dblScalarMulSecp256k1_double) ; RR = 40 + :JMP(dblScalarMulSecp256k1_double) ; RR = 41 + :JMP(dblScalarMulSecp256k1_double) ; RR = 42 + :JMP(dblScalarMulSecp256k1_double) ; RR = 43 + :JMP(dblScalarMulSecp256k1_double) ; RR = 44 + :JMP(dblScalarMulSecp256k1_double) ; RR = 45 + :JMP(dblScalarMulSecp256k1_double) ; RR = 46 + :JMP(dblScalarMulSecp256k1_double) ; RR = 47 + :JMP(dblScalarMulSecp256k1_double) ; RR = 48 + :JMP(dblScalarMulSecp256k1_double) ; RR = 49 + :JMP(dblScalarMulSecp256k1_double) ; RR = 50 + :JMP(dblScalarMulSecp256k1_double) ; RR = 51 + :JMP(dblScalarMulSecp256k1_double) ; RR = 52 + :JMP(dblScalarMulSecp256k1_double) ; RR = 53 + :JMP(dblScalarMulSecp256k1_double) ; RR = 54 + :JMP(dblScalarMulSecp256k1_double) ; RR = 55 + :JMP(dblScalarMulSecp256k1_double) ; RR = 56 + :JMP(dblScalarMulSecp256k1_double) ; RR = 57 + :JMP(dblScalarMulSecp256k1_double) ; RR = 58 + :JMP(dblScalarMulSecp256k1_double) ; RR = 59 + :JMP(dblScalarMulSecp256k1_double) ; RR = 60 + :JMP(dblScalarMulSecp256k1_double) ; RR = 61 + :JMP(dblScalarMulSecp256k1_double) ; RR = 62 + :JMP(dblScalarMulSecp256k1_double) ; RR = 63 + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1), JMP(dblScalarMulSecp256k1_save_k10_k20) ; RR = 64 + :JMP(dblScalarMulSecp256k1_double) ; RR = 65 + :JMP(dblScalarMulSecp256k1_double) ; RR = 66 + :JMP(dblScalarMulSecp256k1_double) ; RR = 67 + :JMP(dblScalarMulSecp256k1_double) ; RR = 68 + :JMP(dblScalarMulSecp256k1_double) ; RR = 69 + :JMP(dblScalarMulSecp256k1_double) ; RR = 70 + :JMP(dblScalarMulSecp256k1_double) ; RR = 71 + :JMP(dblScalarMulSecp256k1_double) ; RR = 72 + :JMP(dblScalarMulSecp256k1_double) ; RR = 73 + :JMP(dblScalarMulSecp256k1_double) ; RR = 74 + :JMP(dblScalarMulSecp256k1_double) ; RR = 75 + :JMP(dblScalarMulSecp256k1_double) ; RR = 76 + :JMP(dblScalarMulSecp256k1_double) ; RR = 77 + :JMP(dblScalarMulSecp256k1_double) ; RR = 78 + :JMP(dblScalarMulSecp256k1_double) ; RR = 79 + :JMP(dblScalarMulSecp256k1_double) ; RR = 80 + :JMP(dblScalarMulSecp256k1_double) ; RR = 81 + :JMP(dblScalarMulSecp256k1_double) ; RR = 82 + :JMP(dblScalarMulSecp256k1_double) ; RR = 83 + :JMP(dblScalarMulSecp256k1_double) ; RR = 84 + :JMP(dblScalarMulSecp256k1_double) ; RR = 85 + :JMP(dblScalarMulSecp256k1_double) ; RR = 86 + :JMP(dblScalarMulSecp256k1_double) ; RR = 87 + :JMP(dblScalarMulSecp256k1_double) ; RR = 88 + :JMP(dblScalarMulSecp256k1_double) ; RR = 89 + :JMP(dblScalarMulSecp256k1_double) ; RR = 90 + :JMP(dblScalarMulSecp256k1_double) ; RR = 91 + :JMP(dblScalarMulSecp256k1_double) ; RR = 92 + :JMP(dblScalarMulSecp256k1_double) ; RR = 93 + :JMP(dblScalarMulSecp256k1_double) ; RR = 94 + :JMP(dblScalarMulSecp256k1_double) ; RR = 95 + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1), JMP(dblScalarMulSecp256k1_save_k10_k20) ; RR = 96 + :JMP(dblScalarMulSecp256k1_double) ; RR = 97 + :JMP(dblScalarMulSecp256k1_double) ; RR = 98 + :JMP(dblScalarMulSecp256k1_double) ; RR = 99 + :JMP(dblScalarMulSecp256k1_double) ; RR = 100 + :JMP(dblScalarMulSecp256k1_double) ; RR = 101 + :JMP(dblScalarMulSecp256k1_double) ; RR = 102 + :JMP(dblScalarMulSecp256k1_double) ; RR = 103 + :JMP(dblScalarMulSecp256k1_double) ; RR = 104 + :JMP(dblScalarMulSecp256k1_double) ; RR = 105 + :JMP(dblScalarMulSecp256k1_double) ; RR = 106 + :JMP(dblScalarMulSecp256k1_double) ; RR = 107 + :JMP(dblScalarMulSecp256k1_double) ; RR = 108 + :JMP(dblScalarMulSecp256k1_double) ; RR = 109 + :JMP(dblScalarMulSecp256k1_double) ; RR = 110 + :JMP(dblScalarMulSecp256k1_double) ; RR = 111 + :JMP(dblScalarMulSecp256k1_double) ; RR = 112 + :JMP(dblScalarMulSecp256k1_double) ; RR = 113 + :JMP(dblScalarMulSecp256k1_double) ; RR = 114 + :JMP(dblScalarMulSecp256k1_double) ; RR = 115 + :JMP(dblScalarMulSecp256k1_double) ; RR = 116 + :JMP(dblScalarMulSecp256k1_double) ; RR = 117 + :JMP(dblScalarMulSecp256k1_double) ; RR = 118 + :JMP(dblScalarMulSecp256k1_double) ; RR = 119 + :JMP(dblScalarMulSecp256k1_double) ; RR = 120 + :JMP(dblScalarMulSecp256k1_double) ; RR = 121 + :JMP(dblScalarMulSecp256k1_double) ; RR = 122 + :JMP(dblScalarMulSecp256k1_double) ; RR = 123 + :JMP(dblScalarMulSecp256k1_double) ; RR = 124 + :JMP(dblScalarMulSecp256k1_double) ; RR = 125 + :JMP(dblScalarMulSecp256k1_double) ; RR = 126 + :JMP(dblScalarMulSecp256k1_double) ; RR = 127 + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1), JMP(dblScalarMulSecp256k1_save_k10_k20) ; RR = 128 + :JMP(dblScalarMulSecp256k1_double) ; RR = 129 + :JMP(dblScalarMulSecp256k1_double) ; RR = 130 + :JMP(dblScalarMulSecp256k1_double) ; RR = 131 + :JMP(dblScalarMulSecp256k1_double) ; RR = 132 + :JMP(dblScalarMulSecp256k1_double) ; RR = 133 + :JMP(dblScalarMulSecp256k1_double) ; RR = 134 + :JMP(dblScalarMulSecp256k1_double) ; RR = 135 + :JMP(dblScalarMulSecp256k1_double) ; RR = 136 + :JMP(dblScalarMulSecp256k1_double) ; RR = 137 + :JMP(dblScalarMulSecp256k1_double) ; RR = 138 + :JMP(dblScalarMulSecp256k1_double) ; RR = 139 + :JMP(dblScalarMulSecp256k1_double) ; RR = 140 + :JMP(dblScalarMulSecp256k1_double) ; RR = 141 + :JMP(dblScalarMulSecp256k1_double) ; RR = 142 + :JMP(dblScalarMulSecp256k1_double) ; RR = 143 + :JMP(dblScalarMulSecp256k1_double) ; RR = 144 + :JMP(dblScalarMulSecp256k1_double) ; RR = 145 + :JMP(dblScalarMulSecp256k1_double) ; RR = 146 + :JMP(dblScalarMulSecp256k1_double) ; RR = 147 + :JMP(dblScalarMulSecp256k1_double) ; RR = 148 + :JMP(dblScalarMulSecp256k1_double) ; RR = 149 + :JMP(dblScalarMulSecp256k1_double) ; RR = 150 + :JMP(dblScalarMulSecp256k1_double) ; RR = 151 + :JMP(dblScalarMulSecp256k1_double) ; RR = 152 + :JMP(dblScalarMulSecp256k1_double) ; RR = 153 + :JMP(dblScalarMulSecp256k1_double) ; RR = 154 + :JMP(dblScalarMulSecp256k1_double) ; RR = 155 + :JMP(dblScalarMulSecp256k1_double) ; RR = 156 + :JMP(dblScalarMulSecp256k1_double) ; RR = 157 + :JMP(dblScalarMulSecp256k1_double) ; RR = 158 + :JMP(dblScalarMulSecp256k1_double) ; RR = 159 + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1), JMP(dblScalarMulSecp256k1_save_k10_k20) ; RR = 160 + :JMP(dblScalarMulSecp256k1_double) ; RR = 161 + :JMP(dblScalarMulSecp256k1_double) ; RR = 162 + :JMP(dblScalarMulSecp256k1_double) ; RR = 163 + :JMP(dblScalarMulSecp256k1_double) ; RR = 164 + :JMP(dblScalarMulSecp256k1_double) ; RR = 165 + :JMP(dblScalarMulSecp256k1_double) ; RR = 166 + :JMP(dblScalarMulSecp256k1_double) ; RR = 167 + :JMP(dblScalarMulSecp256k1_double) ; RR = 168 + :JMP(dblScalarMulSecp256k1_double) ; RR = 169 + :JMP(dblScalarMulSecp256k1_double) ; RR = 170 + :JMP(dblScalarMulSecp256k1_double) ; RR = 171 + :JMP(dblScalarMulSecp256k1_double) ; RR = 172 + :JMP(dblScalarMulSecp256k1_double) ; RR = 173 + :JMP(dblScalarMulSecp256k1_double) ; RR = 174 + :JMP(dblScalarMulSecp256k1_double) ; RR = 175 + :JMP(dblScalarMulSecp256k1_double) ; RR = 176 + :JMP(dblScalarMulSecp256k1_double) ; RR = 177 + :JMP(dblScalarMulSecp256k1_double) ; RR = 178 + :JMP(dblScalarMulSecp256k1_double) ; RR = 179 + :JMP(dblScalarMulSecp256k1_double) ; RR = 180 + :JMP(dblScalarMulSecp256k1_double) ; RR = 181 + :JMP(dblScalarMulSecp256k1_double) ; RR = 182 + :JMP(dblScalarMulSecp256k1_double) ; RR = 183 + :JMP(dblScalarMulSecp256k1_double) ; RR = 184 + :JMP(dblScalarMulSecp256k1_double) ; RR = 185 + :JMP(dblScalarMulSecp256k1_double) ; RR = 186 + :JMP(dblScalarMulSecp256k1_double) ; RR = 187 + :JMP(dblScalarMulSecp256k1_double) ; RR = 188 + :JMP(dblScalarMulSecp256k1_double) ; RR = 189 + :JMP(dblScalarMulSecp256k1_double) ; RR = 190 + :JMP(dblScalarMulSecp256k1_double) ; RR = 191 + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1), JMP(dblScalarMulSecp256k1_save_k10_k20) ; RR = 192 + :JMP(dblScalarMulSecp256k1_double) ; RR = 193 + :JMP(dblScalarMulSecp256k1_double) ; RR = 194 + :JMP(dblScalarMulSecp256k1_double) ; RR = 195 + :JMP(dblScalarMulSecp256k1_double) ; RR = 196 + :JMP(dblScalarMulSecp256k1_double) ; RR = 197 + :JMP(dblScalarMulSecp256k1_double) ; RR = 198 + :JMP(dblScalarMulSecp256k1_double) ; RR = 199 + :JMP(dblScalarMulSecp256k1_double) ; RR = 200 + :JMP(dblScalarMulSecp256k1_double) ; RR = 201 + :JMP(dblScalarMulSecp256k1_double) ; RR = 202 + :JMP(dblScalarMulSecp256k1_double) ; RR = 203 + :JMP(dblScalarMulSecp256k1_double) ; RR = 204 + :JMP(dblScalarMulSecp256k1_double) ; RR = 205 + :JMP(dblScalarMulSecp256k1_double) ; RR = 206 + :JMP(dblScalarMulSecp256k1_double) ; RR = 207 + :JMP(dblScalarMulSecp256k1_double) ; RR = 208 + :JMP(dblScalarMulSecp256k1_double) ; RR = 209 + :JMP(dblScalarMulSecp256k1_double) ; RR = 210 + :JMP(dblScalarMulSecp256k1_double) ; RR = 211 + :JMP(dblScalarMulSecp256k1_double) ; RR = 212 + :JMP(dblScalarMulSecp256k1_double) ; RR = 213 + :JMP(dblScalarMulSecp256k1_double) ; RR = 214 + :JMP(dblScalarMulSecp256k1_double) ; RR = 215 + :JMP(dblScalarMulSecp256k1_double) ; RR = 216 + :JMP(dblScalarMulSecp256k1_double) ; RR = 217 + :JMP(dblScalarMulSecp256k1_double) ; RR = 218 + :JMP(dblScalarMulSecp256k1_double) ; RR = 219 + :JMP(dblScalarMulSecp256k1_double) ; RR = 220 + :JMP(dblScalarMulSecp256k1_double) ; RR = 221 + :JMP(dblScalarMulSecp256k1_double) ; RR = 222 + :JMP(dblScalarMulSecp256k1_double) ; RR = 223 + $ => C :MLOAD(dblScalarMulSecp256k1_acum_k1), JMP(dblScalarMulSecp256k1_save_k10_k20) ; RR = 224 + :JMP(dblScalarMulSecp256k1_double) ; RR = 225 + :JMP(dblScalarMulSecp256k1_double) ; RR = 226 + :JMP(dblScalarMulSecp256k1_double) ; RR = 227 + :JMP(dblScalarMulSecp256k1_double) ; RR = 228 + :JMP(dblScalarMulSecp256k1_double) ; RR = 229 + :JMP(dblScalarMulSecp256k1_double) ; RR = 230 + :JMP(dblScalarMulSecp256k1_double) ; RR = 231 + :JMP(dblScalarMulSecp256k1_double) ; RR = 232 + :JMP(dblScalarMulSecp256k1_double) ; RR = 233 + :JMP(dblScalarMulSecp256k1_double) ; RR = 234 + :JMP(dblScalarMulSecp256k1_double) ; RR = 235 + :JMP(dblScalarMulSecp256k1_double) ; RR = 236 + :JMP(dblScalarMulSecp256k1_double) ; RR = 237 + :JMP(dblScalarMulSecp256k1_double) ; RR = 238 + :JMP(dblScalarMulSecp256k1_double) ; RR = 239 + :JMP(dblScalarMulSecp256k1_double) ; RR = 240 + :JMP(dblScalarMulSecp256k1_double) ; RR = 241 + :JMP(dblScalarMulSecp256k1_double) ; RR = 242 + :JMP(dblScalarMulSecp256k1_double) ; RR = 243 + :JMP(dblScalarMulSecp256k1_double) ; RR = 244 + :JMP(dblScalarMulSecp256k1_double) ; RR = 245 + :JMP(dblScalarMulSecp256k1_double) ; RR = 246 + :JMP(dblScalarMulSecp256k1_double) ; RR = 247 + :JMP(dblScalarMulSecp256k1_double) ; RR = 248 + :JMP(dblScalarMulSecp256k1_double) ; RR = 249 + :JMP(dblScalarMulSecp256k1_double) ; RR = 250 + :JMP(dblScalarMulSecp256k1_double) ; RR = 251 + :JMP(dblScalarMulSecp256k1_double) ; RR = 252 + :JMP(dblScalarMulSecp256k1_double) ; RR = 253 + :JMP(dblScalarMulSecp256k1_double) ; RR = 254 + :JMP(dblScalarMulSecp256k1_double) ; RR = 255 + +; Sage code +; ---------------------------------------- +; binLen = 256 +; clock = 32 +; for i in range(binLen): +; latch = i % clock +; power = 2**latch +; a = f"{power:#0{10}x}" +; if (latch == 0): +; print("\tRCX + {0}n => RCX\t\t:JMP(dblScalarMulSecp256k1_save_k11_k20)\t; RR = {1}".format(a,i)) +; else: +; print("\tRCX + {0}n => RCX\t\t:JMP(dblScalarMulSecp256k1_k11_k20_add)\t\t; RR = {1}".format(a,i)) +; ---------------------------------------- +dblScalarMulSecp256k1_scalar_table_k11_k20: + RCX + 0x00000001n => RCX :JMP(dblScalarMulSecp256k1_save_k11_k20) ; RR = 0 + RCX + 0x00000002n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 1 + RCX + 0x00000004n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 2 + RCX + 0x00000008n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 3 + RCX + 0x00000010n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 4 + RCX + 0x00000020n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 5 + RCX + 0x00000040n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 6 + RCX + 0x00000080n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 7 + RCX + 0x00000100n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 8 + RCX + 0x00000200n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 9 + RCX + 0x00000400n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 10 + RCX + 0x00000800n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 11 + RCX + 0x00001000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 12 + RCX + 0x00002000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 13 + RCX + 0x00004000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 14 + RCX + 0x00008000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 15 + RCX + 0x00010000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 16 + RCX + 0x00020000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 17 + RCX + 0x00040000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 18 + RCX + 0x00080000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 19 + RCX + 0x00100000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 20 + RCX + 0x00200000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 21 + RCX + 0x00400000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 22 + RCX + 0x00800000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 23 + RCX + 0x01000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 24 + RCX + 0x02000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 25 + RCX + 0x04000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 26 + RCX + 0x08000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 27 + RCX + 0x10000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 28 + RCX + 0x20000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 29 + RCX + 0x40000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 30 + RCX + 0x80000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 31 + RCX + 0x00000001n => RCX :JMP(dblScalarMulSecp256k1_save_k11_k20) ; RR = 32 + RCX + 0x00000002n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 33 + RCX + 0x00000004n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 34 + RCX + 0x00000008n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 35 + RCX + 0x00000010n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 36 + RCX + 0x00000020n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 37 + RCX + 0x00000040n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 38 + RCX + 0x00000080n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 39 + RCX + 0x00000100n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 40 + RCX + 0x00000200n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 41 + RCX + 0x00000400n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 42 + RCX + 0x00000800n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 43 + RCX + 0x00001000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 44 + RCX + 0x00002000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 45 + RCX + 0x00004000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 46 + RCX + 0x00008000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 47 + RCX + 0x00010000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 48 + RCX + 0x00020000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 49 + RCX + 0x00040000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 50 + RCX + 0x00080000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 51 + RCX + 0x00100000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 52 + RCX + 0x00200000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 53 + RCX + 0x00400000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 54 + RCX + 0x00800000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 55 + RCX + 0x01000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 56 + RCX + 0x02000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 57 + RCX + 0x04000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 58 + RCX + 0x08000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 59 + RCX + 0x10000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 60 + RCX + 0x20000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 61 + RCX + 0x40000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 62 + RCX + 0x80000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 63 + RCX + 0x00000001n => RCX :JMP(dblScalarMulSecp256k1_save_k11_k20) ; RR = 64 + RCX + 0x00000002n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 65 + RCX + 0x00000004n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 66 + RCX + 0x00000008n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 67 + RCX + 0x00000010n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 68 + RCX + 0x00000020n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 69 + RCX + 0x00000040n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 70 + RCX + 0x00000080n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 71 + RCX + 0x00000100n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 72 + RCX + 0x00000200n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 73 + RCX + 0x00000400n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 74 + RCX + 0x00000800n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 75 + RCX + 0x00001000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 76 + RCX + 0x00002000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 77 + RCX + 0x00004000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 78 + RCX + 0x00008000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 79 + RCX + 0x00010000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 80 + RCX + 0x00020000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 81 + RCX + 0x00040000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 82 + RCX + 0x00080000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 83 + RCX + 0x00100000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 84 + RCX + 0x00200000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 85 + RCX + 0x00400000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 86 + RCX + 0x00800000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 87 + RCX + 0x01000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 88 + RCX + 0x02000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 89 + RCX + 0x04000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 90 + RCX + 0x08000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 91 + RCX + 0x10000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 92 + RCX + 0x20000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 93 + RCX + 0x40000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 94 + RCX + 0x80000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 95 + RCX + 0x00000001n => RCX :JMP(dblScalarMulSecp256k1_save_k11_k20) ; RR = 96 + RCX + 0x00000002n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 97 + RCX + 0x00000004n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 98 + RCX + 0x00000008n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 99 + RCX + 0x00000010n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 100 + RCX + 0x00000020n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 101 + RCX + 0x00000040n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 102 + RCX + 0x00000080n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 103 + RCX + 0x00000100n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 104 + RCX + 0x00000200n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 105 + RCX + 0x00000400n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 106 + RCX + 0x00000800n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 107 + RCX + 0x00001000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 108 + RCX + 0x00002000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 109 + RCX + 0x00004000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 110 + RCX + 0x00008000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 111 + RCX + 0x00010000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 112 + RCX + 0x00020000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 113 + RCX + 0x00040000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 114 + RCX + 0x00080000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 115 + RCX + 0x00100000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 116 + RCX + 0x00200000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 117 + RCX + 0x00400000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 118 + RCX + 0x00800000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 119 + RCX + 0x01000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 120 + RCX + 0x02000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 121 + RCX + 0x04000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 122 + RCX + 0x08000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 123 + RCX + 0x10000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 124 + RCX + 0x20000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 125 + RCX + 0x40000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 126 + RCX + 0x80000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 127 + RCX + 0x00000001n => RCX :JMP(dblScalarMulSecp256k1_save_k11_k20) ; RR = 128 + RCX + 0x00000002n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 129 + RCX + 0x00000004n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 130 + RCX + 0x00000008n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 131 + RCX + 0x00000010n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 132 + RCX + 0x00000020n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 133 + RCX + 0x00000040n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 134 + RCX + 0x00000080n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 135 + RCX + 0x00000100n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 136 + RCX + 0x00000200n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 137 + RCX + 0x00000400n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 138 + RCX + 0x00000800n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 139 + RCX + 0x00001000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 140 + RCX + 0x00002000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 141 + RCX + 0x00004000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 142 + RCX + 0x00008000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 143 + RCX + 0x00010000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 144 + RCX + 0x00020000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 145 + RCX + 0x00040000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 146 + RCX + 0x00080000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 147 + RCX + 0x00100000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 148 + RCX + 0x00200000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 149 + RCX + 0x00400000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 150 + RCX + 0x00800000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 151 + RCX + 0x01000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 152 + RCX + 0x02000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 153 + RCX + 0x04000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 154 + RCX + 0x08000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 155 + RCX + 0x10000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 156 + RCX + 0x20000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 157 + RCX + 0x40000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 158 + RCX + 0x80000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 159 + RCX + 0x00000001n => RCX :JMP(dblScalarMulSecp256k1_save_k11_k20) ; RR = 160 + RCX + 0x00000002n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 161 + RCX + 0x00000004n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 162 + RCX + 0x00000008n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 163 + RCX + 0x00000010n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 164 + RCX + 0x00000020n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 165 + RCX + 0x00000040n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 166 + RCX + 0x00000080n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 167 + RCX + 0x00000100n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 168 + RCX + 0x00000200n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 169 + RCX + 0x00000400n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 170 + RCX + 0x00000800n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 171 + RCX + 0x00001000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 172 + RCX + 0x00002000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 173 + RCX + 0x00004000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 174 + RCX + 0x00008000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 175 + RCX + 0x00010000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 176 + RCX + 0x00020000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 177 + RCX + 0x00040000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 178 + RCX + 0x00080000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 179 + RCX + 0x00100000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 180 + RCX + 0x00200000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 181 + RCX + 0x00400000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 182 + RCX + 0x00800000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 183 + RCX + 0x01000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 184 + RCX + 0x02000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 185 + RCX + 0x04000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 186 + RCX + 0x08000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 187 + RCX + 0x10000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 188 + RCX + 0x20000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 189 + RCX + 0x40000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 190 + RCX + 0x80000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 191 + RCX + 0x00000001n => RCX :JMP(dblScalarMulSecp256k1_save_k11_k20) ; RR = 192 + RCX + 0x00000002n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 193 + RCX + 0x00000004n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 194 + RCX + 0x00000008n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 195 + RCX + 0x00000010n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 196 + RCX + 0x00000020n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 197 + RCX + 0x00000040n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 198 + RCX + 0x00000080n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 199 + RCX + 0x00000100n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 200 + RCX + 0x00000200n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 201 + RCX + 0x00000400n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 202 + RCX + 0x00000800n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 203 + RCX + 0x00001000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 204 + RCX + 0x00002000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 205 + RCX + 0x00004000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 206 + RCX + 0x00008000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 207 + RCX + 0x00010000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 208 + RCX + 0x00020000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 209 + RCX + 0x00040000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 210 + RCX + 0x00080000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 211 + RCX + 0x00100000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 212 + RCX + 0x00200000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 213 + RCX + 0x00400000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 214 + RCX + 0x00800000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 215 + RCX + 0x01000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 216 + RCX + 0x02000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 217 + RCX + 0x04000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 218 + RCX + 0x08000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 219 + RCX + 0x10000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 220 + RCX + 0x20000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 221 + RCX + 0x40000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 222 + RCX + 0x80000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 223 + RCX + 0x00000001n => RCX :JMP(dblScalarMulSecp256k1_save_k11_k20) ; RR = 224 + RCX + 0x00000002n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 225 + RCX + 0x00000004n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 226 + RCX + 0x00000008n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 227 + RCX + 0x00000010n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 228 + RCX + 0x00000020n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 229 + RCX + 0x00000040n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 230 + RCX + 0x00000080n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 231 + RCX + 0x00000100n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 232 + RCX + 0x00000200n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 233 + RCX + 0x00000400n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 234 + RCX + 0x00000800n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 235 + RCX + 0x00001000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 236 + RCX + 0x00002000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 237 + RCX + 0x00004000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 238 + RCX + 0x00008000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 239 + RCX + 0x00010000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 240 + RCX + 0x00020000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 241 + RCX + 0x00040000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 242 + RCX + 0x00080000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 243 + RCX + 0x00100000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 244 + RCX + 0x00200000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 245 + RCX + 0x00400000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 246 + RCX + 0x00800000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 247 + RCX + 0x01000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 248 + RCX + 0x02000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 249 + RCX + 0x04000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 250 + RCX + 0x08000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 251 + RCX + 0x10000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 252 + RCX + 0x20000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 253 + RCX + 0x40000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 254 + RCX + 0x80000000n => RCX :JMP(dblScalarMulSecp256k1_k11_k20) ; RR = 255 + +; Sage code +; ---------------------------------------- +; binLen = 256 +; clock = 32 +; for i in range(binLen): +; latch = i % clock +; power = 2**latch +; a = f"{power:#0{10}x}" +; print("\tRCX + {0}n => RCX\t\t:JMP(dblScalarMulSecp256k1_scalar_table_k11_k21_part2)\t; RR = {1}".format(a,i)) +; ---------------------------------------- +dblScalarMulSecp256k1_scalar_table_k11_k21_part1: + RCX + 0x00000001n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 0 + RCX + 0x00000002n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 1 + RCX + 0x00000004n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 2 + RCX + 0x00000008n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 3 + RCX + 0x00000010n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 4 + RCX + 0x00000020n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 5 + RCX + 0x00000040n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 6 + RCX + 0x00000080n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 7 + RCX + 0x00000100n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 8 + RCX + 0x00000200n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 9 + RCX + 0x00000400n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 10 + RCX + 0x00000800n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 11 + RCX + 0x00001000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 12 + RCX + 0x00002000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 13 + RCX + 0x00004000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 14 + RCX + 0x00008000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 15 + RCX + 0x00010000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 16 + RCX + 0x00020000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 17 + RCX + 0x00040000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 18 + RCX + 0x00080000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 19 + RCX + 0x00100000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 20 + RCX + 0x00200000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 21 + RCX + 0x00400000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 22 + RCX + 0x00800000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 23 + RCX + 0x01000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 24 + RCX + 0x02000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 25 + RCX + 0x04000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 26 + RCX + 0x08000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 27 + RCX + 0x10000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 28 + RCX + 0x20000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 29 + RCX + 0x40000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 30 + RCX + 0x80000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 31 + RCX + 0x00000001n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 32 + RCX + 0x00000002n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 33 + RCX + 0x00000004n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 34 + RCX + 0x00000008n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 35 + RCX + 0x00000010n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 36 + RCX + 0x00000020n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 37 + RCX + 0x00000040n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 38 + RCX + 0x00000080n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 39 + RCX + 0x00000100n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 40 + RCX + 0x00000200n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 41 + RCX + 0x00000400n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 42 + RCX + 0x00000800n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 43 + RCX + 0x00001000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 44 + RCX + 0x00002000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 45 + RCX + 0x00004000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 46 + RCX + 0x00008000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 47 + RCX + 0x00010000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 48 + RCX + 0x00020000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 49 + RCX + 0x00040000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 50 + RCX + 0x00080000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 51 + RCX + 0x00100000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 52 + RCX + 0x00200000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 53 + RCX + 0x00400000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 54 + RCX + 0x00800000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 55 + RCX + 0x01000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 56 + RCX + 0x02000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 57 + RCX + 0x04000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 58 + RCX + 0x08000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 59 + RCX + 0x10000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 60 + RCX + 0x20000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 61 + RCX + 0x40000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 62 + RCX + 0x80000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 63 + RCX + 0x00000001n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 64 + RCX + 0x00000002n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 65 + RCX + 0x00000004n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 66 + RCX + 0x00000008n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 67 + RCX + 0x00000010n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 68 + RCX + 0x00000020n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 69 + RCX + 0x00000040n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 70 + RCX + 0x00000080n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 71 + RCX + 0x00000100n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 72 + RCX + 0x00000200n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 73 + RCX + 0x00000400n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 74 + RCX + 0x00000800n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 75 + RCX + 0x00001000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 76 + RCX + 0x00002000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 77 + RCX + 0x00004000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 78 + RCX + 0x00008000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 79 + RCX + 0x00010000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 80 + RCX + 0x00020000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 81 + RCX + 0x00040000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 82 + RCX + 0x00080000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 83 + RCX + 0x00100000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 84 + RCX + 0x00200000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 85 + RCX + 0x00400000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 86 + RCX + 0x00800000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 87 + RCX + 0x01000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 88 + RCX + 0x02000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 89 + RCX + 0x04000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 90 + RCX + 0x08000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 91 + RCX + 0x10000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 92 + RCX + 0x20000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 93 + RCX + 0x40000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 94 + RCX + 0x80000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 95 + RCX + 0x00000001n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 96 + RCX + 0x00000002n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 97 + RCX + 0x00000004n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 98 + RCX + 0x00000008n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 99 + RCX + 0x00000010n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 100 + RCX + 0x00000020n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 101 + RCX + 0x00000040n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 102 + RCX + 0x00000080n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 103 + RCX + 0x00000100n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 104 + RCX + 0x00000200n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 105 + RCX + 0x00000400n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 106 + RCX + 0x00000800n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 107 + RCX + 0x00001000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 108 + RCX + 0x00002000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 109 + RCX + 0x00004000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 110 + RCX + 0x00008000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 111 + RCX + 0x00010000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 112 + RCX + 0x00020000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 113 + RCX + 0x00040000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 114 + RCX + 0x00080000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 115 + RCX + 0x00100000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 116 + RCX + 0x00200000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 117 + RCX + 0x00400000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 118 + RCX + 0x00800000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 119 + RCX + 0x01000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 120 + RCX + 0x02000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 121 + RCX + 0x04000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 122 + RCX + 0x08000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 123 + RCX + 0x10000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 124 + RCX + 0x20000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 125 + RCX + 0x40000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 126 + RCX + 0x80000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 127 + RCX + 0x00000001n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 128 + RCX + 0x00000002n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 129 + RCX + 0x00000004n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 130 + RCX + 0x00000008n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 131 + RCX + 0x00000010n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 132 + RCX + 0x00000020n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 133 + RCX + 0x00000040n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 134 + RCX + 0x00000080n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 135 + RCX + 0x00000100n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 136 + RCX + 0x00000200n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 137 + RCX + 0x00000400n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 138 + RCX + 0x00000800n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 139 + RCX + 0x00001000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 140 + RCX + 0x00002000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 141 + RCX + 0x00004000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 142 + RCX + 0x00008000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 143 + RCX + 0x00010000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 144 + RCX + 0x00020000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 145 + RCX + 0x00040000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 146 + RCX + 0x00080000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 147 + RCX + 0x00100000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 148 + RCX + 0x00200000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 149 + RCX + 0x00400000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 150 + RCX + 0x00800000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 151 + RCX + 0x01000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 152 + RCX + 0x02000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 153 + RCX + 0x04000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 154 + RCX + 0x08000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 155 + RCX + 0x10000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 156 + RCX + 0x20000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 157 + RCX + 0x40000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 158 + RCX + 0x80000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 159 + RCX + 0x00000001n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 160 + RCX + 0x00000002n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 161 + RCX + 0x00000004n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 162 + RCX + 0x00000008n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 163 + RCX + 0x00000010n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 164 + RCX + 0x00000020n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 165 + RCX + 0x00000040n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 166 + RCX + 0x00000080n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 167 + RCX + 0x00000100n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 168 + RCX + 0x00000200n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 169 + RCX + 0x00000400n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 170 + RCX + 0x00000800n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 171 + RCX + 0x00001000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 172 + RCX + 0x00002000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 173 + RCX + 0x00004000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 174 + RCX + 0x00008000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 175 + RCX + 0x00010000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 176 + RCX + 0x00020000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 177 + RCX + 0x00040000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 178 + RCX + 0x00080000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 179 + RCX + 0x00100000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 180 + RCX + 0x00200000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 181 + RCX + 0x00400000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 182 + RCX + 0x00800000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 183 + RCX + 0x01000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 184 + RCX + 0x02000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 185 + RCX + 0x04000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 186 + RCX + 0x08000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 187 + RCX + 0x10000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 188 + RCX + 0x20000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 189 + RCX + 0x40000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 190 + RCX + 0x80000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 191 + RCX + 0x00000001n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 192 + RCX + 0x00000002n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 193 + RCX + 0x00000004n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 194 + RCX + 0x00000008n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 195 + RCX + 0x00000010n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 196 + RCX + 0x00000020n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 197 + RCX + 0x00000040n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 198 + RCX + 0x00000080n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 199 + RCX + 0x00000100n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 200 + RCX + 0x00000200n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 201 + RCX + 0x00000400n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 202 + RCX + 0x00000800n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 203 + RCX + 0x00001000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 204 + RCX + 0x00002000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 205 + RCX + 0x00004000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 206 + RCX + 0x00008000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 207 + RCX + 0x00010000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 208 + RCX + 0x00020000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 209 + RCX + 0x00040000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 210 + RCX + 0x00080000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 211 + RCX + 0x00100000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 212 + RCX + 0x00200000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 213 + RCX + 0x00400000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 214 + RCX + 0x00800000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 215 + RCX + 0x01000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 216 + RCX + 0x02000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 217 + RCX + 0x04000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 218 + RCX + 0x08000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 219 + RCX + 0x10000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 220 + RCX + 0x20000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 221 + RCX + 0x40000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 222 + RCX + 0x80000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 223 + RCX + 0x00000001n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 224 + RCX + 0x00000002n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 225 + RCX + 0x00000004n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 226 + RCX + 0x00000008n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 227 + RCX + 0x00000010n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 228 + RCX + 0x00000020n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 229 + RCX + 0x00000040n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 230 + RCX + 0x00000080n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 231 + RCX + 0x00000100n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 232 + RCX + 0x00000200n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 233 + RCX + 0x00000400n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 234 + RCX + 0x00000800n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 235 + RCX + 0x00001000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 236 + RCX + 0x00002000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 237 + RCX + 0x00004000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 238 + RCX + 0x00008000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 239 + RCX + 0x00010000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 240 + RCX + 0x00020000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 241 + RCX + 0x00040000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 242 + RCX + 0x00080000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 243 + RCX + 0x00100000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 244 + RCX + 0x00200000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 245 + RCX + 0x00400000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 246 + RCX + 0x00800000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 247 + RCX + 0x01000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 248 + RCX + 0x02000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 249 + RCX + 0x04000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 250 + RCX + 0x08000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 251 + RCX + 0x10000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 252 + RCX + 0x20000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 253 + RCX + 0x40000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 254 + RCX + 0x80000000n => RCX :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part2 + RR) ; RR = 255 + +; Sage code +; ---------------------------------------- +; binLen = 256 +; clock = 32 +; for i in range(binLen): +; latch = i % clock +; power = 2**latch +; a = f"{power:#0{10}x}" +; if (latch == 0): +; print("\tHASHPOS + {0}n => HASHPOS\t\t:JMP(dblScalarMulSecp256k1_save_k11_k21)\t; RR = {1}".format(a,i)) +; else: +; print("\tHASHPOS + {0}n => HASHPOS\t\t:JMP(dblScalarMulSecp256k1_k11_k21_continue)\t\t; RR = {1}".format(a,i)) +; ---------------------------------------- +dblScalarMulSecp256k1_scalar_table_k11_k21_part2: + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k11_k21) ; RR = 0 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 1 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 2 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 3 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 4 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 5 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 6 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 7 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 8 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 9 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 10 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 11 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 12 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 13 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 14 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 15 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 16 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 17 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 18 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 19 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 20 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 21 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 22 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 23 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 24 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 25 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 26 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 27 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 28 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 29 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 30 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 31 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k11_k21) ; RR = 32 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 33 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 34 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 35 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 36 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 37 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 38 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 39 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 40 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 41 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 42 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 43 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 44 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 45 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 46 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 47 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 48 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 49 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 50 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 51 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 52 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 53 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 54 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 55 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 56 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 57 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 58 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 59 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 60 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 61 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 62 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 63 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k11_k21) ; RR = 64 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 65 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 66 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 67 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 68 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 69 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 70 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 71 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 72 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 73 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 74 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 75 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 76 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 77 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 78 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 79 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 80 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 81 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 82 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 83 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 84 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 85 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 86 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 87 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 88 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 89 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 90 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 91 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 92 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 93 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 94 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 95 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k11_k21) ; RR = 96 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 97 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 98 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 99 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 100 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 101 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 102 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 103 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 104 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 105 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 106 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 107 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 108 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 109 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 110 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 111 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 112 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 113 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 114 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 115 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 116 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 117 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 118 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 119 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 120 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 121 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 122 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 123 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 124 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 125 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 126 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 127 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k11_k21) ; RR = 128 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 129 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 130 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 131 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 132 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 133 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 134 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 135 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 136 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 137 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 138 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 139 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 140 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 141 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 142 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 143 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 144 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 145 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 146 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 147 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 148 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 149 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 150 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 151 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 152 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 153 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 154 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 155 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 156 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 157 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 158 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 159 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k11_k21) ; RR = 160 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 161 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 162 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 163 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 164 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 165 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 166 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 167 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 168 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 169 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 170 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 171 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 172 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 173 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 174 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 175 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 176 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 177 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 178 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 179 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 180 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 181 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 182 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 183 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 184 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 185 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 186 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 187 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 188 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 189 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 190 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 191 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k11_k21) ; RR = 192 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 193 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 194 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 195 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 196 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 197 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 198 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 199 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 200 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 201 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 202 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 203 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 204 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 205 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 206 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 207 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 208 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 209 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 210 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 211 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 212 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 213 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 214 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 215 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 216 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 217 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 218 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 219 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 220 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 221 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 222 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 223 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k11_k21) ; RR = 224 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 225 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 226 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 227 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 228 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 229 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 230 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 231 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 232 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 233 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 234 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 235 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 236 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 237 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 238 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 239 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 240 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 241 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 242 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 243 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 244 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 245 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 246 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 247 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 248 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 249 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 250 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 251 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 252 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 253 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 254 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k11_k21_continue) ; RR = 255 + +; Sage code +; ---------------------------------------- +; binLen = 256 +; clock = 32 +; for i in range(binLen): +; latch = i % clock +; power = 2**latch +; a = f"{power:#0{10}x}" +; if (latch == 0): +; print("\tHASHPOS + {0}n => HASHPOS\t\t:JMP(dblScalarMulSecp256k1_save_k10_k21)\t; RR = {1}".format(a,i)) +; else: +; print("\tHASHPOS + {0}n => HASHPOS\t\t:JMP(dblScalarMulSecp256k1_k10_k21_continue)\t\t; RR = {1}".format(a,i)) +; ---------------------------------------- +dblScalarMulSecp256k1_scalar_table_k10_k21: + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k10_k21) ; RR = 0 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 1 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 2 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 3 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 4 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 5 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 6 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 7 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 8 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 9 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 10 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 11 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 12 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 13 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 14 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 15 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 16 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 17 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 18 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 19 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 20 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 21 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 22 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 23 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 24 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 25 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 26 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 27 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 28 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 29 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 30 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 31 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k10_k21) ; RR = 32 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 33 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 34 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 35 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 36 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 37 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 38 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 39 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 40 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 41 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 42 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 43 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 44 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 45 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 46 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 47 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 48 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 49 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 50 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 51 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 52 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 53 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 54 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 55 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 56 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 57 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 58 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 59 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 60 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 61 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 62 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 63 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k10_k21) ; RR = 64 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 65 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 66 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 67 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 68 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 69 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 70 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 71 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 72 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 73 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 74 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 75 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 76 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 77 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 78 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 79 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 80 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 81 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 82 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 83 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 84 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 85 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 86 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 87 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 88 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 89 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 90 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 91 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 92 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 93 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 94 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 95 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k10_k21) ; RR = 96 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 97 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 98 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 99 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 100 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 101 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 102 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 103 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 104 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 105 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 106 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 107 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 108 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 109 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 110 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 111 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 112 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 113 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 114 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 115 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 116 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 117 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 118 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 119 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 120 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 121 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 122 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 123 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 124 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 125 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 126 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 127 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k10_k21) ; RR = 128 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 129 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 130 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 131 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 132 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 133 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 134 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 135 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 136 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 137 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 138 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 139 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 140 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 141 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 142 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 143 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 144 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 145 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 146 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 147 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 148 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 149 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 150 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 151 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 152 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 153 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 154 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 155 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 156 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 157 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 158 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 159 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k10_k21) ; RR = 160 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 161 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 162 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 163 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 164 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 165 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 166 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 167 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 168 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 169 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 170 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 171 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 172 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 173 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 174 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 175 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 176 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 177 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 178 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 179 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 180 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 181 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 182 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 183 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 184 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 185 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 186 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 187 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 188 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 189 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 190 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 191 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k10_k21) ; RR = 192 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 193 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 194 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 195 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 196 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 197 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 198 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 199 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 200 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 201 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 202 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 203 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 204 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 205 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 206 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 207 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 208 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 209 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 210 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 211 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 212 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 213 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 214 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 215 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 216 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 217 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 218 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 219 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 220 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 221 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 222 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 223 + HASHPOS + 0x00000001n => HASHPOS :JMP(dblScalarMulSecp256k1_save_k10_k21) ; RR = 224 + HASHPOS + 0x00000002n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 225 + HASHPOS + 0x00000004n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 226 + HASHPOS + 0x00000008n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 227 + HASHPOS + 0x00000010n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 228 + HASHPOS + 0x00000020n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 229 + HASHPOS + 0x00000040n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 230 + HASHPOS + 0x00000080n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 231 + HASHPOS + 0x00000100n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 232 + HASHPOS + 0x00000200n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 233 + HASHPOS + 0x00000400n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 234 + HASHPOS + 0x00000800n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 235 + HASHPOS + 0x00001000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 236 + HASHPOS + 0x00002000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 237 + HASHPOS + 0x00004000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 238 + HASHPOS + 0x00008000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 239 + HASHPOS + 0x00010000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 240 + HASHPOS + 0x00020000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 241 + HASHPOS + 0x00040000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 242 + HASHPOS + 0x00080000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 243 + HASHPOS + 0x00100000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 244 + HASHPOS + 0x00200000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 245 + HASHPOS + 0x00400000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 246 + HASHPOS + 0x00800000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 247 + HASHPOS + 0x01000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 248 + HASHPOS + 0x02000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 249 + HASHPOS + 0x04000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 250 + HASHPOS + 0x08000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 251 + HASHPOS + 0x10000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 252 + HASHPOS + 0x20000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 253 + HASHPOS + 0x40000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 254 + HASHPOS + 0x80000000n => HASHPOS :JMP(dblScalarMulSecp256k1_k10_k21_continue) ; RR = 255 \ No newline at end of file diff --git a/main/ecrecover/ecrecover.zkasm b/main/ecrecover/ecrecover.zkasm index ebe99b09..dcd95a06 100644 --- a/main/ecrecover/ecrecover.zkasm +++ b/main/ecrecover/ecrecover.zkasm @@ -1,9 +1,10 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; ecrecover in: A = hash, B = r, C = s, D = v -;; out: A = result, B = result_code +;; ecrecover: +;; in: A = hash, B = r, C = s, D = v +;; out: A = result, B = result_code ;; -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VAR GLOBAL ecrecover_hash VAR GLOBAL ecrecover_r @@ -18,45 +19,42 @@ VAR GLOBAL ecrecover_RR VAR GLOBAL ecrecover_v_parity VAR GLOBAL ecrecover_s_upperlimit -INCLUDE "constEc.zkasm" +INCLUDE "constSecp256k1.zkasm" ; ERROR CODES (B) ; 0 - no error -; 1 - r is zero (0) +; 1 - r is zero ; 2 - r is too big -; 3 - s is zero (0) +; 3 - s is zero ; 4 - s is too big ; 5 - v not valid value (1b, 1c) -; 6 - not exists sqrt of y -; 100 - fail sqrt, but has solution (!!!) +; 6 - sqrt of y does not exist +; 100 - sqrt failed, but it has a solution (!!!) ; MAP: MAlicious Prover -; + ; RESOURCES: -; PATH without root: 1014 arith + 10 binaries + 4527 steps -; PATH with root: 528 arith + 523 binaries + 6294 steps - 1 keccak -; PATH fail checks: 2 arith + 8 binaries + 45 steps +; PATH without root: 1014 arith + 10 binaries + 4609 steps +; PATH with root: 527 arith + 16 binaries + 7586 steps - 1 keccak +; PATH fail checks: 2 arith + 8 binaries + 45 steps ecrecover_precompiled: - %FNEC_MINUS_ONE :MSTORE(ecrecover_s_upperlimit),JMP(ecrecover_store_args) + %SECP256K1_N_MINUS_ONE :MSTORE(ecrecover_s_upperlimit), JMP(ecrecover_store_args) ecrecover_tx: - %FNEC_DIV_TWO :MSTORE(ecrecover_s_upperlimit) + %SECP256K1_N_DIV_TWO :MSTORE(ecrecover_s_upperlimit) ecrecover_store_args: ; save arguments - A :MSTORE(ecrecover_hash) B :MSTORE(ecrecover_r) C :MSTORE(ecrecover_s) D :MSTORE(ecrecover_v) - - - %MAX_CNT_BINARY - CNT_BINARY - 550 :JMPN(outOfCountersBinary) - %MAX_CNT_ARITH - CNT_ARITH - 1100 :JMPN(outOfCountersArith) - %MAX_CNT_STEPS - STEP - 6400 :JMPN(outOfCountersStep) + %MAX_CNT_BINARY - CNT_BINARY - 20 :JMPN(outOfCountersBinary) + %MAX_CNT_ARITH - CNT_ARITH - 1100 :JMPN(outOfCountersArith) + %MAX_CNT_STEPS - STEP - 7600 :JMPN(outOfCountersStep) $ => A :MLOAD(cntKeccakPreProcess) %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 :JMPN(outOfCountersKeccak) @@ -64,74 +62,68 @@ ecrecover_store_args: ; save RR to call return at end of routine RR :MSTORE(ecrecover_RR) - ; r in [1, FNEC-1] + ; r in [1, SECP256K1_N-1] + 0 => A $ => B :MLOAD(ecrecover_r) - 0n => A - $ :EQ,JMPC(ecrecover_r_is_zero) - %FNEC_MINUS_ONE => A - - $ :LT,JMPC(ecrecover_r_is_too_big) + $ :EQ, JMPC(ecrecover_r_is_zero) + %SECP256K1_N_MINUS_ONE => A + $ :LT, JMPC(ecrecover_r_is_too_big) ; s in [1, ecrecover_s_upperlimit] - $ => A :MLOAD(ecrecover_s_upperlimit) + 0 => A $ => B :MLOAD(ecrecover_s) - $ :LT,JMPC(ecrecover_s_is_too_big) - 0n => A - $ :EQ,JMPC(ecrecover_s_is_zero) - - ; compute r inverse + $ :EQ, JMPC(ecrecover_s_is_zero) + $ => A :MLOAD(ecrecover_s_upperlimit) + $ :LT, JMPC(ecrecover_s_is_too_big) ; [steps: 23, bin: 4] - $ => A :MLOAD(ecrecover_r),CALL(invFnEc) - B :MSTORE(ecrecover_r_inv) - ; [steps: 37, bin: 6, arith: 2] - 0x1Bn => B + 0x1Bn => B ; 27 $ => A :MLOAD(ecrecover_v) - $ => E :EQ,JMPNC(ecrecover_v_not_eq_1b) + $ => E :EQ, JMPNC(ecrecover_v_not_eq_1b) ; ecrecover_v_eq_1b: - 0n :MSTORE(ecrecover_v_parity),JMP(ecrecover_v_ok) + 0n :MSTORE(ecrecover_v_parity), JMP(ecrecover_v_ok) ecrecover_v_not_eq_1b: 0x1Cn => B - ; [steps: 42, bin: 8, arith: 2] - $ => E :EQ,JMPNC(ecrecover_v_not_eq_1b1c) + ; [steps: 39, bin: 7, arith: 2] + $ => E :EQ, JMPNC(ecrecover_v_not_eq_1b1c) ; ecrecover_v_eq_1c: - 1n :MSTORE(ecrecover_v_parity),JMP(ecrecover_v_ok) + 1n :MSTORE(ecrecover_v_parity) ecrecover_v_ok: ; - ; y^2 = x^3 + 7 + ; y² = x³ + 7 ; - ; A*B*A + 7 = calculate y from x + ; A·B·A + 7 = calculate y from x ; - ; [steps: 44, bin: 8, arith: 2] - $ => A,B :MLOAD(ecrecover_r),CALL(mulFpEc) + ; [steps: 41, bin: 8, arith: 2] + $ => A,B :MLOAD(ecrecover_r), CALL(mulFpSecp256k1) C => A - $ => B :MLOAD(ecrecover_r),CALL(mulFpEc) + $ => B :MLOAD(ecrecover_r), CALL(mulFpSecp256k1) - 7 => A :CALL(addFpEc) + 7 => A :CALL(addFpSecp256k1) ; load on A parity expected - ; [steps: 69, bin: 8, arith: 8] + ; [steps: 66, bin: 8, arith: 8] $ => A :MLOAD(ecrecover_v_parity) - C :MSTORE(ecrecover_y2),CALL(sqrtFpEc) + C :MSTORE(ecrecover_y2), CALL(sqrtFpSecp256k1) - ; If has root B = 1 else B = 0 - ; If B = 1 => C is alias-free (see sqrtFpEc) + ; If it has root B = 1, else B = 0 + ; If B = 1 => C is alias-free (see sqrtFpSecp256k1) - ; [steps: 85, bin: 9, arith: 10] + ; [steps: 82, bin: 9, arith: 10] B :JMPNZ(ecrecover_has_sqrt) ; hasn't sqrt, now verify - $ => C :MLOAD(ecrecover_y2),CALL(checkSqrtFpEc) + $ => C :MLOAD(ecrecover_y2), CALL(checkSqrtFpSecp256k1) ; check must return on A register 1, because the root has no solution - ; [steps: 4524, bin: 10, arith: 1014] - 1 :ASSERT,JMP(ecrecover_not_exists_sqrt_of_y) + ; [steps: 4609, bin: 10, arith: 1014] + 1 :ASSERT, JMP(ecrecover_not_exists_sqrt_of_y) ecrecover_has_sqrt: ; (v == 1b) ecrecover_y_parity = 0x00 @@ -139,10 +131,8 @@ ecrecover_has_sqrt: ; C: y = sqrt(y^2) [it's alias free, verified in previous lines] - 0x01n => A + 1 => A C => B - - ; A = parity(y) $ => A :AND ; how solution y = 0 not exists because -7 not has a cubic root, @@ -153,70 +143,71 @@ ecrecover_has_sqrt: C :MSTORE(ecrecover_y) - ; calculate C as (hash * inv_r) % FNEC - $ => A :MLOAD(ecrecover_hash) - ; [steps: 92, bin: 10, arith: 10] - $ => B :MLOAD(ecrecover_r_inv),CALL(mulFnEc) + ; compute r inverse + $ => A :MLOAD(ecrecover_r), CALL(invFnSecp256k1) + B :MSTORE(ecrecover_r_inv) - ; calculate k1 as (FNEC - hash * inv_r) % FNEC - ; C = (hash * inv_r) % FNEC no alias free (MAP) + ; calculate C as (hash * inv_r) % SECP256K1_N + $ => A :MLOAD(ecrecover_hash), CALL(mulFnSecp256k1) + + ; calculate k1 as (SECP256K1_N - hash * inv_r) % SECP256K1_N + ; C = (hash * inv_r) % SECP256K1_N no alias free (MAP) C => A 0 => B ; C is zero, special case - $ :EQ,JMPNC(k1_c_is_not_zero) + $ :EQ, JMPNC(k1_c_is_not_zero) - ; [steps: 100, bin: 9, arith: 12] + ; [steps: 100, bin: 11, arith: 12] k1_c_is_zero: ; k1 = 0 is alias-free - 0 :MSTORE(mulPointEc_k1), JMP(k1_calculated) + 0 :MSTORE(dblScalarMulSecp256k1_k1), JMP(k1_calculated) k1_c_is_not_zero: - ; A,C = (hash * inv_r) % FNEC + ; A,C = (hash * inv_r) % SECP256K1_N ; check A is alias-free, if not MAP ==> proof fails - %FNEC => B - 1 :LT ; ASSERT A < FNEC + %SECP256K1_N => B + 1 :LT ; ASSERT A < SECP256K1_N - ; FNEC - A = FNEC - (hash * inv_r) % FNEC + ; SECP256K1_N - A = SECP256K1_N - (hash * inv_r) % SECP256K1_N A => B - %FNEC => A - ; B != 0 ==> mulPointEc_k1 = FNEC - B + %SECP256K1_N => A + ; B != 0 ==> dblScalarMulSecp256k1_k1 = SECP256K1_N - B ; k1 is alias-free - $ :SUB, MSTORE(mulPointEc_k1) + $ :SUB, MSTORE(dblScalarMulSecp256k1_k1) k1_calculated: - $ => A :MLOAD(ecrecover_s) - ; [steps: 105, bin: 9, arith: 13] - $ => B :MLOAD(ecrecover_r_inv),CALL(mulFnEc) + ; [steps: 106, bin: 13, arith: 13] + $ => B :MLOAD(ecrecover_r_inv), CALL(mulFnSecp256k1) - ; C = (s * inv_r) % FNEC => k2 - ; [steps: 113, bin: 9, arith: 15] - C => A :MSTORE(mulPointEc_k2) - %FNEC => B + ; C = (s * inv_r) % SECP256K1_N => k2 + ; [steps: 114, bin: 13, arith: 15] + C => A :MSTORE(dblScalarMulSecp256k1_k2) + %SECP256K1_N => B ; ASSERT(k2 is alias free) 1 :LT - %ECGX :MSTORE(mulPointEc_p1_x) - %ECGY :MSTORE(mulPointEc_p1_y) + %SECP256K1_GX :MSTORE(dblScalarMulSecp256k1_p1_x) + %SECP256K1_GY :MSTORE(dblScalarMulSecp256k1_p1_y) ; r isn't an alias because the range has been checked at beginning $ => A :MLOAD(ecrecover_r) - A :MSTORE(mulPointEc_p2_x) + A :MSTORE(dblScalarMulSecp256k1_p2_x) ; y isn't an alias because was checked before ; (r,y) is a point of curve because it satisfies the curve equation $ => A :MLOAD(ecrecover_y) - ; [steps: 120, bin: 10, arith: 15] - A :MSTORE(mulPointEc_p2_y),CALL(mulPointEc) + ; [steps: 122, bin: 14, arith: 15] + A :MSTORE(dblScalarMulSecp256k1_p2_y), CALL(dblScalarMulSecp256k1) - ; check if result of mulPointEc is point at infinity - HASHPOS :JMPZ(ecrecover_p3_point_at_infinity) + ; check if result of dblScalarMulSecp256k1 is point at infinity + $ :MLOAD(dblScalarMulSecp256k1_p3_is_zero), JMPNZ(ecrecover_p3_point_at_infinity) - ; [steps: 6280, bin: 522, arith: 527] + ; [steps: 7574, bin: 15, arith: 527] ; generate keccak of public key to obtain ethereum address $ => E :MLOAD(lastHashKIdUsed) E + 1 => E :MSTORE(lastHashKIdUsed) @@ -224,9 +215,9 @@ k1_calculated: 32 => D ; p3_x, p3_y are alias free because arithmetic guarantees it - $ => A :MLOAD(mulPointEc_p3_x) + $ => A :MLOAD(dblScalarMulSecp256k1_p3_x) A :HASHK(E) - $ => A :MLOAD(mulPointEc_p3_y) + $ => A :MLOAD(dblScalarMulSecp256k1_p3_y) A :HASHK(E) 64 :HASHKLEN(E) @@ -235,7 +226,7 @@ k1_calculated: ; for address take only last 20 bytes 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFn => B $ => A :AND - ; AtEnd [steps: 6294, bin: 523, keccak: 1, arith: 528] + ; AtEnd [steps: 7586, bin: 16, keccak: 1, arith: 527] 0 => B :JMP(ecrecover_end) ; ERRORS @@ -269,12 +260,14 @@ ecrecover_end: $ => RR :MLOAD(ecrecover_RR) :RETURN -INCLUDE "addFpEc.zkasm" -INCLUDE "sqFpEc.zkasm" -INCLUDE "mulFpEc.zkasm" -INCLUDE "mulFnEc.zkasm" -INCLUDE "invFpEc.zkasm" -INCLUDE "invFnEc.zkasm" -INCLUDE "sqrtFpEc.zkasm" -INCLUDE "checkSqrtFpEc.zkasm" -INCLUDE "mulPointEc.zkasm" +INCLUDE "./FPSECP256K1/addFpSecp256k1.zkasm" +INCLUDE "./FPSECP256K1/mulFpSecp256k1.zkasm" +INCLUDE "./FPSECP256K1/squareFpSecp256k1.zkasm" +INCLUDE "./FPSECP256K1/invFpSecp256k1.zkasm" +INCLUDE "./FPSECP256K1/sqrtFpSecp256k1.zkasm" +INCLUDE "./FPSECP256K1/checkSqrtFpSecp256k1.zkasm" + +INCLUDE "./FNSECP256K1/mulFnSecp256k1.zkasm" +INCLUDE "./FNSECP256K1/invFnSecp256k1.zkasm" + +INCLUDE "dblScalarMulSecp256k1.zkasm" \ No newline at end of file diff --git a/main/ecrecover/invFnEc.zkasm b/main/ecrecover/invFnEc.zkasm deleted file mode 100644 index 245b99a7..00000000 --- a/main/ecrecover/invFnEc.zkasm +++ /dev/null @@ -1,44 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; invFnEc B = inv(A) -;; -;; PRE: A no alias-free -;; POST: B no alias-free (on MAP) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; RESOURCES: -; non-normalized: 2 ariths + 2 binaries + 12 steps -; normalized: 2 ariths + 1 binaries + 11 steps -; TOTAL (worst case): 2 ariths + 2 binaries + 12 steps - -VAR GLOBAL invFnEc_tmp - -invFnEc: - - %FNEC => B - $ :LT,JMPC(invFnEc_normalized) - $ => A :SUB - -invFnEc_normalized: - 0 => C - - ; B = inv(A) - ${var _invFnEc_A = inverseFnEc(A)} => B :MSTORE(invFnEc_tmp) - ; A * B + 0 = [D] * 2 ** 256 + [E] - - $${var _invFnEc_AB = A * B} - - ${_invFnEc_AB >> 256} => D - ${_invFnEc_AB} => E :ARITH - - ; - ; with committed E,D - ; FnEc * [k] + 1 = D * 2 ** 256 + E - ; - - 1 => C - ${_invFnEc_AB / const.FNEC} => B - %FNEC => A - - E :ARITH - $ => B :MLOAD(invFnEc_tmp), RETURN \ No newline at end of file diff --git a/main/ecrecover/invFpEc.zkasm b/main/ecrecover/invFpEc.zkasm deleted file mode 100644 index 581bc211..00000000 --- a/main/ecrecover/invFpEc.zkasm +++ /dev/null @@ -1,45 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; invFpEc B = inv(A) -;; -;; PRE: A no alias-free -;; POST: B no alias-free (on MAP) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; RESOURCES: -; non-normalized: 2 ariths + 2 binaries + 12 steps -; normalized: 2 ariths + 1 binaries + 11 steps -; TOTAL (worst case): 2 ariths + 2 binaries + 12 steps - -VAR GLOBAL invFpEc_tmp - -invFpEc: - - %FPEC => B - $ :LT,JMPC(invFpEc_normalized) - $ => A :SUB - -invFpEc_normalized: - 0n => C - ; B = inv(A) - - ${var _invFpEc_A = inverseFpEc(A)} => B :MSTORE(invFpEc_tmp); - - ; A * B + 0 = [D] * 2 ** 256 + [E] - - $${var _invFpEc_AB = A * _invFpEc_A} - - ${_invFpEc_AB >> 256} => D - ${_invFpEc_AB} => E :ARITH - - ; - ; with committed E,D - ; FpEc * [k] + 1 = D * 2 ** 256 + E - ; - - 1n => C - ${_invFpEc_AB / const.FPEC} => B - %FPEC => A - - E :ARITH - $ => B :MLOAD(invFpEc_tmp),RETURN \ No newline at end of file diff --git a/main/ecrecover/mulFnEc.zkasm b/main/ecrecover/mulFnEc.zkasm deleted file mode 100644 index 74c7a792..00000000 --- a/main/ecrecover/mulFnEc.zkasm +++ /dev/null @@ -1,36 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; mulFnEc (C = A * B) -;; -;; PRE: A,B no alias-free -;; POST: C no alias-free (on MAP) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; RESOURCES: -; 2 arith + 7 steps - -mulFnEc: - 0 => C - - ; A * B + 0 = [D] * 2 ** 256 + [E] - - $${var _mulFnEc_AB = A * B} - - ${_mulFnEc_AB >> 256} => D - - ;; - ;; result of command was only 256 bits, not need mask - ;; ${_mulFnEc_AB & ((1 << 256) - 1)} == ${_mulFnEc_AB} - - ${_mulFnEc_AB} => E :ARITH - - ; - ; with committed E,D - ; FnEc * [k] + [C] = D * 2 ** 256 + E - ; - - ${_mulFnEc_AB % const.FNEC} => C - ${_mulFnEc_AB / const.FNEC} => B - %FNEC => A - - E :ARITH,RETURN \ No newline at end of file diff --git a/main/ecrecover/mulFpEc.zkasm b/main/ecrecover/mulFpEc.zkasm deleted file mode 100644 index 8b7cba7a..00000000 --- a/main/ecrecover/mulFpEc.zkasm +++ /dev/null @@ -1,36 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; mulFpEc (C = A * B) -;; -;; PRE: A,B no alias-free -;; POST: C no alias-free (on MAP) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; RESOURCES: -; 2 arith + 7 steps - -mulFpEc: - 0 => C - - ; A * B + 0 = [D] * 2 ** 256 + [E] - - $${var _mulFpEc_AB = A * B} - - ${_mulFpEc_AB >> 256} => D - - ;; - ;; result of command was only 256 bits, not need mask - ;; ${_mulFpEc_AB & ((1 << 256) - 1)} == ${_mulFpEc_AB} - - ${_mulFpEc_AB} => E:ARITH - - ; - ; with committed E,D - ; FpEc * [k] + [C] = D * 2 ** 256 + E - ; - - ${_mulFpEc_AB % const.FPEC} => C - ${_mulFpEc_AB / const.FPEC} => B - %FPEC => A - - E :ARITH,RETURN \ No newline at end of file diff --git a/main/ecrecover/mulPointEc.zkasm b/main/ecrecover/mulPointEc.zkasm deleted file mode 100644 index 2f25b941..00000000 --- a/main/ecrecover/mulPointEc.zkasm +++ /dev/null @@ -1,311 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; mulPointEc (p1_x,p1_y,p2_x,p2_y,k1,k2) = (p3_x, p3_y, HASHPOS) -;; -;; PRE: p1_x, p1_y, p2_x, p2_y, k1, k2 are alias-free -;; POST: p3_x, p3_y is alias-free HASHPOS = [0,1] -;; -;; HASHPOS = 0 ==> p3 is the point at infinity -;; HASHPOS = 1 ==> p3 is not the point at infinity -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -VAR GLOBAL mulPointEc_p1_x -VAR GLOBAL mulPointEc_p1_y -VAR GLOBAL mulPointEc_p2_x -VAR GLOBAL mulPointEc_p2_y -VAR GLOBAL mulPointEc_k1 -VAR GLOBAL mulPointEc_k2 - -; p3 output point -VAR GLOBAL mulPointEc_p3_x -VAR GLOBAL mulPointEc_p3_y - -; point p12 = p1 + p2 -VAR GLOBAL mulPointEc_p12_x -VAR GLOBAL mulPointEc_p12_y - -; mulPointEc_p12_empty = 1 ==> p12 is the point at infinity -; mulPointEc_p12_empty = 0 ==> p12 isn't the point at infinity -VAR GLOBAL mulPointEc_p12_empty - -; backups -VAR GLOBAL mulPointEc_RR -VAR GLOBAL mulPointEc_RCX - -; PRECONDITION: p1,p2 are points of curve -; PRECONDITION: p1,p2 are alias-free - -; RESOURCES (k1,k2): -; 1 arith + 18 steps // setup, calculation p12 -; + 2 binaries * 256 // get bits of k1,k2 (steps evaluated inside loop) -; + number_of_bits_1(k1|k2) * arith // additions -; + (256 - left_bits_zero(k1|k2) * arith // squares -; + 24 * 256 steps // get bits k1,k2 + additions + squares (steps, regular) -; - (24 - 8) * left_bits_zero(k1|k2) * steps // get bits k1,k2 + additions + squares (steps first bits = 0) -; - (24 - 12) * number_of_bits_1(k1|k2) * steps // get bits k1,k2 + additions + squares (k1,k2 bits = 0) -; + (3 - 5) steps // last part - last part square no done -; - 1 arith // first assignation -; -; -; RESOURCES (worst case): 512 arith + 512 binaries + 6160 steps // 18 + 256 * 24 - 2 = 6160 - -mulPointEc: - RR :MSTORE(mulPointEc_RR) - RCX :MSTORE(mulPointEc_RCX) - - 256 => RCX - - ; HASHPOS used to mulPointEc_p3_no_infinity - ; HASHPOS = 0 ==> p3 is the point at infinity - ; HASHPOS = 1 ==> p3 is not the point at infinity - - 0n => HASHPOS :MSTORE(mulPointEc_p3_x) - - 0n :MSTORE(mulPointEc_p3_y) - - $ => A :MLOAD(mulPointEc_p1_x) - $ => B :MLOAD(mulPointEc_p1_y) - $ => C :MLOAD(mulPointEc_p2_x) - $ => D :MLOAD(mulPointEc_p2_y) - - ; check p1.x == p2.x - ; [steps: 11] - ${A == C} :JMPZ(mulPointDiffInitialPoints) - - ; verify path p1.x == p2.x - C :ASSERT - - ; check p1.y (B) == p2.y (D) - ; [steps: 13] - ${B == D} :JMPNZ(mulPointSameInitialPoints) - - ; verify path p1.y != p2.y ==> p1.y = -p2.y - ; use arith because in this path save a lot of arith, - ; because when add p12 do nothing. - - ; y + (-y) = y + P - y = P - ; y != 0, because cubic root of -7 not exists (y^2 = x^3 + 7) - - B => A ; A = p1_y - D => C ; C = p2_y - 1 => B - 0 => D ; check p1_y * 1 + p2_y = 0 * 2^256 * 0 + FPEC - %FPEC :ARITH - - ; p2 == -p1 - ; mulPointEc_p12_empty = 1: no add p12 because it was origin point p = O + p = p - ; [steps: 18] - 1n :MSTORE(mulPointEc_p12_empty),JMP(mulPointEc_loop) - - -mulPointSameInitialPoints: - ; [steps.before: 13] - ; verify path p1.y (B) == p2.y (D) - ; as an ASSERT(B == mulPointEc_p2_y) - B :MLOAD(mulPointEc_p2_y) - - ; p2 == p1 - 0n :MSTORE(mulPointEc_p12_empty) - ; A == p1_x - ; B == p1_y - ; (A,B) * 2 = (E, op) - ${xDblPointEc(A,B)} => E :MSTORE(mulPointEc_p12_x) - - ; [steps: 17] - ${yDblPointEc(A,B)} :ARITH_ECADD_SAME, MSTORE(mulPointEc_p12_y),JMP(mulPointEc_loop) - -mulPointDiffInitialPoints: - ; [steps.before: 11] - ; verify path p1.x != p2.x - ; p2.x != p1.x ==> p2 != p1 - ; [MAP] if p1 == p2 => arith fails because p1 = p2 - - 0n :MSTORE(mulPointEc_p12_empty) - ; (A, B) + (C, D) = (E, op) - ${xAddPointEc(A,B,C,D)} => E :MSTORE(mulPointEc_p12_x) - ; [steps: 14] - ${yAddPointEc(A,B,C,D)} :ARITH_ECADD_DIFFERENT, MSTORE(mulPointEc_p12_y) - - -; Goes forward in different branches of code depending on the values of the -; most significant bits of k1 and k2. -; First branch was determined by k1 most significant bit. - -; -; Most Significant bit was calculated ki + ki, -; -; A b255 b254 b253 ... b1 b0 -; A b255 b254 b253 ... b1 b0 -; --------------------------- -; E b254 b253 b252 ... b0 0 -; -; if b255 == 1 then carry = 1 -; if b255 == 0 then carry = 0 -; -; E = A << 1 (equivalent A + A) -; -; store E to be used in next round -; -; [steps.before (worst case): 18] -; -; [steps.byloop (p3initialempty.nolast): 8] -; [steps.byloop (bit.k1|bit.k2 == 0): 12] -; [steps.byloop (worst case): 7 + 17 = 24] - -mulPointEc_loop: - $ => A,B :MLOAD(mulPointEc_k1) - ; E = A*2 [carry] => bit 255 = 1 - $ => E :ADD,MSTORE(mulPointEc_k1),JMPC(mulPointEc_k11) - -; high_bit(k1) == 0 high_bit(k2) == ?? -mulPointEc_k10: - ; store E on multipointEc_k1, E was A*2 equivalent SHL and 255 bit on carry. - $ => A,B :MLOAD(mulPointEc_k2) - ; E = A*2 [carry] => bit 255 = 1 - $ => E :ADD,MSTORE(mulPointEc_k2),JMPC(mulPointEc_k10_k21) - -; high_bit(k1) == 0 high_bit(k2) == 0 -mulPointEc_k10_k20: - $ => A :MLOAD(mulPointEc_p3_x) - $ => B :MLOAD(mulPointEc_p3_y), JMP(mulPointEc_square) - -; high_bit(k1) == 1 high_bit(k2) == ?? -mulPointEc_k11: - $ => A,B :MLOAD(mulPointEc_k2) - $ => E :ADD,MSTORE(mulPointEc_k2),JMPC(mulPointEc_k11_k21) - -; high_bit(k1) == 1 high_bit(k2) == 0 -mulPointEc_k11_k20: - $ => C :MLOAD(mulPointEc_p1_x) - $ => D :MLOAD(mulPointEc_p1_y), JMP(mulPointEc_p2_loaded) - -; high_bit(k1) == 1 high_bit(k2) == 1 -mulPointEc_k11_k21: - ; if (mulPointEc_p12_empty) k11_k21 same as k10_k20 - $ :MLOAD(mulPointEc_p12_empty),JMPNZ(mulPointEc_k10_k20) - - $ => C :MLOAD(mulPointEc_p12_x) - $ => D :MLOAD(mulPointEc_p12_y), JMP(mulPointEc_p2_loaded) - -; high_bit(k1) == 0 high_bit(k2) == 1 -mulPointEc_k10_k21: - $ => C :MLOAD(mulPointEc_p2_x) - $ => D :MLOAD(mulPointEc_p2_y), JMP(mulPointEc_p2_loaded) - -; [steps.loadp2 (worst case): 7 (regular case 6) - -; in this point C,D have point to be add -mulPointEc_p2_loaded: - ; [steps.p3empty.nolast: 10] - ; [steps.p3empty.last: 5] - ; [steps.xeq.yeq: 10 + steps.square = 16] - ; [steps.xeq.yneq: 11 + steps.square = 17] - ; [steps.xneq.nolast: 7 + steps.square = 13] - ; [steps.xneq.last: 7 + steps.square = 13] - ; [steps.block: 17] - - ; check if p3 has a value, isn't point at infinity (Origin point) - HASHPOS :JMPZ(mulPointEc_p3_assignment) - - - ; check C == p3.x - ${ C == mem.mulPointEc_p3_x } :JMPNZ(mulPointEc_x_equals_before_add) - - ; [MAP] if C == mem.mulPointEc_p3_x ==> fails arithmetic because check - ; points are different - - ; p3 = (A,B) - $ => A :MLOAD(mulPointEc_p3_x) - $ => B :MLOAD(mulPointEc_p3_y) - - ; p3 = p3 + (C,D) - ; (C, D) is point to add (p1 or p2 or p12) - ; (A, B) + (C, D) = (E, op) - - ${xAddPointEc(A,B,C,D)} => E :MSTORE(mulPointEc_p3_x) - ${yAddPointEc(A,B,C,D)} => B :ARITH_ECADD_DIFFERENT, MSTORE(mulPointEc_p3_y) - -mulPointEc_after_add: - - E => A :JMP(mulPointEc_square) - -mulPointEc_p3_assignment: - - ; p3 = (C,D) - 1 => HASHPOS ; flag, mulPointEc_p3 has a value, no-empty - C => A :MSTORE(mulPointEc_p3_x) - D => B :MSTORE(mulPointEc_p3_y) - -mulPointEc_square: - ; [steps.last: 1] - ; [steps.nolast.p3empty: 2] - ; [steps.nolast.p3: 6] - ; [steps.block: 6] - - ; E,A = p3_x B = p3_y - RCX - 1 => RCX :JMPZ(mulPointEc_end_loop) - - ; if p3 was empty, no square, because O = O + O - HASHPOS :JMPZ(mulPointEc_loop) - - $ => A :MLOAD(mulPointEc_p3_x) - $ => B :MLOAD(mulPointEc_p3_y) - - ; (A, B) * 2 = (E, op) - ${xDblPointEc(A,B)} => E :MSTORE(mulPointEc_p3_x) - ${yDblPointEc(A,B)} :ARITH_ECADD_SAME, MSTORE(mulPointEc_p3_y), JMP(mulPointEc_loop) - -mulPointEc_x_equals_before_add: - ; [MAP] if C != mem.mulPointEc_p3_x ==> fails, MLOAD fails because read something different - ; for memory. It verifies C and mulPointEc_p3_x are same value, as an ASSERT. - C :MLOAD(mulPointEc_p3_x) - - ; points to add: point1 (p3) + point2 (C,D) - - ; C: point2.x - ; D: point2.y - - ; p3_x == C, check if points are same or a point was opposite point - - ${ D == mem.mulPointEc_p3_y } :JMPNZ(mulPointEc_same_point_to_add) - - ; In this path must be verified that D != mulPointEc_p3_y to - ; how p2_y and p3_y are different for same x, it implies that - ; p2_y == -p3_y. In this case next operation with p3 doesn't - ; spend arithmetics, for this reason is used an arithmetic - ; instead of binary to use similar resources on different paths. - - ; if p2_y == -p3_y, and them are alias free ==> p2_y + p3_y === FPEC - - 1 => B - D => A - 0 => D - $ => C :MLOAD(mulPointEc_p3_y) - - ; p2_y * 1 + p3_y = 2^256 * 0 + FPEC - %FPEC :ARITH - - ; NOTE: all points are free of alias because arithmetic guaranties it - - ; HASHPOS flag = 0, mulPointEc_p3 was empty, need addition must be an assignation - 0n => HASHPOS :MSTORE(mulPointEc_p3_x) - 0n :MSTORE(mulPointEc_p3_y), JMP(mulPointEc_square) - -mulPointEc_same_point_to_add: - ; [steps.block: 5] - ; must check really are equals, use MLOAD as ASSERT - ; ASSERT(D == mulPointEc_p3_y) - - D :MLOAD(mulPointEc_p3_y) - C => A - D => B - - ; (A,B) * 2 = (E, op) - ${xDblPointEc(A,B)} => E :MSTORE(mulPointEc_p3_x) - ${yDblPointEc(A,B)} => B :ARITH_ECADD_SAME, MSTORE(mulPointEc_p3_y), JMP(mulPointEc_after_add) - -mulPointEc_end_loop: - ; [steps.block: 3] - - $ => RR :MLOAD(mulPointEc_RR) - $ => RCX :MLOAD(mulPointEc_RCX), RETURN diff --git a/main/ecrecover/sqFpEc.zkasm b/main/ecrecover/sqFpEc.zkasm deleted file mode 100644 index 9c542c8b..00000000 --- a/main/ecrecover/sqFpEc.zkasm +++ /dev/null @@ -1,38 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; sqFpEc (C = C * C) -;; -;; PRE: C no alias-free -;; POST: C no alias-free (on MAP) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - -; RESOURCES: -; 2 arith + 8 steps - -sqFpEc: - C => A,B - 0n => C - - ; A * A + 0 = [D] * 2 ** 256 + [E] - - $${var _sqFpEc_AA = A * A} - - ${_sqFpEc_AA >> 256} => D - - ;; - ;; result of command was only 256 bits, not need mask - ;; ${_sqFpEc_AA & ((1 << 256) - 1)} == ${_sqFpEc_AA} - - ${_sqFpEc_AA} => E :ARITH - - ; - ; with committed E,D - ; FpEc * [k] + [C] = D * 2 ** 256 + E - ; - - ${_sqFpEc_AA % const.FPEC} => C - ${_sqFpEc_AA / const.FPEC} => B - %FPEC => A - - E :ARITH,RETURN \ No newline at end of file diff --git a/main/ecrecover/sqrtFpEc.zkasm b/main/ecrecover/sqrtFpEc.zkasm deleted file mode 100644 index c739251d..00000000 --- a/main/ecrecover/sqrtFpEc.zkasm +++ /dev/null @@ -1,70 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; -;; sqrtFpEc (C = sqrt(C,A)) -;; -;; PRE: A = [0,1], C no alias-free -;; POST: C is alias-free -;; NOTE: if C has sqrt B = 1 if not B = 0 -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -; RESOURCES: -; with root: 2 arith + 1 binary + 14 steps -; without root: 1 binary + 5 steps -; TOTAL (worst case): 2 arith + 1 binary + 14 steps - -VAR GLOBAL sqrtFpC_tmp -VAR GLOBAL sqrtFpC_res - -sqrtFpEc: - - ; PATH: hasn't sqrt => 1 binary - ; PATH: has sqrt => 1 binary + 2 arith - ; TOTAL resources: 1 binary + 2 arith - - C :MSTORE(sqrtFpC_tmp) - - ; [A] * [A] + 0 = [D] * 2 ** 256 + [E] - - ; set C because if jmp to sqrtFpEc C must have return value (FPEC_NON_SQRT) - ${var _sqrtFpEc_sqrt = sqrtFpEcParity(C,A) } => A,C :MSTORE(sqrtFpC_res) - - ; In this point we check if C is LT than FPEC because if not: - ; a) A = FPEC_NON_SQRT, check hasn't sqrt. - ; b) A is an alias, it's a MAP, we check hasn't sqrt, but has => no proof generated - - ; A and C has same value - - %FPEC => B - - ; A - $ => B :LT,JMPNC(sqrtFpEc_End) - - ; A,C < FPEC (alias free) - A => B - 0 => C - - ; A = B => A * A + 0 =? - - $${var _sqrtFpEc_sq = _sqrtFpEc_sqrt * _sqrtFpEc_sqrt } - - ${_sqrtFpEc_sq >> 256} => D - ${_sqrtFpEc_sq} => E :ARITH - - ; - ; with committed E,D - ; FpEc * [k] + C = D * 2 ** 256 + E - ; - - $ => C :MLOAD(sqrtFpC_tmp) - ${_sqrtFpEc_sq / const.FPEC} => B - %FPEC => A - E :ARITH - - ; sqrtFpC_res hasn't alias because in this path sqrtFpC_res < FPEC - - 1 => B - $ => C :MLOAD(sqrtFpC_res),RETURN - -sqrtFpEc_End: - ; B is 0, because C >= FPEC - :RETURN \ No newline at end of file diff --git a/test/ecrecover.zkasm b/test/ecrecover.zkasm index bff8bf55..b1b6ac32 100644 --- a/test/ecrecover.zkasm +++ b/test/ecrecover.zkasm @@ -14,6 +14,7 @@ start: -1 :MSTORE(lastHashKIdUsed) ; :JMP(repeat_ecrecover_test) :JMP(edge_cases) + ; :JMP(point_arith_tests) INCLUDE "../main/ecrecover/ecrecover.zkasm" @@ -21,14 +22,14 @@ repeat_ecrecover_test: ; A:ecrecover_hash B:ecrecover_r C:ecrecover_s D:ecrecover_v 0xd9eba16ed0ecae432b71fe008c98cc872bb4cc214d3220a36f365326cf807d68n => A - 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798n => B ; ECGX + 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798n => B ; SECP256K1_GX 0x265e99e47ad31bb2cab9646c504576b3abc6939a1710afc08cbf3034d73214b8n => C 0x1cn => D :CALL(ecrecover_tx) 0xBC44674AD5868F642EAD3FDF94E2D9C9185EAFB7n :ASSERT 0xd9eba16ed0ecae432b71fe008c98cc872bb4cc214d3220a36f365326cf807d68n => A - 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798n => B ; ECGX + 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798n => B ; SECP256K1_GX 0x265e99e47ad31bb2cab9646c504576b3abc6939a1710afc08cbf3034d73214b8n => C 0x1bn => D :CALL(ecrecover_tx) @@ -293,7 +294,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1an => D :CALL(ecrecover_tx) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT ; #28 v > 28 @@ -302,7 +303,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1dn => D :CALL(ecrecover_tx) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT ; #29 r == 0 @@ -311,7 +312,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT ; #30 r == field @@ -320,7 +321,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT ; #31 r > field @@ -329,7 +330,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT ; #32 r = field - 1 @@ -338,7 +339,7 @@ repeat_ecrecover_test: 0x4f8ae3bd7535248d0bd448298cc2e2071e56992d0774dc340c368ae950852adan => C 0x1cn => D :CALL(ecrecover_tx) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT ; #33 s == 0 @@ -347,7 +348,7 @@ repeat_ecrecover_test: 0x0000000000000000000000000000000000000000000000000000000000000000n => C 0x1cn => D :CALL(ecrecover_tx) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT ; #34 s == field/2 + 1. Valid (precompiled) @@ -405,7 +406,7 @@ repeat_ecrecover_test: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n => C 0x1cn => D :CALL(ecrecover_tx) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT B => A 4n :ASSERT @@ -425,7 +426,7 @@ repeat_ecrecover_test: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140n => C 0x1cn => D :CALL(ecrecover_tx) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT B => A 4n :ASSERT @@ -436,14 +437,14 @@ repeat_ecrecover_test: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142n => C 0x1cn => D :CALL(ecrecover_tx) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT edge_cases: ; #40 EGX 0x3cc4cb050478c49877188e4fbd022f35ccb41cee02d9d4417194cbf7ebc1eeben => A - %ECGX => B + %SECP256K1_GX => B 0x2bcf13b5e4f34a04a77344d5943e0228ba2e787583036325450c889d597a16c4n => C 0x1bn => D :CALL(ecrecover_tx) @@ -452,7 +453,7 @@ edge_cases: ; #41 -EGX 0x3cc4cb050478c49877188e4fbd022f35ccb41cee02d9d4417194cbf7ebc1eeben => A - %ECGX => B + %SECP256K1_GX => B 0x2bcf13b5e4f34a04a77344d5943e0228ba2e787583036325450c889d597a16c4n => C 0x1cn => D :CALL(ecrecover_tx) @@ -489,11 +490,11 @@ edge_cases: 0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1n => C ; s 0x1bn => D :CALL(ecrecover_precompiled) - 0 :ASSERT + 0x0000000000000000000000000000000000000000n :ASSERT B => A 7 :ASSERT -CONSTL %P2_C0_EGX = %ECGX & 0xFFFF +CONSTL %P2_C0_EGX = %SECP256K1_GX & 0xFFFF ; # p2 & 0xFFFF == EGX & 0xFFFF @@ -508,7 +509,7 @@ CONSTL %P2_C0_EGX = %ECGX & 0xFFFF ; # p2 & 0x001FFFF....FFFF == EGX & 0x001FFFF....FFFF -CONSTL %P2_CH_EGX = %ECGX & 0x001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFn +CONSTL %P2_CH_EGX = %SECP256K1_GX & 0x001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFn 0x3cc4cb050478c49877188e4fbd022f35ccb41cee02d9d4417194cbf7ebc1eeben => A %P2_CH_EGX => B @@ -516,7 +517,17 @@ CONSTL %P2_CH_EGX = %ECGX & 0x001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 0x1bn => D :CALL(ecrecover_tx) 0x4c90563674ab8de6f7731475a01a2bd09fd7b4b1n :ASSERT - $${dump(STEP)} + +; point_arith_tests: +; 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n :MSTORE(dblScalarMulSecp256k1_p1_x) +; 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n :MSTORE(dblScalarMulSecp256k1_p1_y) +; 0xeb8e1a4eebb21f302bb161c4f716a5f7811f98936e3e3064380d7ad3884c4a6an :MSTORE(dblScalarMulSecp256k1_p2_x) +; 0x8d4be7f1115c36369738f4a0ed3eb1435d0c8e01e99d62f05e5617ec2ec1dacen :MSTORE(dblScalarMulSecp256k1_p2_y) +; 4n :MSTORE(dblScalarMulSecp256k1_k1) +; 5n :MSTORE(dblScalarMulSecp256k1_k2) +; :CALL(dblScalarMulSecp256k1) +; 0xdf60fa077df9278809b7b55ac3640c6e3bb2807b2efee66c83bcc3fbfdb9a941n :MLOAD(dblScalarMulSecp256k1_p3_x) +; 0xc40bf0727719ab00044b9c4260d2599ef8db3a0ac47ca626aef24d28c9c7e4f8n :MLOAD(dblScalarMulSecp256k1_p3_y) :JMP(end) From 2ec5cfa31df5024f35a6024bb9a533da265eb9fb Mon Sep 17 00:00:00 2001 From: krlosMata Date: Mon, 5 Feb 2024 22:20:37 +0100 Subject: [PATCH 2/4] allow gha on develop-feijoa --- .github/workflows/main.yaml | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index ed4e69b8..80264b76 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -6,7 +6,7 @@ name: Test executor inputs on: workflow_dispatch: pull_request: - branches: [main, develop, develop-etrog, feature/fork-etrog, feature/l1-info-tree] + branches: [main, develop, develop-feijoa] jobs: build: diff --git a/package.json b/package.json index be762e4e..3e61d08c 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#b1540abf1fd1306e5eb11817abe40145b27a48ae", + "@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 560a989bc3f11c809f9370bfb490799f7d2655dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Masip?= Date: Tue, 6 Feb 2024 16:17:43 +0100 Subject: [PATCH 3/4] Counters recomputed and w.c. test added --- main/ecrecover/dblScalarMulSecp256k1.zkasm | 64 +++++++++++++--------- main/ecrecover/ecrecover.zkasm | 55 ++++++++++--------- test/ecrecover.zkasm | 44 +++++++++++---- 3 files changed, 100 insertions(+), 63 deletions(-) diff --git a/main/ecrecover/dblScalarMulSecp256k1.zkasm b/main/ecrecover/dblScalarMulSecp256k1.zkasm index f5846ce7..9a86b8aa 100644 --- a/main/ecrecover/dblScalarMulSecp256k1.zkasm +++ b/main/ecrecover/dblScalarMulSecp256k1.zkasm @@ -43,15 +43,15 @@ VAR GLOBAL dblScalarMulSecp256k1_RR VAR GLOBAL dblScalarMulSecp256k1_RCX ; RESOURCES (k1,k2): -; 1 arith + 23 steps // setup, calculation p12 -; + number_of_bits_1(k1|k2) * arith // additions -; + max_bin_len(k1,k2) * arith // doubles -; + 29 * max_bin_len(k1,k2) // additions + doubles (steps, worst case) -; + (8 - 5) steps // last part - last part double no done -; - 1 arith // first assignation +; 1 arith + 19 steps // setup, calculation p12 +; + number_of_bits_1(k1|k2) * arith // additions +; + max_bin_len(k1,k2) * arith // doubles +; + max_bin_len(k1,k2)/32 * 29 steps // additions + doubles (steps, worst case) +; + (256 - max_bin_len(k1,k2)/32) * 24 steps // additions + doubles (steps, worst case) +; + 8 steps + 2 bin // last part ; ; -; RESOURCES (worst case): 512 arith + 2 binaries + 7451 steps // 23 + 256 * 29 + 3 = 7451 +; RESOURCES (worst case): 513 arith + 2 binaries + 6239 steps // 20 + 256/32 * 29 + (256 - 256/32) * 24 + 8 = 6212 dblScalarMulSecp256k1: RR :MSTORE(dblScalarMulSecp256k1_RR) @@ -60,7 +60,6 @@ dblScalarMulSecp256k1: $0{receiveLen(mem.dblScalarMulSecp256k1_k1, mem.dblScalarMulSecp256k1_k2)} => RR ; receive the maximum length between the binary ; representations of k1 and k2 - ; start the acummulator of k1 and k2 0 => RCX :MSTORE(dblScalarMulSecp256k1_acum_k1) 0 => HASHPOS :MSTORE(dblScalarMulSecp256k1_acum_k2) @@ -75,15 +74,15 @@ dblScalarMulSecp256k1: $ => D :MLOAD(dblScalarMulSecp256k1_p2_y) ; check p1_x == p2_x - ; [steps: 14] ${A == C} :JMPZ(dblScalarMulSecp256k1DiffInitialPoints) + ; [steps: 11] ; verify path p1_x == p2_x C :ASSERT ; check p1_y == p2_y - ; [steps: 16] ${B == D} :JMPNZ(dblScalarMulSecp256k1SameInitialPoints) + ; [steps: 13] ; verify path p1_y != p2_y <==> p1_y = -p2_y or p1_y + p2_y = 0 ; use arith because in this path save a lot of arith, @@ -100,11 +99,11 @@ dblScalarMulSecp256k1: ; We have p2 == -p1 ; p12 = p1 - p1 = 𝒪, therefore is the point at infinity - ; [steps: 23] 1n :MSTORE(dblScalarMulSecp256k1_p12_zero), JMP(dblScalarMulSecp256k1_loop) + ; [steps: 19, arith: 1] dblScalarMulSecp256k1SameInitialPoints: - ; [steps.before: 16] + ; [steps.before: 13] ; verify path p1_y (B) == p2_y (D) ; as an ASSERT(B == mulPointEc_p2_y) B :MLOAD(dblScalarMulSecp256k1_p2_y) @@ -118,9 +117,10 @@ dblScalarMulSecp256k1SameInitialPoints: ; (A,B) * 2 = (E, op) ${xDblPointEc(A,B)} => E :MSTORE(dblScalarMulSecp256k1_p12_x) ${yDblPointEc(A,B)} :ARITH_ECADD_SAME, MSTORE(dblScalarMulSecp256k1_p12_y), JMP(dblScalarMulSecp256k1_loop) + ; [steps: 17, arith: 1] dblScalarMulSecp256k1DiffInitialPoints: - ; [steps.before: 14] + ; [steps.before: 11] ; verify path p1_x != p2_x ; p2_x != p1_x ==> p2 != p1 ; [MAP] if p1 == p2 => arith fails because p1 = p2 @@ -132,18 +132,21 @@ dblScalarMulSecp256k1DiffInitialPoints: ; (A, B) + (C, D) = (E, op) ${xAddPointEc(A,B,C,D)} => E :MSTORE(dblScalarMulSecp256k1_p12_x) ${yAddPointEc(A,B,C,D)} :ARITH_ECADD_DIFFERENT, MSTORE(dblScalarMulSecp256k1_p12_y) + ; [steps: 14, arith: 1] -; [steps.before (worst case): 23] +; [steps.before (worst case): 19, arith.before: 1] ; Goes forward in different branches of code depending on the values of the ; most significant bits of k1 and k2. -; [steps.byloop (worst case): 12 + 17 = 29] +; [steps.byloop (worst case & nosave): 8 + 16 = 24] +; [steps.byloop (worst case & save): 13 + 16 = 29] -; [steps.byloop (p3initialempty.nolast): 12] -; [steps.byloop (bit.k1 || bit.k2 == 1): 8] -; [steps.byloop (bit.k1 && bit.k2 == 1): 12] +; [steps.byloop ((bit.k1 || bit.k2) == 1) & nosave: 6 + 16 = 22] +; [steps.byloop ((bit.k1 && bit.k2) == 1) & nosave: 8 + 16 = 24] +; [steps.byloop ((bit.k1 || bit.k2) == 1) & save: 11 + 16 = 27] +; [steps.byloop ((bit.k1 && bit.k2) == 1) & save: 13 + 16 = 29] dblScalarMulSecp256k1_loop: ; Receive the next MSB bit of k1 @@ -158,6 +161,9 @@ dblScalarMulSecp256k1_k10: dblScalarMulSecp256k1_k10_k21: :JMP(@dblScalarMulSecp256k1_scalar_table_k10_k21 + RR) dblScalarMulSecp256k1_k10_k21_continue: + ; [steps.before.nosave: 4] + ; [steps.before.save: 9] + ; [steps.before (w.c.): 9] $ => C :MLOAD(dblScalarMulSecp256k1_p2_x) $ => D :MLOAD(dblScalarMulSecp256k1_p2_y), JMP(dblScalarMulSecp256k1_add) @@ -170,6 +176,10 @@ dblScalarMulSecp256k1_k11: dblScalarMulSecp256k1_k11_k21: :JMP(@dblScalarMulSecp256k1_scalar_table_k11_k21_part1 + RR) dblScalarMulSecp256k1_k11_k21_continue: + ; [steps.before.nosave: 5] + ; [steps.before.save: 10] + ; [steps.before (w.c.): 10] + ; if (dblScalarMulSecp256k1_p12_zero) k11_k21 is the same as k10_k20 ; because adding the point at infinity to a point is the point itself $ :MLOAD(dblScalarMulSecp256k1_p12_zero), JMPNZ(dblScalarMulSecp256k1_double) @@ -179,19 +189,21 @@ dblScalarMulSecp256k1_k11_k21_continue: ; high_bit(k1) == 1 high_bit(k2) == 0 dblScalarMulSecp256k1_k11_k20: + ; [steps.before.nosave: 3] + ; [steps.before.save: 9] + ; [steps.before (w.c.): 9] $ => C :MLOAD(dblScalarMulSecp256k1_p1_x) $ => D :MLOAD(dblScalarMulSecp256k1_p1_y), JMP(dblScalarMulSecp256k1_add) -; [steps.loadp2 (worst case): 7 (regular case 6) ; in this point C,D have point to be add dblScalarMulSecp256k1_add: - ; [steps.p3empty.nolast: 10] - ; [steps.p3empty.last: 5] + ; [steps.p3empty.nolast: 4 + steps.double = 10] + ; [steps.p3empty.last: 4 + steps.double = 5] ; [steps.xeq.yeq: 9 + steps.double = 15] - ; [steps.xeq.yneq: 11 + steps.double = 17] + ; [steps.xeq.yneq: 10 + steps.double = 16] ; [steps.xneq.nolast: 7 + steps.double = 13] - ; [steps.xneq.last: 7 + steps.double = 13] - ; [steps.block: 17] + ; [steps.xneq.last: 7 + steps.double = 8] + ; [steps.block: 16] ; if p3 is the point at infinity do not add, just assign, since 𝒪 + P = P $ :MLOAD(dblScalarMulSecp256k1_p3_is_zero), JMPNZ(dblScalarMulSecp256k1_p3_assignment) @@ -242,8 +254,8 @@ dblScalarMulSecp256k1_double: dblScalarMulSecp256k1_x_equals_before_add: ; [steps.same.point: 7] - ; [steps.opposite.point: 9] - ; [steps.block: 9] + ; [steps.opposite.point: 8] + ; [steps.block: 8] ; [MAP] if C != mem.dblScalarMulSecp256k1_p3_x ==> fails, MLOAD fails because read something different ; for memory. It verifies C and dblScalarMulSecp256k1_p3_x are same value, as an ASSERT. diff --git a/main/ecrecover/ecrecover.zkasm b/main/ecrecover/ecrecover.zkasm index dcd95a06..eb2eb7a4 100644 --- a/main/ecrecover/ecrecover.zkasm +++ b/main/ecrecover/ecrecover.zkasm @@ -34,9 +34,11 @@ INCLUDE "constSecp256k1.zkasm" ; MAP: MAlicious Prover ; RESOURCES: -; PATH without root: 1014 arith + 10 binaries + 4609 steps -; PATH with root: 527 arith + 16 binaries + 7586 steps - 1 keccak -; PATH fail checks: 2 arith + 8 binaries + 45 steps +; PATH without root: [steps: 4601, bin: 8, arith: 1010] +; PATH with root: [steps: 6383, bin: 17, arith: 527, keccak: 1] +; PATH with result of dbl is infinity: [steps: 6368, bin: 16, arith: 527] +; -------------------------------------------------------------------------------------- +; worst case: [steps: 6383, bin: 17, arith: 1010] ecrecover_precompiled: %SECP256K1_N_MINUS_ONE :MSTORE(ecrecover_s_upperlimit), JMP(ecrecover_store_args) @@ -54,7 +56,7 @@ ecrecover_store_args: %MAX_CNT_BINARY - CNT_BINARY - 20 :JMPN(outOfCountersBinary) %MAX_CNT_ARITH - CNT_ARITH - 1100 :JMPN(outOfCountersArith) - %MAX_CNT_STEPS - STEP - 7600 :JMPN(outOfCountersStep) + %MAX_CNT_STEPS - STEP - 6400 :JMPN(outOfCountersStep) $ => A :MLOAD(cntKeccakPreProcess) %MAX_CNT_KECCAK_F - CNT_KECCAK_F - A - 1 :JMPN(outOfCountersKeccak) @@ -83,49 +85,52 @@ ecrecover_store_args: ; ecrecover_v_eq_1b: 0n :MSTORE(ecrecover_v_parity), JMP(ecrecover_v_ok) + ; 1] [steps: 27, bin: 5] ecrecover_v_not_eq_1b: 0x1Cn => B - ; [steps: 39, bin: 7, arith: 2] $ => E :EQ, JMPNC(ecrecover_v_not_eq_1b1c) ; ecrecover_v_eq_1c: 1n :MSTORE(ecrecover_v_parity) + ; 2] [steps: 29, bin: 6] ecrecover_v_ok: + ; before (w.c.) -> [steps: 29, bin: 6] ; ; y² = x³ + 7 ; ; A·B·A + 7 = calculate y from x ; - ; [steps: 41, bin: 8, arith: 2] - $ => A,B :MLOAD(ecrecover_r), CALL(mulFpSecp256k1) + $ => A,B :MLOAD(ecrecover_r), CALL(mulFpSecp256k1) ; 2 arith + 8 steps C => A - $ => B :MLOAD(ecrecover_r), CALL(mulFpSecp256k1) + $ => B :MLOAD(ecrecover_r), CALL(mulFpSecp256k1) ; 2 arith + 8 steps - 7 => A :CALL(addFpSecp256k1) + 7 => A :CALL(addFpSecp256k1) ; 2 ariths + 8 steps ; load on A parity expected - ; [steps: 66, bin: 8, arith: 8] + ; [steps: 53, bin: 6, arith: 6] $ => A :MLOAD(ecrecover_v_parity) - C :MSTORE(ecrecover_y2), CALL(sqrtFpSecp256k1) + C :MSTORE(ecrecover_y2), CALL(sqrtFpSecp256k1) ; with sqrt: [steps: 15, bin: 1, arith: 2] + ;without sqrt: [steps: 15, bin: 1, arith: 0] ; If it has root B = 1, else B = 0 ; If B = 1 => C is alias-free (see sqrtFpSecp256k1) - ; [steps: 82, bin: 9, arith: 10] B :JMPNZ(ecrecover_has_sqrt) + ; [steps: 71, bin: 7, arith: 6] ; hasn't sqrt, now verify - $ => C :MLOAD(ecrecover_y2), CALL(checkSqrtFpSecp256k1) + $ => C :MLOAD(ecrecover_y2), CALL(checkSqrtFpSecp256k1) ; [steps: 4524, bin: 1, arith: 1004] ; check must return on A register 1, because the root has no solution - ; [steps: 4609, bin: 10, arith: 1014] 1 :ASSERT, JMP(ecrecover_not_exists_sqrt_of_y) + ; till the end -> [steps: 4601, bin: 8, arith: 1010] ecrecover_has_sqrt: + ; before -> [steps: 71, bin: 7, arith: 8] ; (v == 1b) ecrecover_y_parity = 0x00 ; (v == 1c) ecrecover_y_parity = 0x01 @@ -144,11 +149,11 @@ ecrecover_has_sqrt: C :MSTORE(ecrecover_y) ; compute r inverse - $ => A :MLOAD(ecrecover_r), CALL(invFnSecp256k1) + $ => A :MLOAD(ecrecover_r), CALL(invFnSecp256k1) ; 2 ariths + 2 binaries + 13 steps B :MSTORE(ecrecover_r_inv) ; calculate C as (hash * inv_r) % SECP256K1_N - $ => A :MLOAD(ecrecover_hash), CALL(mulFnSecp256k1) + $ => A :MLOAD(ecrecover_hash), CALL(mulFnSecp256k1) ; 2 arith + 8 steps ; calculate k1 as (SECP256K1_N - hash * inv_r) % SECP256K1_N ; C = (hash * inv_r) % SECP256K1_N no alias free (MAP) @@ -156,8 +161,7 @@ ecrecover_has_sqrt: 0 => B ; C is zero, special case $ :EQ, JMPNC(k1_c_is_not_zero) - - ; [steps: 100, bin: 11, arith: 12] + ; [steps: 103, bin: 11, arith: 12] k1_c_is_zero: ; k1 = 0 is alias-free @@ -165,6 +169,8 @@ k1_c_is_zero: k1_c_is_not_zero: + ; before (w.c.) -> [steps: 103, bin: 11, arith: 12] + ; A,C = (hash * inv_r) % SECP256K1_N ; check A is alias-free, if not MAP ==> proof fails %SECP256K1_N => B @@ -176,12 +182,13 @@ k1_c_is_not_zero: ; B != 0 ==> dblScalarMulSecp256k1_k1 = SECP256K1_N - B ; k1 is alias-free $ :SUB, MSTORE(dblScalarMulSecp256k1_k1) + ; [steps: 109, bin: 13, arith: 12] k1_calculated: $ => A :MLOAD(ecrecover_s) ; [steps: 106, bin: 13, arith: 13] - $ => B :MLOAD(ecrecover_r_inv), CALL(mulFnSecp256k1) + $ => B :MLOAD(ecrecover_r_inv), CALL(mulFnSecp256k1) ; 2 arith + 8 steps ; C = (s * inv_r) % SECP256K1_N => k2 ; [steps: 114, bin: 13, arith: 15] @@ -201,13 +208,13 @@ k1_calculated: ; y isn't an alias because was checked before ; (r,y) is a point of curve because it satisfies the curve equation $ => A :MLOAD(ecrecover_y) - ; [steps: 122, bin: 14, arith: 15] - A :MSTORE(dblScalarMulSecp256k1_p2_y), CALL(dblScalarMulSecp256k1) + ; [steps: 127, bin: 14, arith: 14] + A :MSTORE(dblScalarMulSecp256k1_p2_y), CALL(dblScalarMulSecp256k1) ; 513 arith + 2 binaries + 6239 steps ; check if result of dblScalarMulSecp256k1 is point at infinity $ :MLOAD(dblScalarMulSecp256k1_p3_is_zero), JMPNZ(ecrecover_p3_point_at_infinity) + ; [steps: 6368, bin: 16, arith: 527] - ; [steps: 7574, bin: 15, arith: 527] ; generate keccak of public key to obtain ethereum address $ => E :MLOAD(lastHashKIdUsed) E + 1 => E :MSTORE(lastHashKIdUsed) @@ -226,7 +233,7 @@ k1_calculated: ; for address take only last 20 bytes 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFn => B $ => A :AND - ; AtEnd [steps: 7586, bin: 16, keccak: 1, arith: 527] + ; till the end -> [steps: 6383, bin: 17, arith: 527] 0 => B :JMP(ecrecover_end) ; ERRORS @@ -243,11 +250,9 @@ ecrecover_s_is_too_big: 4 => B :JMP(ecrecover_error) ecrecover_v_not_eq_1b1c: - ; AtEnd [steps: 45, bin: 8, arith: 2] 5 => B :JMP(ecrecover_error) ecrecover_not_exists_sqrt_of_y: - ; AtEnd [steps: 4527, bin: 10, arith: 1014] 6 => B :JMP(ecrecover_error) ecrecover_p3_point_at_infinity: diff --git a/test/ecrecover.zkasm b/test/ecrecover.zkasm index b1b6ac32..8c847a63 100644 --- a/test/ecrecover.zkasm +++ b/test/ecrecover.zkasm @@ -12,8 +12,9 @@ start: CTX :MSTORE(originalCTX) -1 :MSTORE(lastHashKIdUsed) - ; :JMP(repeat_ecrecover_test) - :JMP(edge_cases) + :JMP(repeat_ecrecover_test) + ; :JMP(edge_cases) + ; :JMP(worst_case) ; :JMP(point_arith_tests) INCLUDE "../main/ecrecover/ecrecover.zkasm" @@ -518,16 +519,35 @@ CONSTL %P2_CH_EGX = %SECP256K1_GX & 0x001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF :CALL(ecrecover_tx) 0x4c90563674ab8de6f7731475a01a2bd09fd7b4b1n :ASSERT -; point_arith_tests: -; 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n :MSTORE(dblScalarMulSecp256k1_p1_x) -; 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n :MSTORE(dblScalarMulSecp256k1_p1_y) -; 0xeb8e1a4eebb21f302bb161c4f716a5f7811f98936e3e3064380d7ad3884c4a6an :MSTORE(dblScalarMulSecp256k1_p2_x) -; 0x8d4be7f1115c36369738f4a0ed3eb1435d0c8e01e99d62f05e5617ec2ec1dacen :MSTORE(dblScalarMulSecp256k1_p2_y) -; 4n :MSTORE(dblScalarMulSecp256k1_k1) -; 5n :MSTORE(dblScalarMulSecp256k1_k2) -; :CALL(dblScalarMulSecp256k1) -; 0xdf60fa077df9278809b7b55ac3640c6e3bb2807b2efee66c83bcc3fbfdb9a941n :MLOAD(dblScalarMulSecp256k1_p3_x) -; 0xc40bf0727719ab00044b9c4260d2599ef8db3a0ac47ca626aef24d28c9c7e4f8n :MLOAD(dblScalarMulSecp256k1_p3_y) +worst_case: + 0x3ebaaedce6af48a03bbfd25e8cd0364142n => A + 0x1n => B + 0xffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffn => C + 0x1bn => D + :CALL(ecrecover_precompiled) + 0x7e38c8326cedaee2262b28bd1923d6ad4cb8ee0n :ASSERT + +point_arith_tests: + 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n :MSTORE(dblScalarMulSecp256k1_p1_x) + 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n :MSTORE(dblScalarMulSecp256k1_p1_y) + 0xeb8e1a4eebb21f302bb161c4f716a5f7811f98936e3e3064380d7ad3884c4a6an :MSTORE(dblScalarMulSecp256k1_p2_x) + 0x8d4be7f1115c36369738f4a0ed3eb1435d0c8e01e99d62f05e5617ec2ec1dacen :MSTORE(dblScalarMulSecp256k1_p2_y) + 4n :MSTORE(dblScalarMulSecp256k1_k1) + 5n :MSTORE(dblScalarMulSecp256k1_k2) + :CALL(dblScalarMulSecp256k1) + 0xdf60fa077df9278809b7b55ac3640c6e3bb2807b2efee66c83bcc3fbfdb9a941n :MLOAD(dblScalarMulSecp256k1_p3_x) + 0xc40bf0727719ab00044b9c4260d2599ef8db3a0ac47ca626aef24d28c9c7e4f8n :MLOAD(dblScalarMulSecp256k1_p3_y) + + ; worst case test + 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n :MSTORE(dblScalarMulSecp256k1_p1_x) + 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n :MSTORE(dblScalarMulSecp256k1_p1_y) + 0xeb8e1a4eebb21f302bb161c4f716a5f7811f98936e3e3064380d7ad3884c4a6an :MSTORE(dblScalarMulSecp256k1_p2_x) + 0x8d4be7f1115c36369738f4a0ed3eb1435d0c8e01e99d62f05e5617ec2ec1dacen :MSTORE(dblScalarMulSecp256k1_p2_y) + 0xffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffn :MSTORE(dblScalarMulSecp256k1_k1) + 0xffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffn :MSTORE(dblScalarMulSecp256k1_k2) + :CALL(dblScalarMulSecp256k1) + 0xfd7a1e96af355f55b5836449b599b69c32349abf1327c6b58a582b3a9cd6b88an :MLOAD(dblScalarMulSecp256k1_p3_x) + 0xc9337fc5565b2c4fc235f4f3aa196948aba84d7af369f4d4096853e4730e4f2dn :MLOAD(dblScalarMulSecp256k1_p3_y) :JMP(end) From 5f6306edc391217607c9b75da498cd46b1c77345 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 4/4] Upadte package --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3e61d08c..29877d5a 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#v2.0.0-rc.2-fork.7", + "@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/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",