Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
uintx.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
18#pragma once
19
20#include "../uint256/uint256.hpp"
23#include <cstdint>
24#include <iomanip>
25#include <iostream>
26
27namespace bb::numeric {
28
29template <class base_uint> class uintx {
30 public:
31 constexpr uintx(const uint64_t& data = 0)
32 : lo(data)
33 , hi(base_uint(0))
34 {}
35
36 constexpr uintx(const uint256_t& data)
38 : lo(data)
39 , hi(base_uint(0))
40
41 {}
42 constexpr uintx(const base_uint input_lo)
43 : lo(input_lo)
44 , hi(base_uint(0))
45 {}
46
47 constexpr uintx(const base_uint input_lo, const base_uint input_hi)
48 : lo(input_lo)
49 , hi(input_hi)
50 {}
51
52 constexpr uintx(const uintx& other) = default;
53 constexpr uintx(uintx&& other) noexcept = default;
54
55 static constexpr size_t length() { return 2 * base_uint::length(); }
56 uintx& operator=(const uintx& other) = default;
57 uintx& operator=(uintx&& other) noexcept = default;
58
59 ~uintx() = default;
60 constexpr explicit operator bool() const { return static_cast<bool>(lo); };
61 constexpr explicit operator uint8_t() const { return static_cast<uint8_t>(lo); };
62 constexpr explicit operator uint16_t() const { return static_cast<uint16_t>(lo); };
63 constexpr explicit operator uint32_t() const { return static_cast<uint32_t>(lo); };
64 constexpr explicit operator uint64_t() const { return static_cast<uint64_t>(lo); };
65
66 constexpr explicit operator base_uint() const { return lo; }
67
68 [[nodiscard]] bool get_bit(uint64_t bit_index) const;
69 [[nodiscard]] constexpr uint64_t get_msb() const
70 {
71 uint64_t hi_idx = hi.get_msb();
72 uint64_t lo_idx = lo.get_msb();
73 return (hi_idx || (hi > base_uint(0))) ? (hi_idx + base_uint::length()) : lo_idx;
74 }
75
82 constexpr uintx slice(const uint64_t start, const uint64_t end) const
83 {
84 const uint64_t range = end - start;
85 const uintx mask = range == base_uint::length() ? -uintx(1) : (uintx(1) << range) - 1;
86 return ((*this) >> start) & mask;
87 }
88
89 // constexpr to be used in constant calculation.
90 constexpr uintx operator-(const uintx& other) const
91 {
92 base_uint res_lo = lo - other.lo;
93 bool borrow = res_lo > lo;
94 base_uint res_hi = hi - other.hi - ((borrow) ? base_uint(1) : base_uint(0));
95 return { res_lo, res_hi };
96 }
97
98 // constexpr to be used in constant calculation.
99 constexpr uintx operator<<(const uint64_t other) const
100 {
101 const uint64_t total_shift = other;
102 if (total_shift >= length()) {
103 return uintx(0);
104 }
105 if (total_shift == 0) {
106 return *this;
107 }
108 const uint64_t num_shifted_limbs = total_shift >> (base_uint(base_uint::length()).get_msb());
109 const uint64_t limb_shift = total_shift & static_cast<uint64_t>(base_uint::length() - 1);
110
111 std::array<base_uint, 2> shifted_limbs = { 0, 0 };
112 if (limb_shift == 0) {
113 shifted_limbs[0] = lo;
114 shifted_limbs[1] = hi;
115 } else {
116 const uint64_t remainder_shift = static_cast<uint64_t>(base_uint::length()) - limb_shift;
117
118 shifted_limbs[0] = lo << limb_shift;
119
120 base_uint remainder = lo >> remainder_shift;
121
122 shifted_limbs[1] = (hi << limb_shift) + remainder;
123 }
124 uintx result(0);
125 if (num_shifted_limbs == 0) {
126 result.hi = shifted_limbs[1];
127 result.lo = shifted_limbs[0];
128 } else {
129 result.hi = shifted_limbs[0];
130 }
131 return result;
132 }
133
134 // constexpr to be used in constant calculation.
135 constexpr uintx operator>>(const uint64_t other) const
136 {
137 const uint64_t total_shift = other;
138 if (total_shift >= length()) {
139 return uintx(0);
140 }
141 if (total_shift == 0) {
142 return *this;
143 }
144 const uint64_t num_shifted_limbs = total_shift >> (base_uint(base_uint::length()).get_msb());
145
146 const uint64_t limb_shift = total_shift & static_cast<uint64_t>(base_uint::length() - 1);
147
148 std::array<base_uint, 2> shifted_limbs = { 0, 0 };
149 if (limb_shift == 0) {
150 shifted_limbs[0] = lo;
151 shifted_limbs[1] = hi;
152 } else {
153 const uint64_t remainder_shift = static_cast<uint64_t>(base_uint::length()) - limb_shift;
154
155 shifted_limbs[1] = hi >> limb_shift;
156
157 base_uint remainder = (hi) << remainder_shift;
158
159 shifted_limbs[0] = (lo >> limb_shift) + remainder;
160 }
161 uintx result(0);
162 if (num_shifted_limbs == 0) {
163 result.hi = shifted_limbs[1];
164 result.lo = shifted_limbs[0];
165 } else {
166 result.lo = shifted_limbs[1];
167 }
168 return result;
169 }
170
171 // constexpr to be used in constant calculation.
172 constexpr uintx operator+(const uintx& other) const
173 {
174 base_uint res_lo = lo + other.lo;
175 bool carry = res_lo < lo;
176 base_uint res_hi = hi + other.hi + ((carry) ? base_uint(1) : base_uint(0));
177 return { res_lo, res_hi };
178 };
179 uintx operator-() const;
180
181 uintx operator*(const uintx& other) const;
182 uintx operator/(const uintx& other) const;
183 uintx operator%(const uintx& other) const;
184
185 std::pair<uintx, uintx> mul_extended(const uintx& other) const;
186
187 // constexpr to be used in constant calculation.
188 constexpr uintx operator&(const uintx& other) const { return { lo & other.lo, hi & other.hi }; }
189
190 uintx operator^(const uintx& other) const;
191 uintx operator|(const uintx& other) const;
192 uintx operator~() const;
193
194 bool operator==(const uintx& other) const;
195 bool operator!=(const uintx& other) const;
196 bool operator!() const;
197
198 bool operator>(const uintx& other) const;
199 bool operator<(const uintx& other) const;
200 bool operator>=(const uintx& other) const;
201 bool operator<=(const uintx& other) const;
202
203 uintx& operator+=(const uintx& other)
204 {
205 *this = *this + other;
206 return *this;
207 };
208 uintx& operator-=(const uintx& other)
209 {
210 *this = *this - other;
211 return *this;
212 };
213 uintx& operator*=(const uintx& other)
214 {
215 *this = *this * other;
216 return *this;
217 };
218 uintx& operator/=(const uintx& other)
219
220 {
221 *this = *this / other;
222 return *this;
223 };
224 uintx& operator%=(const uintx& other)
225
226 {
227 *this = *this % other;
228 return *this;
229 };
230
232 {
233 *this += uintx(1);
234 return *this;
235 };
237 {
238 *this -= uintx(1);
239 return *this;
240 };
241
242 uintx& operator&=(const uintx& other)
243 {
244 *this = *this & other;
245 return *this;
246 };
247 uintx& operator^=(const uintx& other)
248 {
249 *this = *this ^ other;
250 return *this;
251 };
252 uintx& operator|=(const uintx& other)
253 {
254 *this = *this | other;
255 return *this;
256 };
257
258 uintx& operator>>=(const uint64_t other)
259 {
260 *this = *this >> other;
261 return *this;
262 };
263 uintx& operator<<=(const uint64_t other)
264 {
265 *this = *this << other;
266 return *this;
267 };
268
269 uintx invmod(const uintx& modulus) const;
270 uintx unsafe_invmod(const uintx& modulus) const;
271
272 base_uint lo;
273 base_uint hi;
274
275 template <base_uint modulus> std::pair<uintx, uintx> barrett_reduction() const;
276
277 // This only works (and is only used) for uint256_t
279 // This only works (and is only used) for uint256_t
281};
282
283template <typename B, typename Params> inline void read(B& it, uintx<Params>& value)
284{
285 using serialize::read;
286 Params a;
287 Params b;
288 read(it, b);
289 read(it, a);
291}
292
293template <typename B, typename Params> inline void write(B& it, uintx<Params> const& value)
294{
295 using serialize::write;
296 write(it, value.hi);
297 write(it, value.lo);
298}
299
300template <class base_uint> inline std::ostream& operator<<(std::ostream& os, uintx<base_uint> const& a)
301{
302 os << a.lo << ", " << a.hi << std::endl;
303 return os;
304}
305
306extern template class uintx<uint256_t>;
308extern template class uintx<uint512_t>;
310
311} // namespace bb::numeric
312
313using bb::numeric::uint1024_t; // NOLINT
314using bb::numeric::uint512_t; // NOLINT
constexpr uintx(uintx &&other) noexcept=default
constexpr uintx(const uint256_t &data)
Definition uintx.hpp:36
constexpr uintx operator+(const uintx &other) const
Definition uintx.hpp:172
uintx operator%(const uintx &other) const
uintx & operator|=(const uintx &other)
Definition uintx.hpp:252
uintx & operator*=(const uintx &other)
Definition uintx.hpp:213
std::pair< uintx, uintx > divmod(const uintx &b) const
constexpr uintx(const base_uint input_lo, const base_uint input_hi)
Definition uintx.hpp:47
constexpr uintx slice(const uint64_t start, const uint64_t end) const
Definition uintx.hpp:82
uintx & operator>>=(const uint64_t other)
Definition uintx.hpp:258
bool operator!=(const uintx &other) const
bool operator<(const uintx &other) const
uintx operator*(const uintx &other) const
uintx & operator&=(const uintx &other)
Definition uintx.hpp:242
static constexpr size_t length()
Definition uintx.hpp:55
uintx unsafe_invmod(const uintx &modulus) const
constexpr uintx operator-(const uintx &other) const
Definition uintx.hpp:90
uintx & operator+=(const uintx &other)
Definition uintx.hpp:203
uintx & operator=(uintx &&other) noexcept=default
uintx operator-() const
std::pair< uintx, uintx > divmod_base(const uintx &b) const
bool operator!() const
bool operator==(const uintx &other) const
uintx & operator^=(const uintx &other)
Definition uintx.hpp:247
bool operator>(const uintx &other) const
bool operator<=(const uintx &other) const
uintx operator~() const
bool get_bit(uint64_t bit_index) const
constexpr uint64_t get_msb() const
Definition uintx.hpp:69
uintx & operator-=(const uintx &other)
Definition uintx.hpp:208
std::pair< uintx, uintx > barrett_reduction() const
uintx & operator<<=(const uint64_t other)
Definition uintx.hpp:263
uintx & operator++()
Definition uintx.hpp:231
constexpr uintx operator&(const uintx &other) const
Definition uintx.hpp:188
uintx & operator--()
Definition uintx.hpp:236
uintx operator|(const uintx &other) const
uintx & operator=(const uintx &other)=default
bool operator>=(const uintx &other) const
uintx operator/(const uintx &other) const
uintx & operator/=(const uintx &other)
Definition uintx.hpp:218
std::pair< uintx, uintx > mul_extended(const uintx &other) const
constexpr uintx(const uint64_t &data=0)
Definition uintx.hpp:31
constexpr uintx operator>>(const uint64_t other) const
Definition uintx.hpp:135
uintx invmod(const uintx &modulus) const
uintx operator^(const uintx &other) const
constexpr uintx operator<<(const uint64_t other) const
Definition uintx.hpp:99
uintx & operator%=(const uintx &other)
Definition uintx.hpp:224
constexpr uintx(const uintx &other)=default
constexpr uintx(const base_uint input_lo)
Definition uintx.hpp:42
const std::vector< FF > data
FF a
FF b
crypto::Poseidon2Bn254ScalarFieldParams Params
void read(B &it, uint256_t &value)
Definition uint256.hpp:255
std::ostream & operator<<(std::ostream &os, uint256_t const &a)
Definition uint256.hpp:246
void write(B &it, uint256_t const &value)
Definition uint256.hpp:269
void read(auto &it, msgpack_concepts::HasMsgPack auto &obj)
Automatically derived read for any object that defines .msgpack() (implicitly defined by MSGPACK_FIEL...
void write(auto &buf, const msgpack_concepts::HasMsgPack auto &obj)
Automatically derived write for any object that defines .msgpack() (implicitly defined by MSGPACK_FIE...
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13