LCOV - code coverage report
Current view: top level - src - hash.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 32 87 36.8 %
Date: 2023-09-26 12:08:55 Functions: 27 83 32.5 %

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

Generated by: LCOV version 1.14