/root/bitcoin/src/uint256.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2009-2010 Satoshi Nakamoto |
2 | | // Copyright (c) 2009-present The Bitcoin Core developers |
3 | | // Distributed under the MIT software license, see the accompanying |
4 | | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
5 | | |
6 | | #ifndef BITCOIN_UINT256_H |
7 | | #define BITCOIN_UINT256_H |
8 | | |
9 | | #include <crypto/common.h> |
10 | | #include <span.h> |
11 | | #include <util/strencodings.h> |
12 | | #include <util/string.h> |
13 | | |
14 | | #include <algorithm> |
15 | | #include <array> |
16 | | #include <cassert> |
17 | | #include <cstdint> |
18 | | #include <cstring> |
19 | | #include <optional> |
20 | | #include <string> |
21 | | #include <string_view> |
22 | | |
23 | | /** Template base class for fixed-sized opaque blobs. */ |
24 | | template<unsigned int BITS> |
25 | | class base_blob |
26 | | { |
27 | | protected: |
28 | | static constexpr int WIDTH = BITS / 8; |
29 | | static_assert(BITS % 8 == 0, "base_blob currently only supports whole bytes."); |
30 | | std::array<uint8_t, WIDTH> m_data; |
31 | | static_assert(WIDTH == sizeof(m_data), "Sanity check"); |
32 | | |
33 | | public: |
34 | | /* construct 0 value by default */ |
35 | 1.18G | constexpr base_blob() : m_data() {} _ZN9base_blobILj256EEC2Ev Line | Count | Source | 35 | 1.15G | constexpr base_blob() : m_data() {} |
_ZN9base_blobILj160EEC2Ev Line | Count | Source | 35 | 25.2M | constexpr base_blob() : m_data() {} |
|
36 | | |
37 | | /* constructor for constants between 1 and 255 */ |
38 | 8.08k | constexpr explicit base_blob(uint8_t v) : m_data{v} {} |
39 | | |
40 | | constexpr explicit base_blob(std::span<const unsigned char> vch) |
41 | 11.5M | { |
42 | 11.5M | assert(vch.size() == WIDTH); |
43 | 11.5M | std::copy(vch.begin(), vch.end(), m_data.begin()); |
44 | 11.5M | } _ZN9base_blobILj256EEC2ESt4spanIKhLm18446744073709551615EE Line | Count | Source | 41 | 2.79M | { | 42 | 2.79M | assert(vch.size() == WIDTH); | 43 | 2.79M | std::copy(vch.begin(), vch.end(), m_data.begin()); | 44 | 2.79M | } |
_ZN9base_blobILj160EEC2ESt4spanIKhLm18446744073709551615EE Line | Count | Source | 41 | 8.78M | { | 42 | 8.78M | assert(vch.size() == WIDTH); | 43 | 8.78M | std::copy(vch.begin(), vch.end(), m_data.begin()); | 44 | 8.78M | } |
|
45 | | |
46 | | consteval explicit base_blob(std::string_view hex_str); |
47 | | |
48 | | constexpr bool IsNull() const |
49 | 22.5M | { |
50 | 212M | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { |
51 | 212M | return val == 0; |
52 | 212M | }); _ZZNK9base_blobILj256EE6IsNullEvENKUlhE_clEh Line | Count | Source | 50 | 212M | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 51 | 212M | return val == 0; | 52 | 212M | }); |
_ZZNK9base_blobILj160EE6IsNullEvENKUlhE_clEh Line | Count | Source | 50 | 167k | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 51 | 167k | return val == 0; | 52 | 167k | }); |
|
53 | 22.5M | } _ZNK9base_blobILj256EE6IsNullEv Line | Count | Source | 49 | 22.5M | { | 50 | 22.5M | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 51 | 22.5M | return val == 0; | 52 | 22.5M | }); | 53 | 22.5M | } |
_ZNK9base_blobILj160EE6IsNullEv Line | Count | Source | 49 | 10.5k | { | 50 | 10.5k | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 51 | 10.5k | return val == 0; | 52 | 10.5k | }); | 53 | 10.5k | } |
|
54 | | |
55 | | constexpr void SetNull() |
56 | 9.22M | { |
57 | 9.22M | std::fill(m_data.begin(), m_data.end(), 0); |
58 | 9.22M | } _ZN9base_blobILj256EE7SetNullEv Line | Count | Source | 56 | 9.21M | { | 57 | 9.21M | std::fill(m_data.begin(), m_data.end(), 0); | 58 | 9.21M | } |
_ZN9base_blobILj160EE7SetNullEv Line | Count | Source | 56 | 15.1k | { | 57 | 15.1k | std::fill(m_data.begin(), m_data.end(), 0); | 58 | 15.1k | } |
|
59 | | |
60 | | /** Lexicographic ordering |
61 | | * @note Does NOT match the ordering on the corresponding \ref |
62 | | * base_uint::CompareTo, which starts comparing from the end. |
63 | | */ |
64 | 4.11G | constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); } _ZNK9base_blobILj256EE7CompareERKS0_ Line | Count | Source | 64 | 4.06G | constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); } |
_ZNK9base_blobILj160EE7CompareERKS0_ Line | Count | Source | 64 | 48.6M | constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); } |
|
65 | | |
66 | 75.5M | friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } _ZeqRK9base_blobILj256EES2_ Line | Count | Source | 66 | 75.4M | friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } |
_ZeqRK9base_blobILj160EES2_ Line | Count | Source | 66 | 54.6k | friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } |
|
67 | 1.74M | friend constexpr bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; } _ZneRK9base_blobILj256EES2_ Line | Count | Source | 67 | 1.74M | friend constexpr bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; } |
Unexecuted instantiation: _ZneRK9base_blobILj160EES2_ |
68 | 633M | friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } _ZltRK9base_blobILj256EES2_ Line | Count | Source | 68 | 584M | friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } |
_ZltRK9base_blobILj160EES2_ Line | Count | Source | 68 | 48.6M | friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } |
|
69 | | |
70 | | /** @name Hex representation |
71 | | * |
72 | | * The hex representation used by GetHex(), ToString(), FromHex() and |
73 | | * SetHexDeprecated() is unusual, since it shows bytes of the base_blob in |
74 | | * reverse order. For example, a 4-byte blob {0x12, 0x34, 0x56, 0x78} is |
75 | | * represented as "78563412" instead of the more typical "12345678" |
76 | | * representation that would be shown in a hex editor or used by typical |
77 | | * byte-array / hex conversion functions like python's bytes.hex() and |
78 | | * bytes.fromhex(). |
79 | | * |
80 | | * The nice thing about the reverse-byte representation, even though it is |
81 | | * unusual, is that if a blob contains an arithmetic number in little endian |
82 | | * format (with least significant bytes first, and most significant bytes |
83 | | * last), the GetHex() output will match the way the number would normally |
84 | | * be written in base-16 (with most significant digits first and least |
85 | | * significant digits last). |
86 | | * |
87 | | * This means, for example, that ArithToUint256(num).GetHex() can be used to |
88 | | * display an arith_uint256 num value as a number, because |
89 | | * ArithToUint256() converts the number to a blob in little-endian format, |
90 | | * so the arith_uint256 class doesn't need to have its own number parsing |
91 | | * and formatting functions. |
92 | | * |
93 | | * @{*/ |
94 | | std::string GetHex() const; |
95 | | /** Unlike FromHex this accepts any invalid input, thus it is fragile and deprecated! |
96 | | * |
97 | | * - Hex numbers that don't specify enough bytes to fill the internal array |
98 | | * will be treated as setting the beginning of it, which corresponds to |
99 | | * the least significant bytes when converted to base_uint. |
100 | | * |
101 | | * - Hex numbers specifying too many bytes will have the numerically most |
102 | | * significant bytes (the beginning of the string) narrowed away. |
103 | | * |
104 | | * - An odd count of hex digits will result in the high bits of the leftmost |
105 | | * byte being zero. |
106 | | * "0x123" => {0x23, 0x1, 0x0, ..., 0x0} |
107 | | */ |
108 | | void SetHexDeprecated(std::string_view str); |
109 | | std::string ToString() const; |
110 | | /**@}*/ |
111 | | |
112 | 35.5M | constexpr const unsigned char* data() const { return m_data.data(); } _ZNK9base_blobILj160EE4dataEv Line | Count | Source | 112 | 36.3k | constexpr const unsigned char* data() const { return m_data.data(); } |
_ZNK9base_blobILj256EE4dataEv Line | Count | Source | 112 | 35.5M | constexpr const unsigned char* data() const { return m_data.data(); } |
|
113 | 44.4M | constexpr unsigned char* data() { return m_data.data(); } _ZN9base_blobILj160EE4dataEv Line | Count | Source | 113 | 17.2M | constexpr unsigned char* data() { return m_data.data(); } |
_ZN9base_blobILj256EE4dataEv Line | Count | Source | 113 | 27.1M | constexpr unsigned char* data() { return m_data.data(); } |
|
114 | | |
115 | 364M | constexpr unsigned char* begin() { return m_data.data(); } _ZN9base_blobILj160EE5beginEv Line | Count | Source | 115 | 6.23M | constexpr unsigned char* begin() { return m_data.data(); } |
_ZN9base_blobILj256EE5beginEv Line | Count | Source | 115 | 358M | constexpr unsigned char* begin() { return m_data.data(); } |
|
116 | 4.76k | constexpr unsigned char* end() { return m_data.data() + WIDTH; } _ZN9base_blobILj160EE3endEv Line | Count | Source | 116 | 4.76k | constexpr unsigned char* end() { return m_data.data() + WIDTH; } |
Unexecuted instantiation: _ZN9base_blobILj256EE3endEv |
117 | | |
118 | 21.0M | constexpr const unsigned char* begin() const { return m_data.data(); } _ZNK9base_blobILj160EE5beginEv Line | Count | Source | 118 | 2.88M | constexpr const unsigned char* begin() const { return m_data.data(); } |
_ZNK9base_blobILj256EE5beginEv Line | Count | Source | 118 | 18.2M | constexpr const unsigned char* begin() const { return m_data.data(); } |
|
119 | 7.42M | constexpr const unsigned char* end() const { return m_data.data() + WIDTH; } _ZNK9base_blobILj160EE3endEv Line | Count | Source | 119 | 2.88M | constexpr const unsigned char* end() const { return m_data.data() + WIDTH; } |
_ZNK9base_blobILj256EE3endEv Line | Count | Source | 119 | 4.54M | constexpr const unsigned char* end() const { return m_data.data() + WIDTH; } |
|
120 | | |
121 | 74.7M | static constexpr unsigned int size() { return WIDTH; } _ZN9base_blobILj160EE4sizeEv Line | Count | Source | 121 | 17.3M | static constexpr unsigned int size() { return WIDTH; } |
_ZN9base_blobILj256EE4sizeEv Line | Count | Source | 121 | 57.4M | static constexpr unsigned int size() { return WIDTH; } |
|
122 | | |
123 | 1.09G | constexpr uint64_t GetUint64(int pos) const { return ReadLE64(m_data.data() + pos * 8); } |
124 | | |
125 | | template<typename Stream> |
126 | | void Serialize(Stream& s) const |
127 | 1.04G | { |
128 | 1.04G | s << std::span(m_data); |
129 | 1.04G | } _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR12SizeComputer20TransactionSerParamsEEEvRT_ Line | Count | Source | 127 | 896M | { | 128 | 896M | s << std::span(m_data); | 129 | 896M | } |
_ZNK9base_blobILj256EE9SerializeI10DataStreamEEvRT_ Line | Count | Source | 127 | 6.15M | { | 128 | 6.15M | s << std::span(m_data); | 129 | 6.15M | } |
_ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR10DataStream20TransactionSerParamsEEEvRT_ Line | Count | Source | 127 | 839k | { | 128 | 839k | s << std::span(m_data); | 129 | 839k | } |
_ZNK9base_blobILj256EE9SerializeI12SizeComputerEEvRT_ Line | Count | Source | 127 | 20.2k | { | 128 | 20.2k | s << std::span(m_data); | 129 | 20.2k | } |
_ZNK9base_blobILj256EE9SerializeI12VectorWriterEEvRT_ Line | Count | Source | 127 | 329k | { | 128 | 329k | s << std::span(m_data); | 129 | 329k | } |
_ZNK9base_blobILj160EE9SerializeI10DataStreamEEvRT_ Line | Count | Source | 127 | 340 | { | 128 | 340 | s << std::span(m_data); | 129 | 340 | } |
_ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR12VectorWriter20TransactionSerParamsEEEvRT_ Line | Count | Source | 127 | 417k | { | 128 | 417k | s << std::span(m_data); | 129 | 417k | } |
_ZNK9base_blobILj256EE9SerializeI12ParamsStreamIRS2_IR12VectorWriter20TransactionSerParamsES5_EEEvRT_ Line | Count | Source | 127 | 3.13k | { | 128 | 3.13k | s << std::span(m_data); | 129 | 3.13k | } |
_ZNK9base_blobILj256EE9SerializeI8AutoFileEEvRT_ Line | Count | Source | 127 | 109k | { | 128 | 109k | s << std::span(m_data); | 129 | 109k | } |
_ZNK9base_blobILj256EE9SerializeI10HashWriterEEvRT_ Line | Count | Source | 127 | 103M | { | 128 | 103M | s << std::span(m_data); | 129 | 103M | } |
Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR18HashedSourceWriterI8AutoFileEN8CAddress9SerParamsEEEEvRT_ _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT_ Line | Count | Source | 127 | 4.56k | { | 128 | 4.56k | s << std::span(m_data); | 129 | 4.56k | } |
_ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR8AutoFile20TransactionSerParamsEEEvRT_ Line | Count | Source | 127 | 201k | { | 128 | 201k | s << std::span(m_data); | 129 | 201k | } |
_ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR10HashWriter20TransactionSerParamsEEEvRT_ Line | Count | Source | 127 | 40.0M | { | 128 | 40.0M | s << std::span(m_data); | 129 | 40.0M | } |
|
130 | | |
131 | | template<typename Stream> |
132 | | void Unserialize(Stream& s) |
133 | 12.3M | { |
134 | 12.3M | s.read(MakeWritableByteSpan(m_data)); |
135 | 12.3M | } _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR10DataStream20TransactionSerParamsEEEvRT_ Line | Count | Source | 133 | 3.26M | { | 134 | 3.26M | s.read(MakeWritableByteSpan(m_data)); | 135 | 3.26M | } |
_ZN9base_blobILj256EE11UnserializeI10DataStreamEEvRT_ Line | Count | Source | 133 | 7.44M | { | 134 | 7.44M | s.read(MakeWritableByteSpan(m_data)); | 135 | 7.44M | } |
_ZN9base_blobILj256EE11UnserializeI10SpanReaderEEvRT_ Line | Count | Source | 133 | 20.2k | { | 134 | 20.2k | s.read(MakeWritableByteSpan(m_data)); | 135 | 20.2k | } |
_ZN9base_blobILj160EE11UnserializeI10DataStreamEEvRT_ Line | Count | Source | 133 | 347 | { | 134 | 347 | s.read(MakeWritableByteSpan(m_data)); | 135 | 347 | } |
Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR10SpanReader20TransactionSerParamsEEEvRT_ _ZN9base_blobILj256EE11UnserializeI8AutoFileEEvRT_ Line | Count | Source | 133 | 330k | { | 134 | 330k | s.read(MakeWritableByteSpan(m_data)); | 135 | 330k | } |
Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR8AutoFileN8CAddress9SerParamsEEEEvRT_ Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR12HashVerifierI8AutoFileEN8CAddress9SerParamsEEEEvRT_ _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT_ Line | Count | Source | 133 | 3.31k | { | 134 | 3.31k | s.read(MakeWritableByteSpan(m_data)); | 135 | 3.31k | } |
_ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR12HashVerifierI10DataStreamEN8CAddress9SerParamsEEEEvRT_ Line | Count | Source | 133 | 1.01k | { | 134 | 1.01k | s.read(MakeWritableByteSpan(m_data)); | 135 | 1.01k | } |
_ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR8AutoFile20TransactionSerParamsEEEvRT_ Line | Count | Source | 133 | 791k | { | 134 | 791k | s.read(MakeWritableByteSpan(m_data)); | 135 | 791k | } |
_ZN9base_blobILj256EE11UnserializeI12BufferedFileEEvRT_ Line | Count | Source | 133 | 324k | { | 134 | 324k | s.read(MakeWritableByteSpan(m_data)); | 135 | 324k | } |
_ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR12BufferedFile20TransactionSerParamsEEEvRT_ Line | Count | Source | 133 | 167k | { | 134 | 167k | s.read(MakeWritableByteSpan(m_data)); | 135 | 167k | } |
|
136 | | }; |
137 | | |
138 | | template <unsigned int BITS> |
139 | | consteval base_blob<BITS>::base_blob(std::string_view hex_str) |
140 | | { |
141 | | if (hex_str.length() != m_data.size() * 2) throw "Hex string must fit exactly"; |
142 | | auto str_it = hex_str.rbegin(); |
143 | | for (auto& elem : m_data) { |
144 | | auto lo = util::ConstevalHexDigit(*(str_it++)); |
145 | | elem = (util::ConstevalHexDigit(*(str_it++)) << 4) | lo; |
146 | | } |
147 | | } |
148 | | |
149 | | namespace detail { |
150 | | /** |
151 | | * Writes the hex string (in reverse byte order) into a new uintN_t object |
152 | | * and only returns a value iff all of the checks pass: |
153 | | * - Input length is uintN_t::size()*2 |
154 | | * - All characters are hex |
155 | | */ |
156 | | template <class uintN_t> |
157 | | std::optional<uintN_t> FromHex(std::string_view str) |
158 | 4.37k | { |
159 | 4.37k | if (uintN_t::size() * 2 != str.size() || !IsHex(str)) return std::nullopt; |
160 | 496 | uintN_t rv; |
161 | 496 | rv.SetHexDeprecated(str); |
162 | 496 | return rv; |
163 | 4.37k | } Unexecuted instantiation: _ZN6detail7FromHexI7uint160EESt8optionalIT_ESt17basic_string_viewIcSt11char_traitsIcEE _ZN6detail7FromHexI7uint256EESt8optionalIT_ESt17basic_string_viewIcSt11char_traitsIcEE Line | Count | Source | 158 | 4.37k | { | 159 | 4.37k | if (uintN_t::size() * 2 != str.size() || !IsHex(str)) return std::nullopt; | 160 | 496 | uintN_t rv; | 161 | 496 | rv.SetHexDeprecated(str); | 162 | 496 | return rv; | 163 | 4.37k | } |
|
164 | | /** |
165 | | * @brief Like FromHex(std::string_view str), but allows an "0x" prefix |
166 | | * and pads the input with leading zeroes if it is shorter than |
167 | | * the expected length of uintN_t::size()*2. |
168 | | * |
169 | | * Designed to be used when dealing with user input. |
170 | | */ |
171 | | template <class uintN_t> |
172 | | std::optional<uintN_t> FromUserHex(std::string_view input) |
173 | 233 | { |
174 | 233 | input = util::RemovePrefixView(input, "0x"); |
175 | 233 | constexpr auto expected_size{uintN_t::size() * 2}; |
176 | 233 | if (input.size() < expected_size) { |
177 | 44 | auto padded = std::string(expected_size, '0'); |
178 | 44 | std::copy(input.begin(), input.end(), padded.begin() + expected_size - input.size()); |
179 | 44 | return FromHex<uintN_t>(padded); |
180 | 44 | } |
181 | 189 | return FromHex<uintN_t>(input); |
182 | 233 | } |
183 | | } // namespace detail |
184 | | |
185 | | /** 160-bit opaque blob. |
186 | | * @note This type is called uint160 for historical reasons only. It is an opaque |
187 | | * blob of 160 bits and has no integer operations. |
188 | | */ |
189 | | class uint160 : public base_blob<160> { |
190 | | public: |
191 | 0 | static std::optional<uint160> FromHex(std::string_view str) { return detail::FromHex<uint160>(str); } |
192 | 25.2M | constexpr uint160() = default; |
193 | 8.78M | constexpr explicit uint160(std::span<const unsigned char> vch) : base_blob<160>(vch) {} |
194 | | }; |
195 | | |
196 | | /** 256-bit opaque blob. |
197 | | * @note This type is called uint256 for historical reasons only. It is an |
198 | | * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if |
199 | | * those are required. |
200 | | */ |
201 | | class uint256 : public base_blob<256> { |
202 | | public: |
203 | 4.13k | static std::optional<uint256> FromHex(std::string_view str) { return detail::FromHex<uint256>(str); } |
204 | 233 | static std::optional<uint256> FromUserHex(std::string_view str) { return detail::FromUserHex<uint256>(str); } |
205 | 1.15G | constexpr uint256() = default; |
206 | 0 | consteval explicit uint256(std::string_view hex_str) : base_blob<256>(hex_str) {} |
207 | 8.08k | constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {} |
208 | 2.79M | constexpr explicit uint256(std::span<const unsigned char> vch) : base_blob<256>(vch) {} |
209 | | static const uint256 ZERO; |
210 | | static const uint256 ONE; |
211 | | }; |
212 | | |
213 | | #endif // BITCOIN_UINT256_H |