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: 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
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() { 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 { return static_cast<bool>(data[0]); };
46
47 template <std::integral T> explicit constexpr operator T() const { return static_cast<T>(data[0]); };
48
49 [[nodiscard]] constexpr bool get_bit(uint64_t bit_index) const;
50 [[nodiscard]] constexpr uint64_t get_msb() const;
51
52 [[nodiscard]] constexpr uint128_t slice(uint64_t start, uint64_t end) const;
53 [[nodiscard]] constexpr uint128_t pow(const uint128_t& exponent) const;
54
55 constexpr uint128_t operator+(const uint128_t& other) const;
56 constexpr uint128_t operator-(const uint128_t& other) const;
57 constexpr uint128_t operator-() const;
58
59 constexpr uint128_t operator*(const uint128_t& other) const;
60 constexpr uint128_t operator/(const uint128_t& other) const;
61 constexpr uint128_t operator%(const uint128_t& other) const;
62
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 constexpr uint128_t operator|(const uint128_t& other) const;
69 constexpr uint128_t operator~() const;
70
71 constexpr bool operator==(const uint128_t& other) const;
72 constexpr bool operator!=(const uint128_t& other) const;
73 constexpr bool operator!() const;
74
75 constexpr bool operator>(const uint128_t& other) const;
76 constexpr bool operator<(const uint128_t& other) const;
77 constexpr bool operator>=(const uint128_t& other) const;
78 constexpr bool operator<=(const uint128_t& other) const;
79
80 static constexpr size_t length() { return 128; }
81
82 constexpr uint128_t& operator+=(const uint128_t& other)
83 {
84 *this = *this + other;
85 return *this;
86 };
87 constexpr uint128_t& operator-=(const uint128_t& other)
88 {
89 *this = *this - other;
90 return *this;
91 };
92 constexpr uint128_t& operator*=(const uint128_t& other)
93 {
94 *this = *this * other;
95 return *this;
96 };
97 constexpr uint128_t& operator/=(const uint128_t& other)
98 {
99 *this = *this / other;
100 return *this;
101 };
102 constexpr uint128_t& operator%=(const uint128_t& other)
103 {
104 *this = *this % other;
105 return *this;
106 };
107
108 constexpr uint128_t& operator++()
109 {
110 *this += uint128_t(1);
111 return *this;
112 };
113 constexpr uint128_t& operator--()
114 {
115 *this -= uint128_t(1);
116 return *this;
117 };
118
119 constexpr uint128_t& operator&=(const uint128_t& other)
120 {
121 *this = *this & other;
122 return *this;
123 };
124 constexpr uint128_t& operator^=(const uint128_t& other)
125 {
126 *this = *this ^ other;
127 return *this;
128 };
129 constexpr uint128_t& operator|=(const uint128_t& other)
130 {
131 *this = *this | other;
132 return *this;
133 };
134
135 constexpr uint128_t& operator>>=(const uint128_t& other)
136 {
137 *this = *this >> other;
138 return *this;
139 };
140 constexpr uint128_t& operator<<=(const uint128_t& other)
141 {
142 *this = *this << other;
143 return *this;
144 };
145
146 [[nodiscard]] constexpr std::pair<uint128_t, uint128_t> mul_extended(const uint128_t& other) const;
147
148 [[nodiscard]] constexpr std::pair<uint128_t, uint128_t> divmod(const uint128_t& b) const;
149
150 private:
151 [[nodiscard]] static constexpr std::pair<uint32_t, uint32_t> mul_wide(uint32_t a, uint32_t b);
152 [[nodiscard]] static constexpr std::pair<uint32_t, uint32_t> addc(uint32_t a, uint32_t b, uint32_t carry_in);
153 [[nodiscard]] static constexpr uint32_t addc_discard_hi(uint32_t a, uint32_t b, uint32_t carry_in);
154 [[nodiscard]] static constexpr uint32_t sbb_discard_hi(uint32_t a, uint32_t b, uint32_t borrow_in);
155
156 [[nodiscard]] static constexpr std::pair<uint32_t, uint32_t> sbb(uint32_t a, uint32_t b, uint32_t borrow_in);
157 [[nodiscard]] static constexpr uint32_t mac_discard_hi(uint32_t a, uint32_t b, uint32_t c, uint32_t carry_in);
158 [[nodiscard]] static constexpr std::pair<uint32_t, uint32_t> mac(uint32_t a,
159 uint32_t b,
160 uint32_t c,
161 uint32_t carry_in);
162};
163
164inline std::ostream& operator<<(std::ostream& os, uint128_t const& a)
165{
166 std::ios_base::fmtflags f(os.flags());
167 os << std::hex << "0x" << std::setfill('0') << std::setw(8) << a.data[3] << std::setw(8) << a.data[2]
168 << std::setw(8) << a.data[1] << std::setw(8) << a.data[0];
169 os.flags(f);
170 return os;
171}
172
173template <typename B> inline void read(B& it, uint128_t& value)
174{
175 using serialize::read;
176 uint32_t a = 0;
177 uint32_t b = 0;
178 uint32_t c = 0;
179 uint32_t d = 0;
180 read(it, d);
181 read(it, c);
182 read(it, b);
183 read(it, a);
184 value = uint128_t(a, b, c, d);
185}
186
187template <typename B> inline void write(B& it, uint128_t const& value)
188{
189 using serialize::write;
190 write(it, value.data[3]);
191 write(it, value.data[2]);
192 write(it, value.data[1]);
193 write(it, value.data[0]);
194}
195
196} // namespace bb::numeric
197
198#include "./uint128_impl.hpp"
199
200// disable linter errors; we want to expose a global uint128_t type to mimic uint64_t, uint32_t etc
201// NOLINTNEXTLINE(tidymisc-unused-using-decls, google-global-names-in-headers, misc-unused-using-decls)
202using numeric::uint128_t;
203#else
204__extension__ using uint128_t = unsigned __int128;
205
206namespace std {
207// can ignore linter error for streaming operations, we need to add to std namespace to support printing this type!
208// NOLINTNEXTLINE(cert-dcl58-cpp)
209inline std::ostream& operator<<(std::ostream& os, uint128_t const& a)
210{
211 std::ios_base::fmtflags f(os.flags());
212 os << std::hex << "0x" << std::setfill('0') << std::setw(16) << static_cast<uint64_t>(a >> 64) << std::setw(16)
213 << static_cast<uint64_t>(a);
214 os.flags(f);
215 return os;
216}
217} // namespace std
218#endif
const std::vector< FF > data
FF a
FF b
uint8_t const size_t length
Definition data_store.hpp:9
bool operator==(ecdsa_signature const &lhs, ecdsa_signature const &rhs)
Definition ecdsa.hpp:45
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
constexpr T get_msb(const T in)
Definition get_msb.hpp:47
void write(B &it, uint256_t const &value)
Definition uint256.hpp:269
Univariate< Fr, domain_end, domain_start, skip_count > operator*(const Fr &ff, const Univariate< Fr, domain_end, domain_start, skip_count > &uv)
C slice(C const &container, size_t start)
Definition container.hpp:9
Univariate< Fr, domain_end, domain_start, skip_count > operator-(const Fr &ff, const Univariate< Fr, domain_end, domain_start, skip_count > &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:44