Bitcoin Core 28.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
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
20BOOST_AUTO_TEST_SUITE(uint256_tests)
21
22const 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";
25const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
26const uint256 R1L = uint256(std::vector<unsigned char>(R1Array,R1Array+32));
27const uint160 R1S = uint160(std::vector<unsigned char>(R1Array,R1Array+20));
28
29const 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";
32const uint256 R2L = uint256(std::vector<unsigned char>(R2Array,R2Array+32));
33const uint160 R2S = uint160(std::vector<unsigned char>(R2Array,R2Array+20));
34
35const 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";
38const uint256 ZeroL = uint256(std::vector<unsigned char>(ZeroArray,ZeroArray+32));
39const uint160 ZeroS = uint160(std::vector<unsigned char>(ZeroArray,ZeroArray+20));
40
41const 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";
44const uint256 OneL = uint256(std::vector<unsigned char>(OneArray,OneArray+32));
45const uint160 OneS = uint160(std::vector<unsigned char>(OneArray,OneArray+20));
46
47const 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";
50const uint256 MaxL = uint256(std::vector<unsigned char>(MaxArray,MaxArray+32));
51const uint160 MaxS = uint160(std::vector<unsigned char>(MaxArray,MaxArray+20));
52
53static 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.
65inline uint160 uint160S(std::string_view str)
66{
67 uint160 rv;
68 rv.SetHexDeprecated(str);
69 return rv;
70}
71
72BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
73{
74 // constructor uint256(vector<char>):
87
88 // == and !=
93
94 // String Constructor and Copy Constructor
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
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
128BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
129{
130 uint256 LastL;
131 for (int i = 255; i >= 0; --i) {
133 *(TmpL.begin() + (i>>3)) |= 1<<(7-(i&7));
134 BOOST_CHECK_LT(LastL, TmpL);
135 LastL = TmpL;
136 }
137
144
146 for (int i = 159; i >= 0; --i) {
148 *(TmpS.begin() + (i>>3)) |= 1<<(7-(i&7));
150 LastS = TmpS;
151 }
158
159 // Non-arithmetic uint256s compare from the beginning of their inner arrays:
161 // Ensure first element comparisons give the same order as above:
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
170BOOST_AUTO_TEST_CASE(methods) // GetHex SetHexDeprecated FromHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize
171{
178 // Verify previous values don't persist when setting to truncated string.
180 BOOST_CHECK_EQUAL(TmpL.ToString(), "0000000000000000000000000000000000000000000000000000000000000021");
183
191 BOOST_CHECK_EQUAL(sizeof(R1L), 32);
203
205 ss << R1L;
206 BOOST_CHECK_EQUAL(ss.str(), std::string(R1Array,R1Array+32));
207 ss >> TmpL;
210 ss << ZeroL;
211 BOOST_CHECK_EQUAL(ss.str(), std::string(ZeroArray,ZeroArray+32));
212 ss >> TmpL;
214 ss.clear();
215 ss << MaxL;
216 BOOST_CHECK_EQUAL(ss.str(), std::string(MaxArray,MaxArray+32));
217 ss >> TmpL;
219 ss.clear();
220
229
237 BOOST_CHECK_EQUAL(sizeof(R1S), 20);
249
250 ss << R1S;
251 BOOST_CHECK_EQUAL(ss.str(), std::string(R1Array,R1Array+20));
252 ss >> TmpS;
254 ss.clear();
255 ss << ZeroS;
256 BOOST_CHECK_EQUAL(ss.str(), std::string(ZeroArray,ZeroArray+20));
257 ss >> TmpS;
259 ss.clear();
260 ss << MaxS;
261 BOOST_CHECK_EQUAL(ss.str(), std::string(MaxArray,MaxArray+20));
262 ss >> TmpS;
264 ss.clear();
265}
266
282
283BOOST_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
347template <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
395
397{
398 uint256 one = uint256{"0000000000000000000000000000000000000000000000000000000000000001"};
400}
401
402BOOST_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
arith_uint256 UintToArith256(const uint256 &a)
uint256 ArithToUint256(const arith_uint256 &a)
Double ended buffer combining vector and stream-like interfaces.
Definition streams.h:147
std::string str() const
Definition streams.h:168
void clear()
Definition streams.h:187
256-bit unsigned big integer.
std::string GetHex() const
Definition uint256.cpp:11
constexpr unsigned char * end()
Definition uint256.h:103
static constexpr unsigned int size()
Definition uint256.h:108
constexpr unsigned char * begin()
Definition uint256.h:102
std::string ToString() const
Definition uint256.cpp:47
void SetHexDeprecated(std::string_view str)
Unlike FromHex this accepts any invalid input, thus it is fragile and deprecated!
Definition uint256.cpp:21
160-bit opaque blob.
Definition uint256.h:166
static std::optional< uint160 > FromHex(std::string_view str)
Definition uint256.h:168
256-bit opaque blob.
Definition uint256.h:178
static const uint256 ONE
Definition uint256.h:186
static const uint256 ZERO
Definition uint256.h:185
static std::optional< uint256 > FromHex(std::string_view str)
Definition uint256.h:180
BOOST_AUTO_TEST_SUITE(cuckoocache_tests)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
#define BOOST_CHECK_EQUAL(v1, v2)
Definition object.cpp:18
#define BOOST_CHECK(expr)
Definition object.cpp:17
size_t GetSerializeSize(const T &t)
Definition serialize.h:1101
static void from_hex(unsigned char *data, int len, const char *hex)
Definition test.c:41
uint256 uint256S(std::string_view str)
Definition uint256.h:192
BOOST_CHECK_NE(OneL.ToString(), ArrayToString(ZeroArray, 32))
BOOST_AUTO_TEST_CASE(conversion)
BOOST_CHECK_LT(ZeroL, R1L)
const unsigned char ZeroArray[]
const unsigned char R1Array[]
uint160 uint160S(std::string_view str)
uint256 TmpL(R1L)
const unsigned char OneArray[]
const uint160 OneS
uint160 TmpS(R1S)
const uint160 MaxS
const char R1ArrayHex[]
const uint160 ZeroS
const uint256 MaxL
const uint160 R1S
const unsigned char R2Array[]
const uint256 R2L
const uint160 R2S
DataStream ss
const uint256 R1L
static std::string ArrayToString(const unsigned char A[], unsigned int width)
const unsigned char MaxArray[]
BOOST_CHECK_EQUAL_COLLECTIONS(R1L.begin(), R1L.end(), R1Array, R1Array+uint256::size())
const uint256 ZeroL
const uint256 OneL
void TestFromHex()
Implemented as a templated function so it can be reused by other classes that have a FromHex() method...
uint160 LastS
std::string ToLower(std::string_view str)
Returns the lowercase equivalent of the given string.