Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto 2 : // Copyright (c) 2009-2021 The Bitcoin developers 3 : // Copyright (c) 2014-2015 The Dash developers 4 : // Copyright (c) 2017-2021 The PIVX Core developers 5 : // Distributed under the MIT software license, see the accompanying 6 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 7 : 8 : #ifndef PIVX_UINT256_H 9 : #define PIVX_UINT256_H 10 : 11 : #include "crypto/common.h" 12 : 13 : #include <assert.h> 14 : #include <cstring> 15 : #include <stdexcept> 16 : #include <stdint.h> 17 : #include <string> 18 : #include <vector> 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 : uint8_t m_data[WIDTH]; 27 : public: 28 : /* construct 0 value by default */ 29 19140737410 : constexpr base_blob() : m_data() {} 30 : 31 : /* constructor for constants between 1 and 255 */ 32 : constexpr explicit base_blob(uint8_t v) : m_data{v} {} 33 : 34 : explicit base_blob(const std::vector<unsigned char>& vch); 35 : 36 48917575 : bool IsNull() const 37 : { 38 252733127 : for (int i = 0; i < WIDTH; i++) 39 247326620 : if (m_data[i] != 0) 40 : return false; 41 : return true; 42 : } 43 : 44 15703543 : void SetNull() 45 : { 46 10930252 : memset(m_data, 0, sizeof(m_data)); 47 62637 : } 48 : 49 1532821288 : inline int Compare(const base_blob& other) const { return memcmp(m_data, other.m_data, sizeof(m_data)); } 50 : 51 304751330 : friend inline bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; } 52 4078308 : friend inline bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; } 53 1205764724 : friend inline bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; } 54 : 55 : std::string GetHex() const; 56 : void SetHex(const char* psz); 57 : void SetHex(const std::string& str); 58 : std::string ToString() const; 59 : 60 : const unsigned char* data() const { return m_data; } 61 2 : unsigned char* data() { return m_data; } 62 : 63 11522179 : unsigned char* begin() 64 : { 65 5443688 : return &m_data[0]; 66 : } 67 : 68 135700 : unsigned char* end() 69 : { 70 120282 : return &m_data[WIDTH]; 71 : } 72 : 73 41103806 : const unsigned char* begin() const 74 : { 75 40985899 : return &m_data[0]; 76 : } 77 : 78 2484062 : const unsigned char* end() const 79 : { 80 2484054 : return &m_data[WIDTH]; 81 : } 82 : 83 504101 : unsigned int size() const 84 : { 85 : return sizeof(m_data); 86 : } 87 : 88 390878000 : uint64_t GetUint64(int pos) const 89 : { 90 390878000 : const uint8_t* ptr = m_data + pos * 8; 91 390878000 : return ((uint64_t)ptr[0]) | \ 92 390878000 : ((uint64_t)ptr[1]) << 8 | \ 93 390878000 : ((uint64_t)ptr[2]) << 16 | \ 94 390878000 : ((uint64_t)ptr[3]) << 24 | \ 95 390878000 : ((uint64_t)ptr[4]) << 32 | \ 96 390878000 : ((uint64_t)ptr[5]) << 40 | \ 97 390878000 : ((uint64_t)ptr[6]) << 48 | \ 98 390878000 : ((uint64_t)ptr[7]) << 56; 99 : } 100 : 101 : template<typename Stream> 102 49046704 : void Serialize(Stream& s) const 103 : { 104 76335067 : s.write((char*)m_data, sizeof(m_data)); 105 : } 106 : 107 : template<typename Stream> 108 10214274 : void Unserialize(Stream& s) 109 : { 110 9806764 : s.read((char*)m_data, sizeof(m_data)); 111 : } 112 : }; 113 : 114 : /** 88-bit opaque blob. 115 : */ 116 : class blob88 : public base_blob<88> { 117 : public: 118 31254 : blob88() {} 119 : explicit blob88(const base_blob<88>& b) : base_blob<88>(b) {} 120 : explicit blob88(const std::vector<unsigned char>& vch) : base_blob<88>(vch) {} 121 : }; 122 : 123 : /** 160-bit opaque blob. 124 : * @note This type is called uint160 for historical reasons only. It is an opaque 125 : * blob of 160 bits and has no integer operations. 126 : */ 127 : class uint160 : public base_blob<160> { 128 : public: 129 32420013 : uint160() {} 130 12545269 : explicit uint160(const std::vector<unsigned char>& vch) : base_blob<160>(vch) {} 131 : }; 132 : 133 : /** 256-bit opaque blob. 134 : * @note This type is called uint256 for historical reasons only. It is an 135 : * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if 136 : * those are required. 137 : */ 138 : class uint256 : public base_blob<256> { 139 : public: 140 1110360783 : uint256() {} 141 7669 : explicit uint256(const std::vector<unsigned char>& vch) : base_blob<256>(vch) {} 142 : 143 : /** A cheap hash function that just returns 64 bits from the result, it can be 144 : * used when the contents are considered uniformly random. It is not appropriate 145 : * when the value can easily be influenced from outside as e.g. a network adversary could 146 : * provide values to trigger worst-case behavior. 147 : * @note The result of this function is not stable between little and big endian. 148 : */ 149 13343183 : uint64_t GetCheapHash() const { return ReadLE64(begin()); } 150 : 151 : }; 152 : 153 : /* uint256 from const char *. 154 : * This is a separate function because the constructor uint256(const char*) can result 155 : * in dangerously catching UINT256_ZERO. 156 : */ 157 8360 : inline uint256 uint256S(const char* str) 158 : { 159 8360 : uint256 rv; 160 8360 : rv.SetHex(str); 161 8356 : return rv; 162 : } 163 : /* uint256 from std::string. 164 : * This is a separate function because the constructor uint256(const std::string &str) can result 165 : * in dangerously catching UINT256_ZERO via std::string(const char*). 166 : */ 167 7371 : inline uint256 uint256S(const std::string& str) 168 : { 169 7371 : uint256 rv; 170 7371 : rv.SetHex(str); 171 7378 : return rv; 172 : } 173 : 174 : /** constant uint256 instances */ 175 : const uint256 UINT256_ZERO = uint256(); 176 : const uint256 UINT256_ONE = uint256S("0000000000000000000000000000000000000000000000000000000000000001"); 177 : const uint256 UINT256_MAX = uint256S("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); 178 : 179 : /** 512-bit opaque blob. 180 : * @note This type is called uint256 for historical reasons only. It is an 181 : * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if 182 : * those are required. 183 : */ 184 : class uint512 : public base_blob<512> { 185 : public: 186 4 : uint512() {} 187 : explicit uint512(const base_blob<512>& b) : base_blob<512>(b) {} 188 : explicit uint512(const std::vector<unsigned char>& vch) : base_blob<512>(vch) {} 189 : }; 190 : 191 : /* uint512 from const char *. 192 : * This is a separate function because the constructor uint512(const char*) can result 193 : * in dangerously catching uint512(0). 194 : */ 195 : inline uint512 uint512S(const char* str) 196 : { 197 : uint512 rv; 198 : rv.SetHex(str); 199 : return rv; 200 : } 201 : /* uint512 from std::string. 202 : * This is a separate function because the constructor uint512(const std::string &str) can result 203 : * in dangerously catching uint512(0) via std::string(const char*). 204 : */ 205 0 : inline uint512 uint512S(const std::string& str) 206 : { 207 0 : uint512 rv; 208 0 : rv.SetHex(str); 209 0 : return rv; 210 : } 211 : 212 : namespace std { 213 : template <> 214 : struct hash<uint256> 215 : { 216 826402 : std::size_t operator()(const uint256& k) const 217 : { 218 826402 : return (std::size_t)k.GetCheapHash(); 219 : } 220 : }; 221 : } 222 : 223 : #endif // PIVX_UINT256_H