/ src / uint256.h
uint256.h
  1  // Copyright (c) 2009-2010 Satoshi Nakamoto
  2  // Copyright (c) 2009-2022 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  
 12  #include <algorithm>
 13  #include <array>
 14  #include <cassert>
 15  #include <cstring>
 16  #include <stdint.h>
 17  #include <string>
 18  
 19  /** Template base class for fixed-sized opaque blobs. */
 20  template<unsigned int BITS>
 21  class base_blob
 22  {
 23  protected:
 24      static constexpr int WIDTH = BITS / 8;
 25      static_assert(BITS % 8 == 0, "base_blob currently only supports whole bytes.");
 26      std::array<uint8_t, WIDTH> m_data;
 27      static_assert(WIDTH == sizeof(m_data), "Sanity check");
 28  
 29  public:
 30      /* construct 0 value by default */
 31      constexpr base_blob() : m_data() {}
 32  
 33      /* constructor for constants between 1 and 255 */
 34      constexpr explicit base_blob(uint8_t v) : m_data{v} {}
 35  
 36      constexpr explicit base_blob(Span<const unsigned char> vch)
 37      {
 38          assert(vch.size() == WIDTH);
 39          std::copy(vch.begin(), vch.end(), m_data.begin());
 40      }
 41  
 42      constexpr bool IsNull() const
 43      {
 44          return std::all_of(m_data.begin(), m_data.end(), [](uint8_t val) {
 45              return val == 0;
 46          });
 47      }
 48  
 49      constexpr void SetNull()
 50      {
 51          std::fill(m_data.begin(), m_data.end(), 0);
 52      }
 53  
 54      constexpr int Compare(const base_blob& other) const { return std::memcmp(m_data.data(), other.m_data.data(), WIDTH); }
 55  
 56      friend constexpr bool operator==(const base_blob& a, const base_blob& b) { return a.Compare(b) == 0; }
 57      friend constexpr bool operator!=(const base_blob& a, const base_blob& b) { return a.Compare(b) != 0; }
 58      friend constexpr bool operator<(const base_blob& a, const base_blob& b) { return a.Compare(b) < 0; }
 59  
 60      std::string GetHex() const;
 61      void SetHex(const char* psz);
 62      void SetHex(const std::string& str);
 63      std::string ToString() const;
 64  
 65      constexpr const unsigned char* data() const { return m_data.data(); }
 66      constexpr unsigned char* data() { return m_data.data(); }
 67  
 68      constexpr unsigned char* begin() { return m_data.data(); }
 69      constexpr unsigned char* end() { return m_data.data() + WIDTH; }
 70  
 71      constexpr const unsigned char* begin() const { return m_data.data(); }
 72      constexpr const unsigned char* end() const { return m_data.data() + WIDTH; }
 73  
 74      static constexpr unsigned int size() { return WIDTH; }
 75  
 76      constexpr uint64_t GetUint64(int pos) const { return ReadLE64(m_data.data() + pos * 8); }
 77  
 78      template<typename Stream>
 79      void Serialize(Stream& s) const
 80      {
 81          s << Span(m_data);
 82      }
 83  
 84      template<typename Stream>
 85      void Unserialize(Stream& s)
 86      {
 87          s.read(MakeWritableByteSpan(m_data));
 88      }
 89  };
 90  
 91  /** 160-bit opaque blob.
 92   * @note This type is called uint160 for historical reasons only. It is an opaque
 93   * blob of 160 bits and has no integer operations.
 94   */
 95  class uint160 : public base_blob<160> {
 96  public:
 97      constexpr uint160() = default;
 98      constexpr explicit uint160(Span<const unsigned char> vch) : base_blob<160>(vch) {}
 99  };
100  
101  /** 256-bit opaque blob.
102   * @note This type is called uint256 for historical reasons only. It is an
103   * opaque blob of 256 bits and has no integer operations. Use arith_uint256 if
104   * those are required.
105   */
106  class uint256 : public base_blob<256> {
107  public:
108      constexpr uint256() = default;
109      constexpr explicit uint256(uint8_t v) : base_blob<256>(v) {}
110      constexpr explicit uint256(Span<const unsigned char> vch) : base_blob<256>(vch) {}
111      static const uint256 ZERO;
112      static const uint256 ONE;
113  };
114  
115  /* uint256 from const char *.
116   * This is a separate function because the constructor uint256(const char*) can result
117   * in dangerously catching uint256(0).
118   */
119  inline uint256 uint256S(const char *str)
120  {
121      uint256 rv;
122      rv.SetHex(str);
123      return rv;
124  }
125  /* uint256 from std::string.
126   * This is a separate function because the constructor uint256(const std::string &str) can result
127   * in dangerously catching uint256(0) via std::string(const char*).
128   */
129  inline uint256 uint256S(const std::string& str)
130  {
131      uint256 rv;
132      rv.SetHex(str);
133      return rv;
134  }
135  
136  #endif // BITCOIN_UINT256_H