hash.h raw

   1  // Copyright (c) 2009-2010 Satoshi Nakamoto
   2  // Copyright (c) 2009-2022 The Limenka 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 LIMENKA_HASH_H
   7  #define LIMENKA_HASH_H
   8  
   9  #include <attributes.h>
  10  #include <crypto/common.h>
  11  #include <crypto/ripemd160.h>
  12  #include <crypto/sha256.h>
  13  #include <prevector.h>
  14  #include <serialize.h>
  15  #include <span.h>
  16  #include <uint256.h>
  17  
  18  #include <string>
  19  #include <vector>
  20  
  21  typedef uint256 ChainCode;
  22  
  23  /** A hasher class for Limenka's 256-bit hash (double SHA-256). */
  24  class CHash256 {
  25  private:
  26      CSHA256 sha;
  27  public:
  28      static const size_t OUTPUT_SIZE = CSHA256::OUTPUT_SIZE;
  29  
  30      void Finalize(Span<unsigned char> output) {
  31          assert(output.size() == OUTPUT_SIZE);
  32          unsigned char buf[CSHA256::OUTPUT_SIZE];
  33          sha.Finalize(buf);
  34          sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data());
  35      }
  36  
  37      CHash256& Write(Span<const unsigned char> input) {
  38          sha.Write(input.data(), input.size());
  39          return *this;
  40      }
  41  
  42      CHash256& Reset() {
  43          sha.Reset();
  44          return *this;
  45      }
  46  };
  47  
  48  /** A hasher class for Limenka's 160-bit hash (SHA-256 + RIPEMD-160). */
  49  class CHash160 {
  50  private:
  51      CSHA256 sha;
  52  public:
  53      static const size_t OUTPUT_SIZE = CRIPEMD160::OUTPUT_SIZE;
  54  
  55      void Finalize(Span<unsigned char> output) {
  56          assert(output.size() == OUTPUT_SIZE);
  57          unsigned char buf[CSHA256::OUTPUT_SIZE];
  58          sha.Finalize(buf);
  59          CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data());
  60      }
  61  
  62      CHash160& Write(Span<const unsigned char> input) {
  63          sha.Write(input.data(), input.size());
  64          return *this;
  65      }
  66  
  67      CHash160& Reset() {
  68          sha.Reset();
  69          return *this;
  70      }
  71  };
  72  
  73  /** Compute the 256-bit hash of an object. */
  74  template<typename T>
  75  inline uint256 Hash(const T& in1)
  76  {
  77      uint256 result;
  78      CHash256().Write(MakeUCharSpan(in1)).Finalize(result);
  79      return result;
  80  }
  81  
  82  /** Compute the 256-bit hash of the concatenation of two objects. */
  83  template<typename T1, typename T2>
  84  inline uint256 Hash(const T1& in1, const T2& in2) {
  85      uint256 result;
  86      CHash256().Write(MakeUCharSpan(in1)).Write(MakeUCharSpan(in2)).Finalize(result);
  87      return result;
  88  }
  89  
  90  /** Compute the 160-bit hash an object. */
  91  template<typename T1>
  92  inline uint160 Hash160(const T1& in1)
  93  {
  94      uint160 result;
  95      CHash160().Write(MakeUCharSpan(in1)).Finalize(result);
  96      return result;
  97  }
  98  
  99  /** A writer stream (for serialization) that computes a 256-bit hash. */
 100  class HashWriter
 101  {
 102  private:
 103      CSHA256 ctx;
 104  
 105  public:
 106      void write(Span<const std::byte> src)
 107      {
 108          ctx.Write(UCharCast(src.data()), src.size());
 109      }
 110  
 111      /** Compute the double-SHA256 hash of all data written to this object.
 112       *
 113       * Invalidates this object.
 114       */
 115      uint256 GetHash() {
 116          uint256 result;
 117          ctx.Finalize(result.begin());
 118          ctx.Reset().Write(result.begin(), CSHA256::OUTPUT_SIZE).Finalize(result.begin());
 119          return result;
 120      }
 121  
 122      /** Compute the SHA256 hash of all data written to this object.
 123       *
 124       * Invalidates this object.
 125       */
 126      uint256 GetSHA256() {
 127          uint256 result;
 128          ctx.Finalize(result.begin());
 129          return result;
 130      }
 131  
 132      /**
 133       * Returns the first 64 bits from the resulting hash.
 134       */
 135      inline uint64_t GetCheapHash() {
 136          uint256 result = GetHash();
 137          return ReadLE64(result.begin());
 138      }
 139  
 140      template <typename T>
 141      HashWriter& operator<<(const T& obj)
 142      {
 143          ::Serialize(*this, obj);
 144          return *this;
 145      }
 146  };
 147  
 148  /** Reads data from an underlying stream, while hashing the read data. */
 149  template <typename Source>
 150  class HashVerifier : public HashWriter
 151  {
 152  private:
 153      Source& m_source;
 154  
 155  public:
 156      explicit HashVerifier(Source& source LIFETIMEBOUND) : m_source{source} {}
 157  
 158      void read(Span<std::byte> dst)
 159      {
 160          m_source.read(dst);
 161          this->write(dst);
 162      }
 163  
 164      void ignore(size_t num_bytes)
 165      {
 166          std::byte data[1024];
 167          while (num_bytes > 0) {
 168              size_t now = std::min<size_t>(num_bytes, 1024);
 169              read({data, now});
 170              num_bytes -= now;
 171          }
 172      }
 173  
 174      template <typename T>
 175      HashVerifier<Source>& operator>>(T&& obj)
 176      {
 177          ::Unserialize(*this, obj);
 178          return *this;
 179      }
 180  };
 181  
 182  /** Writes data to an underlying source stream, while hashing the written data. */
 183  template <typename Source>
 184  class HashedSourceWriter : public HashWriter
 185  {
 186  private:
 187      Source& m_source;
 188  
 189  public:
 190      explicit HashedSourceWriter(Source& source LIFETIMEBOUND) : HashWriter{}, m_source{source} {}
 191  
 192      void write(Span<const std::byte> src)
 193      {
 194          m_source.write(src);
 195          HashWriter::write(src);
 196      }
 197  
 198      template <typename T>
 199      HashedSourceWriter& operator<<(const T& obj)
 200      {
 201          ::Serialize(*this, obj);
 202          return *this;
 203      }
 204  };
 205  
 206  /** Single-SHA256 a 32-byte input (represented as uint256). */
 207  [[nodiscard]] uint256 SHA256Uint256(const uint256& input);
 208  
 209  unsigned int MurmurHash3(unsigned int nHashSeed, Span<const unsigned char> vDataToHash);
 210  
 211  void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
 212  
 213  /** Return a HashWriter primed for tagged hashes (as specified in BIP 340).
 214   *
 215   * The returned object will have SHA256(tag) written to it twice (= 64 bytes).
 216   * A tagged hash can be computed by feeding the message into this object, and
 217   * then calling HashWriter::GetSHA256().
 218   */
 219  HashWriter TaggedHash(const std::string& tag);
 220  
 221  /** Compute the 160-bit RIPEMD-160 hash of an array. */
 222  inline uint160 RIPEMD160(Span<const unsigned char> data)
 223  {
 224      uint160 result;
 225      CRIPEMD160().Write(data.data(), data.size()).Finalize(result.begin());
 226      return result;
 227  }
 228  
 229  #endif // LIMENKA_HASH_H
 230