Line | Count | Source (jump to first uncovered line) |
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 | | |
18 | | #include <string> |
19 | | #include <vector> |
20 | | |
21 | | typedef uint256 ChainCode; |
22 | | |
23 | | /** A hasher class for Bitcoin'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 | 0 | void Finalize(Span<unsigned char> output) { |
31 | 0 | assert(output.size() == OUTPUT_SIZE); |
32 | 0 | unsigned char buf[CSHA256::OUTPUT_SIZE]; |
33 | 0 | sha.Finalize(buf); |
34 | 0 | sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data()); |
35 | 0 | } |
36 | | |
37 | 0 | CHash256& Write(Span<const unsigned char> input) { |
38 | 0 | sha.Write(input.data(), input.size()); |
39 | 0 | return *this; |
40 | 0 | } |
41 | | |
42 | 0 | CHash256& Reset() { |
43 | 0 | sha.Reset(); |
44 | 0 | return *this; |
45 | 0 | } |
46 | | }; |
47 | | |
48 | | /** A hasher class for Bitcoin'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 | 0 | void Finalize(Span<unsigned char> output) { |
56 | 0 | assert(output.size() == OUTPUT_SIZE); |
57 | 0 | unsigned char buf[CSHA256::OUTPUT_SIZE]; |
58 | 0 | sha.Finalize(buf); |
59 | 0 | CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data()); |
60 | 0 | } |
61 | | |
62 | 0 | CHash160& Write(Span<const unsigned char> input) { |
63 | 0 | sha.Write(input.data(), input.size()); |
64 | 0 | return *this; |
65 | 0 | } |
66 | | |
67 | 0 | CHash160& Reset() { |
68 | 0 | sha.Reset(); |
69 | 0 | return *this; |
70 | 0 | } |
71 | | }; |
72 | | |
73 | | /** Compute the 256-bit hash of an object. */ |
74 | | template<typename T> |
75 | | inline uint256 Hash(const T& in1) |
76 | 0 | { |
77 | 0 | uint256 result; |
78 | 0 | CHash256().Write(MakeUCharSpan(in1)).Finalize(result); |
79 | 0 | return result; |
80 | 0 | } Unexecuted instantiation: _Z4HashI4SpanIKhEE7uint256RKT_ Unexecuted instantiation: _Z4HashISt6vectorIhSaIhEEE7uint256RKT_ Unexecuted instantiation: _Z4HashISt4spanIKhLm18446744073709551615EEE7uint256RKT_ Unexecuted instantiation: _Z4HashI4SpanIhEE7uint256RKT_ |
81 | | |
82 | | /** Compute the 256-bit hash of the concatenation of two objects. */ |
83 | | template<typename T1, typename T2> |
84 | 0 | inline uint256 Hash(const T1& in1, const T2& in2) { |
85 | 0 | uint256 result; |
86 | 0 | CHash256().Write(MakeUCharSpan(in1)).Write(MakeUCharSpan(in2)).Finalize(result); |
87 | 0 | return result; |
88 | 0 | } Unexecuted instantiation: _Z4HashINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEA8_hE7uint256RKT_RKT0_ Unexecuted instantiation: _Z4HashI7uint256S0_ES0_RKT_RKT0_ |
89 | | |
90 | | /** Compute the 160-bit hash an object. */ |
91 | | template<typename T1> |
92 | | inline uint160 Hash160(const T1& in1) |
93 | 0 | { |
94 | 0 | uint160 result; |
95 | 0 | CHash160().Write(MakeUCharSpan(in1)).Finalize(result); |
96 | 0 | return result; |
97 | 0 | } Unexecuted instantiation: _Z7Hash160I4SpanIKhEE7uint160RKT_ Unexecuted instantiation: _Z7Hash160ISt6vectorIhSaIhEEE7uint160RKT_ Unexecuted instantiation: _Z7Hash160I11XOnlyPubKeyE7uint160RKT_ Unexecuted instantiation: _Z7Hash160I7CPubKeyE7uint160RKT_ Unexecuted instantiation: _Z7Hash160I7CScriptE7uint160RKT_ |
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 | 125M | { |
108 | 125M | ctx.Write(UCharCast(src.data()), src.size()); |
109 | 125M | } |
110 | | |
111 | | /** Compute the double-SHA256 hash of all data written to this object. |
112 | | * |
113 | | * Invalidates this object. |
114 | | */ |
115 | 165k | uint256 GetHash() { |
116 | 165k | uint256 result; |
117 | 165k | ctx.Finalize(result.begin()); |
118 | 165k | ctx.Reset().Write(result.begin(), CSHA256::OUTPUT_SIZE).Finalize(result.begin()); |
119 | 165k | return result; |
120 | 165k | } |
121 | | |
122 | | /** Compute the SHA256 hash of all data written to this object. |
123 | | * |
124 | | * Invalidates this object. |
125 | | */ |
126 | 12.2k | uint256 GetSHA256() { |
127 | 12.2k | uint256 result; |
128 | 12.2k | ctx.Finalize(result.begin()); |
129 | 12.2k | return result; |
130 | 12.2k | } |
131 | | |
132 | | /** |
133 | | * Returns the first 64 bits from the resulting hash. |
134 | | */ |
135 | 0 | inline uint64_t GetCheapHash() { |
136 | 0 | uint256 result = GetHash(); |
137 | 0 | return ReadLE64(result.begin()); |
138 | 0 | } |
139 | | |
140 | | template <typename T> |
141 | | HashWriter& operator<<(const T& obj) |
142 | 214k | { |
143 | 214k | ::Serialize(*this, obj); |
144 | 214k | return *this; |
145 | 214k | } Unexecuted instantiation: _ZN10HashWriterlsIjEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsISt6vectorIhSaIhEEEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI4SpanIcEEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI7uint256EERS_RKT_ _ZN10HashWriterlsI4SpanIKhEEERS_RKT_ Line | Count | Source | 142 | 24.4k | { | 143 | 24.4k | ::Serialize(*this, obj); | 144 | 24.4k | return *this; | 145 | 24.4k | } |
Unexecuted instantiation: _ZN10HashWriterlsImEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsIhEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsIiEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsISt6vectorIbSaIbEEEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI9COutPointEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI6CTxOutEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI10CBlockUndoEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI7WrapperI15VarIntFormatterIL10VarIntMode0EERmEEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI4SpanIhEEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI7WrapperI15VarIntFormatterIL10VarIntMode0EERjEEERS_RKT_ _ZN10HashWriterlsI22transaction_identifierILb1EEEERS_RKT_ Line | Count | Source | 142 | 24.4k | { | 143 | 24.4k | ::Serialize(*this, obj); | 144 | 24.4k | return *this; | 145 | 24.4k | } |
Unexecuted instantiation: _ZN10HashWriterlsI12CBlockHeaderEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI13ParamsWrapperI20TransactionSerParamsK19CMutableTransactionEEERS_RKT_ _ZN10HashWriterlsI13ParamsWrapperI20TransactionSerParamsK12CTransactionEEERS_RKT_ Line | Count | Source | 142 | 165k | { | 143 | 165k | ::Serialize(*this, obj); | 144 | 165k | return *this; | 145 | 165k | } |
Unexecuted instantiation: _ZN10HashWriterlsIlEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI7CScriptEERS_RKT_ Unexecuted instantiation: interpreter.cpp:_ZN10HashWriterlsIN12_GLOBAL__N_131CTransactionSignatureSerializerI12CTransactionEEEERS_RKT_ Unexecuted instantiation: interpreter.cpp:_ZN10HashWriterlsIN12_GLOBAL__N_131CTransactionSignatureSerializerI19CMutableTransactionEEEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsI17CompactSizeWriterEERS_RKT_ Unexecuted instantiation: _ZN10HashWriterlsIA384_hEERS_RKT_ |
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 | 0 | explicit HashVerifier(Source& source LIFETIMEBOUND) : m_source{source} {} Unexecuted instantiation: _ZN12HashVerifierI10DataStreamEC2ERS0_ Unexecuted instantiation: _ZN12HashVerifierI8AutoFileEC2ERS0_ |
157 | | |
158 | | void read(Span<std::byte> dst) |
159 | 0 | { |
160 | 0 | m_source.read(dst); |
161 | 0 | this->write(dst); |
162 | 0 | } Unexecuted instantiation: _ZN12HashVerifierI10DataStreamE4readE4SpanISt4byteE Unexecuted instantiation: _ZN12HashVerifierI8AutoFileE4readE4SpanISt4byteE |
163 | | |
164 | | void ignore(size_t num_bytes) |
165 | 0 | { |
166 | 0 | std::byte data[1024]; |
167 | 0 | while (num_bytes > 0) { |
168 | 0 | size_t now = std::min<size_t>(num_bytes, 1024); |
169 | 0 | read({data, now}); |
170 | 0 | num_bytes -= now; |
171 | 0 | } |
172 | 0 | } Unexecuted instantiation: _ZN12HashVerifierI8AutoFileE6ignoreEm Unexecuted instantiation: _ZN12HashVerifierI10DataStreamE6ignoreEm |
173 | | |
174 | | template <typename T> |
175 | | HashVerifier<Source>& operator>>(T&& obj) |
176 | 0 | { |
177 | 0 | ::Unserialize(*this, obj); |
178 | 0 | return *this; |
179 | 0 | } Unexecuted instantiation: _ZN12HashVerifierI10DataStreamErsIRSt5arrayIhLm4EEEERS1_OT_ Unexecuted instantiation: _ZN12HashVerifierI10DataStreamErsIR7AddrManEERS1_OT_ Unexecuted instantiation: _ZN12HashVerifierI8AutoFileErsIRSt5arrayIhLm4EEEERS1_OT_ Unexecuted instantiation: _ZN12HashVerifierI8AutoFileErsIR7AddrManEERS1_OT_ Unexecuted instantiation: _ZN12HashVerifierI8AutoFileErsIR13ParamsWrapperIN8CAddress9SerParamsESt6vectorIS4_SaIS4_EEEEERS1_OT_ Unexecuted instantiation: _ZN12HashVerifierI8AutoFileErsI7WrapperI19CustomUintFormatterILi1ELb0EERN11AddrManImpl6FormatEEEERS1_OT_ Unexecuted instantiation: _ZN12HashVerifierI10DataStreamErsI7WrapperI19CustomUintFormatterILi1ELb0EERN11AddrManImpl6FormatEEEERS1_OT_ Unexecuted instantiation: _ZN12HashVerifierI8AutoFileErsIR10CBlockUndoEERS1_OT_ Unexecuted instantiation: _ZN12HashVerifierI8AutoFileErsI7WrapperI15VarIntFormatterIL10VarIntMode0EERmEEERS1_OT_ Unexecuted instantiation: _ZN12HashVerifierI8AutoFileErsI7WrapperI15VarIntFormatterIL10VarIntMode0EERjEEERS1_OT_ Unexecuted instantiation: _ZN12HashVerifierI8AutoFileErsI4SpanIhEEERS1_OT_ |
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 | 0 | explicit HashedSourceWriter(Source& source LIFETIMEBOUND) : HashWriter{}, m_source{source} {} |
191 | | |
192 | | void write(Span<const std::byte> src) |
193 | 0 | { |
194 | 0 | m_source.write(src); |
195 | 0 | HashWriter::write(src); |
196 | 0 | } |
197 | | |
198 | | template <typename T> |
199 | | HashedSourceWriter& operator<<(const T& obj) |
200 | 0 | { |
201 | 0 | ::Serialize(*this, obj); |
202 | 0 | return *this; |
203 | 0 | } Unexecuted instantiation: _ZN18HashedSourceWriterI8AutoFileElsISt5arrayIhLm4EEEERS1_RKT_ Unexecuted instantiation: _ZN18HashedSourceWriterI8AutoFileElsI7AddrManEERS1_RKT_ Unexecuted instantiation: _ZN18HashedSourceWriterI8AutoFileElsI13ParamsWrapperIN8CAddress9SerParamsEKSt6vectorIS4_SaIS4_EEEEERS1_RKT_ |
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 | 0 | { |
224 | 0 | uint160 result; |
225 | 0 | CRIPEMD160().Write(data.data(), data.size()).Finalize(result.begin()); |
226 | 0 | return result; |
227 | 0 | } |
228 | | |
229 | | #endif // BITCOIN_HASH_H |