Bitcoin Core  28.1.0
P2P Digital Currency
uint256_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2021 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <arith_uint256.h>
6 #include <streams.h>
8 #include <uint256.h>
9 #include <util/strencodings.h>
11 
12 #include <boost/test/unit_test.hpp>
13 
14 #include <iomanip>
15 #include <sstream>
16 #include <string>
17 #include <string_view>
18 #include <vector>
19 
20 BOOST_AUTO_TEST_SUITE(uint256_tests)
21 
22 const unsigned char R1Array[] =
23  "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
24  "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
25 const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
26 const uint256 R1L = uint256(std::vector<unsigned char>(R1Array,R1Array+32));
27 const uint160 R1S = uint160(std::vector<unsigned char>(R1Array,R1Array+20));
28 
29 const unsigned char R2Array[] =
30  "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
31  "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
32 const uint256 R2L = uint256(std::vector<unsigned char>(R2Array,R2Array+32));
33 const uint160 R2S = uint160(std::vector<unsigned char>(R2Array,R2Array+20));
34 
35 const unsigned char ZeroArray[] =
36  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
37  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
38 const uint256 ZeroL = uint256(std::vector<unsigned char>(ZeroArray,ZeroArray+32));
39 const uint160 ZeroS = uint160(std::vector<unsigned char>(ZeroArray,ZeroArray+20));
40 
41 const unsigned char OneArray[] =
42  "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
43  "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
44 const uint256 OneL = uint256(std::vector<unsigned char>(OneArray,OneArray+32));
45 const uint160 OneS = uint160(std::vector<unsigned char>(OneArray,OneArray+20));
46 
47 const unsigned char MaxArray[] =
48  "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
49  "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
50 const uint256 MaxL = uint256(std::vector<unsigned char>(MaxArray,MaxArray+32));
51 const uint160 MaxS = uint160(std::vector<unsigned char>(MaxArray,MaxArray+20));
52 
53 static std::string ArrayToString(const unsigned char A[], unsigned int width)
54 {
55  std::stringstream Stream;
56  Stream << std::hex;
57  for (unsigned int i = 0; i < width; ++i)
58  {
59  Stream<<std::setw(2)<<std::setfill('0')<<(unsigned int)A[width-i-1];
60  }
61  return Stream.str();
62 }
63 
64 // Takes hex string in reverse byte order.
65 inline uint160 uint160S(std::string_view str)
66 {
67  uint160 rv;
68  rv.SetHexDeprecated(str);
69  return rv;
70 }
71 
72 BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
73 {
74  // constructor uint256(vector<char>):
85  BOOST_CHECK_NE(OneL.ToString(), ArrayToString(ZeroArray,32));
86  BOOST_CHECK_NE(OneS.ToString(), ArrayToString(ZeroArray,20));
87 
88  // == and !=
89  BOOST_CHECK_NE(R1L, R2L); BOOST_CHECK_NE(R1S, R2S);
90  BOOST_CHECK_NE(ZeroL, OneL); BOOST_CHECK_NE(ZeroS, OneS);
91  BOOST_CHECK_NE(OneL, ZeroL); BOOST_CHECK_NE(OneS, ZeroS);
92  BOOST_CHECK_NE(MaxL, ZeroL); BOOST_CHECK_NE(MaxS, ZeroS);
93 
94  // String Constructor and Copy Constructor
101  BOOST_CHECK_EQUAL(uint256S(" 0x"+R1L.ToString()+" "), R1L);
102  BOOST_CHECK_EQUAL(uint256S(" 0x"+R1L.ToString()+"-trash;%^& "), R1L);
103  BOOST_CHECK_EQUAL(uint256S("\t \n \n \f\n\r\t\v\t 0x"+R1L.ToString()+" \t \n \n \f\n\r\t\v\t "), R1L);
110 
117  BOOST_CHECK_EQUAL(uint160S(" 0x"+R1S.ToString()+" "), R1S);
118  BOOST_CHECK_EQUAL(uint160S(" 0x"+R1S.ToString()+"-trash;%^& "), R1S);
119  BOOST_CHECK_EQUAL(uint160S(" \t \n \n \f\n\r\t\v\t 0x"+R1S.ToString()+" \t \n \n \f\n\r\t\v\t"), R1S);
122 
126 }
127 
128 BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
129 {
130  uint256 LastL;
131  for (int i = 255; i >= 0; --i) {
132  uint256 TmpL;
133  *(TmpL.begin() + (i>>3)) |= 1<<(7-(i&7));
134  BOOST_CHECK_LT(LastL, TmpL);
135  LastL = TmpL;
136  }
137 
138  BOOST_CHECK_LT(ZeroL, R1L);
139  BOOST_CHECK_LT(R2L, R1L);
140  BOOST_CHECK_LT(ZeroL, OneL);
141  BOOST_CHECK_LT(OneL, MaxL);
142  BOOST_CHECK_LT(R1L, MaxL);
143  BOOST_CHECK_LT(R2L, MaxL);
144 
145  uint160 LastS;
146  for (int i = 159; i >= 0; --i) {
147  uint160 TmpS;
148  *(TmpS.begin() + (i>>3)) |= 1<<(7-(i&7));
149  BOOST_CHECK_LT(LastS, TmpS);
150  LastS = TmpS;
151  }
152  BOOST_CHECK_LT(ZeroS, R1S);
153  BOOST_CHECK_LT(R2S, R1S);
154  BOOST_CHECK_LT(ZeroS, OneS);
155  BOOST_CHECK_LT(OneS, MaxS);
156  BOOST_CHECK_LT(R1S, MaxS);
157  BOOST_CHECK_LT(R2S, MaxS);
158 
159  // Non-arithmetic uint256s compare from the beginning of their inner arrays:
160  BOOST_CHECK_LT(R2L, R1L);
161  // Ensure first element comparisons give the same order as above:
162  BOOST_CHECK_LT(*R2L.begin(), *R1L.begin());
163  // Ensure last element comparisons give a different result (swapped params):
164  BOOST_CHECK_LT(*(R1L.end()-1), *(R2L.end()-1));
165  // Hex strings represent reverse-encoded bytes, with lexicographic ordering:
166  BOOST_CHECK_LT(uint256{"1000000000000000000000000000000000000000000000000000000000000000"},
167  uint256{"0000000000000000000000000000000000000000000000000000000000000001"});
168 }
169 
170 BOOST_AUTO_TEST_CASE(methods) // GetHex SetHexDeprecated FromHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize
171 {
176  uint256 TmpL(R1L);
177  BOOST_CHECK_EQUAL(TmpL, R1L);
178  // Verify previous values don't persist when setting to truncated string.
179  TmpL.SetHexDeprecated("21");
180  BOOST_CHECK_EQUAL(TmpL.ToString(), "0000000000000000000000000000000000000000000000000000000000000021");
183 
184  TmpL = uint256::FromHex(R1L.ToString()).value();
185  BOOST_CHECK_EQUAL_COLLECTIONS(R1L.begin(), R1L.end(), R1Array, R1Array + uint256::size());
186  BOOST_CHECK_EQUAL_COLLECTIONS(TmpL.begin(), TmpL.end(), R1Array, R1Array + uint256::size());
187  BOOST_CHECK_EQUAL_COLLECTIONS(R2L.begin(), R2L.end(), R2Array, R2Array + uint256::size());
188  BOOST_CHECK_EQUAL_COLLECTIONS(ZeroL.begin(), ZeroL.end(), ZeroArray, ZeroArray + uint256::size());
189  BOOST_CHECK_EQUAL_COLLECTIONS(OneL.begin(), OneL.end(), OneArray, OneArray + uint256::size());
190  BOOST_CHECK_EQUAL(R1L.size(), sizeof(R1L));
191  BOOST_CHECK_EQUAL(sizeof(R1L), 32);
192  BOOST_CHECK_EQUAL(R1L.size(), 32);
193  BOOST_CHECK_EQUAL(R2L.size(), 32);
195  BOOST_CHECK_EQUAL(MaxL.size(), 32);
196  BOOST_CHECK_EQUAL(R1L.begin() + 32, R1L.end());
197  BOOST_CHECK_EQUAL(R2L.begin() + 32, R2L.end());
198  BOOST_CHECK_EQUAL(OneL.begin() + 32, OneL.end());
199  BOOST_CHECK_EQUAL(MaxL.begin() + 32, MaxL.end());
200  BOOST_CHECK_EQUAL(TmpL.begin() + 32, TmpL.end());
203 
204  DataStream ss{};
205  ss << R1L;
206  BOOST_CHECK_EQUAL(ss.str(), std::string(R1Array,R1Array+32));
207  ss >> TmpL;
208  BOOST_CHECK_EQUAL(R1L, TmpL);
209  ss.clear();
210  ss << ZeroL;
211  BOOST_CHECK_EQUAL(ss.str(), std::string(ZeroArray,ZeroArray+32));
212  ss >> TmpL;
213  BOOST_CHECK_EQUAL(ZeroL, TmpL);
214  ss.clear();
215  ss << MaxL;
216  BOOST_CHECK_EQUAL(ss.str(), std::string(MaxArray,MaxArray+32));
217  ss >> TmpL;
218  BOOST_CHECK_EQUAL(MaxL, TmpL);
219  ss.clear();
220 
225  uint160 TmpS(R1S);
226  BOOST_CHECK_EQUAL(TmpS, R1S);
229 
230  TmpS = uint160::FromHex(R1S.ToString()).value();
231  BOOST_CHECK_EQUAL_COLLECTIONS(R1S.begin(), R1S.end(), R1Array, R1Array + uint160::size());
232  BOOST_CHECK_EQUAL_COLLECTIONS(TmpS.begin(), TmpS.end(), R1Array, R1Array + uint160::size());
233  BOOST_CHECK_EQUAL_COLLECTIONS(R2S.begin(), R2S.end(), R2Array, R2Array + uint160::size());
234  BOOST_CHECK_EQUAL_COLLECTIONS(ZeroS.begin(), ZeroS.end(), ZeroArray, ZeroArray + uint160::size());
235  BOOST_CHECK_EQUAL_COLLECTIONS(OneS.begin(), OneS.end(), OneArray, OneArray + uint160::size());
236  BOOST_CHECK_EQUAL(R1S.size(), sizeof(R1S));
237  BOOST_CHECK_EQUAL(sizeof(R1S), 20);
238  BOOST_CHECK_EQUAL(R1S.size(), 20);
239  BOOST_CHECK_EQUAL(R2S.size(), 20);
241  BOOST_CHECK_EQUAL(MaxS.size(), 20);
242  BOOST_CHECK_EQUAL(R1S.begin() + 20, R1S.end());
243  BOOST_CHECK_EQUAL(R2S.begin() + 20, R2S.end());
244  BOOST_CHECK_EQUAL(OneS.begin() + 20, OneS.end());
245  BOOST_CHECK_EQUAL(MaxS.begin() + 20, MaxS.end());
246  BOOST_CHECK_EQUAL(TmpS.begin() + 20, TmpS.end());
249 
250  ss << R1S;
251  BOOST_CHECK_EQUAL(ss.str(), std::string(R1Array,R1Array+20));
252  ss >> TmpS;
253  BOOST_CHECK_EQUAL(R1S, TmpS);
254  ss.clear();
255  ss << ZeroS;
256  BOOST_CHECK_EQUAL(ss.str(), std::string(ZeroArray,ZeroArray+20));
257  ss >> TmpS;
258  BOOST_CHECK_EQUAL(ZeroS, TmpS);
259  ss.clear();
260  ss << MaxS;
261  BOOST_CHECK_EQUAL(ss.str(), std::string(MaxArray,MaxArray+20));
262  ss >> TmpS;
263  BOOST_CHECK_EQUAL(MaxS, TmpS);
264  ss.clear();
265 }
266 
267 BOOST_AUTO_TEST_CASE( conversion )
268 {
281 }
282 
283 BOOST_AUTO_TEST_CASE( operator_with_self )
284 {
285 
286 /* Clang 16 and earlier detects v -= v and v /= v as self-assignments
287  to 0 and 1 respectively.
288  See: https://github.com/llvm/llvm-project/issues/42469
289  and the fix in commit c5302325b2a62d77cf13dd16cd5c19141862fed0 .
290 
291  This makes some sense for arithmetic classes, but could be considered a bug
292  elsewhere. Disable the warning here so that the code can be tested, but the
293  warning should remain on as there will likely always be a better way to
294  express this.
295 */
296 
297 #if defined(__clang__)
298 # pragma clang diagnostic push
299 # pragma clang diagnostic ignored "-Wself-assign-overloaded"
300 #endif
302  v *= v;
304  v /= v;
306  v += v;
308  v -= v;
310 #if defined(__clang__)
311 # pragma clang diagnostic pop
312 #endif
313 }
314 
316 {
317  {
318  std::string s_12{"0000000000000000000000000000000000000000000000000000000000000012"};
319  BOOST_CHECK_EQUAL(uint256S("12\0").GetHex(), s_12);
320  BOOST_CHECK_EQUAL(uint256S(std::string_view{"12\0", 3}).GetHex(), s_12);
321  BOOST_CHECK_EQUAL(uint256S("0x12").GetHex(), s_12);
322  BOOST_CHECK_EQUAL(uint256S(" 0x12").GetHex(), s_12);
323  BOOST_CHECK_EQUAL(uint256S(" 12").GetHex(), s_12);
324  }
325  {
326  std::string s_1{uint256::ONE.GetHex()};
327  BOOST_CHECK_EQUAL(uint256S("1\0").GetHex(), s_1);
328  BOOST_CHECK_EQUAL(uint256S(std::string_view{"1\0", 2}).GetHex(), s_1);
329  BOOST_CHECK_EQUAL(uint256S("0x1").GetHex(), s_1);
330  BOOST_CHECK_EQUAL(uint256S(" 0x1").GetHex(), s_1);
331  BOOST_CHECK_EQUAL(uint256S(" 1").GetHex(), s_1);
332  }
333  {
334  std::string s_0{uint256::ZERO.GetHex()};
335  BOOST_CHECK_EQUAL(uint256S("\0").GetHex(), s_0);
336  BOOST_CHECK_EQUAL(uint256S(std::string_view{"\0", 1}).GetHex(), s_0);
337  BOOST_CHECK_EQUAL(uint256S("0x").GetHex(), s_0);
338  BOOST_CHECK_EQUAL(uint256S(" 0x").GetHex(), s_0);
339  BOOST_CHECK_EQUAL(uint256S(" ").GetHex(), s_0);
340  }
341 }
342 
347 template <typename T>
349 {
350  constexpr unsigned int num_chars{T::size() * 2};
351  static_assert(num_chars <= 64); // this test needs to be modified to allow for more than 64 hex chars
352  const std::string valid_64char_input{"0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF"};
353  const auto valid_input{valid_64char_input.substr(0, num_chars)};
354  {
355  // check that lower and upper case hex characters are accepted
356  auto valid_result{T::FromHex(valid_input)};
357  BOOST_REQUIRE(valid_result);
358  BOOST_CHECK_EQUAL(valid_result->ToString(), ToLower(valid_input));
359  }
360  {
361  // check that only strings of size num_chars are accepted
362  BOOST_CHECK(!T::FromHex(""));
363  BOOST_CHECK(!T::FromHex("0"));
364  BOOST_CHECK(!T::FromHex(valid_input.substr(0, num_chars / 2)));
365  BOOST_CHECK(!T::FromHex(valid_input.substr(0, num_chars - 1)));
366  BOOST_CHECK(!T::FromHex(valid_input + "0"));
367  }
368  {
369  // check that non-hex characters are not accepted
370  std::string invalid_chars{R"( !"#$%&'()*+,-./:;<=>?@GHIJKLMNOPQRSTUVWXYZ[\]^_`ghijklmnopqrstuvwxyz{|}~)"};
371  for (auto c : invalid_chars) {
372  BOOST_CHECK(!T::FromHex(valid_input.substr(0, num_chars - 1) + c));
373  }
374  // 0x prefixes are invalid
375  std::string invalid_prefix{"0x" + valid_input};
376  BOOST_CHECK(!T::FromHex(std::string_view(invalid_prefix.data(), num_chars)));
377  BOOST_CHECK(!T::FromHex(invalid_prefix));
378  }
379  {
380  // check that string_view length is respected
381  std::string chars_68{valid_64char_input + "0123"};
382  BOOST_CHECK_EQUAL(T::FromHex(std::string_view(chars_68.data(), num_chars)).value().ToString(), ToLower(valid_input));
383  BOOST_CHECK(!T::FromHex(std::string_view(chars_68.data(), num_chars - 1))); // too short
384  BOOST_CHECK(!T::FromHex(std::string_view(chars_68.data(), num_chars + 1))); // too long
385  }
386 }
387 
389 {
390  TestFromHex<uint160>();
391  TestFromHex<uint256>();
392  TestFromHex<Txid>();
393  TestFromHex<Wtxid>();
394 }
395 
396 BOOST_AUTO_TEST_CASE( check_ONE )
397 {
398  uint256 one = uint256{"0000000000000000000000000000000000000000000000000000000000000001"};
400 }
401 
402 BOOST_AUTO_TEST_CASE(FromHex_vs_uint256)
403 {
404  auto runtime_uint{uint256::FromHex("4A5E1E4BAAB89F3A32518A88C31BC87F618f76673e2cc77ab2127b7afdeda33b").value()};
405  constexpr uint256 consteval_uint{ "4a5e1e4baab89f3a32518a88c31bc87f618F76673E2CC77AB2127B7AFDEDA33B"};
406  BOOST_CHECK_EQUAL(consteval_uint, runtime_uint);
407 }
408 
static const uint256 ONE
Definition: uint256.h:186
const uint256 R1L
static constexpr unsigned int size()
Definition: uint256.h:108
size_t GetSerializeSize(const T &t)
Definition: serialize.h:1101
const uint160 OneS
static void from_hex(unsigned char *data, int len, const char *hex)
Definition: test.c:41
const uint256 MaxL
void TestFromHex()
Implemented as a templated function so it can be reused by other classes that have a FromHex() method...
const unsigned char R1Array[]
const unsigned char ZeroArray[]
arith_uint256 UintToArith256(const uint256 &a)
constexpr unsigned char * begin()
Definition: uint256.h:102
const unsigned char MaxArray[]
void SetHexDeprecated(std::string_view str)
Unlike FromHex this accepts any invalid input, thus it is fragile and deprecated! ...
Definition: uint256.cpp:21
const uint160 R1S
static std::string ArrayToString(const unsigned char A[], unsigned int width)
std::optional< uintN_t > FromHex(std::string_view str)
Writes the hex string (in reverse byte order) into a new uintN_t object and only returns a value iff ...
Definition: uint256.h:153
BOOST_AUTO_TEST_CASE(basics)
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:146
BOOST_AUTO_TEST_SUITE_END()
static std::optional< uint256 > FromHex(std::string_view str)
Definition: uint256.h:180
const char R1ArrayHex[]
static const uint256 ZERO
Definition: uint256.h:185
const uint160 R2S
const unsigned char R2Array[]
std::string ToString() const
Definition: uint256.cpp:47
256-bit unsigned big integer.
const unsigned char OneArray[]
std::string ToLower(std::string_view str)
Returns the lowercase equivalent of the given string.
256-bit opaque blob.
Definition: uint256.h:178
uint256 ArithToUint256(const arith_uint256 &a)
const uint160 ZeroS
const uint256 OneL
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
static std::optional< uint160 > FromHex(std::string_view str)
Definition: uint256.h:168
const uint256 R2L
constexpr unsigned char * end()
Definition: uint256.h:103
std::string GetHex() const
Definition: uint256.cpp:11
160-bit opaque blob.
Definition: uint256.h:166
const uint160 MaxS
BOOST_AUTO_TEST_SUITE(cuckoocache_tests)
Test Suite for CuckooCache.
uint256 uint256S(std::string_view str)
Definition: uint256.h:192
std::string GetHex() const
Hex encoding of the number (with the most significant digits first).
const uint256 ZeroL
#define BOOST_CHECK(expr)
Definition: object.cpp:17
uint160 uint160S(std::string_view str)