hasher.h raw

   1  // Copyright (c) 2019-present The Bitcoin Core developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #ifndef BITCOIN_UTIL_HASHER_H
   6  #define BITCOIN_UTIL_HASHER_H
   7  
   8  #include <crypto/common.h>
   9  #include <crypto/siphash.h>
  10  #include <primitives/transaction.h>
  11  #include <uint256.h>
  12  
  13  #include <cstdint>
  14  #include <cstring>
  15  #include <span>
  16  
  17  class SaltedUint256Hasher
  18  {
  19      const PresaltedSipHasher m_hasher;
  20  
  21  public:
  22      SaltedUint256Hasher();
  23  
  24      size_t operator()(const uint256& hash) const
  25      {
  26          return m_hasher(hash);
  27      }
  28  };
  29  
  30  class SaltedTxidHasher
  31  {
  32      const PresaltedSipHasher m_hasher;
  33  
  34  public:
  35      SaltedTxidHasher();
  36  
  37      size_t operator()(const Txid& txid) const
  38      {
  39          return m_hasher(txid.ToUint256());
  40      }
  41  };
  42  
  43  class SaltedWtxidHasher
  44  {
  45      const PresaltedSipHasher m_hasher;
  46  
  47  public:
  48      SaltedWtxidHasher();
  49  
  50      size_t operator()(const Wtxid& wtxid) const
  51      {
  52          return m_hasher(wtxid.ToUint256());
  53      }
  54  };
  55  
  56  class SaltedOutpointHasher
  57  {
  58      const PresaltedSipHasher m_hasher;
  59  
  60  public:
  61      SaltedOutpointHasher(bool deterministic = false);
  62  
  63      /**
  64       * Having the hash noexcept allows libstdc++'s unordered_map to recalculate
  65       * the hash during rehash, so it does not have to cache the value. This
  66       * reduces node's memory by sizeof(size_t). The required recalculation has
  67       * a slight performance penalty (around 1.6%), but this is compensated by
  68       * memory savings of about 9% which allow for a larger dbcache setting.
  69       *
  70       * @see https://gcc.gnu.org/onlinedocs/gcc-13.2.0/libstdc++/manual/manual/unordered_associative.html
  71       */
  72      size_t operator()(const COutPoint& id) const noexcept
  73      {
  74          return m_hasher(id.hash.ToUint256(), id.n);
  75      }
  76  };
  77  
  78  /**
  79   * We're hashing a nonce into the entries themselves, so we don't need extra
  80   * blinding in the set hash computation.
  81   *
  82   * This may exhibit platform endian dependent behavior but because these are
  83   * nonced hashes (random) and this state is only ever used locally it is safe.
  84   * All that matters is local consistency.
  85   */
  86  class SignatureCacheHasher
  87  {
  88  public:
  89      template <uint8_t hash_select>
  90      uint32_t operator()(const uint256& key) const
  91      {
  92          static_assert(hash_select <8, "SignatureCacheHasher only has 8 hashes available.");
  93          uint32_t u;
  94          std::memcpy(&u, key.begin()+4*hash_select, 4);
  95          return u;
  96      }
  97  };
  98  
  99  struct BlockHasher
 100  {
 101      // this used to call `GetCheapHash()` in uint256, which was later moved; the
 102      // cheap hash function simply calls ReadLE64() however, so the end result is
 103      // identical
 104      size_t operator()(const uint256& hash) const { return ReadLE64(hash.begin()); }
 105  };
 106  
 107  class SaltedSipHasher
 108  {
 109  private:
 110      /** Salt */
 111      const uint64_t m_k0, m_k1;
 112  
 113  public:
 114      SaltedSipHasher();
 115  
 116      size_t operator()(const std::span<const unsigned char>& script) const;
 117  };
 118  
 119  #endif // BITCOIN_UTIL_HASHER_H
 120