Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2021 The Bitcoin Core developers 3 : // Copyright (c) 2014-2024 The Dash Core developers 4 : // Distributed under the MIT software license, see the accompanying 5 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 6 : 7 : #ifndef BITCOIN_UINT256_H 8 : #define BITCOIN_UINT256_H 9 : 10 : #include <crypto/common.h> 11 : #include <span.h> 12 : 13 : #include <algorithm> 14 : #include <array> 15 : #include <cassert> 16 : #include <cstring> 17 : #include <stdint.h> 18 : #include <string> 19 : 20 : /** Template base class for fixed-sized opaque blobs. */ 21 : template<unsigned int BITS> 22 : class base_blob 23 : { 24 : protected: 25 : static constexpr int WIDTH = BITS / 8; 26 : static_assert(BITS % 8 == 0, "base_blob currently only supports whole bytes."); 27 : std::array<uint8_t, WIDTH> m_data; 28 : static_assert(WIDTH == sizeof(m_data), "Sanity check"); 29 : 30 : public: 31 : /* construct 0 value by default */ 32 3457944957 : constexpr base_blob() : m_data() {} 33 : 34 : /* constructor for constants between 1 and 255 */ 35 34153 : constexpr explicit base_blob(uint8_t v) : m_data{v} {} 36 : 37 3444889 : constexpr explicit base_blob(Span<const unsigned char> vch) 38 : { 39 3444889 : assert(vch.size() == WIDTH); 40 3444889 : std::copy(vch.begin(), vch.end(), m_data.begin()); 41 3444889 : } 42 : 43 46749293 : constexpr bool IsNull() const 44 : { 45 715741227 : return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) { 46 668991934 : return val == 0; 47 : }); 48 : } 49 : 50 15088937 : constexpr void SetNull() 51 : { 52 15088937 : std::fill(m_data.begin(), m_data.end(), 0); 53 15088937 : } 54 : 55 740071231 : constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); } 56 : 57 158335283 : friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } 58 5718050 : friend constexpr bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; } 59 216695795 : friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } 60 : 61 : std::string GetHex() const; 62 : void SetHex(const char* psz); 63 : void SetHex(const std::string& str); 64 : std::string ToString() const; 65 : 66 3595264 : constexpr const unsigned char* data() const { return m_data.data(); } 67 18814810 : constexpr unsigned char* data() { return m_data.data(); } 68 : 69 34074469 : constexpr unsigned char* begin() { return m_data.data(); } 70 420203 : constexpr unsigned char* end() { return m_data.data() + WIDTH; } 71 : 72 100905954 : constexpr const unsigned char* begin() const { return m_data.data(); } 73 976776 : constexpr const unsigned char* end() const { return m_data.data() + WIDTH; } 74 : 75 24145587 : static constexpr unsigned int size() { return WIDTH; } 76 : 77 1015392818 : constexpr uint64_t GetUint64(int pos) const { return ReadLE64(m_data.data() + pos * 8); } 78 : 79 : template<typename Stream> 80 71688202 : void Serialize(Stream& s) const 81 : { 82 71688202 : s.write(MakeByteSpan(m_data)); 83 71688202 : } 84 : 85 : template<typename Stream> 86 10731880 : void Unserialize(Stream& s) 87 : { 88 10731880 : s.read(MakeWritableByteSpan(m_data)); 89 10731880 : } 90 : }; 91 : 92 : /** 160-bit opaque blob. 93 : * @note This type is called uint160 for historical reasons only. It is an opaque 94 : * blob of 160 bits and has no integer operations. 95 : */ 96 : class uint160 : public base_blob<160> { 97 : public: 98 18933138 : constexpr uint160() = default; 99 6832516 : constexpr explicit uint160(Span<const unsigned char> vch) : base_blob<160>(vch) {} 100 : }; 101 : 102 : /** 256-bit opaque blob. 103 : * @note This type is called uint256 for historical reasons only. It is an 104 : * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if 105 : * those are required. 106 : */ 107 : class uint256 : public base_blob<256> { 108 : public: 109 6755446475 : constexpr uint256() = default; 110 68306 : constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {} 111 57262 : constexpr explicit uint256(Span<const unsigned char> vch) : base_blob<256>(vch) {} 112 : static const uint256 ZERO; 113 : static const uint256 ONE; 114 : static const uint256 TWO; 115 : }; 116 : 117 : /* uint256 from const char *. 118 : * This is a separate function because the constructor uint256(const char*) can result 119 : * in dangerously catching uint256(0). 120 : */ 121 395475 : inline uint256 uint256S(const char *str) 122 : { 123 395475 : uint256 rv; 124 395475 : rv.SetHex(str); 125 395475 : return rv; 126 : } 127 : /* uint256 from std::string. 128 : * This is a separate function because the constructor uint256(const std::string &str) can result 129 : * in dangerously catching uint256(0) via std::string(const char*). 130 : */ 131 77233 : inline uint256 uint256S(const std::string& str) 132 : { 133 77233 : uint256 rv; 134 77233 : rv.SetHex(str); 135 77233 : return rv; 136 : } 137 : 138 : /** 512-bit unsigned big integer. */ 139 : class uint512 : public base_blob<512> { 140 : public: 141 137270930 : constexpr uint512() = default; 142 : constexpr uint512(const base_blob<512>& b) : base_blob<512>(b) {} 143 : constexpr explicit uint512(Span<unsigned char> vch) : base_blob<512>(vch) {} 144 : 145 6239864 : uint256 trim256() const 146 : { 147 6239864 : uint256 result; 148 6239864 : memcpy((void*)&result, (void*)m_data.data(), 32); 149 6239864 : return result; 150 : } 151 : }; 152 : 153 : 154 : #endif // BITCOIN_UINT256_H