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_