Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
uint128.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Luke], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8#include <cstdint>
9#include <iomanip>
10#include <ostream>
11
12#ifdef __i386__
14#include <concepts>
15
16namespace bb::numeric {
17
18class alignas(32) uint128_t {
19 public:
20 uint32_t data[4]; // NOLINT
21
22 constexpr uint128_t(const uint64_t a = 0)
23 : data{ static_cast<uint32_t>(a), static_cast<uint32_t>(a >> 32), 0, 0 }
24 {}
25
26 constexpr uint128_t(const uint32_t a, const uint32_t b, const uint32_t c, const uint32_t d)
27 : data{ a, b, c, d }
28 {}
29
30 constexpr uint128_t(const uint128_t& other)
31 : data{ other.data[0], other.data[1], other.data[2], other.data[3] }
32 {}
33 constexpr uint128_t(uint128_t&& other) = default;
34
35 static constexpr uint128_t from_uint64(const uint64_t a)
36 {
37 return { static_cast<uint32_t>(a), static_cast<uint32_t>(a >> 32), 0, 0 };
38 }
39
40 constexpr explicit operator uint64_t() const { return (static_cast<uint64_t>(data[1]) << 32) + data[0]; }
41
42 constexpr uint128_t& operator=(const uint128_t& other) = default;
43 constexpr uint128_t& operator=(uint128_t&& other) = default;
44 constexpr ~uint128_t() = default;
45 explicit constexpr operator bool() const
46 {
47 return (data[0] != 0) || (data[1] != 0) || (data[2] != 0) || (data[3] != 0);
48 };
49
50 template <std::integral T> explicit constexpr operator T() const { return static_cast<T>(data[0]); };
51
52 [[nodiscard]] constexpr bool get_bit(uint64_t bit_index) const;
53 [[nodiscard]] constexpr uint64_t get_msb() const;
54
55 [[nodiscard]] constexpr uint128_t slice(uint64_t start, uint64_t end) const;
56 [[nodiscard]] constexpr uint128_t pow(const uint128_t& exponent) const;
57
58 constexpr uint128_t operator+(const uint128_t& other) const;
59 constexpr uint128_t operator-(const uint128_t& other) const;
60 constexpr uint128_t operator-() const;
61
62 constexpr uint128_t operator*(const uint128_t& other) const;
63 constexpr uint128_t operator/(const uint128_t& other) const;
64 constexpr uint128_t operator%(const uint128_t& other) const;
65
66 constexpr uint128_t operator>>(const uint128_t& other) const;
67 constexpr uint128_t operator<<(const uint128_t& other) const;
68
69 constexpr uint128_t operator&(const uint128_t& other) const;
70 constexpr uint128_t operator^(const uint128_t& other) const;
71 constexpr uint128_t operator|(const uint128_t& other) const;
72 constexpr uint128_t operator~() const;
73
74 constexpr bool operator==(const uint128_t& other) const;
75 constexpr bool operator!=(const uint128_t& other) const;
76 constexpr bool operator!() const;
77
78 constexpr bool operator>(const uint128_t& other) const;
79 constexpr bool operator<(const uint128_t& other) const;
80 constexpr bool operator>=(const uint128_t& other) const;
81 constexpr bool operator<=(const uint128_t& other) const;
82
83 static constexpr size_t length() { return 128; }
84
85 constexpr uint128_t& operator+=(const uint128_t& other)
86 {
87 *this = *this + other;
88 return *this;
89 };
90 constexpr uint128_t& operator-=(const uint128_t& other)
91 {
92 *this = *this - other;
93 return *this;
94 };
95 constexpr uint128_t& operator*=(const uint128_t& other)
96 {
97 *this = *this * other;
98 return *this;
99 };
100 constexpr uint128_t& operator/=(const uint128_t& other)
101 {
102 *this = *this / other;
103 return *this;
104 };
105 constexpr uint128_t& operator%=(const uint128_t& other)
106 {
107 *this = *this % other;
108 return *this;
109 };
110
111 constexpr uint128_t& operator++()
112 {
113 *this += uint128_t(1);
114 return *this;
115 };
116 constexpr uint128_t& operator--()
117 {
118 *this -= uint128_t(1);
119 return *this;
120 };
121
122 constexpr uint128_t& operator&=(const uint128_t& other)
123 {
124 *this = *this & other;
125 return *this;
126 };
127 constexpr uint128_t& operator^=(const uint128_t& other)
128 {
129 *this = *this ^ other;
130 return *this;
131 };
132 constexpr uint128_t& operator|=(const uint128_t& other)
133 {
134 *this = *this | other;
135 return *this;
136 };
137
138 constexpr uint128_t& operator>>=(const uint128_t& other)
139 {
140 *this = *this >> other;
141 return *this;
142 };
143 constexpr uint128_t& operator<<=(const uint128_t& other)
144 {
145 *this = *this << other;
146 return *this;
147 };
148
149 [[nodiscard]] constexpr std::pair<uint128_t, uint128_t> mul_extended(const uint128_t& other) const;
150
151 [[nodiscard]] constexpr std::pair<uint128_t, uint128_t> divmod(const uint128_t& b) const;
152
153 private:
154 [[nodiscard]] static constexpr std::pair<uint32_t, uint32_t> mul_wide(uint32_t a, uint32_t b);
155 [[nodiscard]] static constexpr std::pair<uint32_t, uint32_t> addc(uint32_t a, uint32_t b, uint32_t carry_in);
156 [[nodiscard]] static constexpr uint32_t addc_discard_hi(uint32_t a, uint32_t b, uint32_t carry_in);
157 [[nodiscard]] static constexpr uint32_t sbb_discard_hi(uint32_t a, uint32_t b, uint32_t borrow_in);
158
159 [[nodiscard]] static constexpr std::pair<uint32_t, uint32_t> sbb(uint32_t a, uint32_t b, uint32_t borrow_in);
160 [[nodiscard]] static constexpr uint32_t mac_discard_hi(uint32_t a, uint32_t b, uint32_t c, uint32_t carry_in);
161 [[nodiscard]] static constexpr std::pair<uint32_t, uint32_t> mac(uint32_t a,
162 uint32_t b,
163 uint32_t c,
164 uint32_t carry_in);
165};
166
167inline std::ostream& operator<<(std::ostream& os, uint128_t const& a)
168{
169 std::ios_base::fmtflags f(os.flags());
170 os << std::hex << "0x" << std::setfill('0') << std::setw(8) << a.data[3] << std::setw(8) << a.data[2]
171 << std::setw(8) << a.data[1] << std::setw(8) << a.data[0];
172 os.flags(f);
173 return os;
174}
175
176template <typename B> inline void read(B& it, uint128_t& value)
177{
178 using serialize::read;
179 uint32_t a = 0;
180 uint32_t b = 0;
181 uint32_t c = 0;
182 uint32_t d = 0;
183 read(it, d);
184 read(it, c);
185 read(it, b);
186 read(it, a);
187 value = uint128_t(a, b, c, d);
188}
189
190template <typename B> inline void write(B& it, uint128_t const& value)
191{
192 using serialize::write;
193 write(it, value.data[3]);
194 write(it, value.data[2]);
195 write(it, value.data[1]);
196 write(it, value.data[0]);
197}
198
199} // namespace bb::numeric
200
201#include "./uint128_impl.hpp"
202
203// disable linter errors; we want to expose a global uint128_t type to mimic uint64_t, uint32_t etc
204// NOLINTNEXTLINE(tidymisc-unused-using-decls, google-global-names-in-headers, misc-unused-using-decls)
205using numeric::uint128_t;
206#else
207__extension__ using uint128_t = unsigned __int128;
208
209namespace std {
210// can ignore linter error for streaming operations, we need to add to std namespace to support printing this type!
211// NOLINTNEXTLINE(cert-dcl58-cpp)
212inline std::ostream& operator<<(std::ostream& os, uint128_t const& a)
213{
214 std::ios_base::fmtflags f(os.flags());
215 os << std::hex << "0x" << std::setfill('0') << std::setw(16) << static_cast<uint64_t>(a >> 64) << std::setw(16)
216 << static_cast<uint64_t>(a);
217 os.flags(f);
218 return os;
219}
220} // namespace std
221#endif
constexpr InputType operator!(InputType type)
const std::vector< MemoryValue > data
FF a
FF b
std::ostream & operator<<(std::ostream &os, const CFGInstruction &instruction)
uint8_t const size_t length
Definition data_store.hpp:9
bool operator==(schnorr_signature const &lhs, schnorr_signature const &rhs)
Definition schnorr.hpp:45
void read(B &it, uint256_t &value)
Definition uint256.hpp:267
std::ostream & operator<<(std::ostream &os, uint256_t const &a)
Definition uint256.hpp:258
constexpr T get_msb(const T in)
Definition get_msb.hpp:49
void write(B &it, uint256_t const &value)
Definition uint256.hpp:281
C slice(C const &container, size_t start)
Definition container.hpp:9
Univariate< Fr, domain_end > operator-(const Fr &ff, const Univariate< Fr, domain_end > &uv)
Univariate< Fr, domain_end > operator*(const Fr &ff, const Univariate< Fr, domain_end > &uv)
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...
STerm operator&(const bb::fr &lhs, const STerm &rhs)
Definition term.cpp:511
STerm operator|(const bb::fr &lhs, const STerm &rhs)
Definition term.cpp:516
void operator!=(const bb::fr &lhs, const STerm &rhs)
Definition term.cpp:531
STerm operator^(const bb::fr &lhs, const STerm &rhs)
Definition term.cpp:506
STerm operator/(const bb::fr &lhs, const STerm &rhs)
Definition term.cpp:521
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::ostream & operator<<(std::ostream &os, const T &obj)
Automatically derived stream operator for any object that defines .msgpack() (implicitly defined by M...
Definition streams.hpp:79
TUPLET_INLINE constexpr auto operator+(type_list< Ls... >, type_list< Rs... >)
Convinience + operator for catenating type lists.
Definition tuplet.hpp:117
unsigned __int128 uint128_t
Definition serialize.hpp:45