/Users/eugenesiegel/btc/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 | 54.0G |     constexpr base_blob() : m_data() {}_ZN9base_blobILj256EEC2Ev| Line | Count | Source |  | 35 | 54.0G |     constexpr base_blob() : m_data() {} | 
_ZN9base_blobILj160EEC2Ev| Line | Count | Source |  | 35 | 649k |     constexpr base_blob() : m_data() {} | 
 | 
| 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(std::span<const unsigned char> vch) | 
| 41 | 0 |     { | 
| 42 | 0 |         assert(vch.size() == WIDTH); | 
| 43 | 0 |         std::copy(vch.begin(), vch.end(), m_data.begin()); | 
| 44 | 0 |     } Unexecuted instantiation: _ZN9base_blobILj256EEC2ENSt3__14spanIKhLm18446744073709551615EEEUnexecuted instantiation: _ZN9base_blobILj160EEC2ENSt3__14spanIKhLm18446744073709551615EEE | 
| 45 |  |  | 
| 46 |  |     consteval explicit base_blob(std::string_view hex_str); | 
| 47 |  |  | 
| 48 |  |     constexpr bool IsNull() const | 
| 49 | 103M |     { | 
| 50 | 785M |         return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { | 
| 51 | 785M |             return val == 0; | 
| 52 | 785M |         }); _ZZNK9base_blobILj256EE6IsNullEvENKUlhE_clEh| Line | Count | Source |  | 50 | 785M |         return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { |  | 51 | 785M |             return val == 0; |  | 52 | 785M |         }); | 
Unexecuted instantiation: _ZZNK9base_blobILj160EE6IsNullEvENKUlhE_clEh | 
| 53 | 103M |     } _ZNK9base_blobILj256EE6IsNullEv| Line | Count | Source |  | 49 | 103M |     { |  | 50 | 103M |         return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { |  | 51 | 103M |             return val == 0; |  | 52 | 103M |         }); |  | 53 | 103M |     } | 
Unexecuted instantiation: _ZNK9base_blobILj160EE6IsNullEv | 
| 54 |  |  | 
| 55 |  |     constexpr void SetNull() | 
| 56 | 72.6M |     { | 
| 57 | 72.6M |         std::fill(m_data.begin(), m_data.end(), 0); | 
| 58 | 72.6M |     } _ZN9base_blobILj256EE7SetNullEv| Line | Count | Source |  | 56 | 72.6M |     { |  | 57 | 72.6M |         std::fill(m_data.begin(), m_data.end(), 0); |  | 58 | 72.6M |     } | 
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 | 814M |     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 | 814M |     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 | 39.7M |     friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; }_ZeqRK9base_blobILj256EES2_| Line | Count | Source |  | 66 | 39.7M |     friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } | 
Unexecuted instantiation: _ZeqRK9base_blobILj160EES2_ | 
| 67 | 3.34M |     friend constexpr bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; }_ZneRK9base_blobILj256EES2_| Line | Count | Source |  | 67 | 3.34M |     friend constexpr bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; } | 
Unexecuted instantiation: _ZneRK9base_blobILj160EES2_ | 
| 68 | 28.5M |     friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; }_ZltRK9base_blobILj256EES2_| Line | Count | Source |  | 68 | 28.5M |     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 hex representation used by GetHex(), ToString(), and FromHex() | 
| 73 |  |      * is unusual, since it shows bytes of the base_blob in reverse order. | 
| 74 |  |      * For example, a 4-byte blob {0x12, 0x34, 0x56, 0x78} is represented | 
| 75 |  |      * as "78563412" instead of the more typical "12345678" representation | 
| 76 |  |      * 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 |  |     std::string ToString() const; | 
| 96 |  |     /**@}*/ | 
| 97 |  |  | 
| 98 | 23.5M |     constexpr const unsigned char* data() const { return m_data.data(); }Unexecuted instantiation: _ZNK9base_blobILj160EE4dataEv_ZNK9base_blobILj256EE4dataEv| Line | Count | Source |  | 98 | 23.5M |     constexpr const unsigned char* data() const { return m_data.data(); } | 
 | 
