veriblock-pop-cpp
C++11 Libraries for leveraging VeriBlock Proof-Of-Proof blockchain technology.
arith_uint256.hpp
1// Copyright (c) 2019-2022 Xenios SEZC
2// https://www.veriblock.org
3// Distributed under the MIT software license, see the accompanying
4// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
5
6#ifndef ALT_INTEGRATION_VERIBLOCK_ARITH_UINT256_HPP
7#define ALT_INTEGRATION_VERIBLOCK_ARITH_UINT256_HPP
8
9#include <cstdint>
10#include <cstring>
11#include <iosfwd>
12#include <limits>
13#include <stdexcept>
14#include <string>
15#include <vector>
16
17#include "blob.hpp"
18#include "consts.hpp"
19#include "strutil.hpp"
20#include "veriblock/pop/assert.hpp"
21
22namespace altintegration {
23
25class uint_error : public std::runtime_error {
26 public:
27 explicit uint_error(const std::string& str) : std::runtime_error(str) {}
28};
29
35class ArithUint256 : public Blob<SHA256_HASH_SIZE> {
36 public:
37 ArithUint256() = default;
38
39 ArithUint256(const std::vector<uint8_t>& v) : Blob<SHA256_HASH_SIZE>(v) {}
40
41 // regular bytes should not be reversed
42 template <size_t N>
43 ArithUint256(const Blob<N>& b) {
44 VBK_ASSERT(b.size() <= SHA256_HASH_SIZE);
45 assign(b);
46 }
47
48 ArithUint256(uint64_t b) {
49 data_[0] = (uint8_t)b;
50 data_[1] = (uint8_t)(b >> 8);
51 data_[2] = (uint8_t)(b >> 16);
52 data_[3] = (uint8_t)(b >> 24);
53 data_[4] = (uint8_t)(b >> 32);
54 data_[5] = (uint8_t)(b >> 40);
55 data_[6] = (uint8_t)(b >> 48);
56 data_[7] = (uint8_t)(b >> 56);
57 for (int i = 8; i < SHA256_HASH_SIZE; i++) {
58 data_[i] = 0;
59 }
60 }
61
62 const ArithUint256 operator~() const {
63 ArithUint256 ret;
64 for (int i = 0; i < SHA256_HASH_SIZE; i++) {
65 ret.data_[i] = ~data_[i];
66 }
67 return ret;
68 }
69
70 const ArithUint256 operator-() const {
71 ArithUint256 ret;
72 for (int i = 0; i < SHA256_HASH_SIZE; i++) {
73 ret.data_[i] = ~data_[i];
74 }
75 ++ret;
76 return ret;
77 }
78
79 ArithUint256& operator=(uint64_t b) {
80 data_[0] = (uint8_t)b;
81 data_[1] = (uint8_t)(b >> 8);
82 data_[2] = (uint8_t)(b >> 16);
83 data_[3] = (uint8_t)(b >> 24);
84 data_[4] = (uint8_t)(b >> 32);
85 data_[5] = (uint8_t)(b >> 40);
86 data_[6] = (uint8_t)(b >> 48);
87 data_[7] = (uint8_t)(b >> 56);
88 for (int i = 8; i < SHA256_HASH_SIZE; i++) {
89 data_[i] = 0;
90 }
91 return *this;
92 }
93
94 ArithUint256& operator^=(const ArithUint256& b) {
95 for (int i = 0; i < SHA256_HASH_SIZE; i++) {
96 data_[i] ^= b.data_[i];
97 }
98 return *this;
99 }
100
101 ArithUint256& operator&=(const ArithUint256& b) {
102 for (int i = 0; i < SHA256_HASH_SIZE; i++) {
103 data_[i] &= b.data_[i];
104 }
105 return *this;
106 }
107
108 ArithUint256& operator|=(const ArithUint256& b) {
109 for (int i = 0; i < SHA256_HASH_SIZE; i++) {
110 data_[i] |= b.data_[i];
111 }
112 return *this;
113 }
114
115 ArithUint256& operator^=(uint64_t b) {
116 data_[0] ^= (uint8_t)b;
117 data_[1] ^= (uint8_t)(b >> 8);
118 data_[2] ^= (uint8_t)(b >> 16);
119 data_[3] ^= (uint8_t)(b >> 24);
120 data_[4] ^= (uint8_t)(b >> 32);
121 data_[5] ^= (uint8_t)(b >> 40);
122 data_[6] ^= (uint8_t)(b >> 48);
123 data_[7] ^= (uint8_t)(b >> 56);
124 return *this;
125 }
126
127 ArithUint256& operator|=(uint64_t b) {
128 data_[0] |= (uint8_t)b;
129 data_[1] |= (uint8_t)(b >> 8);
130 data_[2] |= (uint8_t)(b >> 16);
131 data_[3] |= (uint8_t)(b >> 24);
132 data_[4] |= (uint8_t)(b >> 32);
133 data_[5] |= (uint8_t)(b >> 40);
134 data_[6] |= (uint8_t)(b >> 48);
135 data_[7] |= (uint8_t)(b >> 56);
136 return *this;
137 }
138
139 ArithUint256& operator<<=(unsigned int shift);
140 ArithUint256& operator>>=(unsigned int shift);
141
142 ArithUint256& operator+=(const ArithUint256& b) {
143 uint64_t carry = 0;
144 for (int i = 0; i < SHA256_HASH_SIZE; i++) {
145 uint64_t n = carry + data_[i] + b.data_[i];
146 data_[i] = n & 0xff;
147 carry = n >> 8;
148 }
149 return *this;
150 }
151
152 ArithUint256& operator-=(const ArithUint256& b) {
153 *this += -b;
154 return *this;
155 }
156
157 ArithUint256& operator+=(uint64_t b64) {
158 ArithUint256 b;
159 b = b64;
160 *this += b;
161 return *this;
162 }
163
164 ArithUint256& operator-=(uint64_t b64) {
165 ArithUint256 b;
166 b = b64;
167 *this += -b;
168 return *this;
169 }
170
171 ArithUint256& operator*=(uint32_t b32);
172 ArithUint256& operator*=(const ArithUint256& b);
173 ArithUint256& operator/=(const ArithUint256& b);
174
175 ArithUint256& operator++() {
176 // prefix operator
177 for (int i = 0; i < SHA256_HASH_SIZE && ++data_[i] == 0; ++i) {
178 }
179 return *this;
180 }
181
182 const ArithUint256 operator++(int) {
183 // postfix operator
184 const ArithUint256 ret = *this;
185 ++(*this);
186 return ret;
187 }
188
189 ArithUint256& operator--() {
190 // prefix operator
191 for (int i = 0; i < SHA256_HASH_SIZE &&
192 --data_[i] == (std::numeric_limits<uint8_t>::max)();
193 ++i) {
194 }
195 return *this;
196 }
197
198 const ArithUint256 operator--(int) {
199 // postfix operator
200 const ArithUint256 ret = *this;
201 --(*this);
202 return ret;
203 }
204
209 unsigned int bits() const;
210
211 int compareTo(const ArithUint256& b) const;
212
213 std::string toString() const;
214
215 static ArithUint256 fromString(const std::string& num);
216
217 friend inline const ArithUint256 operator+(const ArithUint256& a,
218 const ArithUint256& b) {
219 return ArithUint256(a) += b;
220 }
221 friend inline const ArithUint256 operator-(const ArithUint256& a,
222 const ArithUint256& b) {
223 return ArithUint256(a) -= b;
224 }
225 friend inline const ArithUint256 operator*(const ArithUint256& a,
226 const ArithUint256& b) {
227 return ArithUint256(a) *= b;
228 }
229 friend inline const ArithUint256 operator/(const ArithUint256& a,
230 const ArithUint256& b) {
231 return ArithUint256(a) /= b;
232 }
233 friend inline const ArithUint256 operator|(const ArithUint256& a,
234 const ArithUint256& b) {
235 return ArithUint256(a) |= b;
236 }
237 friend inline const ArithUint256 operator&(const ArithUint256& a,
238 const ArithUint256& b) {
239 return ArithUint256(a) &= b;
240 }
241 friend inline const ArithUint256 operator^(const ArithUint256& a,
242 const ArithUint256& b) {
243 return ArithUint256(a) ^= b;
244 }
245 friend inline const ArithUint256 operator>>(const ArithUint256& a,
246 int shift) {
247 return ArithUint256(a) >>= shift;
248 }
249 friend inline const ArithUint256 operator<<(const ArithUint256& a,
250 int shift) {
251 return ArithUint256(a) <<= shift;
252 }
253 friend inline const ArithUint256 operator*(const ArithUint256& a,
254 uint32_t b) {
255 return ArithUint256(a) *= b;
256 }
257 friend inline bool operator>(const ArithUint256& a, const ArithUint256& b) {
258 return a.compareTo(b) > 0;
259 }
260 friend inline bool operator<(const ArithUint256& a, const ArithUint256& b) {
261 return a.compareTo(b) < 0;
262 }
263 friend inline bool operator>=(const ArithUint256& a, const ArithUint256& b) {
264 return a.compareTo(b) >= 0;
265 }
266 friend inline bool operator<=(const ArithUint256& a, const ArithUint256& b) {
267 return a.compareTo(b) <= 0;
268 }
269 friend inline bool operator==(const ArithUint256& a, uint64_t b) {
270 return a.compareTo(b) == 0;
271 }
272
274 static ArithUint256 fromHex(const std::string& hex);
275
276 template <size_t N>
277 static ArithUint256 fromLEBytes(const Blob<N>& b) {
278 return ArithUint256(b.reverse());
279 }
280
281 // toHex should be inverted
282 std::string toHex() const;
283
284 uint64_t getLow64() const;
285
286 static ArithUint256 fromBits(uint32_t bits,
287 bool* negative = nullptr,
288 bool* overflow = nullptr);
289
290 uint32_t toBits(bool negative = false) const;
291
292 void setHex(const std::string& value);
293};
294
297inline void PrintTo(const ArithUint256& uint, ::std::ostream* os) {
298 *os << uint.toHex();
299}
300
301} // namespace altintegration
302
303#endif // BITCOIN_ARITH_UINT256_H
256-bit unsigned big integer.
static ArithUint256 fromHex(const std::string &hex)
unsigned int bits() const
Returns the position of the highest bit set plus one, or zero if the value is zero.
All constants in alt-cpp.
Defines logging helpers.
Definition: block.hpp:14
constexpr const auto SHA256_HASH_SIZE
sha256 hash size
Definition: consts.hpp:39
void PrintTo(const ArithUint256 &uint, ::std::ostream *os)
custom gtest printer, which prints Blob of any size as hexstring @ private
Contiguous byte array of fixed size.
Definition: blob.hpp:25