LCOV - differential code coverage report
Current view: top level - lib/evmone_precompiles - bn254.cpp (source / functions) Coverage Total Hit UBC
Current: DIFF_COVERAGE Lines: 0.0 % 159 0 159
Current Date: 2024-03-20 16:29:22 Functions: 0.0 % 4 0 4
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                 : 
       5                 : #include "bn254.hpp"
       6                 : 
       7                 : namespace evmmax::bn254
       8                 : {
       9                 : 
      10                 : namespace
      11                 : {
      12                 : const ModArith<uint256> Fp{FieldPrime};
      13                 : const auto B = Fp.to_mont(3);
      14                 : const auto B3 = Fp.to_mont(3 * 3);
      15                 : }  // namespace
      16                 : 
      17 UBC           0 : bool validate(const Point& pt) noexcept
      18                 : {
      19               0 :     if (pt.is_inf())
      20               0 :         return true;
      21                 : 
      22               0 :     const auto xm = Fp.to_mont(pt.x);
      23               0 :     const auto ym = Fp.to_mont(pt.y);
      24               0 :     const auto y2 = Fp.mul(ym, ym);
      25               0 :     const auto x2 = Fp.mul(xm, xm);
      26               0 :     const auto x3 = Fp.mul(x2, xm);
      27               0 :     const auto x3_3 = Fp.add(x3, B);
      28               0 :     return y2 == x3_3;
      29                 : }
      30                 : 
      31               0 : Point add(const Point& pt1, const Point& pt2) noexcept
      32                 : {
      33               0 :     if (pt1.is_inf())
      34               0 :         return pt2;
      35               0 :     if (pt2.is_inf())
      36               0 :         return pt1;
      37                 : 
      38                 :     // b3 == 9 for y^2 == x^3 + 3
      39               0 :     const auto r = ecc::add(Fp, ecc::to_proj(Fp, pt1), ecc::to_proj(Fp, pt2), B3);
      40                 : 
      41               0 :     return ecc::to_affine(Fp, field_inv, r);
      42                 : }
      43                 : 
      44               0 : Point mul(const Point& pt, const uint256& c) noexcept
      45                 : {
      46               0 :     if (pt.is_inf())
      47               0 :         return pt;
      48                 : 
      49               0 :     if (c == 0)
      50               0 :         return {};
      51                 : 
      52               0 :     const auto pr = ecc::mul(Fp, ecc::to_proj(Fp, pt), c, B3);
      53                 : 
      54               0 :     return ecc::to_affine(Fp, field_inv, pr);
      55                 : }
      56                 : 
      57               0 : uint256 field_inv(const ModArith<uint256>& m, const uint256& x) noexcept
      58                 : {
      59                 :     // Computes modular exponentiation
      60                 :     // x^0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45
      61                 :     // Operations: 247 squares 56 multiplies
      62                 :     // Generated by github.com/mmcloughlin/addchain v0.4.0.
      63                 :     //   addchain search 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45
      64                 :     //     > bn254_field_inv.acc
      65                 :     //   addchain gen -tmpl expmod.tmpl bn254_field_inv.acc
      66                 :     //     > bn254_field_inv.cpp
      67                 :     //
      68                 :     // Inversion computation is derived from the addition chain:
      69                 :     //
      70                 :     //  _10       = 2*1
      71                 :     //  _11       = 1 + _10
      72                 :     //  _101      = _10 + _11
      73                 :     //  _110      = 1 + _101
      74                 :     //  _1000     = _10 + _110
      75                 :     //  _1101     = _101 + _1000
      76                 :     //  _10010    = _101 + _1101
      77                 :     //  _10011    = 1 + _10010
      78                 :     //  _10100    = 1 + _10011
      79                 :     //  _10111    = _11 + _10100
      80                 :     //  _11100    = _101 + _10111
      81                 :     //  _100000   = _1101 + _10011
      82                 :     //  _100011   = _11 + _100000
      83                 :     //  _101011   = _1000 + _100011
      84                 :     //  _101111   = _10011 + _11100
      85                 :     //  _1000001  = _10010 + _101111
      86                 :     //  _1010011  = _10010 + _1000001
      87                 :     //  _1011011  = _1000 + _1010011
      88                 :     //  _1100001  = _110 + _1011011
      89                 :     //  _1110101  = _10100 + _1100001
      90                 :     //  _10010001 = _11100 + _1110101
      91                 :     //  _10010101 = _100000 + _1110101
      92                 :     //  _10110101 = _100000 + _10010101
      93                 :     //  _10111011 = _110 + _10110101
      94                 :     //  _11000001 = _110 + _10111011
      95                 :     //  _11000011 = _10 + _11000001
      96                 :     //  _11010011 = _10010 + _11000001
      97                 :     //  _11100001 = _100000 + _11000001
      98                 :     //  _11100011 = _10 + _11100001
      99                 :     //  _11100111 = _110 + _11100001
     100                 :     //  i57       = ((_11000001 << 8 + _10010001) << 10 + _11100111) << 7
     101                 :     //  i76       = ((_10111 + i57) << 9 + _10011) << 7 + _1101
     102                 :     //  i109      = ((i76 << 14 + _1010011) << 9 + _11100001) << 8
     103                 :     //  i127      = ((_1000001 + i109) << 10 + _1011011) << 5 + _1101
     104                 :     //  i161      = ((i127 << 8 + _11) << 12 + _101011) << 12
     105                 :     //  i186      = ((_10111011 + i161) << 8 + _101111) << 14 + _10110101
     106                 :     //  i214      = ((i186 << 9 + _10010001) << 5 + _1101) << 12
     107                 :     //  i236      = ((_11100011 + i214) << 8 + _10010101) << 11 + _11010011
     108                 :     //  i268      = ((i236 << 7 + _1100001) << 11 + _100011) << 12
     109                 :     //  i288      = ((_1011011 + i268) << 9 + _11000011) << 8 + _11100111
     110                 :     //  return      (i288 << 7 + _1110101) << 6 + _101
     111                 :     //
     112                 :     // Operations: 247 squares 56 m.multiplies
     113                 :     //
     114                 :     // Generated by github.com/mmcloughlin/addchain v0.4.0.
     115                 : 
     116                 :     // Allocate Temporaries.
     117               0 :     uint256 t0;
     118               0 :     uint256 t1;
     119               0 :     uint256 t2;
     120               0 :     uint256 t3;
     121               0 :     uint256 t4;
     122               0 :     uint256 t5;
     123               0 :     uint256 t6;
     124               0 :     uint256 t7;
     125               0 :     uint256 t8;
     126               0 :     uint256 t9;
     127               0 :     uint256 t10;
     128               0 :     uint256 t11;
     129               0 :     uint256 t12;
     130               0 :     uint256 t13;
     131               0 :     uint256 t14;
     132               0 :     uint256 t15;
     133               0 :     uint256 t16;
     134               0 :     uint256 t17;
     135               0 :     uint256 t18;
     136               0 :     uint256 t19;
     137               0 :     uint256 t20;
     138               0 :     uint256 t21;
     139                 :     // Step 1: t8 = x^0x2
     140               0 :     t8 = m.mul(x, x);
     141                 : 
     142                 :     // Step 2: t15 = x^0x3
     143               0 :     t15 = m.mul(x, t8);
     144                 : 
     145                 :     // Step 3: z = x^0x5
     146               0 :     auto z = m.mul(t8, t15);
     147                 : 
     148                 :     // Step 4: t1 = x^0x6
     149               0 :     t1 = m.mul(x, z);
     150                 : 
     151                 :     // Step 5: t3 = x^0x8
     152               0 :     t3 = m.mul(t8, t1);
     153                 : 
     154                 :     // Step 6: t9 = x^0xd
     155               0 :     t9 = m.mul(z, t3);
     156                 : 
     157                 :     // Step 7: t6 = x^0x12
     158               0 :     t6 = m.mul(z, t9);
     159                 : 
     160                 :     // Step 8: t19 = x^0x13
     161               0 :     t19 = m.mul(x, t6);
     162                 : 
     163                 :     // Step 9: t0 = x^0x14
     164               0 :     t0 = m.mul(x, t19);
     165                 : 
     166                 :     // Step 10: t20 = x^0x17
     167               0 :     t20 = m.mul(t15, t0);
     168                 : 
     169                 :     // Step 11: t2 = x^0x1c
     170               0 :     t2 = m.mul(z, t20);
     171                 : 
     172                 :     // Step 12: t17 = x^0x20
     173               0 :     t17 = m.mul(t9, t19);
     174                 : 
     175                 :     // Step 13: t4 = x^0x23
     176               0 :     t4 = m.mul(t15, t17);
     177                 : 
     178                 :     // Step 14: t14 = x^0x2b
     179               0 :     t14 = m.mul(t3, t4);
     180                 : 
     181                 :     // Step 15: t12 = x^0x2f
     182               0 :     t12 = m.mul(t19, t2);
     183                 : 
     184                 :     // Step 16: t16 = x^0x41
     185               0 :     t16 = m.mul(t6, t12);
     186                 : 
     187                 :     // Step 17: t18 = x^0x53
     188               0 :     t18 = m.mul(t6, t16);
     189                 : 
     190                 :     // Step 18: t3 = x^0x5b
     191               0 :     t3 = m.mul(t3, t18);
     192                 : 
     193                 :     // Step 19: t5 = x^0x61
     194               0 :     t5 = m.mul(t1, t3);
     195                 : 
     196                 :     // Step 20: t0 = x^0x75
     197               0 :     t0 = m.mul(t0, t5);
     198                 : 
     199                 :     // Step 21: t10 = x^0x91
     200               0 :     t10 = m.mul(t2, t0);
     201                 : 
     202                 :     // Step 22: t7 = x^0x95
     203               0 :     t7 = m.mul(t17, t0);
     204                 : 
     205                 :     // Step 23: t11 = x^0xb5
     206               0 :     t11 = m.mul(t17, t7);
     207                 : 
     208                 :     // Step 24: t13 = x^0xbb
     209               0 :     t13 = m.mul(t1, t11);
     210                 : 
     211                 :     // Step 25: t21 = x^0xc1
     212               0 :     t21 = m.mul(t1, t13);
     213                 : 
     214                 :     // Step 26: t2 = x^0xc3
     215               0 :     t2 = m.mul(t8, t21);
     216                 : 
     217                 :     // Step 27: t6 = x^0xd3
     218               0 :     t6 = m.mul(t6, t21);
     219                 : 
     220                 :     // Step 28: t17 = x^0xe1
     221               0 :     t17 = m.mul(t17, t21);
     222                 : 
     223                 :     // Step 29: t8 = x^0xe3
     224               0 :     t8 = m.mul(t8, t17);
     225                 : 
     226                 :     // Step 30: t1 = x^0xe7
     227               0 :     t1 = m.mul(t1, t17);
     228                 : 
     229                 :     // Step 38: t21 = x^0xc100
     230               0 :     for (int i = 0; i < 8; ++i)
     231               0 :         t21 = m.mul(t21, t21);
     232                 : 
     233                 :     // Step 39: t21 = x^0xc191
     234               0 :     t21 = m.mul(t10, t21);
     235                 : 
     236                 :     // Step 49: t21 = x^0x3064400
     237               0 :     for (int i = 0; i < 10; ++i)
     238               0 :         t21 = m.mul(t21, t21);
     239                 : 
     240                 :     // Step 50: t21 = x^0x30644e7
     241               0 :     t21 = m.mul(t1, t21);
     242                 : 
     243                 :     // Step 57: t21 = x^0x183227380
     244               0 :     for (int i = 0; i < 7; ++i)
     245               0 :         t21 = m.mul(t21, t21);
     246                 : 
     247                 :     // Step 58: t20 = x^0x183227397
     248               0 :     t20 = m.mul(t20, t21);
     249                 : 
     250                 :     // Step 67: t20 = x^0x30644e72e00
     251               0 :     for (int i = 0; i < 9; ++i)
     252               0 :         t20 = m.mul(t20, t20);
     253                 : 
     254                 :     // Step 68: t19 = x^0x30644e72e13
     255               0 :     t19 = m.mul(t19, t20);
     256                 : 
     257                 :     // Step 75: t19 = x^0x1832273970980
     258               0 :     for (int i = 0; i < 7; ++i)
     259               0 :         t19 = m.mul(t19, t19);
     260                 : 
     261                 :     // Step 76: t19 = x^0x183227397098d
     262               0 :     t19 = m.mul(t9, t19);
     263                 : 
     264                 :     // Step 90: t19 = x^0x60c89ce5c2634000
     265               0 :     for (int i = 0; i < 14; ++i)
     266               0 :         t19 = m.mul(t19, t19);
     267                 : 
     268                 :     // Step 91: t18 = x^0x60c89ce5c2634053
     269               0 :     t18 = m.mul(t18, t19);
     270                 : 
     271                 :     // Step 100: t18 = x^0xc19139cb84c680a600
     272               0 :     for (int i = 0; i < 9; ++i)
     273               0 :         t18 = m.mul(t18, t18);
     274                 : 
     275                 :     // Step 101: t17 = x^0xc19139cb84c680a6e1
     276               0 :     t17 = m.mul(t17, t18);
     277                 : 
     278                 :     // Step 109: t17 = x^0xc19139cb84c680a6e100
     279               0 :     for (int i = 0; i < 8; ++i)
     280               0 :         t17 = m.mul(t17, t17);
     281                 : 
     282                 :     // Step 110: t16 = x^0xc19139cb84c680a6e141
     283               0 :     t16 = m.mul(t16, t17);
     284                 : 
     285                 :     // Step 120: t16 = x^0x30644e72e131a029b850400
     286               0 :     for (int i = 0; i < 10; ++i)
     287               0 :         t16 = m.mul(t16, t16);
     288                 : 
     289                 :     // Step 121: t16 = x^0x30644e72e131a029b85045b
     290               0 :     t16 = m.mul(t3, t16);
     291                 : 
     292                 :     // Step 126: t16 = x^0x60c89ce5c263405370a08b60
     293               0 :     for (int i = 0; i < 5; ++i)
     294               0 :         t16 = m.mul(t16, t16);
     295                 : 
     296                 :     // Step 127: t16 = x^0x60c89ce5c263405370a08b6d
     297               0 :     t16 = m.mul(t9, t16);
     298                 : 
     299                 :     // Step 135: t16 = x^0x60c89ce5c263405370a08b6d00
     300               0 :     for (int i = 0; i < 8; ++i)
     301               0 :         t16 = m.mul(t16, t16);
     302                 : 
     303                 :     // Step 136: t15 = x^0x60c89ce5c263405370a08b6d03
     304               0 :     t15 = m.mul(t15, t16);
     305                 : 
     306                 :     // Step 148: t15 = x^0x60c89ce5c263405370a08b6d03000
     307               0 :     for (int i = 0; i < 12; ++i)
     308               0 :         t15 = m.mul(t15, t15);
     309                 : 
     310                 :     // Step 149: t14 = x^0x60c89ce5c263405370a08b6d0302b
     311               0 :     t14 = m.mul(t14, t15);
     312                 : 
     313                 :     // Step 161: t14 = x^0x60c89ce5c263405370a08b6d0302b000
     314               0 :     for (int i = 0; i < 12; ++i)
     315               0 :         t14 = m.mul(t14, t14);
     316                 : 
     317                 :     // Step 162: t13 = x^0x60c89ce5c263405370a08b6d0302b0bb
     318               0 :     t13 = m.mul(t13, t14);
     319                 : 
     320                 :     // Step 170: t13 = x^0x60c89ce5c263405370a08b6d0302b0bb00
     321               0 :     for (int i = 0; i < 8; ++i)
     322               0 :         t13 = m.mul(t13, t13);
     323                 : 
     324                 :     // Step 171: t12 = x^0x60c89ce5c263405370a08b6d0302b0bb2f
     325               0 :     t12 = m.mul(t12, t13);
     326                 : 
     327                 :     // Step 185: t12 = x^0x183227397098d014dc2822db40c0ac2ecbc000
     328               0 :     for (int i = 0; i < 14; ++i)
     329               0 :         t12 = m.mul(t12, t12);
     330                 : 
     331                 :     // Step 186: t11 = x^0x183227397098d014dc2822db40c0ac2ecbc0b5
     332               0 :     t11 = m.mul(t11, t12);
     333                 : 
     334                 :     // Step 195: t11 = x^0x30644e72e131a029b85045b68181585d97816a00
     335               0 :     for (int i = 0; i < 9; ++i)
     336               0 :         t11 = m.mul(t11, t11);
     337                 : 
     338                 :     // Step 196: t10 = x^0x30644e72e131a029b85045b68181585d97816a91
     339               0 :     t10 = m.mul(t10, t11);
     340                 : 
     341                 :     // Step 201: t10 = x^0x60c89ce5c263405370a08b6d0302b0bb2f02d5220
     342               0 :     for (int i = 0; i < 5; ++i)
     343               0 :         t10 = m.mul(t10, t10);
     344                 : 
     345                 :     // Step 202: t9 = x^0x60c89ce5c263405370a08b6d0302b0bb2f02d522d
     346               0 :     t9 = m.mul(t9, t10);
     347                 : 
     348                 :     // Step 214: t9 = x^0x60c89ce5c263405370a08b6d0302b0bb2f02d522d000
     349               0 :     for (int i = 0; i < 12; ++i)
     350               0 :         t9 = m.mul(t9, t9);
     351                 : 
     352                 :     // Step 215: t8 = x^0x60c89ce5c263405370a08b6d0302b0bb2f02d522d0e3
     353               0 :     t8 = m.mul(t8, t9);
     354                 : 
     355                 :     // Step 223: t8 = x^0x60c89ce5c263405370a08b6d0302b0bb2f02d522d0e300
     356               0 :     for (int i = 0; i < 8; ++i)
     357               0 :         t8 = m.mul(t8, t8);
     358                 : 
     359                 :     // Step 224: t7 = x^0x60c89ce5c263405370a08b6d0302b0bb2f02d522d0e395
     360               0 :     t7 = m.mul(t7, t8);
     361                 : 
     362                 :     // Step 235: t7 = x^0x30644e72e131a029b85045b68181585d97816a916871ca800
     363               0 :     for (int i = 0; i < 11; ++i)
     364               0 :         t7 = m.mul(t7, t7);
     365                 : 
     366                 :     // Step 236: t6 = x^0x30644e72e131a029b85045b68181585d97816a916871ca8d3
     367               0 :     t6 = m.mul(t6, t7);
     368                 : 
     369                 :     // Step 243: t6 = x^0x183227397098d014dc2822db40c0ac2ecbc0b548b438e546980
     370               0 :     for (int i = 0; i < 7; ++i)
     371               0 :         t6 = m.mul(t6, t6);
     372                 : 
     373                 :     // Step 244: t5 = x^0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e1
     374               0 :     t5 = m.mul(t5, t6);
     375                 : 
     376                 :     // Step 255: t5 = x^0xc19139cb84c680a6e14116da060561765e05aa45a1c72a34f0800
     377               0 :     for (int i = 0; i < 11; ++i)
     378               0 :         t5 = m.mul(t5, t5);
     379                 : 
     380                 :     // Step 256: t4 = x^0xc19139cb84c680a6e14116da060561765e05aa45a1c72a34f0823
     381               0 :     t4 = m.mul(t4, t5);
     382                 : 
     383                 :     // Step 268: t4 = x^0xc19139cb84c680a6e14116da060561765e05aa45a1c72a34f0823000
     384               0 :     for (int i = 0; i < 12; ++i)
     385               0 :         t4 = m.mul(t4, t4);
     386                 : 
     387                 :     // Step 269: t3 = x^0xc19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b
     388               0 :     t3 = m.mul(t3, t4);
     389                 : 
     390                 :     // Step 278: t3 = x^0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b600
     391               0 :     for (int i = 0; i < 9; ++i)
     392               0 :         t3 = m.mul(t3, t3);
     393                 : 
     394                 :     // Step 279: t2 = x^0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3
     395               0 :     t2 = m.mul(t2, t3);
     396                 : 
     397                 :     // Step 287: t2 = x^0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c300
     398               0 :     for (int i = 0; i < 8; ++i)
     399               0 :         t2 = m.mul(t2, t2);
     400                 : 
     401                 :     // Step 288: t1 = x^0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7
     402               0 :     t1 = m.mul(t1, t2);
     403                 : 
     404                 :     // Step 295: t1 = x^0xc19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f380
     405               0 :     for (int i = 0; i < 7; ++i)
     406               0 :         t1 = m.mul(t1, t1);
     407                 : 
     408                 :     // Step 296: t0 = x^0xc19139cb84c680a6e14116da060561765e05aa45a1c72a34f082305b61f3f5
     409               0 :     t0 = m.mul(t0, t1);
     410                 : 
     411                 :     // Step 302: t0 = x^0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd40
     412               0 :     for (int i = 0; i < 6; ++i)
     413               0 :         t0 = m.mul(t0, t0);
     414                 : 
     415                 :     // Step 303: z = x^0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45
     416               0 :     z = m.mul(z, t0);
     417                 : 
     418               0 :     return z;
     419                 : }
     420                 : 
     421                 : }  // namespace evmmax::bn254
        

Generated by: LCOV version 2.0-1