Bitcoin Core 31.0.0
P2P Digital Currency
Loading...
Searching...
No Matches
uint256_tests.cpp
Go to the documentation of this file.
1// Copyright (c) 2011-present 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
6#include <streams.h>
7#include <test/util/common.h>
8#include <uint256.h>
9#include <util/strencodings.h>
10
11#include <boost/test/unit_test.hpp>
12
13#include <iomanip>
14#include <sstream>
15#include <string>
16#include <string_view>
17#include <vector>
18
19BOOST_AUTO_TEST_SUITE(uint256_tests)
20
21const unsigned char R1Array[] =
22 "\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2"
23 "\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d";
24const char R1ArrayHex[] = "7D1DE5EAF9B156D53208F033B5AA8122D2d2355d5e12292b121156cfdb4a529c";
25const uint256 R1L = uint256(std::vector<unsigned char>(R1Array,R1Array+32));
26const uint160 R1S = uint160(std::vector<unsigned char>(R1Array,R1Array+20));
27
28const unsigned char R2Array[] =
29 "\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf"
30 "\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7";
31const uint256 R2L = uint256(std::vector<unsigned char>(R2Array,R2Array+32));
32const uint160 R2S = uint160(std::vector<unsigned char>(R2Array,R2Array+20));
33
34const unsigned char ZeroArray[] =
35 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
36 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
37const uint256 ZeroL = uint256(std::vector<unsigned char>(ZeroArray,ZeroArray+32));
38const uint160 ZeroS = uint160(std::vector<unsigned char>(ZeroArray,ZeroArray+20));
39
40const unsigned char OneArray[] =
41 "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
42 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
43const uint256 OneL = uint256(std::vector<unsigned char>(OneArray,OneArray+32));
44const uint160 OneS = uint160(std::vector<unsigned char>(OneArray,OneArray+20));
45
46const unsigned char MaxArray[] =
47 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
48 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff";
49const uint256 MaxL = uint256(std::vector<unsigned char>(MaxArray,MaxArray+32));
50const uint160 MaxS = uint160(std::vector<unsigned char>(MaxArray,MaxArray+20));
51
52static std::string ArrayToString(const unsigned char A[], unsigned int width)
53{
54 std::stringstream Stream;
55 Stream << std::hex;
56 for (unsigned int i = 0; i < width; ++i)
57 {
58 Stream<<std::setw(2)<<std::setfill('0')<<(unsigned int)A[width-i-1];
59 }
60 return Stream.str();
61}
62
63BOOST_AUTO_TEST_CASE( basics ) // constructors, equality, inequality
64{
65 // constructor uint256(vector<char>):
78
79 // == and !=
84
85 // String Constructor and Copy Constructor
95
101 BOOST_CHECK_EQUAL(uint160::FromHex(std::string_view{R1ArrayHex + 24, 40}).value(), R1S);
102
106}
107
108BOOST_AUTO_TEST_CASE( comparison ) // <= >= < >
109{
110 uint256 LastL;
111 for (int i = 255; i >= 0; --i) {
113 *(TmpL.begin() + (i>>3)) |= 1<<(7-(i&7));
114 BOOST_CHECK_LT(LastL, TmpL);
115 LastL = TmpL;
116 }
117
124
126 for (int i = 159; i >= 0; --i) {
128 *(TmpS.begin() + (i>>3)) |= 1<<(7-(i&7));
130 LastS = TmpS;
131 }
138
139 // Non-arithmetic uint256s compare from the beginning of their inner arrays:
141 // Ensure first element comparisons give the same order as above:
142 BOOST_CHECK_LT(*R2L.begin(), *R1L.begin());
143 // Ensure last element comparisons give a different result (swapped params):
144 BOOST_CHECK_LT(*(R1L.end()-1), *(R2L.end()-1));
145 // Hex strings represent reverse-encoded bytes, with lexicographic ordering:
146 BOOST_CHECK_LT(uint256{"1000000000000000000000000000000000000000000000000000000000000000"},
147 uint256{"0000000000000000000000000000000000000000000000000000000000000001"});
148}
149
150BOOST_AUTO_TEST_CASE(methods) // GetHex FromHex begin() end() size() GetLow64 GetSerializeSize, Serialize, Unserialize
151{
152 BOOST_CHECK_EQUAL(R1L.GetHex(), R1L.ToString());
153 BOOST_CHECK_EQUAL(R2L.GetHex(), R2L.ToString());
154 BOOST_CHECK_EQUAL(OneL.GetHex(), OneL.ToString());
155 BOOST_CHECK_EQUAL(MaxL.GetHex(), MaxL.ToString());
158 BOOST_CHECK_EQUAL(uint256::FromHex(R2L.ToString()).value(), R2L);
160
161 TmpL = uint256::FromHex(R1L.ToString()).value();
167 BOOST_CHECK_EQUAL(R1L.size(), sizeof(R1L));
168 BOOST_CHECK_EQUAL(sizeof(R1L), 32);
173 BOOST_CHECK_EQUAL(R1L.begin() + 32, R1L.end());
174 BOOST_CHECK_EQUAL(R2L.begin() + 32, R2L.end());
175 BOOST_CHECK_EQUAL(OneL.begin() + 32, OneL.end());
176 BOOST_CHECK_EQUAL(MaxL.begin() + 32, MaxL.end());
177 BOOST_CHECK_EQUAL(TmpL.begin() + 32, TmpL.end());
180
182 ss << R1L;
183 BOOST_CHECK_EQUAL(ss.str(), std::string(R1Array,R1Array+32));
184 ss >> TmpL;
186 ss.clear();
187 ss << ZeroL;
188 BOOST_CHECK_EQUAL(ss.str(), std::string(ZeroArray,ZeroArray+32));
189 ss >> TmpL;
191 ss.clear();
192 ss << MaxL;
193 BOOST_CHECK_EQUAL(ss.str(), std::string(MaxArray,MaxArray+32));
194 ss >> TmpL;
196 ss.clear();
197
198 BOOST_CHECK_EQUAL(R1S.GetHex(), R1S.ToString());
199 BOOST_CHECK_EQUAL(R2S.GetHex(), R2S.ToString());
200 BOOST_CHECK_EQUAL(OneS.GetHex(), OneS.ToString());
201 BOOST_CHECK_EQUAL(MaxS.GetHex(), MaxS.ToString());
204 BOOST_CHECK_EQUAL(uint160::FromHex(R2S.ToString()).value(), R2S);
206
207 TmpS = uint160::FromHex(R1S.ToString()).value();
213 BOOST_CHECK_EQUAL(R1S.size(), sizeof(R1S));
214 BOOST_CHECK_EQUAL(sizeof(R1S), 20);
219 BOOST_CHECK_EQUAL(R1S.begin() + 20, R1S.end());
220 BOOST_CHECK_EQUAL(R2S.begin() + 20, R2S.end());
221 BOOST_CHECK_EQUAL(OneS.begin() + 20, OneS.end());
222 BOOST_CHECK_EQUAL(MaxS.begin() + 20, MaxS.end());
223 BOOST_CHECK_EQUAL(TmpS.begin() + 20, TmpS.end());
226
227 ss << R1S;
228 BOOST_CHECK_EQUAL(ss.str(), std::string(R1Array,R1Array+20));
229 ss >> TmpS;
231 ss.clear();
232 ss << ZeroS;
233 BOOST_CHECK_EQUAL(ss.str(), std::string(ZeroArray,ZeroArray+20));
234 ss >> TmpS;
236 ss.clear();
237 ss << MaxS;
238 BOOST_CHECK_EQUAL(ss.str(), std::string(MaxArray,MaxArray+20));
239 ss >> TmpS;
241 ss.clear();
242}
243
248template <typename T>
250{
251 constexpr unsigned int num_chars{T::size() * 2};
252 static_assert(num_chars <= 64); // this test needs to be modified to allow for more than 64 hex chars
253 const std::string valid_64char_input{"0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF"};
254 const auto valid_input{valid_64char_input.substr(0, num_chars)};
255 {
256 // check that lower and upper case hex characters are accepted
257 auto valid_result{T::FromHex(valid_input)};
258 BOOST_REQUIRE(valid_result);
259 BOOST_CHECK_EQUAL(valid_result->ToString(), ToLower(valid_input));
260 }
261 {
262 // check that only strings of size num_chars are accepted
263 BOOST_CHECK(!T::FromHex(""));
264 BOOST_CHECK(!T::FromHex("0"));
265 BOOST_CHECK(!T::FromHex(valid_input.substr(0, num_chars / 2)));
266 BOOST_CHECK(!T::FromHex(valid_input.substr(0, num_chars - 1)));
267 BOOST_CHECK(!T::FromHex(valid_input + "0"));
268 }
269 {
270 // check that non-hex characters are not accepted
271 std::string invalid_chars{R"( !"#$%&'()*+,-./:;<=>?@GHIJKLMNOPQRSTUVWXYZ[\‍]^_`ghijklmnopqrstuvwxyz{|}~)"};
272 for (auto c : invalid_chars) {
273 BOOST_CHECK(!T::FromHex(valid_input.substr(0, num_chars - 1) + c));
274 }
275 // 0x prefixes are invalid
276 std::string invalid_prefix{"0x" + valid_input};
277 BOOST_CHECK(!T::FromHex(std::string_view(invalid_prefix.data(), num_chars)));
278 BOOST_CHECK(!T::FromHex(invalid_prefix));
279 }
280 {
281 // check that string_view length is respected
282 std::string chars_68{valid_64char_input + "0123"};
283 BOOST_CHECK_EQUAL(T::FromHex(std::string_view(chars_68.data(), num_chars)).value().ToString(), ToLower(valid_input));
284 BOOST_CHECK(!T::FromHex(std::string_view(chars_68.data(), num_chars - 1))); // too short
285 BOOST_CHECK(!T::FromHex(std::string_view(chars_68.data(), num_chars + 1))); // too long
286 }
287}
288
296
298{
308 const std::string valid_hex_64{"0x0123456789abcdef0123456789abcdef0123456789ABDCEF0123456789ABCDEF"};
309 BOOST_REQUIRE_EQUAL(valid_hex_64.size(), 2 + 64); // 0x prefix and 64 hex digits
310 BOOST_CHECK_EQUAL(uint256::FromUserHex(valid_hex_64.substr(2)).value().ToString(), ToLower(valid_hex_64.substr(2)));
311 BOOST_CHECK_EQUAL(uint256::FromUserHex(valid_hex_64.substr(0)).value().ToString(), ToLower(valid_hex_64.substr(2)));
312
313 BOOST_CHECK(!uint256::FromUserHex("0x0 ")); // no spaces at end,
314 BOOST_CHECK(!uint256::FromUserHex(" 0x0")); // or beginning,
315 BOOST_CHECK(!uint256::FromUserHex("0x 0")); // or middle,
316 BOOST_CHECK(!uint256::FromUserHex(" ")); // etc.
317 BOOST_CHECK(!uint256::FromUserHex("0x0ga")); // invalid character
318 BOOST_CHECK(!uint256::FromUserHex("x0")); // broken prefix
319 BOOST_CHECK(!uint256::FromUserHex("0x0x00")); // two prefixes not allowed
320 BOOST_CHECK(!uint256::FromUserHex(valid_hex_64.substr(2) + "0")); // 1 hex digit too many
321 BOOST_CHECK(!uint256::FromUserHex(valid_hex_64 + "a")); // 1 hex digit too many
322 BOOST_CHECK(!uint256::FromUserHex(valid_hex_64 + " ")); // whitespace after max length
323 BOOST_CHECK(!uint256::FromUserHex(valid_hex_64 + "z")); // invalid character after max length
324}
325
327{
328 uint256 one = uint256{"0000000000000000000000000000000000000000000000000000000000000001"};
330}
331
332BOOST_AUTO_TEST_CASE(FromHex_vs_uint256)
333{
334 auto runtime_uint{uint256::FromHex("4A5E1E4BAAB89F3A32518A88C31BC87F618f76673e2cc77ab2127b7afdeda33b")};
335 constexpr uint256 consteval_uint{ "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"};
336 BOOST_CHECK_EQUAL(consteval_uint, runtime_uint);
337}
338
const arith_uint256 OneL
const arith_uint256 R2L
const arith_uint256 R1L
const arith_uint256 MaxL
const unsigned char ZeroArray[]
const unsigned char R1Array[]
const unsigned char OneArray[]
const char R1ArrayHex[]
const unsigned char R2Array[]
static std::string ArrayToString(const unsigned char A[], unsigned int width)
const unsigned char MaxArray[]
const arith_uint256 ZeroL
Double ended buffer combining vector and stream-like interfaces.
Definition streams.h:133
static constexpr unsigned int size()
Definition uint256.h:106
160-bit opaque blob.
Definition uint256.h:183
static std::optional< uint160 > FromHex(std::string_view str)
Definition uint256.h:185
256-bit opaque blob.
Definition uint256.h:195
static std::optional< uint256 > FromUserHex(std::string_view str)
Definition uint256.h:198
static const uint256 ONE
Definition uint256.h:204
static const uint256 ZERO
Definition uint256.h:203
static std::optional< uint256 > FromHex(std::string_view str)
Definition uint256.h:197
BOOST_AUTO_TEST_SUITE_END()
Definition common.h:29
#define BOOST_CHECK_EQUAL(v1, v2)
Definition object.cpp:17
#define BOOST_CHECK(expr)
Definition object.cpp:16
uint64_t GetSerializeSize(const T &t)
Definition serialize.h:1095
static void from_hex(unsigned char *data, int len, const char *hex)
Definition test.c:41
BOOST_CHECK_NE(OneL.ToString(), ArrayToString(ZeroArray, 32))
BOOST_CHECK_LT(ZeroL, R1L)
uint256 TmpL(R1L)
const uint160 OneS
uint160 TmpS(R1S)
const uint160 MaxS
const uint160 ZeroS
const uint160 R1S
const uint160 R2S
DataStream ss
BOOST_AUTO_TEST_CASE(from_hex)
BOOST_CHECK_EQUAL_COLLECTIONS(R1L.begin(), R1L.end(), R1Array, R1Array+uint256::size())
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.