| 99 | 48.7M |     constexpr unsigned char* data() { return m_data.data(); }Unexecuted instantiation: _ZN9base_blobILj160EE4dataEv_ZN9base_blobILj256EE4dataEv| Line | Count | Source |  | 99 | 48.7M |     constexpr unsigned char* data() { return m_data.data(); } | 
 | 
| 100 |  |  | 
| 101 | 209M |     constexpr unsigned char* begin() { return m_data.data(); }Unexecuted instantiation: _ZN9base_blobILj160EE5beginEv_ZN9base_blobILj256EE5beginEv| Line | Count | Source |  | 101 | 209M |     constexpr unsigned char* begin() { return m_data.data(); } | 
 | 
| 102 | 0 |     constexpr unsigned char* end() { return m_data.data() + WIDTH; }Unexecuted instantiation: _ZN9base_blobILj160EE3endEvUnexecuted instantiation: _ZN9base_blobILj256EE3endEv | 
| 103 |  |  | 
| 104 | 59.1M |     constexpr const unsigned char* begin() const { return m_data.data(); }Unexecuted instantiation: _ZNK9base_blobILj160EE5beginEv_ZNK9base_blobILj256EE5beginEv| Line | Count | Source |  | 104 | 59.1M |     constexpr const unsigned char* begin() const { return m_data.data(); } | 
 | 
| 105 | 0 |     constexpr const unsigned char* end() const { return m_data.data() + WIDTH; }Unexecuted instantiation: _ZNK9base_blobILj160EE3endEvUnexecuted instantiation: _ZNK9base_blobILj256EE3endEv | 
| 106 |  |  | 
| 107 | 55.1M |     static constexpr unsigned int size() { return WIDTH; }Unexecuted instantiation: _ZN9base_blobILj160EE4sizeEv_ZN9base_blobILj256EE4sizeEv| Line | Count | Source |  | 107 | 55.1M |     static constexpr unsigned int size() { return WIDTH; } | 
 | 
| 108 |  |  | 
| 109 | 910M |     constexpr uint64_t GetUint64(int pos) const { return ReadLE64(m_data.data() + pos * 8); } | 
| 110 |  |  | 
| 111 |  |     template<typename Stream> | 
| 112 |  |     void Serialize(Stream& s) const | 
| 113 | 108M |     { | 
| 114 | 108M |         s << std::span(m_data); | 
| 115 | 108M |     } _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR12SizeComputer20TransactionSerParamsEEEvRT_| Line | Count | Source |  | 113 | 6.44M |     { |  | 114 | 6.44M |         s << std::span(m_data); |  | 115 | 6.44M |     } | 
_ZNK9base_blobILj256EE9SerializeI12VectorWriterEEvRT_| Line | Count | Source |  | 113 | 5.45M |     { |  | 114 | 5.45M |         s << std::span(m_data); |  | 115 | 5.45M |     } | 
_ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR12VectorWriter20TransactionSerParamsEEEvRT_| Line | Count | Source |  | 113 | 7.20M |     { |  | 114 | 7.20M |         s << std::span(m_data); |  | 115 | 7.20M |     } | 
_ZNK9base_blobILj256EE9SerializeI10DataStreamEEvRT_| Line | Count | Source |  | 113 | 7.62M |     { |  | 114 | 7.62M |         s << std::span(m_data); |  | 115 | 7.62M |     } | 
Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR10DataStream20TransactionSerParamsEEEvRT_Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12SizeComputerEEvRT_Unexecuted instantiation: _ZNK9base_blobILj160EE9SerializeI10DataStreamEEvRT_Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIRS2_IR12VectorWriter20TransactionSerParamsES5_EEEvRT_Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI8AutoFileEEvRT__ZNK9base_blobILj256EE9SerializeI10HashWriterEEvRT_| Line | Count | Source |  | 113 | 50.3M |     { |  | 114 | 50.3M |         s << std::span(m_data); |  | 115 | 50.3M |     } | 
Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR18HashedSourceWriterI8AutoFileEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT__ZNK9base_blobILj256EE9SerializeI14BufferedWriterI8AutoFileEEEvRT_| Line | Count | Source |  | 113 | 21.7k |     { |  | 114 | 21.7k |         s << std::span(m_data); |  | 115 | 21.7k |     } | 
_ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR14BufferedWriterI8AutoFileE20TransactionSerParamsEEEvRT_| Line | Count | Source |  | 113 | 218k |     { |  | 114 | 218k |         s << std::span(m_data); |  | 115 | 218k |     } | 
Unexecuted instantiation: _ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR8AutoFile20TransactionSerParamsEEEvRT__ZNK9base_blobILj256EE9SerializeI12ParamsStreamIR10HashWriter20TransactionSerParamsEEEvRT_| Line | Count | Source |  | 113 | 30.8M |     { |  | 114 | 30.8M |         s << std::span(m_data); |  | 115 | 30.8M |     } | 
 | 
