LCOV - differential code coverage report
Current view: top level - lib/evmone_precompiles - secp256k1.cpp (source / functions) Coverage Total Hit UBC
Current: DIFF_COVERAGE Lines: 0.0 % 311 0 311
Current Date: 2024-03-20 16:29:22 Functions: 0.0 % 9 0 9
Baseline: coverage_BASE.lcov
Baseline Date: 2024-03-20 14:19:08

           TLA  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 UBC           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