3#include "barretenberg/common/assert.hpp"
6template <
class base_u
int>
14 return { *
this,
uintx(0) };
20 return {
uintx(0), *
this };
24 uintx remainder = *
this;
26 uint64_t bit_difference = get_msb() - b.get_msb();
28 uintx divisor = b << bit_difference;
29 uintx accumulator =
uintx(1) << bit_difference;
32 if (divisor > remainder) {
39 while (remainder >= b) {
43 if (remainder >= divisor) {
47 quotient |= accumulator;
53 return std::make_pair(quotient, remainder);
70 uintx r2 = (*
this > modulus) ? *
this % modulus : *
this;
78 t2 = temp_t1 - q * t2;
80 r2 = temp_r1 - q * r2;
103 if (modulus.get_msb() >= (2 * base_uint::length() - 1)) {
108 return this->unsafe_invmod(modulus);
116template <
class base_u
int>
119 const uint64_t range = end - start;
120 const uintx mask = range == base_uint::length() ? -
uintx(1) : (
uintx(1) << range) - 1;
121 return ((*
this) >> start) & mask;
126 if (bit_index >= base_uint::length()) {
127 return hi.get_bit(bit_index - base_uint::length());
129 return lo.get_bit(bit_index);
134 uint64_t hi_idx = hi.get_msb();
135 uint64_t lo_idx = lo.get_msb();
136 return (hi_idx || (hi > base_uint(0))) ? (hi_idx + base_uint::length()) : lo_idx;
141 base_uint res_lo = lo + other.lo;
142 bool carry = res_lo < lo;
143 base_uint res_hi = hi + other.hi + ((carry) ? base_uint(1) : base_uint(0));
144 return { res_lo, res_hi };
149 base_uint res_lo = lo - other.lo;
150 bool borrow = res_lo > lo;
151 base_uint res_hi = hi - other.hi - ((borrow) ? base_uint(1) : base_uint(0));
152 return { res_lo, res_hi };
157 return uintx(0) - *
this;
162 const auto lolo = lo.mul_extended(other.lo);
163 const auto lohi = lo.mul_extended(other.hi);
164 const auto hilo = hi.mul_extended(other.lo);
166 base_uint top = lolo.second + hilo.first + lohi.first;
167 base_uint bottom = lolo.first;
168 return { bottom, top };
171template <
class base_u
int>
174 const auto lolo = lo.mul_extended(other.lo);
175 const auto lohi = lo.mul_extended(other.hi);
176 const auto hilo = hi.mul_extended(other.lo);
177 const auto hihi = hi.mul_extended(other.hi);
179 base_uint t0 = lolo.first;
180 base_uint t1 = lolo.second;
181 base_uint t2 = hilo.second;
182 base_uint t3 = hihi.second;
183 base_uint t2_carry(0);
184 base_uint t3_carry(0);
186 t2_carry += (t1 < hilo.first ? base_uint(1) : base_uint(0));
188 t2_carry += (t1 < lohi.first ? base_uint(1) : base_uint(0));
190 t3_carry += (t2 < lohi.second ? base_uint(1) : base_uint(0));
192 t3_carry += (t2 < hihi.first ? base_uint(1) : base_uint(0));
194 t3_carry += (t2 < t2_carry ? base_uint(1) : base_uint(0));
201 return divmod(other).first;
206 return divmod(other).second;
212 return { lo & other.lo, hi & other.hi };
217 return { lo ^ other.lo, hi ^ other.hi };
222 return { lo | other.lo, hi | other.hi };
232 return ((lo == other.lo) && (hi == other.hi));
237 return !(*
this == other);
242 return *
this ==
uintx(0ULL);
247 bool hi_gt = hi > other.hi;
248 bool lo_gt = lo > other.lo;
250 bool gt = (hi_gt) || (lo_gt && (hi == other.hi));
256 return (*
this > other) || (*
this == other);
261 return other > *
this;
266 return (*
this < other) || (*
this == other);
271 const uint64_t total_shift = other;
272 if (total_shift >= length()) {
275 if (total_shift == 0) {
278 const uint64_t num_shifted_limbs = total_shift >> (base_uint(base_uint::length()).get_msb());
280 const uint64_t limb_shift = total_shift &
static_cast<uint64_t
>(base_uint::length() - 1);
282 std::array<base_uint, 2> shifted_limbs = { 0, 0 };
283 if (limb_shift == 0) {
284 shifted_limbs[0] = lo;
285 shifted_limbs[1] = hi;
287 const uint64_t remainder_shift =
static_cast<uint64_t
>(base_uint::length()) - limb_shift;
289 shifted_limbs[1] = hi >> limb_shift;
291 base_uint remainder = (hi) << remainder_shift;
293 shifted_limbs[0] = (lo >> limb_shift) + remainder;
296 if (num_shifted_limbs == 0) {
297 result.hi = shifted_limbs[1];
298 result.lo = shifted_limbs[0];
300 result.lo = shifted_limbs[1];
307 const uint64_t total_shift = other;
308 if (total_shift >= length()) {
311 if (total_shift == 0) {
314 const uint64_t num_shifted_limbs = total_shift >> (base_uint(base_uint::length()).get_msb());
315 const uint64_t limb_shift = total_shift &
static_cast<uint64_t
>(base_uint::length() - 1);
317 std::array<base_uint, 2> shifted_limbs = { 0, 0 };
318 if (limb_shift == 0) {
319 shifted_limbs[0] = lo;
320 shifted_limbs[1] = hi;
322 const uint64_t remainder_shift =
static_cast<uint64_t
>(base_uint::length()) - limb_shift;
324 shifted_limbs[0] = lo << limb_shift;
326 base_uint remainder = lo >> remainder_shift;
328 shifted_limbs[1] = (hi << limb_shift) + remainder;
331 if (num_shifted_limbs == 0) {
332 result.hi = shifted_limbs[1];
333 result.lo = shifted_limbs[0];
335 result.hi = shifted_limbs[0];
constexpr uintx unsafe_invmod(const uintx &modulus) const
Definition: uintx_impl.hpp:65
constexpr uintx invmod(const uintx &modulus) const
Definition: uintx_impl.hpp:97
constexpr uintx slice(uint64_t start, uint64_t end) const
Definition: uintx_impl.hpp:117
Definition: field2_declarations.hpp:6