/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.23M | constexpr base_blob() : m_data() {} _ZN9base_blobILj256EEC2Ev Line | Count | Source | 35 | 1.23M | constexpr base_blob() : m_data() {} |
Unexecuted instantiation: _ZN9base_blobILj160EEC2Ev |
36 | | |
37 | | /* constructor for constants between 1 and 255 */ |
38 | 0 | constexpr explicit base_blob(uint8_t v) : m_data{v} {} |
39 | | |
40 | | constexpr explicit base_blob(Span<const unsigned char> vch) |
41 | 2.56k | { |
42 | 2.56k | assert(vch.size() == WIDTH); |
43 | 2.56k | std::copy(vch.begin(), vch.end(), m_data.begin()); |
44 | 2.56k | } _ZN9base_blobILj256EEC2E4SpanIKhE Line | Count | Source | 41 | 2.56k | { | 42 | 2.56k | assert(vch.size() == WIDTH); | 43 | 2.56k | std::copy(vch.begin(), vch.end(), m_data.begin()); | 44 | 2.56k | } |
Unexecuted instantiation: _ZN9base_blobILj160EEC2E4SpanIKhE |
45 | | |
46 | | consteval explicit base_blob(std::string_view hex_str); |
47 | | |
48 | | constexpr bool IsNull() const |
49 | 145k | { |
50 | 2.47M | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { |
51 | 2.47M | return val == 0; |
52 | 2.47M | }); _ZZNK9base_blobILj256EE6IsNullEvENKUlhE_clEh Line | Count | Source | 50 | 2.47M | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 51 | 2.47M | return val == 0; | 52 | 2.47M | }); |
Unexecuted instantiation: _ZZNK9base_blobILj160EE6IsNullEvENKUlhE_clEh |
53 | 145k | } _ZNK9base_blobILj256EE6IsNullEv Line | Count | Source | 49 | 145k | { | 50 | 145k | return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 51 | 145k | return val == 0; | 52 | 145k | }); | 53 | 145k | } |
Unexecuted instantiation: _ZNK9base_blobILj160EE6IsNullEv |
54 | | |
55 | | constexpr void SetNull() |
56 | 986k | { |
57 | 986k | std::fill(m_data.begin(), m_data.end(), 0); |
58 | 986k | } _ZN9base_blobILj256EE7SetNullEv Line | Count | Source | 56 | 986k | { | 57 | 986k | std::fill(m_data.begin(), m_data.end(), 0); | 58 | 986k | } |
Unexecuted instantiation: _ZN9base_blobILj160EE7SetNullEv |
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 | 136k | 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 | 136k | constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); } |
Unexecuted instantiation: _ZNK9base_blobILj160EE7CompareERKS0_ |
65 | | |
66 | 28.7k | friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } _ZeqRK9base_blobILj256EES2_ Line | Count | Source | 66 | 28.7k | friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } |
Unexecuted instantiation: _ZeqRK9base_blobILj160EES2_ |
67 | 88.2k | friend constexpr bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; } _ZneRK9base_blobILj256EES2_ Line | Count | Source | 67 | 88.2k | friend constexpr bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; } |
Unexecuted instantiation: _ZneRK9base_blobILj160EES2_ |
68 | 19.1k | friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } _ZltRK9base_blobILj256EES2_ Line | Count | Source | 68 | 19.1k | friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } |
Unexecuted instantiation: _ZltRK9base_blobILj160EES2_ |
69 | | |
70 | | /** @name Hex representation |
71 | | * |
72 | | * The reverse-byte hex representation is a convenient way to view the blob |
73 | | * as a number, because it is consistent with the way the base_uint class |
74 | | * converts blobs to numbers. |
75 | | * |
76 | | * @note base_uint treats the blob as an array of bytes with the numerically |
77 | | * least significant byte first and the most significant byte last. Because |
78 | | * numbers are typically written with the most significant digit first and |
79 | | * the least significant digit last, the reverse hex display of the blob |
80 | | * corresponds to the same numeric value that base_uint interprets from the |
81 | | * blob. |
82 | | * @{*/ |
83 | | std::string GetHex() const; |
84 | | /** Unlike FromHex this accepts any invalid input, thus it is fragile and deprecated! |
85 | | * |
86 | | * - Hex numbers that don't specify enough bytes to fill the internal array |
87 | | * will be treated as setting the beginning of it, which corresponds to |
88 | | * the least significant bytes when converted to base_uint. |
89 | | * |
90 | | * - Hex numbers specifying too many bytes will have the numerically most |
91 | | * significant bytes (the beginning of the string) narrowed away. |
92 | | * |
93 | | * - An odd count of hex digits will result in the high bits of the leftmost |
94 | | * byte being zero. |
95 | | * "0x123" => {0x23, 0x1, 0x0, ..., 0x0} |
96 | | */ |
97 | | void SetHexDeprecated(std::string_view str); |
98 | | std::string ToString() const; |
99 | | /**@}*/ |
100 | | |
101 | 0 | constexpr const unsigned char* data() const { return m_data.data(); } Unexecuted instantiation: _ZNK9base_blobILj256EE4dataEv Unexecuted instantiation: _ZNK9base_blobILj160EE4dataEv |
102 | 309k | constexpr unsigned char* data() { return m_data.data(); } Unexecuted instantiation: _ZN9base_blobILj160EE4dataEv _ZN9base_blobILj256EE4dataEv Line | Count | Source | 102 | 309k | constexpr unsigned char* data() { return m_data.data(); } |
|
103 | | |
104 | 1.44M | constexpr unsigned char* begin() { return m_data.data(); } _ZN9base_blobILj256EE5beginEv Line | Count | Source | 104 | 1.44M | constexpr unsigned char* begin() { return m_data.data(); } |
Unexecuted instantiation: _ZN9base_blobILj160EE5beginEv |
105 | 0 | constexpr unsigned char* end() { return m_data.data() + WIDTH; } Unexecuted instantiation: _ZN9base_blobILj256EE3endEv Unexecuted instantiation: _ZN9base_blobILj160EE3endEv |
106 | | |
107 | 1.35M | constexpr const unsigned char* begin() const { return m_data.data(); } _ZNK9base_blobILj256EE5beginEv Line | Count | Source | 107 | 1.35M | constexpr const unsigned char* begin() const { return m_data.data(); } |
Unexecuted instantiation: _ZNK9base_blobILj160EE5beginEv |
108 | 0 | constexpr const unsigned char* end() const { return m_data.data() + WIDTH; } Unexecuted instantiation: _ZNK9base_blobILj256EE3endEv Unexecuted instantiation: _ZNK9base_blobILj160EE3endEv |
109 | | |
110 | 56.5k | static constexpr unsigned int size() { return WIDTH; } _ZN9base_blobILj256EE4sizeEv Line | Count | Source | 110 | 56.5k | static constexpr unsigned int size() { return WIDTH; } |
Unexecuted instantiation: _ZN9base_blobILj160EE4sizeEv |
111 | | |
112 | 10.3k | constexpr uint64_t GetUint64(int pos) const { return ReadLE64(m_data.data() + pos * 8); } |
113 | | |
114 | | template<typename Stream> |
115 | | void Serialize(Stream& s) const |
116 | 1.12M | { |
117 | 1.12M | s << Span(m_data); |
118 | 1.12M | } _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR12SizeComputer20TransactionSerParamsEEEvRT_ Line | Count | Source | 116 | 38.2k | { | 117 | 38.2k | s << Span(m_data); | 118 | 38.2k | } |
_ZNK9base_blobILj256EE9SerializeI10DataStreamEEvRT_ Line | Count | Source | 116 | 10.3k | { | 117 | 10.3k | s << Span(m_data); | 118 | 10.3k | } |
Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR10DataStream20TransactionSerParamsEEEvRT_ Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12SizeComputerEEvRT_ _ZNK9base_blobILj256EE9SerializeI12VectorWriterEEvRT_ Line | Count | Source | 116 | 5.46k | { | 117 | 5.46k | s << Span(m_data); | 118 | 5.46k | } |
Unexecuted instantiation: _ZNK9base_blobILj160EE9SerializeI10DataStreamEEvRT_ _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR12VectorWriter20TransactionSerParamsEEEvRT_ Line | Count | Source | 116 | 172k | { | 117 | 172k | s << Span(m_data); | 118 | 172k | } |
_ZNK9base_blobILj256EE9SerializeI12ParamsStreamIRS2_IR12VectorWriter20TransactionSerParamsES5_EEEvRT_ Line | Count | Source | 116 | 2.57k | { | 117 | 2.57k | s << Span(m_data); | 118 | 2.57k | } |
Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI8AutoFileEEvRT_ _ZNK9base_blobILj256EE9SerializeI10HashWriterEEvRT_ Line | Count | Source | 116 | 872k | { | 117 | 872k | s << Span(m_data); | 118 | 872k | } |
Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR18HashedSourceWriterI8AutoFileEN8CAddress9SerParamsEEEEvRT_ Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT_ Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR8AutoFile20TransactionSerParamsEEEvRT_ _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR10HashWriter20TransactionSerParamsEEEvRT_ Line | Count | Source | 116 | 24.2k | { | 117 | 24.2k | s << Span(m_data); | 118 | 24.2k | } |
|
119 | | |
120 | | template<typename Stream> |
121 | | void Unserialize(Stream& s) |
122 | 174k | { |
123 | 174k | s.read(MakeWritableByteSpan(m_data)); |
124 | 174k | } _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR10DataStream20TransactionSerParamsEEEvRT_ Line | Count | Source | 122 | 31.2k | { | 123 | 31.2k | s.read(MakeWritableByteSpan(m_data)); | 124 | 31.2k | } |
_ZN9base_blobILj256EE11UnserializeI10DataStreamEEvRT_ Line | Count | Source | 122 | 143k | { | 123 | 143k | s.read(MakeWritableByteSpan(m_data)); | 124 | 143k | } |
Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI10SpanReaderEEvRT_ Unexecuted instantiation: _ZN9base_blobILj160EE11UnserializeI10DataStreamEEvRT_ Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR10SpanReader20TransactionSerParamsEEEvRT_ Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI8AutoFileEEvRT_ Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR8AutoFileN8CAddress9SerParamsEEEEvRT_ Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR12HashVerifierI8AutoFileEN8CAddress9SerParamsEEEEvRT_ Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT_ Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR12HashVerifierI10DataStreamEN8CAddress9SerParamsEEEEvRT_ Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR8AutoFile20TransactionSerParamsEEEvRT_ Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12BufferedFileEEvRT_ Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR12BufferedFile20TransactionSerParamsEEEvRT_ |
125 | | }; |
126 | | |
127 | | template <unsigned int BITS> |
128 | | consteval base_blob<BITS>::base_blob(std::string_view hex_str) |
129 | | { |
130 | | if (hex_str.length() != m_data.size() * 2) throw "Hex string must fit exactly"; |
131 | | auto str_it = hex_str.rbegin(); |
132 | | for (auto& elem : m_data) { |
133 | | auto lo = util::ConstevalHexDigit(*(str_it++)); |
134 | | elem = (util::ConstevalHexDigit(*(str_it++)) << 4) | lo; |
135 | | } |
136 | | } |
137 | | |
138 | | namespace detail { |
139 | | /** |
140 | | * Writes the hex string (in reverse byte order) into a new uintN_t object |
141 | | * and only returns a value iff all of the checks pass: |
142 | | * - Input length is uintN_t::size()*2 |
143 | | * - All characters are hex |
144 | | */ |
145 | | template <class uintN_t> |
146 | | std::optional<uintN_t> FromHex(std::string_view str) |
147 | 0 | { |
148 | 0 | if (uintN_t::size() * 2 != str.size() || !IsHex(str)) return std::nullopt; |
149 | 0 | uintN_t rv; |
150 | 0 | rv.SetHexDeprecated(str); |
151 | 0 | return rv; |
152 | 0 | } Unexecuted instantiation: _ZN6detail7FromHexI7uint160EESt8optionalIT_ESt17basic_string_viewIcSt11char_traitsIcEE Unexecuted instantiation: _ZN6detail7FromHexI7uint256EESt8optionalIT_ESt17basic_string_viewIcSt11char_traitsIcEE |
153 | | /** |
154 | | * @brief Like FromHex(std::string_view str), but allows an "0x" prefix |
155 | | * and pads the input with leading zeroes if it is shorter than |
156 | | * the expected length of uintN_t::size()*2. |
157 | | * |
158 | | * Designed to be used when dealing with user input. |
159 | | */ |
160 | | template <class uintN_t> |
161 | | std::optional<uintN_t> FromUserHex(std::string_view input) |
162 | 0 | { |
163 | 0 | input = util::RemovePrefixView(input, "0x"); |
164 | 0 | constexpr auto expected_size{uintN_t::size() * 2}; |
165 | 0 | if (input.size() < expected_size) { |
166 | 0 | auto padded = std::string(expected_size, '0'); |
167 | 0 | std::copy(input.begin(), input.end(), padded.begin() + expected_size - input.size()); |
168 | 0 | return FromHex<uintN_t>(padded); |
169 | 0 | } |
170 | 0 | return FromHex<uintN_t>(input); |
171 | 0 | } |
172 | | } // namespace detail |
173 | | |
174 | | /** 160-bit opaque blob. |
175 | | * @note This type is called uint160 for historical reasons only. It is an opaque |
176 | | * blob of 160 bits and has no integer operations. |
177 | | */ |
178 | | class uint160 : public base_blob<160> { |
179 | | public: |
180 | 0 | static std::optional<uint160> FromHex(std::string_view str) { return detail::FromHex<uint160>(str); } |
181 | 0 | constexpr uint160() = default; |
182 | 0 | constexpr explicit uint160(Span<const unsigned char> vch) : base_blob<160>(vch) {} |
183 | | }; |
184 | | |
185 | | /** 256-bit opaque blob. |
186 | | * @note This type is called uint256 for historical reasons only. It is an |
187 | | * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if |
188 | | * those are required. |
189 | | */ |
190 | | class uint256 : public base_blob<256> { |
191 | | public: |
192 | 0 | static std::optional<uint256> FromHex(std::string_view str) { return detail::FromHex<uint256>(str); } |
193 | 0 | static std::optional<uint256> FromUserHex(std::string_view str) { return detail::FromUserHex<uint256>(str); } |
194 | 1.23M | constexpr uint256() = default; |
195 | 0 | consteval explicit uint256(std::string_view hex_str) : base_blob<256>(hex_str) {} |
196 | 0 | constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {} |
197 | 2.56k | constexpr explicit uint256(Span<const unsigned char> vch) : base_blob<256>(vch) {} |
198 | | static const uint256 ZERO; |
199 | | static const uint256 ONE; |
200 | | }; |
201 | | |
202 | | #endif // BITCOIN_UINT256_H |