github.com/ledgerwatch/erigon-lib@v1.0.0/pedersen_hash/big_int.h (about)

     1  #ifndef STARKWARE_ALGEBRA_BIG_INT_H_
     2  #define STARKWARE_ALGEBRA_BIG_INT_H_
     3  
     4  #include <cstddef>
     5  #include <iostream>
     6  #include <limits>
     7  #include <string>
     8  #include <utility>
     9  #include <vector>
    10  
    11  #include "gsl-lite.hpp"
    12  
    13  #include "error_handling.h"
    14  #include "prng.h"
    15  
    16  namespace starkware {
    17  
    18  static constexpr inline __uint128_t Umul128(uint64_t x, uint64_t y) {
    19    return static_cast<__uint128_t>(x) * static_cast<__uint128_t>(y);
    20  }
    21  
    22  template <size_t N>
    23  class BigInt {
    24   public:
    25    static constexpr size_t kDigits = N * std::numeric_limits<uint64_t>::digits;
    26  
    27    BigInt() = default;
    28  
    29    template <size_t K>
    30    constexpr BigInt(const BigInt<K>& v) noexcept;  // NOLINT implicit cast.
    31    constexpr explicit BigInt(const std::array<uint64_t, N>& v) noexcept : value_(v) {}
    32    constexpr explicit BigInt(uint64_t v) noexcept : value_(std::array<uint64_t, N>({v})) {}
    33  
    34    static constexpr BigInt One() { return BigInt(std::array<uint64_t, N>({1})); }
    35    static constexpr BigInt Zero() { return BigInt(std::array<uint64_t, N>({0})); }
    36  
    37    static BigInt RandomBigInt(Prng* prng);
    38  
    39    /*
    40      Returns pair of the form (result, overflow_occurred).
    41    */
    42    static constexpr std::pair<BigInt, bool> Add(const BigInt& a, const BigInt& b);
    43    constexpr BigInt operator+(const BigInt& other) const { return Add(*this, other).first; }
    44    constexpr BigInt operator-(const BigInt& other) const { return Sub(*this, other).first; }
    45    constexpr BigInt operator-() const { return Zero() - *this; }
    46  
    47    /*
    48      Multiplies two BigInt<N> numbers, this and other. Returns the result as a
    49      BigInt<2*N>.
    50    */
    51    constexpr BigInt<2 * N> operator*(const BigInt& other) const;
    52  
    53    /*
    54      Multiplies two BigInt<N> numbers modulo a third.
    55    */
    56    static BigInt MulMod(const BigInt& a, const BigInt& b, const BigInt& modulus);
    57  
    58    /*
    59      Computes the inverse of *this in the field GF(prime).
    60      If prime is not a prime number, the behavior is undefined.
    61    */
    62    BigInt InvModPrime(const BigInt& prime) const;
    63  
    64    /*
    65      Return pair of the form (result, underflow_occurred).
    66    */
    67    static constexpr std::pair<BigInt, bool> Sub(const BigInt& a, const BigInt& b);
    68  
    69    constexpr bool operator<(const BigInt& b) const;
    70  
    71    constexpr bool operator>=(const BigInt& b) const { return !(*this < b); }
    72  
    73    constexpr bool operator>(const BigInt& b) const { return b < *this; }
    74  
    75    constexpr bool operator<=(const BigInt& b) const { return !(*this > b); }
    76  
    77    /*
    78      Returns the pair (q, r) such that this == q*divisor + r and r < divisor.
    79    */
    80    std::pair<BigInt, BigInt> Div(const BigInt& divisor) const;
    81  
    82    /*
    83      Returns the representation of the number as a string of the form "0x...".
    84    */
    85    std::string ToString() const;
    86  
    87    std::vector<bool> ToBoolVector() const;
    88  
    89    /*
    90      Returns (x % target) assuming x is in the range [0, 2*target).
    91  
    92      The function assumes that target.NumLeadingZeros() > 0.
    93  
    94      Typically used after a Montgomery reduction which produces an output that
    95      satisfies the range requirement above.
    96    */
    97    static constexpr BigInt ReduceIfNeeded(const BigInt& x, const BigInt& target);
    98  
    99    /*
   100      Calculates x*y/2^256 mod modulus, assuming that montgomery_mprime is
   101      (-(modulus^-1)) mod 2^64. Assumes that modulus.NumLeadingZeros() > 0.
   102    */
   103    static constexpr BigInt MontMul(
   104        const BigInt& x, const BigInt& y, const BigInt& modulus, uint64_t montgomery_mprime);
   105  
   106    constexpr bool operator==(const BigInt& other) const;
   107  
   108    constexpr bool operator!=(const BigInt& other) const { return !(*this == other); }
   109  
   110    constexpr uint64_t& operator[](int i) { return gsl::at(value_, i); }
   111  
   112    constexpr const uint64_t& operator[](int i) const { return gsl::at(value_, i); }
   113  
   114    static constexpr size_t LimbCount() { return N; }
   115  
   116    /*
   117      Returns the number of leading zero's.
   118    */
   119    constexpr size_t NumLeadingZeros() const;
   120  
   121   private:
   122    std::array<uint64_t, N> value_;
   123  };
   124  
   125  template <size_t N>
   126  std::ostream& operator<<(std::ostream& os, const BigInt<N>& bigint);
   127  
   128  }  // namespace starkware
   129  
   130  /*
   131    Implements the user defined _Z literal that constructs a BigInt of an
   132    arbitrary size. For example: BigInt<4> a =
   133    0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001_Z;
   134  */
   135  template <char... Chars>
   136  static constexpr auto operator"" _Z();
   137  
   138  #include "big_int.inl"
   139  
   140  #endif  // STARKWARE_ALGEBRA_BIG_INT_H_