Line | Count | Source |
1 | | // Copyright (c) 2009-2010 Satoshi Nakamoto |
2 | | // Copyright (c) 2009-present 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 | 28.1M | void Finalize(std::span<unsigned char> output) { |
31 | 28.1M | assert(output.size() == OUTPUT_SIZE); Branch (31:9): [True: 28.1M, False: 0]
|
32 | 28.1M | unsigned char buf[CSHA256::OUTPUT_SIZE]; |
33 | 28.1M | sha.Finalize(buf); |
34 | 28.1M | sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data()); |
35 | 28.1M | } |
36 | | |
37 | 32.5M | CHash256& Write(std::span<const unsigned char> input) { |
38 | 32.5M | sha.Write(input.data(), input.size()); |
39 | 32.5M | return *this; |
40 | 32.5M | } |
41 | | |
42 | 5.61M | CHash256& Reset() { |
43 | 5.61M | sha.Reset(); |
44 | 5.61M | return *this; |
45 | 5.61M | } |
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 | 5.47M | void Finalize(std::span<unsigned char> output) { |
56 | 5.47M | assert(output.size() == OUTPUT_SIZE); Branch (56:9): [True: 5.47M, False: 0]
|
57 | 5.47M | unsigned char buf[CSHA256::OUTPUT_SIZE]; |
58 | 5.47M | sha.Finalize(buf); |
59 | 5.47M | CRIPEMD160().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(output.data()); |
60 | 5.47M | } |
61 | | |
62 | 5.47M | CHash160& Write(std::span<const unsigned char> input) { |
63 | 5.47M | sha.Write(input.data(), input.size()); |
64 | 5.47M | return *this; |
65 | 5.47M | } |
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 | 18.1M | { |
77 | 18.1M | uint256 result; |
78 | 18.1M | CHash256().Write(MakeUCharSpan(in1)).Finalize(result); |
79 | 18.1M | return result; |
80 | 18.1M | } Unexecuted instantiation: uint256 Hash<std::span<unsigned char const, 18446744073709551615ul> >(std::span<unsigned char const, 18446744073709551615ul> const&) uint256 Hash<std::vector<unsigned char, std::allocator<unsigned char> > >(std::vector<unsigned char, std::allocator<unsigned char> > const&) Line | Count | Source | 76 | 17.9M | { | 77 | 17.9M | uint256 result; | 78 | 17.9M | CHash256().Write(MakeUCharSpan(in1)).Finalize(result); | 79 | 17.9M | return result; | 80 | 17.9M | } |
uint256 Hash<std::span<unsigned char, 18446744073709551615ul> >(std::span<unsigned char, 18446744073709551615ul> const&) Line | Count | Source | 76 | 177k | { | 77 | 177k | uint256 result; | 78 | 177k | CHash256().Write(MakeUCharSpan(in1)).Finalize(result); | 79 | 177k | return result; | 80 | 177k | } |
|
81 | | |
82 | | /** Compute the 256-bit hash of the concatenation of two objects. */ |
83 | | template<typename T1, typename T2> |
84 | 2.25M | inline uint256 Hash(const T1& in1, const T2& in2) { |
85 | 2.25M | uint256 result; |
86 | 2.25M | CHash256().Write(MakeUCharSpan(in1)).Write(MakeUCharSpan(in2)).Finalize(result); |
87 | 2.25M | return result; |
88 | 2.25M | } uint256 Hash<uint256, uint256>(uint256 const&, uint256 const&) Line | Count | Source | 84 | 2.23M | inline uint256 Hash(const T1& in1, const T2& in2) { | 85 | 2.23M | uint256 result; | 86 | 2.23M | CHash256().Write(MakeUCharSpan(in1)).Write(MakeUCharSpan(in2)).Finalize(result); | 87 | 2.23M | return result; | 88 | 2.23M | } |
uint256 Hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned char [8]>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned char const (&) [8]) Line | Count | Source | 84 | 22.1k | inline uint256 Hash(const T1& in1, const T2& in2) { | 85 | 22.1k | uint256 result; | 86 | 22.1k | CHash256().Write(MakeUCharSpan(in1)).Write(MakeUCharSpan(in2)).Finalize(result); | 87 | 22.1k | return result; | 88 | 22.1k | } |
|
89 | | |
90 | | /** Compute the 160-bit hash an object. */ |
91 | | template<typename T1> |
92 | | inline uint160 Hash160(const T1& in1) |
93 | 5.45M | { |
94 | 5.45M | uint160 result; |
95 | 5.45M | CHash160().Write(MakeUCharSpan(in1)).Finalize(result); |
96 | 5.45M | return result; |
97 | 5.45M | } uint160 Hash160<std::span<unsigned char const, 18446744073709551615ul> >(std::span<unsigned char const, 18446744073709551615ul> const&) Line | Count | Source | 93 | 5.01M | { | 94 | 5.01M | uint160 result; | 95 | 5.01M | CHash160().Write(MakeUCharSpan(in1)).Finalize(result); | 96 | 5.01M | return result; | 97 | 5.01M | } |
Unexecuted instantiation: uint160 Hash160<std::vector<unsigned char, std::allocator<unsigned char> > >(std::vector<unsigned char, std::allocator<unsigned char> > const&) uint160 Hash160<CScript>(CScript const&) Line | Count | Source | 93 | 443k | { | 94 | 443k | uint160 result; | 95 | 443k | CHash160().Write(MakeUCharSpan(in1)).Finalize(result); | 96 | 443k | return result; | 97 | 443k | } |
Unexecuted instantiation: uint160 Hash160<XOnlyPubKey>(XOnlyPubKey const&) |
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(std::span<const std::byte> src) |
107 | 347M | { |
108 | 347M | ctx.Write(UCharCast(src.data()), src.size()); |
109 | 347M | } |
110 | | |
111 | | /** Compute the double-SHA256 hash of all data written to this object. |
112 | | * |
113 | | * Invalidates this object. |
114 | | */ |
115 | 46.3M | uint256 GetHash() { |
116 | 46.3M | uint256 result; |
117 | 46.3M | ctx.Finalize(result.begin()); |
118 | 46.3M | ctx.Reset().Write(result.begin(), CSHA256::OUTPUT_SIZE).Finalize(result.begin()); |
119 | 46.3M | return result; |
120 | 46.3M | } |
121 | | |
122 | | /** Compute the SHA256 hash of all data written to this object. |
123 | | * |
124 | | * Invalidates this object. |
125 | | */ |
126 | 402k | uint256 GetSHA256() { |
127 | 402k | uint256 result; |
128 | 402k | ctx.Finalize(result.begin()); |
129 | 402k | return result; |
130 | 402k | } |
131 | | |
132 | | /** |
133 | | * Returns the first 64 bits from the resulting hash. |
134 | | */ |
135 | 15.1k | inline uint64_t GetCheapHash() { |
136 | 15.1k | uint256 result = GetHash(); |
137 | 15.1k | return ReadLE64(result.begin()); |
138 | 15.1k | } |
139 | | |
140 | | template <typename T> |
141 | | HashWriter& operator<<(const T& obj) |
142 | 126M | { |
143 | 126M | ::Serialize(*this, obj); |
144 | 126M | return *this; |
145 | 126M | } Unexecuted instantiation: HashWriter& HashWriter::operator<< <std::vector<bool, std::allocator<bool> > >(std::vector<bool, std::allocator<bool> > const&) HashWriter& HashWriter::operator<< <uint256>(uint256 const&) Line | Count | Source | 142 | 4.80M | { | 143 | 4.80M | ::Serialize(*this, obj); | 144 | 4.80M | return *this; | 145 | 4.80M | } |
HashWriter& HashWriter::operator<< <std::span<unsigned char const, 32ul> >(std::span<unsigned char const, 32ul> const&) Line | Count | Source | 142 | 76.9M | { | 143 | 76.9M | ::Serialize(*this, obj); | 144 | 76.9M | return *this; | 145 | 76.9M | } |
HashWriter& HashWriter::operator<< <CBlockUndo>(CBlockUndo const&) Line | Count | Source | 142 | 2.22M | { | 143 | 2.22M | ::Serialize(*this, obj); | 144 | 2.22M | return *this; | 145 | 2.22M | } |
HashWriter& HashWriter::operator<< <Wrapper<VarIntFormatter<(VarIntMode)0>, unsigned long&> >(Wrapper<VarIntFormatter<(VarIntMode)0>, unsigned long&> const&) Line | Count | Source | 142 | 12.0k | { | 143 | 12.0k | ::Serialize(*this, obj); | 144 | 12.0k | return *this; | 145 | 12.0k | } |
HashWriter& HashWriter::operator<< <std::span<unsigned char, 18446744073709551615ul> >(std::span<unsigned char, 18446744073709551615ul> const&) Line | Count | Source | 142 | 166 | { | 143 | 166 | ::Serialize(*this, obj); | 144 | 166 | return *this; | 145 | 166 | } |
HashWriter& HashWriter::operator<< <Wrapper<VarIntFormatter<(VarIntMode)0>, unsigned int&> >(Wrapper<VarIntFormatter<(VarIntMode)0>, unsigned int&> const&) Line | Count | Source | 142 | 11.8k | { | 143 | 11.8k | ::Serialize(*this, obj); | 144 | 11.8k | return *this; | 145 | 11.8k | } |
HashWriter& HashWriter::operator<< <std::span<unsigned char const, 18446744073709551615ul> >(std::span<unsigned char const, 18446744073709551615ul> const&) Line | Count | Source | 142 | 11.8k | { | 143 | 11.8k | ::Serialize(*this, obj); | 144 | 11.8k | return *this; | 145 | 11.8k | } |
HashWriter& HashWriter::operator<< <unsigned long>(unsigned long const&) Line | Count | Source | 142 | 5.03k | { | 143 | 5.03k | ::Serialize(*this, obj); | 144 | 5.03k | return *this; | 145 | 5.03k | } |
HashWriter& HashWriter::operator<< <transaction_identifier<true> >(transaction_identifier<true> const&) Line | Count | Source | 142 | 10.6k | { | 143 | 10.6k | ::Serialize(*this, obj); | 144 | 10.6k | return *this; | 145 | 10.6k | } |
HashWriter& HashWriter::operator<< <std::vector<unsigned char, std::allocator<unsigned char> > >(std::vector<unsigned char, std::allocator<unsigned char> > const&) Line | Count | Source | 142 | 31.2k | { | 143 | 31.2k | ::Serialize(*this, obj); | 144 | 31.2k | return *this; | 145 | 31.2k | } |
HashWriter& HashWriter::operator<< <unsigned char>(unsigned char const&) Line | Count | Source | 142 | 5.03k | { | 143 | 5.03k | ::Serialize(*this, obj); | 144 | 5.03k | return *this; | 145 | 5.03k | } |
HashWriter& HashWriter::operator<< <int>(int const&) Line | Count | Source | 142 | 5.03k | { | 143 | 5.03k | ::Serialize(*this, obj); | 144 | 5.03k | return *this; | 145 | 5.03k | } |
HashWriter& HashWriter::operator<< <COutPoint>(COutPoint const&) Line | Count | Source | 142 | 62.7k | { | 143 | 62.7k | ::Serialize(*this, obj); | 144 | 62.7k | return *this; | 145 | 62.7k | } |
HashWriter& HashWriter::operator<< <unsigned int>(unsigned int const&) Line | Count | Source | 142 | 62.7k | { | 143 | 62.7k | ::Serialize(*this, obj); | 144 | 62.7k | return *this; | 145 | 62.7k | } |
HashWriter& HashWriter::operator<< <CTxOut>(CTxOut const&) Line | Count | Source | 142 | 67.1k | { | 143 | 67.1k | ::Serialize(*this, obj); | 144 | 67.1k | return *this; | 145 | 67.1k | } |
Unexecuted instantiation: HashWriter& HashWriter::operator<< <std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) HashWriter& HashWriter::operator<< <CBlockHeader>(CBlockHeader const&) Line | Count | Source | 142 | 36.0M | { | 143 | 36.0M | ::Serialize(*this, obj); | 144 | 36.0M | return *this; | 145 | 36.0M | } |
Unexecuted instantiation: HashWriter& HashWriter::operator<< <ParamsWrapper<TransactionSerParams, CMutableTransaction const> >(ParamsWrapper<TransactionSerParams, CMutableTransaction const> const&) HashWriter& HashWriter::operator<< <ParamsWrapper<TransactionSerParams, CTransaction const> >(ParamsWrapper<TransactionSerParams, CTransaction const> const&) Line | Count | Source | 142 | 5.82M | { | 143 | 5.82M | ::Serialize(*this, obj); | 144 | 5.82M | return *this; | 145 | 5.82M | } |
Unexecuted instantiation: HashWriter& HashWriter::operator<< <long>(long const&) Unexecuted instantiation: HashWriter& HashWriter::operator<< <CScript>(CScript const&) Unexecuted instantiation: interpreter.cpp:HashWriter& HashWriter::operator<< <(anonymous namespace)::CTransactionSignatureSerializer<CTransaction> >((anonymous namespace)::CTransactionSignatureSerializer<CTransaction> const&) Unexecuted instantiation: interpreter.cpp:HashWriter& HashWriter::operator<< <(anonymous namespace)::CTransactionSignatureSerializer<CMutableTransaction> >((anonymous namespace)::CTransactionSignatureSerializer<CMutableTransaction> const&) Unexecuted instantiation: HashWriter& HashWriter::operator<< <CompactSizeWriter>(CompactSizeWriter const&) Unexecuted instantiation: HashWriter& HashWriter::operator<< <unsigned char [384]>(unsigned char const (&) [384]) |
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 | 2.22M | explicit HashVerifier(Source& source LIFETIMEBOUND) : m_source{source} {} HashVerifier<BufferedReader<AutoFile> >::HashVerifier(BufferedReader<AutoFile>&) Line | Count | Source | 156 | 2.22M | explicit HashVerifier(Source& source LIFETIMEBOUND) : m_source{source} {} |
Unexecuted instantiation: HashVerifier<DataStream>::HashVerifier(DataStream&) Unexecuted instantiation: HashVerifier<AutoFile>::HashVerifier(AutoFile&) |
157 | | |
158 | | void read(std::span<std::byte> dst) |
159 | 2.45M | { |
160 | 2.45M | m_source.read(dst); |
161 | 2.45M | this->write(dst); |
162 | 2.45M | } HashVerifier<BufferedReader<AutoFile> >::read(std::span<std::byte, 18446744073709551615ul>) Line | Count | Source | 159 | 2.45M | { | 160 | 2.45M | m_source.read(dst); | 161 | 2.45M | this->write(dst); | 162 | 2.45M | } |
Unexecuted instantiation: HashVerifier<DataStream>::read(std::span<std::byte, 18446744073709551615ul>) Unexecuted instantiation: HashVerifier<AutoFile>::read(std::span<std::byte, 18446744073709551615ul>) |
163 | | |
164 | | void ignore(size_t num_bytes) |
165 | 0 | { |
166 | 0 | std::byte data[1024]; |
167 | 0 | while (num_bytes > 0) { Branch (167:16): [True: 0, False: 0]
Branch (167:16): [True: 0, False: 0]
Branch (167:16): [True: 0, False: 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: HashVerifier<BufferedReader<AutoFile> >::ignore(unsigned long) Unexecuted instantiation: HashVerifier<AutoFile>::ignore(unsigned long) Unexecuted instantiation: HashVerifier<DataStream>::ignore(unsigned long) |
173 | | |
174 | | template <typename T> |
175 | | HashVerifier<Source>& operator>>(T&& obj) |
176 | 2.31M | { |
177 | 2.31M | ::Unserialize(*this, obj); |
178 | 2.31M | return *this; |
179 | 2.31M | } HashVerifier<BufferedReader<AutoFile> >& HashVerifier<BufferedReader<AutoFile> >::operator>><CBlockUndo&>(CBlockUndo&) Line | Count | Source | 176 | 2.22M | { | 177 | 2.22M | ::Unserialize(*this, obj); | 178 | 2.22M | return *this; | 179 | 2.22M | } |
HashVerifier<BufferedReader<AutoFile> >& HashVerifier<BufferedReader<AutoFile> >::operator>><Wrapper<VarIntFormatter<(VarIntMode)0>, unsigned long&> >(Wrapper<VarIntFormatter<(VarIntMode)0>, unsigned long&>&&) Line | Count | Source | 176 | 29.5k | { | 177 | 29.5k | ::Unserialize(*this, obj); | 178 | 29.5k | return *this; | 179 | 29.5k | } |
HashVerifier<BufferedReader<AutoFile> >& HashVerifier<BufferedReader<AutoFile> >::operator>><Wrapper<VarIntFormatter<(VarIntMode)0>, unsigned int&> >(Wrapper<VarIntFormatter<(VarIntMode)0>, unsigned int&>&&) Line | Count | Source | 176 | 29.5k | { | 177 | 29.5k | ::Unserialize(*this, obj); | 178 | 29.5k | return *this; | 179 | 29.5k | } |
HashVerifier<BufferedReader<AutoFile> >& HashVerifier<BufferedReader<AutoFile> >::operator>><std::span<unsigned char, 18446744073709551615ul> >(std::span<unsigned char, 18446744073709551615ul>&&) Line | Count | Source | 176 | 29.5k | { | 177 | 29.5k | ::Unserialize(*this, obj); | 178 | 29.5k | return *this; | 179 | 29.5k | } |
Unexecuted instantiation: HashVerifier<DataStream>& HashVerifier<DataStream>::operator>><std::array<unsigned char, 4ul>&>(std::array<unsigned char, 4ul>&) Unexecuted instantiation: HashVerifier<DataStream>& HashVerifier<DataStream>::operator>><AddrMan&>(AddrMan&) Unexecuted instantiation: HashVerifier<AutoFile>& HashVerifier<AutoFile>::operator>><std::array<unsigned char, 4ul>&>(std::array<unsigned char, 4ul>&) Unexecuted instantiation: HashVerifier<AutoFile>& HashVerifier<AutoFile>::operator>><AddrMan&>(AddrMan&) Unexecuted instantiation: HashVerifier<AutoFile>& HashVerifier<AutoFile>::operator>><ParamsWrapper<CAddress::SerParams, std::vector<CAddress, std::allocator<CAddress> > >&>(ParamsWrapper<CAddress::SerParams, std::vector<CAddress, std::allocator<CAddress> > >&) Unexecuted instantiation: HashVerifier<AutoFile>& HashVerifier<AutoFile>::operator>><Wrapper<CustomUintFormatter<1, false>, AddrManImpl::Format&> >(Wrapper<CustomUintFormatter<1, false>, AddrManImpl::Format&>&&) Unexecuted instantiation: HashVerifier<DataStream>& HashVerifier<DataStream>::operator>><Wrapper<CustomUintFormatter<1, false>, AddrManImpl::Format&> >(Wrapper<CustomUintFormatter<1, false>, AddrManImpl::Format&>&&) |
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 | 33.2k | explicit HashedSourceWriter(Source& source LIFETIMEBOUND) : HashWriter{}, m_source{source} {} |
191 | | |
192 | | void write(std::span<const std::byte> src) |
193 | 22.9M | { |
194 | 22.9M | m_source.write(src); |
195 | 22.9M | HashWriter::write(src); |
196 | 22.9M | } |
197 | | |
198 | | template <typename T> |
199 | | HashedSourceWriter& operator<<(const T& obj) |
200 | 66.5k | { |
201 | 66.5k | ::Serialize(*this, obj); |
202 | 66.5k | return *this; |
203 | 66.5k | } HashedSourceWriter<AutoFile>& HashedSourceWriter<AutoFile>::operator<< <std::array<unsigned char, 4ul> >(std::array<unsigned char, 4ul> const&) Line | Count | Source | 200 | 33.2k | { | 201 | 33.2k | ::Serialize(*this, obj); | 202 | 33.2k | return *this; | 203 | 33.2k | } |
HashedSourceWriter<AutoFile>& HashedSourceWriter<AutoFile>::operator<< <AddrMan>(AddrMan const&) Line | Count | Source | 200 | 22.1k | { | 201 | 22.1k | ::Serialize(*this, obj); | 202 | 22.1k | return *this; | 203 | 22.1k | } |
HashedSourceWriter<AutoFile>& HashedSourceWriter<AutoFile>::operator<< <ParamsWrapper<CAddress::SerParams, std::vector<CAddress, std::allocator<CAddress> > const> >(ParamsWrapper<CAddress::SerParams, std::vector<CAddress, std::allocator<CAddress> > const> const&) Line | Count | Source | 200 | 11.0k | { | 201 | 11.0k | ::Serialize(*this, obj); | 202 | 11.0k | return *this; | 203 | 11.0k | } |
|
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, std::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(std::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 |