| 116 |  |  | 
| 117 |  |     template<typename Stream> | 
| 118 |  |     void Unserialize(Stream& s) | 
| 119 | 41.9M |     { | 
| 120 | 41.9M |         s.read(MakeWritableByteSpan(m_data)); | 
| 121 | 41.9M |     } _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR10DataStream20TransactionSerParamsEEEvRT_| Line | Count | Source |  | 119 | 4.97M |     { |  | 120 | 4.97M |         s.read(MakeWritableByteSpan(m_data)); |  | 121 | 4.97M |     } | 
_ZN9base_blobILj256EE11UnserializeI10DataStreamEEvRT_| Line | Count | Source |  | 119 | 35.4M |     { |  | 120 | 35.4M |         s.read(MakeWritableByteSpan(m_data)); |  | 121 | 35.4M |     } | 
Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI10SpanReaderEEvRT_Unexecuted instantiation: _ZN9base_blobILj160EE11UnserializeI10DataStreamEEvRT__ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR10SpanReader20TransactionSerParamsEEEvRT_| Line | Count | Source |  | 119 | 928k |     { |  | 120 | 928k |         s.read(MakeWritableByteSpan(m_data)); |  | 121 | 928k |     } | 
Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI8AutoFileEEvRT_Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR8AutoFileN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR12HashVerifierI8AutoFileEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR10DataStreamN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR12HashVerifierI10DataStreamEN8CAddress9SerParamsEEEEvRT_Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR8AutoFile20TransactionSerParamsEEEvRT__ZN9base_blobILj256EE11UnserializeI14BufferedReaderI8AutoFileEEEvRT_| Line | Count | Source |  | 119 | 615k |     { |  | 120 | 615k |         s.read(MakeWritableByteSpan(m_data)); |  | 121 | 615k |     } | 
Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12BufferedFileEEvRT_Unexecuted instantiation: _ZN9base_blobILj256EE11UnserializeI12ParamsStreamIR12BufferedFile20TransactionSerParamsEEEvRT_ | 
| 122 |  | }; | 
| 123 |  |  | 
| 124 |  | template <unsigned int BITS> | 
| 125 |  | consteval base_blob<BITS>::base_blob(std::string_view hex_str) | 
| 126 |  | { | 
| 127 |  |     if (hex_str.length() != m_data.size() * 2) throw "Hex string must fit exactly"; | 
| 128 |  |     auto str_it = hex_str.rbegin(); | 
| 129 |  |     for (auto& elem : m_data) { | 
| 130 |  |         auto lo = util::ConstevalHexDigit(*(str_it++)); | 
| 131 |  |         elem = (util::ConstevalHexDigit(*(str_it++)) << 4) | lo; | 
| 132 |  |     } | 
| 133 |  | } | 
| 134 |  |  | 
| 135 |  | namespace detail { | 
| 136 |  | /** | 
| 137 |  |  * Writes the hex string (in reverse byte order) into a new uintN_t object | 
| 138 |  |  * and only returns a value iff all of the checks pass: | 
| 139 |  |  *   - Input length is uintN_t::size()*2 | 
| 140 |  |  *   - All characters are hex | 
| 141 |  |  */ | 
| 142 |  | template <class uintN_t> | 
| 143 |  | std::optional<uintN_t> FromHex(std::string_view str) | 
| 144 | 0 | { | 
| 145 | 0 |     if (uintN_t::size() * 2 != str.size() || !IsHex(str)) return std::nullopt; | 
| 146 | 0 |     uintN_t rv; | 
| 147 | 0 |     unsigned char* p1 = rv.begin(); | 
| 148 | 0 |     unsigned char* pend = rv.end(); | 
| 149 | 0 |     size_t digits = str.size(); | 
| 150 | 0 |     while (digits > 0 && p1 < pend) { | 
| 151 | 0 |         *p1 = ::HexDigit(str[--digits]); | 
| 152 | 0 |         if (digits > 0) { | 
| 153 | 0 |             *p1 |= ((unsigned char)::HexDigit(str[--digits]) << 4); | 
| 154 | 0 |             p1++; | 
| 155 | 0 |         } | 
| 156 | 0 |     } | 
| 157 | 0 |     return rv; | 
| 158 | 0 | } Unexecuted instantiation: _ZN6detail7FromHexI7uint160EENSt3__18optionalIT_EENS2_17basic_string_viewIcNS2_11char_traitsIcEEEEUnexecuted instantiation: _ZN6detail7FromHexI7uint256EENSt3__18optionalIT_EENS2_17basic_string_viewIcNS2_11char_traitsIcEEEE | 
| 159 |  | /** | 
| 160 |  |  * @brief Like FromHex(std::string_view str), but allows an "0x" prefix | 
| 161 |  |  *        and pads the input with leading zeroes if it is shorter than | 
| 162 |  |  *        the expected length of uintN_t::size()*2. | 
| 163 |  |  * | 
| 164 |  |  *        Designed to be used when dealing with user input. | 
| 165 |  |  */ | 
| 166 |  | template <class uintN_t> | 
| 167 |  | std::optional<uintN_t> FromUserHex(std::string_view input) | 
| 168 | 0 | { | 
| 169 | 0 |     input = util::RemovePrefixView(input, "0x"); | 
| 170 | 0 |     constexpr auto expected_size{uintN_t::size() * 2}; | 
| 171 | 0 |     if (input.size() < expected_size) { | 
| 172 | 0 |         auto padded = std::string(expected_size, '0'); | 
| 173 | 0 |         std::copy(input.begin(), input.end(), padded.begin() + expected_size - input.size()); | 
| 174 | 0 |         return FromHex<uintN_t>(padded); | 
| 175 | 0 |     } | 
| 176 | 0 |     return FromHex<uintN_t>(input); | 
| 177 | 0 | } | 
| 178 |  | } // namespace detail | 
| 179 |  |  | 
| 180 |  | /** 160-bit opaque blob. | 
| 181 |  |  * @note This type is called uint160 for historical reasons only. It is an opaque | 
| 182 |  |  * blob of 160 bits and has no integer operations. | 
| 183 |  |  */ | 
| 184 |  | class uint160 : public base_blob<160> { | 
| 185 |  | public: | 
| 186 | 0 |     static std::optional<uint160> FromHex(std::string_view str) { return detail::FromHex<uint160>(str); } | 
| 187 | 649k |     constexpr uint160() = default; | 
| 188 | 0 |     constexpr explicit uint160(std::span<const unsigned char> vch) : base_blob<160>(vch) {} | 
| 189 |  | }; | 
| 190 |  |  | 
| 191 |  | /** 256-bit opaque blob. | 
| 192 |  |  * @note This type is called uint256 for historical reasons only. It is an | 
| 193 |  |  * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if | 
| 194 |  |  * those are required. | 
| 195 |  |  */ | 
| 196 |  | class uint256 : public base_blob<256> { | 
| 197 |  | public: | 
| 198 | 0 |     static std::optional<uint256> FromHex(std::string_view str) { return detail::FromHex<uint256>(str); } | 
| 199 | 0 |     static std::optional<uint256> FromUserHex(std::string_view str) { return detail::FromUserHex<uint256>(str); } | 
| 200 | 54.0G |     constexpr uint256() = default; | 
| 201 | 0 |     consteval explicit uint256(std::string_view hex_str) : base_blob<256>(hex_str) {} | 
| 202 | 0 |     constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {} | 
| 203 | 0 |     constexpr explicit uint256(std::span<const unsigned char> vch) : base_blob<256>(vch) {} | 
| 204 |  |     static const uint256 ZERO; | 
| 205 |  |     static const uint256 ONE; | 
| 206 |  | }; | 
| 207 |  |  | 
| 208 |  | #endif // BITCOIN_UINT256_H |