LCOV - code coverage report
Current view: top level - evmone_precompiles - secp256k1.cpp (source / functions) Coverage Total Hit
Test: PATCH_COVERAGE Lines: 0.0 % 311 0
Test Date: 2024-03-16 09:03:51 Functions: 0.0 % 9 0

            Line data    Source code
       1              : // evmone: Fast Ethereum Virtual Machine implementation
       2              : // Copyright 2023 The evmone Authors.
       3              : // SPDX-License-Identifier: Apache-2.0
       4              : #include "secp256k1.hpp"
       5              : #include <ethash/keccak.hpp>
       6              : 
       7              : namespace evmmax::secp256k1
       8              : {
       9              : namespace
      10              : {
      11              : const ModArith<uint256> Fp{FieldPrime};
      12              : const auto B = Fp.to_mont(7);
      13              : const auto B3 = Fp.to_mont(7 * 3);
      14              : 
      15              : constexpr Point G{0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798_u256,
      16              :     0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8_u256};
      17              : }  // namespace
      18              : 
      19              : // FIXME: Change to "uncompress_point".
      20            0 : std::optional<uint256> calculate_y(
      21              :     const ModArith<uint256>& m, const uint256& x, bool y_parity) noexcept
      22              : {
      23              :     // Calculate sqrt(x^3 + 7)
      24            0 :     const auto x3 = m.mul(m.mul(x, x), x);
      25            0 :     const auto y = field_sqrt(m, m.add(x3, B));
      26            0 :     if (!y.has_value())
      27            0 :         return std::nullopt;
      28              : 
      29              :     // Negate if different parity requested
      30            0 :     const auto candidate_parity = (m.from_mont(*y) & 1) != 0;
      31            0 :     return (candidate_parity == y_parity) ? *y : m.sub(0, *y);
      32              : }
      33              : 
      34            0 : Point add(const Point& p, const Point& q) noexcept
      35              : {
      36            0 :     if (p.is_inf())
      37            0 :         return q;
      38            0 :     if (q.is_inf())
      39            0 :         return p;
      40              : 
      41            0 :     const auto pp = ecc::to_proj(Fp, p);
      42            0 :     const auto pq = ecc::to_proj(Fp, q);
      43              : 
      44              :     // b3 == 21 for y^2 == x^3 + 7
      45            0 :     const auto r = ecc::add(Fp, pp, pq, B3);
      46            0 :     return ecc::to_affine(Fp, field_inv, r);
      47              : }
      48              : 
      49            0 : Point mul(const Point& p, const uint256& c) noexcept
      50              : {
      51            0 :     if (p.is_inf())
      52            0 :         return p;
      53              : 
      54            0 :     if (c == 0)
      55            0 :         return {0, 0};
      56              : 
      57            0 :     const auto r = ecc::mul(Fp, ecc::to_proj(Fp, p), c, B3);
      58            0 :     return ecc::to_affine(Fp, field_inv, r);
      59              : }
      60              : 
      61            0 : evmc::address to_address(const Point& pt) noexcept
      62              : {
      63              :     // This performs Ethereum's address hashing on an uncompressed pubkey.
      64              :     uint8_t serialized[64];
      65            0 :     intx::be::unsafe::store(serialized, pt.x);
      66            0 :     intx::be::unsafe::store(serialized + 32, pt.y);
      67              : 
      68            0 :     const auto hashed = ethash::keccak256(serialized, sizeof(serialized));
      69            0 :     evmc::address ret{};
      70            0 :     std::memcpy(ret.bytes, hashed.bytes + 12, 20);
      71              : 
      72            0 :     return ret;
      73              : }
      74              : 
      75            0 : std::optional<Point> secp256k1_ecdsa_recover(
      76              :     const ethash::hash256& e, const uint256& r, const uint256& s, bool v) noexcept
      77              : {
      78              :     // Follows
      79              :     // https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Public_key_recovery
      80              : 
      81              :     // 1. Validate r and s are within [1, n-1].
      82            0 :     if (r == 0 || r >= Order || s == 0 || s >= Order)
      83            0 :         return std::nullopt;
      84              : 
      85              :     // 3. Hash of the message is already calculated in e.
      86              :     // 4. Convert hash e to z field element by doing z = e % n.
      87              :     //    https://www.rfc-editor.org/rfc/rfc6979#section-2.3.2
      88              :     //    We can do this by n - e because n > 2^255.
      89              :     static_assert(Order > 1_u256 << 255);
      90            0 :     auto z = intx::be::load<uint256>(e.bytes);
      91            0 :     if (z >= Order)
      92            0 :         z -= Order;
      93              : 
      94              : 
      95            0 :     const ModArith<uint256> n{Order};
      96              : 
      97              :     // 5. Calculate u1 and u2.
      98            0 :     const auto r_n = n.to_mont(r);
      99            0 :     const auto r_inv = scalar_inv(n, r_n);
     100              : 
     101            0 :     const auto z_mont = n.to_mont(z);
     102            0 :     const auto z_neg = n.sub(0, z_mont);
     103            0 :     const auto u1_mont = n.mul(z_neg, r_inv);
     104            0 :     const auto u1 = n.from_mont(u1_mont);
     105              : 
     106            0 :     const auto s_mont = n.to_mont(s);
     107            0 :     const auto u2_mont = n.mul(s_mont, r_inv);
     108            0 :     const auto u2 = n.from_mont(u2_mont);
     109              : 
     110              :     // 2. Calculate y coordinate of R from r and v.
     111            0 :     const auto r_mont = Fp.to_mont(r);
     112            0 :     const auto y_mont = calculate_y(Fp, r_mont, v);
     113            0 :     if (!y_mont.has_value())
     114            0 :         return std::nullopt;
     115            0 :     const auto y = Fp.from_mont(*y_mont);
     116              : 
     117              :     // 6. Calculate public key point Q.
     118            0 :     const auto R = ecc::to_proj(Fp, {r, y});
     119            0 :     const auto pG = ecc::to_proj(Fp, G);
     120            0 :     const auto T1 = ecc::mul(Fp, pG, u1, B3);
     121            0 :     const auto T2 = ecc::mul(Fp, R, u2, B3);
     122            0 :     const auto pQ = ecc::add(Fp, T1, T2, B3);
     123              : 
     124            0 :     const auto Q = ecc::to_affine(Fp, field_inv, pQ);
     125              : 
     126              :     // Any other validity check needed?
     127            0 :     if (Q.is_inf())
     128            0 :         return std::nullopt;
     129              : 
     130            0 :     return Q;
     131              : }
     132              : 
     133            0 : std::optional<evmc::address> ecrecover(
     134              :     const ethash::hash256& e, const uint256& r, const uint256& s, bool v) noexcept
     135              : {
     136            0 :     const auto point = secp256k1_ecdsa_recover(e, r, s, v);
     137            0 :     if (!point.has_value())
     138            0 :         return std::nullopt;
     139              : 
     140            0 :     return to_address(*point);
     141              : }
     142              : 
     143            0 : uint256 field_inv(const ModArith<uint256>& m, const uint256& x) noexcept
     144              : {
     145              :     // Computes modular exponentiation
     146              :     // x^0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d
     147              :     // Operations: 255 squares 15 multiplies
     148              :     // Generated by github.com/mmcloughlin/addchain v0.4.0.
     149              :     //   addchain search 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d
     150              :     //     > secp256k1_field_inv.acc
     151              :     //   addchain gen -tmpl expmod.tmpl secp256k1_field_inv.acc
     152              :     //     > secp256k1_field_inv.cpp
     153              :     //
     154              :     // Exponentiation computation is derived from the addition chain:
     155              :     //
     156              :     // _10     = 2*1
     157              :     // _100    = 2*_10
     158              :     // _101    = 1 + _100
     159              :     // _111    = _10 + _101
     160              :     // _1110   = 2*_111
     161              :     // _111000 = _1110 << 2
     162              :     // _111111 = _111 + _111000
     163              :     // i13     = _111111 << 4 + _1110
     164              :     // x12     = i13 << 2 + _111
     165              :     // x22     = x12 << 10 + i13 + 1
     166              :     // i29     = 2*x22
     167              :     // i31     = i29 << 2
     168              :     // i54     = i31 << 22 + i31
     169              :     // i122    = (i54 << 20 + i29) << 46 + i54
     170              :     // x223    = i122 << 110 + i122 + _111
     171              :     // i269    = ((x223 << 23 + x22) << 7 + _101) << 3
     172              :     // return    _101 + i269
     173              : 
     174              :     // Allocate Temporaries.
     175            0 :     uint256 z;
     176            0 :     uint256 t0;
     177            0 :     uint256 t1;
     178            0 :     uint256 t2;
     179            0 :     uint256 t3;
     180            0 :     uint256 t4;
     181              : 
     182              :     // Step 1: t0 = x^0x2
     183            0 :     t0 = m.mul(x, x);
     184              : 
     185              :     // Step 2: z = x^0x4
     186            0 :     z = m.mul(t0, t0);
     187              : 
     188              :     // Step 3: z = x^0x5
     189            0 :     z = m.mul(x, z);
     190              : 
     191              :     // Step 4: t1 = x^0x7
     192            0 :     t1 = m.mul(t0, z);
     193              : 
     194              :     // Step 5: t0 = x^0xe
     195            0 :     t0 = m.mul(t1, t1);
     196              : 
     197              :     // Step 7: t2 = x^0x38
     198            0 :     t2 = m.mul(t0, t0);
     199            0 :     for (int i = 1; i < 2; ++i)
     200            0 :         t2 = m.mul(t2, t2);
     201              : 
     202              :     // Step 8: t2 = x^0x3f
     203            0 :     t2 = m.mul(t1, t2);
     204              : 
     205              :     // Step 12: t2 = x^0x3f0
     206            0 :     for (int i = 0; i < 4; ++i)
     207            0 :         t2 = m.mul(t2, t2);
     208              : 
     209              :     // Step 13: t0 = x^0x3fe
     210            0 :     t0 = m.mul(t0, t2);
     211              : 
     212              :     // Step 15: t2 = x^0xff8
     213            0 :     t2 = m.mul(t0, t0);
     214            0 :     for (int i = 1; i < 2; ++i)
     215            0 :         t2 = m.mul(t2, t2);
     216              : 
     217              :     // Step 16: t2 = x^0xfff
     218            0 :     t2 = m.mul(t1, t2);
     219              : 
     220              :     // Step 26: t2 = x^0x3ffc00
     221            0 :     for (int i = 0; i < 10; ++i)
     222            0 :         t2 = m.mul(t2, t2);
     223              : 
     224              :     // Step 27: t0 = x^0x3ffffe
     225            0 :     t0 = m.mul(t0, t2);
     226              : 
     227              :     // Step 28: t0 = x^0x3fffff
     228            0 :     t0 = m.mul(x, t0);
     229              : 
     230              :     // Step 29: t3 = x^0x7ffffe
     231            0 :     t3 = m.mul(t0, t0);
     232              : 
     233              :     // Step 31: t2 = x^0x1fffff8
     234            0 :     t2 = m.mul(t3, t3);
     235            0 :     for (int i = 1; i < 2; ++i)
     236            0 :         t2 = m.mul(t2, t2);
     237              : 
     238              :     // Step 53: t4 = x^0x7ffffe000000
     239            0 :     t4 = m.mul(t2, t2);
     240            0 :     for (int i = 1; i < 22; ++i)
     241            0 :         t4 = m.mul(t4, t4);
     242              : 
     243              :     // Step 54: t2 = x^0x7ffffffffff8
     244            0 :     t2 = m.mul(t2, t4);
     245              : 
     246              :     // Step 74: t4 = x^0x7ffffffffff800000
     247            0 :     t4 = m.mul(t2, t2);
     248            0 :     for (int i = 1; i < 20; ++i)
     249            0 :         t4 = m.mul(t4, t4);
     250              : 
     251              :     // Step 75: t3 = x^0x7fffffffffffffffe
     252            0 :     t3 = m.mul(t3, t4);
     253              : 
     254              :     // Step 121: t3 = x^0x1ffffffffffffffff800000000000
     255            0 :     for (int i = 0; i < 46; ++i)
     256            0 :         t3 = m.mul(t3, t3);
     257              : 
     258              :     // Step 122: t2 = x^0x1fffffffffffffffffffffffffff8
     259            0 :     t2 = m.mul(t2, t3);
     260              : 
     261              :     // Step 232: t3 = x^0x7ffffffffffffffffffffffffffe0000000000000000000000000000
     262            0 :     t3 = m.mul(t2, t2);
     263            0 :     for (int i = 1; i < 110; ++i)
     264            0 :         t3 = m.mul(t3, t3);
     265              : 
     266              :     // Step 233: t2 = x^0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffff8
     267            0 :     t2 = m.mul(t2, t3);
     268              : 
     269              :     // Step 234: t1 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff
     270            0 :     t1 = m.mul(t1, t2);
     271              : 
     272              :     // Step 257: t1 = x^0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffff800000
     273            0 :     for (int i = 0; i < 23; ++i)
     274            0 :         t1 = m.mul(t1, t1);
     275              : 
     276              :     // Step 258: t0 = x^0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff
     277            0 :     t0 = m.mul(t0, t1);
     278              : 
     279              :     // Step 265: t0 = x^0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff80
     280            0 :     for (int i = 0; i < 7; ++i)
     281            0 :         t0 = m.mul(t0, t0);
     282              : 
     283              :     // Step 266: t0 = x^0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffff85
     284            0 :     t0 = m.mul(z, t0);
     285              : 
     286              :     // Step 269: t0 = x^0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc28
     287            0 :     for (int i = 0; i < 3; ++i)
     288            0 :         t0 = m.mul(t0, t0);
     289              : 
     290              :     // Step 270: z = x^0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2d
     291            0 :     z = m.mul(z, t0);
     292              : 
     293            0 :     return z;
     294              : }
     295              : 
     296            0 : std::optional<uint256> field_sqrt(const ModArith<uint256>& m, const uint256& x) noexcept
     297              : {
     298              :     // Computes modular exponentiation
     299              :     // x^0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c
     300              :     // Operations: 253 squares 13 multiplies
     301              :     // Main part generated by github.com/mmcloughlin/addchain v0.4.0.
     302              :     //   addchain search 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c
     303              :     //     > secp256k1_sqrt.acc
     304              :     //   addchain gen -tmpl expmod.tmpl secp256k1_sqrt.acc
     305              :     //     > secp256k1_sqrt.cpp
     306              :     //
     307              :     // Exponentiation computation is derived from the addition chain:
     308              :     //
     309              :     // _10      = 2*1
     310              :     // _11      = 1 + _10
     311              :     // _1100    = _11 << 2
     312              :     // _1111    = _11 + _1100
     313              :     // _11110   = 2*_1111
     314              :     // _11111   = 1 + _11110
     315              :     // _1111100 = _11111 << 2
     316              :     // _1111111 = _11 + _1111100
     317              :     // x11      = _1111111 << 4 + _1111
     318              :     // x22      = x11 << 11 + x11
     319              :     // x27      = x22 << 5 + _11111
     320              :     // x54      = x27 << 27 + x27
     321              :     // x108     = x54 << 54 + x54
     322              :     // x216     = x108 << 108 + x108
     323              :     // x223     = x216 << 7 + _1111111
     324              :     // return     ((x223 << 23 + x22) << 6 + _11) << 2
     325              : 
     326              :     // Allocate Temporaries.
     327            0 :     uint256 z;
     328            0 :     uint256 t0;
     329            0 :     uint256 t1;
     330            0 :     uint256 t2;
     331            0 :     uint256 t3;
     332              : 
     333              : 
     334              :     // Step 1: z = x^0x2
     335            0 :     z = m.mul(x, x);
     336              : 
     337              :     // Step 2: z = x^0x3
     338            0 :     z = m.mul(x, z);
     339              : 
     340              :     // Step 4: t0 = x^0xc
     341            0 :     t0 = m.mul(z, z);
     342            0 :     for (int i = 1; i < 2; ++i)
     343            0 :         t0 = m.mul(t0, t0);
     344              : 
     345              :     // Step 5: t0 = x^0xf
     346            0 :     t0 = m.mul(z, t0);
     347              : 
     348              :     // Step 6: t1 = x^0x1e
     349            0 :     t1 = m.mul(t0, t0);
     350              : 
     351              :     // Step 7: t2 = x^0x1f
     352            0 :     t2 = m.mul(x, t1);
     353              : 
     354              :     // Step 9: t1 = x^0x7c
     355            0 :     t1 = m.mul(t2, t2);
     356            0 :     for (int i = 1; i < 2; ++i)
     357            0 :         t1 = m.mul(t1, t1);
     358              : 
     359              :     // Step 10: t1 = x^0x7f
     360            0 :     t1 = m.mul(z, t1);
     361              : 
     362              :     // Step 14: t3 = x^0x7f0
     363            0 :     t3 = m.mul(t1, t1);
     364            0 :     for (int i = 1; i < 4; ++i)
     365            0 :         t3 = m.mul(t3, t3);
     366              : 
     367              :     // Step 15: t0 = x^0x7ff
     368            0 :     t0 = m.mul(t0, t3);
     369              : 
     370              :     // Step 26: t3 = x^0x3ff800
     371            0 :     t3 = m.mul(t0, t0);
     372            0 :     for (int i = 1; i < 11; ++i)
     373            0 :         t3 = m.mul(t3, t3);
     374              : 
     375              :     // Step 27: t0 = x^0x3fffff
     376            0 :     t0 = m.mul(t0, t3);
     377              : 
     378              :     // Step 32: t3 = x^0x7ffffe0
     379            0 :     t3 = m.mul(t0, t0);
     380            0 :     for (int i = 1; i < 5; ++i)
     381            0 :         t3 = m.mul(t3, t3);
     382              : 
     383              :     // Step 33: t2 = x^0x7ffffff
     384            0 :     t2 = m.mul(t2, t3);
     385              : 
     386              :     // Step 60: t3 = x^0x3ffffff8000000
     387            0 :     t3 = m.mul(t2, t2);
     388            0 :     for (int i = 1; i < 27; ++i)
     389            0 :         t3 = m.mul(t3, t3);
     390              : 
     391              :     // Step 61: t2 = x^0x3fffffffffffff
     392            0 :     t2 = m.mul(t2, t3);
     393              : 
     394              :     // Step 115: t3 = x^0xfffffffffffffc0000000000000
     395            0 :     t3 = m.mul(t2, t2);
     396            0 :     for (int i = 1; i < 54; ++i)
     397            0 :         t3 = m.mul(t3, t3);
     398              : 
     399              :     // Step 116: t2 = x^0xfffffffffffffffffffffffffff
     400            0 :     t2 = m.mul(t2, t3);
     401              : 
     402              :     // Step 224: t3 = x^0xfffffffffffffffffffffffffff000000000000000000000000000
     403            0 :     t3 = m.mul(t2, t2);
     404            0 :     for (int i = 1; i < 108; ++i)
     405            0 :         t3 = m.mul(t3, t3);
     406              : 
     407              :     // Step 225: t2 = x^0xffffffffffffffffffffffffffffffffffffffffffffffffffffff
     408            0 :     t2 = m.mul(t2, t3);
     409              : 
     410              :     // Step 232: t2 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffffffff80
     411            0 :     for (int i = 0; i < 7; ++i)
     412            0 :         t2 = m.mul(t2, t2);
     413              : 
     414              :     // Step 233: t1 = x^0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff
     415            0 :     t1 = m.mul(t1, t2);
     416              : 
     417              :     // Step 256: t1 = x^0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffff800000
     418            0 :     for (int i = 0; i < 23; ++i)
     419            0 :         t1 = m.mul(t1, t1);
     420              : 
     421              :     // Step 257: t0 = x^0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff
     422            0 :     t0 = m.mul(t0, t1);
     423              : 
     424              :     // Step 263: t0 = x^0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc0
     425            0 :     for (int i = 0; i < 6; ++i)
     426            0 :         t0 = m.mul(t0, t0);
     427              : 
     428              :     // Step 264: z = x^0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc3
     429            0 :     z = m.mul(z, t0);
     430              : 
     431              :     // Step 266: z = x^0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c
     432            0 :     for (int i = 0; i < 2; ++i)
     433            0 :         z = m.mul(z, z);
     434              : 
     435            0 :     if (m.mul(z, z) != x)
     436            0 :         return std::nullopt;  // Computed value is not the square root.
     437              : 
     438            0 :     return z;
     439              : }
     440              : 
     441            0 : uint256 scalar_inv(const ModArith<uint256>& m, const uint256& x) noexcept
     442              : {
     443              :     // Computes modular exponentiation
     444              :     // x^0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f
     445              :     // Operations: 253 squares 40 multiplies
     446              :     // Generated by github.com/mmcloughlin/addchain v0.4.0.
     447              :     //   addchain search 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f
     448              :     //     > secp256k1_scalar_inv.acc
     449              :     //   addchain gen -tmpl expmod.tmpl secp256k1_scalar_inv.acc
     450              :     //     > secp256k1_scalar_inv.cpp
     451              :     //
     452              :     // Exponentiation computation is derived from the addition chain:
     453              :     //
     454              :     // _10       = 2*1
     455              :     // _11       = 1 + _10
     456              :     // _101      = _10 + _11
     457              :     // _111      = _10 + _101
     458              :     // _1001     = _10 + _111
     459              :     // _1011     = _10 + _1001
     460              :     // _1101     = _10 + _1011
     461              :     // _110100   = _1101 << 2
     462              :     // _111111   = _1011 + _110100
     463              :     // _1111110  = 2*_111111
     464              :     // _1111111  = 1 + _1111110
     465              :     // _11111110 = 2*_1111111
     466              :     // _11111111 = 1 + _11111110
     467              :     // i17       = _11111111 << 3
     468              :     // i19       = i17 << 2
     469              :     // i20       = 2*i19
     470              :     // i21       = 2*i20
     471              :     // i39       = (i21 << 7 + i20) << 9 + i21
     472              :     // i73       = (i39 << 6 + i19) << 26 + i39
     473              :     // x127      = (i73 << 4 + i17) << 60 + i73 + _1111111
     474              :     // i154      = ((x127 << 5 + _1011) << 3 + _101) << 4
     475              :     // i166      = ((_101 + i154) << 4 + _111) << 5 + _1101
     476              :     // i181      = ((i166 << 2 + _11) << 5 + _111) << 6
     477              :     // i193      = ((_1101 + i181) << 5 + _1011) << 4 + _1101
     478              :     // i214      = ((i193 << 3 + 1) << 6 + _101) << 10
     479              :     // i230      = ((_111 + i214) << 4 + _111) << 9 + _11111111
     480              :     // i247      = ((i230 << 5 + _1001) << 6 + _1011) << 4
     481              :     // i261      = ((_1101 + i247) << 5 + _11) << 6 + _1101
     482              :     // i283      = ((i261 << 10 + _1101) << 4 + _1001) << 6
     483              :     // return      (1 + i283) << 8 + _111111
     484              : 
     485              :     // Allocate Temporaries.
     486            0 :     uint256 z;
     487            0 :     uint256 t0;
     488            0 :     uint256 t1;
     489            0 :     uint256 t2;
     490            0 :     uint256 t3;
     491            0 :     uint256 t4;
     492            0 :     uint256 t5;
     493            0 :     uint256 t6;
     494            0 :     uint256 t7;
     495            0 :     uint256 t8;
     496            0 :     uint256 t9;
     497            0 :     uint256 t10;
     498            0 :     uint256 t11;
     499            0 :     uint256 t12;
     500              : 
     501              :     // Step 1: z = x^0x2
     502            0 :     z = m.mul(x, x);
     503              : 
     504              :     // Step 2: t2 = x^0x3
     505            0 :     t2 = m.mul(x, z);
     506              : 
     507              :     // Step 3: t6 = x^0x5
     508            0 :     t6 = m.mul(z, t2);
     509              : 
     510              :     // Step 4: t5 = x^0x7
     511            0 :     t5 = m.mul(z, t6);
     512              : 
     513              :     // Step 5: t0 = x^0x9
     514            0 :     t0 = m.mul(z, t5);
     515              : 
     516              :     // Step 6: t3 = x^0xb
     517            0 :     t3 = m.mul(z, t0);
     518              : 
     519              :     // Step 7: t1 = x^0xd
     520            0 :     t1 = m.mul(z, t3);
     521              : 
     522              :     // Step 9: z = x^0x34
     523            0 :     z = m.mul(t1, t1);
     524            0 :     for (int i = 1; i < 2; ++i)
     525            0 :         z = m.mul(z, z);
     526              : 
     527              :     // Step 10: z = x^0x3f
     528            0 :     z = m.mul(t3, z);
     529              : 
     530              :     // Step 11: t4 = x^0x7e
     531            0 :     t4 = m.mul(z, z);
     532              : 
     533              :     // Step 12: t7 = x^0x7f
     534            0 :     t7 = m.mul(x, t4);
     535              : 
     536              :     // Step 13: t4 = x^0xfe
     537            0 :     t4 = m.mul(t7, t7);
     538              : 
     539              :     // Step 14: t4 = x^0xff
     540            0 :     t4 = m.mul(x, t4);
     541              : 
     542              :     // Step 17: t9 = x^0x7f8
     543            0 :     t9 = m.mul(t4, t4);
     544            0 :     for (int i = 1; i < 3; ++i)
     545            0 :         t9 = m.mul(t9, t9);
     546              : 
     547              :     // Step 19: t10 = x^0x1fe0
     548            0 :     t10 = m.mul(t9, t9);
     549            0 :     for (int i = 1; i < 2; ++i)
     550            0 :         t10 = m.mul(t10, t10);
     551              : 
     552              :     // Step 20: t11 = x^0x3fc0
     553            0 :     t11 = m.mul(t10, t10);
     554              : 
     555              :     // Step 21: t8 = x^0x7f80
     556            0 :     t8 = m.mul(t11, t11);
     557              : 
     558              :     // Step 28: t12 = x^0x3fc000
     559            0 :     t12 = m.mul(t8, t8);
     560            0 :     for (int i = 1; i < 7; ++i)
     561            0 :         t12 = m.mul(t12, t12);
     562              : 
     563              :     // Step 29: t11 = x^0x3fffc0
     564            0 :     t11 = m.mul(t11, t12);
     565              : 
     566              :     // Step 38: t11 = x^0x7fff8000
     567            0 :     for (int i = 0; i < 9; ++i)
     568            0 :         t11 = m.mul(t11, t11);
     569              : 
     570              :     // Step 39: t8 = x^0x7fffff80
     571            0 :     t8 = m.mul(t8, t11);
     572              : 
     573              :     // Step 45: t11 = x^0x1fffffe000
     574            0 :     t11 = m.mul(t8, t8);
     575            0 :     for (int i = 1; i < 6; ++i)
     576            0 :         t11 = m.mul(t11, t11);
     577              : 
     578              :     // Step 46: t10 = x^0x1fffffffe0
     579            0 :     t10 = m.mul(t10, t11);
     580              : 
     581              :     // Step 72: t10 = x^0x7fffffff80000000
     582            0 :     for (int i = 0; i < 26; ++i)
     583            0 :         t10 = m.mul(t10, t10);
     584              : 
     585              :     // Step 73: t8 = x^0x7fffffffffffff80
     586            0 :     t8 = m.mul(t8, t10);
     587              : 
     588              :     // Step 77: t10 = x^0x7fffffffffffff800
     589            0 :     t10 = m.mul(t8, t8);
     590            0 :     for (int i = 1; i < 4; ++i)
     591            0 :         t10 = m.mul(t10, t10);
     592              : 
     593              :     // Step 78: t9 = x^0x7fffffffffffffff8
     594            0 :     t9 = m.mul(t9, t10);
     595              : 
     596              :     // Step 138: t9 = x^0x7fffffffffffffff8000000000000000
     597            0 :     for (int i = 0; i < 60; ++i)
     598            0 :         t9 = m.mul(t9, t9);
     599              : 
     600              :     // Step 139: t8 = x^0x7fffffffffffffffffffffffffffff80
     601            0 :     t8 = m.mul(t8, t9);
     602              : 
     603              :     // Step 140: t7 = x^0x7fffffffffffffffffffffffffffffff
     604            0 :     t7 = m.mul(t7, t8);
     605              : 
     606              :     // Step 145: t7 = x^0xfffffffffffffffffffffffffffffffe0
     607            0 :     for (int i = 0; i < 5; ++i)
     608            0 :         t7 = m.mul(t7, t7);
     609              : 
     610              :     // Step 146: t7 = x^0xfffffffffffffffffffffffffffffffeb
     611            0 :     t7 = m.mul(t3, t7);
     612              : 
     613              :     // Step 149: t7 = x^0x7fffffffffffffffffffffffffffffff58
     614            0 :     for (int i = 0; i < 3; ++i)
     615            0 :         t7 = m.mul(t7, t7);
     616              : 
     617              :     // Step 150: t7 = x^0x7fffffffffffffffffffffffffffffff5d
     618            0 :     t7 = m.mul(t6, t7);
     619              : 
     620              :     // Step 154: t7 = x^0x7fffffffffffffffffffffffffffffff5d0
     621            0 :     for (int i = 0; i < 4; ++i)
     622            0 :         t7 = m.mul(t7, t7);
     623              : 
     624              :     // Step 155: t7 = x^0x7fffffffffffffffffffffffffffffff5d5
     625            0 :     t7 = m.mul(t6, t7);
     626              : 
     627              :     // Step 159: t7 = x^0x7fffffffffffffffffffffffffffffff5d50
     628            0 :     for (int i = 0; i < 4; ++i)
     629            0 :         t7 = m.mul(t7, t7);
     630              : 
     631              :     // Step 160: t7 = x^0x7fffffffffffffffffffffffffffffff5d57
     632            0 :     t7 = m.mul(t5, t7);
     633              : 
     634              :     // Step 165: t7 = x^0xfffffffffffffffffffffffffffffffebaae0
     635            0 :     for (int i = 0; i < 5; ++i)
     636            0 :         t7 = m.mul(t7, t7);
     637              : 
     638              :     // Step 166: t7 = x^0xfffffffffffffffffffffffffffffffebaaed
     639            0 :     t7 = m.mul(t1, t7);
     640              : 
     641              :     // Step 168: t7 = x^0x3fffffffffffffffffffffffffffffffaeabb4
     642            0 :     for (int i = 0; i < 2; ++i)
     643            0 :         t7 = m.mul(t7, t7);
     644              : 
     645              :     // Step 169: t7 = x^0x3fffffffffffffffffffffffffffffffaeabb7
     646            0 :     t7 = m.mul(t2, t7);
     647              : 
     648              :     // Step 174: t7 = x^0x7fffffffffffffffffffffffffffffff5d576e0
     649            0 :     for (int i = 0; i < 5; ++i)
     650            0 :         t7 = m.mul(t7, t7);
     651              : 
     652              :     // Step 175: t7 = x^0x7fffffffffffffffffffffffffffffff5d576e7
     653            0 :     t7 = m.mul(t5, t7);
     654              : 
     655              :     // Step 181: t7 = x^0x1fffffffffffffffffffffffffffffffd755db9c0
     656            0 :     for (int i = 0; i < 6; ++i)
     657            0 :         t7 = m.mul(t7, t7);
     658              : 
     659              :     // Step 182: t7 = x^0x1fffffffffffffffffffffffffffffffd755db9cd
     660            0 :     t7 = m.mul(t1, t7);
     661              : 
     662              :     // Step 187: t7 = x^0x3fffffffffffffffffffffffffffffffaeabb739a0
     663            0 :     for (int i = 0; i < 5; ++i)
     664            0 :         t7 = m.mul(t7, t7);
     665              : 
     666              :     // Step 188: t7 = x^0x3fffffffffffffffffffffffffffffffaeabb739ab
     667            0 :     t7 = m.mul(t3, t7);
     668              : 
     669              :     // Step 192: t7 = x^0x3fffffffffffffffffffffffffffffffaeabb739ab0
     670            0 :     for (int i = 0; i < 4; ++i)
     671            0 :         t7 = m.mul(t7, t7);
     672              : 
     673              :     // Step 193: t7 = x^0x3fffffffffffffffffffffffffffffffaeabb739abd
     674            0 :     t7 = m.mul(t1, t7);
     675              : 
     676              :     // Step 196: t7 = x^0x1fffffffffffffffffffffffffffffffd755db9cd5e8
     677            0 :     for (int i = 0; i < 3; ++i)
     678            0 :         t7 = m.mul(t7, t7);
     679              : 
     680              :     // Step 197: t7 = x^0x1fffffffffffffffffffffffffffffffd755db9cd5e9
     681            0 :     t7 = m.mul(x, t7);
     682              : 
     683              :     // Step 203: t7 = x^0x7fffffffffffffffffffffffffffffff5d576e7357a40
     684            0 :     for (int i = 0; i < 6; ++i)
     685            0 :         t7 = m.mul(t7, t7);
     686              : 
     687              :     // Step 204: t6 = x^0x7fffffffffffffffffffffffffffffff5d576e7357a45
     688            0 :     t6 = m.mul(t6, t7);
     689              : 
     690              :     // Step 214: t6 = x^0x1fffffffffffffffffffffffffffffffd755db9cd5e91400
     691            0 :     for (int i = 0; i < 10; ++i)
     692            0 :         t6 = m.mul(t6, t6);
     693              : 
     694              :     // Step 215: t6 = x^0x1fffffffffffffffffffffffffffffffd755db9cd5e91407
     695            0 :     t6 = m.mul(t5, t6);
     696              : 
     697              :     // Step 219: t6 = x^0x1fffffffffffffffffffffffffffffffd755db9cd5e914070
     698            0 :     for (int i = 0; i < 4; ++i)
     699            0 :         t6 = m.mul(t6, t6);
     700              : 
     701              :     // Step 220: t5 = x^0x1fffffffffffffffffffffffffffffffd755db9cd5e914077
     702            0 :     t5 = m.mul(t5, t6);
     703              : 
     704              :     // Step 229: t5 = x^0x3fffffffffffffffffffffffffffffffaeabb739abd2280ee00
     705            0 :     for (int i = 0; i < 9; ++i)
     706            0 :         t5 = m.mul(t5, t5);
     707              : 
     708              :     // Step 230: t4 = x^0x3fffffffffffffffffffffffffffffffaeabb739abd2280eeff
     709            0 :     t4 = m.mul(t4, t5);
     710              : 
     711              :     // Step 235: t4 = x^0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe0
     712            0 :     for (int i = 0; i < 5; ++i)
     713            0 :         t4 = m.mul(t4, t4);
     714              : 
     715              :     // Step 236: t4 = x^0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe9
     716            0 :     t4 = m.mul(t0, t4);
     717              : 
     718              :     // Step 242: t4 = x^0x1fffffffffffffffffffffffffffffffd755db9cd5e9140777fa40
     719            0 :     for (int i = 0; i < 6; ++i)
     720            0 :         t4 = m.mul(t4, t4);
     721              : 
     722              :     // Step 243: t3 = x^0x1fffffffffffffffffffffffffffffffd755db9cd5e9140777fa4b
     723            0 :     t3 = m.mul(t3, t4);
     724              : 
     725              :     // Step 247: t3 = x^0x1fffffffffffffffffffffffffffffffd755db9cd5e9140777fa4b0
     726            0 :     for (int i = 0; i < 4; ++i)
     727            0 :         t3 = m.mul(t3, t3);
     728              : 
     729              :     // Step 248: t3 = x^0x1fffffffffffffffffffffffffffffffd755db9cd5e9140777fa4bd
     730            0 :     t3 = m.mul(t1, t3);
     731              : 
     732              :     // Step 253: t3 = x^0x3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a0
     733            0 :     for (int i = 0; i < 5; ++i)
     734            0 :         t3 = m.mul(t3, t3);
     735              : 
     736              :     // Step 254: t2 = x^0x3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a3
     737            0 :     t2 = m.mul(t2, t3);
     738              : 
     739              :     // Step 260: t2 = x^0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8c0
     740            0 :     for (int i = 0; i < 6; ++i)
     741            0 :         t2 = m.mul(t2, t2);
     742              : 
     743              :     // Step 261: t2 = x^0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd
     744            0 :     t2 = m.mul(t1, t2);
     745              : 
     746              :     // Step 271: t2 = x^0x3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a33400
     747            0 :     for (int i = 0; i < 10; ++i)
     748            0 :         t2 = m.mul(t2, t2);
     749              : 
     750              :     // Step 272: t1 = x^0x3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a3340d
     751            0 :     t1 = m.mul(t1, t2);
     752              : 
     753              :     // Step 276: t1 = x^0x3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a3340d0
     754            0 :     for (int i = 0; i < 4; ++i)
     755            0 :         t1 = m.mul(t1, t1);
     756              : 
     757              :     // Step 277: t0 = x^0x3fffffffffffffffffffffffffffffffaeabb739abd2280eeff497a3340d9
     758            0 :     t0 = m.mul(t0, t1);
     759              : 
     760              :     // Step 283: t0 = x^0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03640
     761            0 :     for (int i = 0; i < 6; ++i)
     762            0 :         t0 = m.mul(t0, t0);
     763              : 
     764              :     // Step 284: t0 = x^0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd03641
     765            0 :     t0 = m.mul(x, t0);
     766              : 
     767              :     // Step 292: t0 = x^0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364100
     768            0 :     for (int i = 0; i < 8; ++i)
     769            0 :         t0 = m.mul(t0, t0);
     770              : 
     771              :     // Step 293: z = x^0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413f
     772            0 :     z = m.mul(z, t0);
     773              : 
     774            0 :     return z;
     775              : }
     776              : }  // namespace evmmax::secp256k1
        

Generated by: LCOV version 2.0-1