LCOV - code coverage report
Current view: top level - src - hash.h (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 75 81 92.6 %
Date: 2026-06-25 07:23:51 Functions: 112 206 54.4 %

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

Generated by: LCOV version 1.16