Skip to content

Commit f8462a6

Browse files
committed
Merge #19601: Refactoring CHashWriter & Get{Prevouts,Sequence,Outputs}Hash to SHA256 (Alternative to #18071)
9ab4caf Refactor Get{Prevout,Sequence,Outputs}Hash to Get{Prevouts,Sequences,Outputs}SHA256. (Jeremy Rubin) 6510d0f Add SHA256Uint256 helper functions (Jeremy Rubin) b475d7d 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 9ab4caf jonatack: Tested ACK 9ab4caf fjahr: tested ACK 9ab4caf instagibbs: reACK bitcoin/bitcoin@9ab4caf Tree-SHA512: 93a7a47697f1657f027b18407bdcce16963f6b23d12372e7ac8fd4ee96769b3e2639369f9956fee669cc881b6338641cddfeeef1516c7104cb50ef4b880bb0a7
2 parents 8e0f341 + 9ab4caf commit f8462a6

File tree

3 files changed

+46
-19
lines changed

3 files changed

+46
-19
lines changed

src/hash.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,10 @@ void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char he
7777
num[3] = (nChild >> 0) & 0xFF;
7878
CHMAC_SHA512(chainCode.begin(), chainCode.size()).Write(&header, 1).Write(data, 32).Write(num, 4).Finalize(output);
7979
}
80+
81+
uint256 SHA256Uint256(const uint256& input)
82+
{
83+
uint256 result;
84+
CSHA256().Write(input.begin(), 32).Finalize(result.begin());
85+
return result;
86+
}

src/hash.h

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#ifndef BITCOIN_HASH_H
77
#define BITCOIN_HASH_H
88

9+
#include <attributes.h>
910
#include <crypto/common.h>
1011
#include <crypto/ripemd160.h>
1112
#include <crypto/sha256.h>
@@ -98,7 +99,7 @@ inline uint160 Hash160(const T1& in1)
9899
class CHashWriter
99100
{
100101
private:
101-
CHash256 ctx;
102+
CSHA256 ctx;
102103

103104
const int nType;
104105
const int nVersion;
@@ -110,23 +111,36 @@ class CHashWriter
110111
int GetVersion() const { return nVersion; }
111112

112113
void write(const char *pch, size_t size) {
113-
ctx.Write({(const unsigned char*)pch, size});
114+
ctx.Write((const unsigned char*)pch, size);
114115
}
115116

116-
// invalidates the object
117+
/** Compute the double-SHA256 hash of all data written to this object.
118+
*
119+
* Invalidates this object.
120+
*/
117121
uint256 GetHash() {
118122
uint256 result;
119-
ctx.Finalize(result);
123+
ctx.Finalize(result.begin());
124+
ctx.Reset().Write(result.begin(), CSHA256::OUTPUT_SIZE).Finalize(result.begin());
125+
return result;
126+
}
127+
128+
/** Compute the SHA256 hash of all data written to this object.
129+
*
130+
* Invalidates this object.
131+
*/
132+
uint256 GetSHA256() {
133+
uint256 result;
134+
ctx.Finalize(result.begin());
120135
return result;
121136
}
122137

123138
/**
124139
* Returns the first 64 bits from the resulting hash.
125140
*/
126141
inline uint64_t GetCheapHash() {
127-
unsigned char result[CHash256::OUTPUT_SIZE];
128-
ctx.Finalize(result);
129-
return ReadLE64(result);
142+
uint256 result = GetHash();
143+
return ReadLE64(result.begin());
130144
}
131145

132146
template<typename T>
@@ -181,6 +195,9 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL
181195
return ss.GetHash();
182196
}
183197

198+
/** Single-SHA256 a 32-byte input (represented as uint256). */
199+
NODISCARD uint256 SHA256Uint256(const uint256& input);
200+
184201
unsigned int MurmurHash3(unsigned int nHashSeed, Span<const unsigned char> vDataToHash);
185202

186203
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);

src/script/interpreter.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,34 +1258,37 @@ class CTransactionSignatureSerializer
12581258
}
12591259
};
12601260

1261+
/** Compute the (single) SHA256 of the concatenation of all prevouts of a tx. */
12611262
template <class T>
1262-
uint256 GetPrevoutHash(const T& txTo)
1263+
uint256 GetPrevoutsSHA256(const T& txTo)
12631264
{
12641265
CHashWriter ss(SER_GETHASH, 0);
12651266
for (const auto& txin : txTo.vin) {
12661267
ss << txin.prevout;
12671268
}
1268-
return ss.GetHash();
1269+
return ss.GetSHA256();
12691270
}
12701271

1272+
/** Compute the (single) SHA256 of the concatenation of all nSequences of a tx. */
12711273
template <class T>
1272-
uint256 GetSequenceHash(const T& txTo)
1274+
uint256 GetSequencesSHA256(const T& txTo)
12731275
{
12741276
CHashWriter ss(SER_GETHASH, 0);
12751277
for (const auto& txin : txTo.vin) {
12761278
ss << txin.nSequence;
12771279
}
1278-
return ss.GetHash();
1280+
return ss.GetSHA256();
12791281
}
12801282

1283+
/** Compute the (single) SHA256 of the concatenation of all txouts of a tx. */
12811284
template <class T>
1282-
uint256 GetOutputsHash(const T& txTo)
1285+
uint256 GetOutputsSHA256(const T& txTo)
12831286
{
12841287
CHashWriter ss(SER_GETHASH, 0);
12851288
for (const auto& txout : txTo.vout) {
12861289
ss << txout;
12871290
}
1288-
return ss.GetHash();
1291+
return ss.GetSHA256();
12891292
}
12901293

12911294
} // namespace
@@ -1297,9 +1300,9 @@ void PrecomputedTransactionData::Init(const T& txTo)
12971300

12981301
// Cache is calculated only for transactions with witness
12991302
if (txTo.HasWitness()) {
1300-
hashPrevouts = GetPrevoutHash(txTo);
1301-
hashSequence = GetSequenceHash(txTo);
1302-
hashOutputs = GetOutputsHash(txTo);
1303+
hashPrevouts = SHA256Uint256(GetPrevoutsSHA256(txTo));
1304+
hashSequence = SHA256Uint256(GetSequencesSHA256(txTo));
1305+
hashOutputs = SHA256Uint256(GetOutputsSHA256(txTo));
13031306
}
13041307

13051308
m_ready = true;
@@ -1329,16 +1332,16 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
13291332
const bool cacheready = cache && cache->m_ready;
13301333

13311334
if (!(nHashType & SIGHASH_ANYONECANPAY)) {
1332-
hashPrevouts = cacheready ? cache->hashPrevouts : GetPrevoutHash(txTo);
1335+
hashPrevouts = cacheready ? cache->hashPrevouts : SHA256Uint256(GetPrevoutsSHA256(txTo));
13331336
}
13341337

13351338
if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
1336-
hashSequence = cacheready ? cache->hashSequence : GetSequenceHash(txTo);
1339+
hashSequence = cacheready ? cache->hashSequence : SHA256Uint256(GetSequencesSHA256(txTo));
13371340
}
13381341

13391342

13401343
if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
1341-
hashOutputs = cacheready ? cache->hashOutputs : GetOutputsHash(txTo);
1344+
hashOutputs = cacheready ? cache->hashOutputs : SHA256Uint256(GetOutputsSHA256(txTo));
13421345
} else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) {
13431346
CHashWriter ss(SER_GETHASH, 0);
13441347
ss << txTo.vout[nIn];

0 commit comments

Comments
 (0)