aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfanquake <fanquake@gmail.com>2020-08-25 18:02:11 +0800
committerfanquake <fanquake@gmail.com>2020-08-25 20:18:40 +0800
commitf8462a6d2794be728cf8550f45d19a354aae59cf (patch)
treece281795b129468e20c4a13c3394c36a207f7ff8 /src
parent8e0f341779e1d2754432765ec09deb7488f5b093 (diff)
parent9ab4cafabda227ccee5b241d7690fc67f9a27221 (diff)
downloadbitcoin-f8462a6d2794be728cf8550f45d19a354aae59cf.tar.xz
Merge #19601: Refactoring CHashWriter & Get{Prevouts,Sequence,Outputs}Hash to SHA256 (Alternative to #18071)
9ab4cafabda227ccee5b241d7690fc67f9a27221 Refactor Get{Prevout,Sequence,Outputs}Hash to Get{Prevouts,Sequences,Outputs}SHA256. (Jeremy Rubin) 6510d0ff4173a7b01d6728051303c7c38eb34533 Add SHA256Uint256 helper functions (Jeremy Rubin) b475d7d0fa000d5802caf3065b8b2abcea60719b Add single sha256 call to CHashWriter (Jeremy Rubin) Pull request description: Opened as an alternative to #18071 to be more similar to #17977. I'm fine with either, deferring to others. cc jnewbery Sjors ACKs for top commit: jnewbery: Code review ACK 9ab4cafabda227ccee5b241d7690fc67f9a27221 jonatack: Tested ACK 9ab4caf fjahr: tested ACK 9ab4cafabda227ccee5b241d7690fc67f9a27221 instagibbs: reACK https://github.com/bitcoin/bitcoin/pull/19601/commits/9ab4cafabda227ccee5b241d7690fc67f9a27221 Tree-SHA512: 93a7a47697f1657f027b18407bdcce16963f6b23d12372e7ac8fd4ee96769b3e2639369f9956fee669cc881b6338641cddfeeef1516c7104cb50ef4b880bb0a7
Diffstat (limited to 'src')
-rw-r--r--src/hash.cpp7
-rw-r--r--src/hash.h31
-rw-r--r--src/script/interpreter.cpp27
3 files changed, 46 insertions, 19 deletions
diff --git a/src/hash.cpp b/src/hash.cpp
index 4c09f5f646..83b90ae063 100644
--- a/src/hash.cpp
+++ b/src/hash.cpp
@@ -77,3 +77,10 @@ void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char he
num[3] = (nChild >> 0) & 0xFF;
CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output);
}
+
+uint256 SHA256Uint256(const uint256& input)
+{
+ uint256 result;
+ CSHA256().Write(input.begin(), 32).Finalize(result.begin());
+ return result;
+}
diff --git a/src/hash.h b/src/hash.h
index 71806483ff..c16bbb48ce 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -6,6 +6,7 @@
#ifndef BITCOIN_HASH_H
#define BITCOIN_HASH_H
+#include <attributes.h>
#include <crypto/common.h>
#include <crypto/ripemd160.h>
#include <crypto/sha256.h>
@@ -98,7 +99,7 @@ inline uint160 Hash160(const T1& in1)
class CHashWriter
{
private:
- CHash256 ctx;
+ CSHA256 ctx;
const int nType;
const int nVersion;
@@ -110,13 +111,27 @@ public:
int GetVersion() const { return nVersion; }
void write(const char *pch, size_t size) {
- ctx.Write({(const unsigned char*)pch, size});
+ ctx.Write((const unsigned char*)pch, size);
}
- // invalidates the object
+ /** Compute the double-SHA256 hash of all data written to this object.
+ *
+ * Invalidates this object.
+ */
uint256 GetHash() {
uint256 result;
- ctx.Finalize(result);
+ ctx.Finalize(result.begin());
+ ctx.Reset().Write(result.begin(), CSHA256::OUTPUT_SIZE).Finalize(result.begin());
+ return result;
+ }
+
+ /** Compute the SHA256 hash of all data written to this object.
+ *
+ * Invalidates this object.
+ */
+ uint256 GetSHA256() {
+ uint256 result;
+ ctx.Finalize(result.begin());
return result;
}
@@ -124,9 +139,8 @@ public:
* Returns the first 64 bits from the resulting hash.
*/
inline uint64_t GetCheapHash() {
- unsigned char result[CHash256::OUTPUT_SIZE];
- ctx.Finalize(result);
- return ReadLE64(result);
+ uint256 result = GetHash();
+ return ReadLE64(result.begin());
}
template<typename T>
@@ -181,6 +195,9 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL
return ss.GetHash();
}
+/** Single-SHA256 a 32-byte input (represented as uint256). */
+NODISCARD uint256 SHA256Uint256(const uint256& input);
+
unsigned int MurmurHash3(unsigned int nHashSeed, Span<const unsigned char> vDataToHash);
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 39feb4ccc9..7b2457a5e3 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1258,34 +1258,37 @@ public:
}
};
+/** Compute the (single) SHA256 of the concatenation of all prevouts of a tx. */
template <class T>
-uint256 GetPrevoutHash(const T& txTo)
+uint256 GetPrevoutsSHA256(const T& txTo)
{
CHashWriter ss(SER_GETHASH, 0);
for (const auto& txin : txTo.vin) {
ss << txin.prevout;
}
- return ss.GetHash();
+ return ss.GetSHA256();
}
+/** Compute the (single) SHA256 of the concatenation of all nSequences of a tx. */
template <class T>
-uint256 GetSequenceHash(const T& txTo)
+uint256 GetSequencesSHA256(const T& txTo)
{
CHashWriter ss(SER_GETHASH, 0);
for (const auto& txin : txTo.vin) {
ss << txin.nSequence;
}
- return ss.GetHash();
+ return ss.GetSHA256();
}
+/** Compute the (single) SHA256 of the concatenation of all txouts of a tx. */
template <class T>
-uint256 GetOutputsHash(const T& txTo)
+uint256 GetOutputsSHA256(const T& txTo)
{
CHashWriter ss(SER_GETHASH, 0);
for (const auto& txout : txTo.vout) {
ss << txout;
}
- return ss.GetHash();
+ return ss.GetSHA256();
}
} // namespace
@@ -1297,9 +1300,9 @@ void PrecomputedTransactionData::Init(const T& txTo)
// Cache is calculated only for transactions with witness
if (txTo.HasWitness()) {
- hashPrevouts = GetPrevoutHash(txTo);
- hashSequence = GetSequenceHash(txTo);
- hashOutputs = GetOutputsHash(txTo);
+ hashPrevouts = SHA256Uint256(GetPrevoutsSHA256(txTo));
+ hashSequence = SHA256Uint256(GetSequencesSHA256(txTo));
+ hashOutputs = SHA256Uint256(GetOutputsSHA256(txTo));
}
m_ready = true;
@@ -1329,16 +1332,16 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
const bool cacheready = cache && cache->m_ready;
if (!(nHashType & SIGHASH_ANYONECANPAY)) {
- hashPrevouts = cacheready ? cache->hashPrevouts : GetPrevoutHash(txTo);
+ hashPrevouts = cacheready ? cache->hashPrevouts : SHA256Uint256(GetPrevoutsSHA256(txTo));
}
if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
- hashSequence = cacheready ? cache->hashSequence : GetSequenceHash(txTo);
+ hashSequence = cacheready ? cache->hashSequence : SHA256Uint256(GetSequencesSHA256(txTo));
}
if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
- hashOutputs = cacheready ? cache->hashOutputs : GetOutputsHash(txTo);
+ hashOutputs = cacheready ? cache->hashOutputs : SHA256Uint256(GetOutputsSHA256(txTo));
} else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) {
CHashWriter ss(SER_GETHASH, 0);
ss << txTo.vout[nIn];