Skip to content

Commit

Permalink
Merge #494: [0.17] Add Elements-style witness structure
Browse files Browse the repository at this point in the history
52c8601 Remove manual byte editing in wallet_tx_clone func test (Gregory Sanders)
0c05901 Add functional test for Elements witness serialization (Steven Roose)
fb72ee8 Add Elements-style witness serialization (Steven Roose)
6ed8fd8 Add -con_elementswitness flag and global variable (Steven Roose)
01b03a9 Add calcfastmerkleroot RPC and test-framework support (Steven Roose)
3f902b0 Add ComputeFastMerkleRoot unit test example generated by elements-0.14.1 (Gregory Sanders)
3b72dab Add CalcFastMerkleRoot (Steven Roose)
7f65e76 Add support for SHA-256 midstate access (Steven Roose)
7a01d4f Remove unnecessary include (Steven Roose)

Pull request description:

  Ports the Elements-style transaction witness structure from v0.14.1. Additionally, the Elements-compatible serialization of the witness data is gated behind a new `-con_elementswitness` flag.

  Fixes #479.

Tree-SHA512: 337fb8a1f0bac7a0c7908d86eefe2f63c6e729ca91372938e6c751e3dec9e4097333f243bec891bd7e63c6e26a5ee0fca55e9ac82190b641db65014da825bfcc
  • Loading branch information
instagibbs committed Feb 13, 2019
2 parents e51ed82 + 52c8601 commit fd9bdc6
Show file tree
Hide file tree
Showing 62 changed files with 1,211 additions and 417 deletions.
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ libbitcoin_consensus_a_SOURCES = \
prevector.h \
primitives/block.cpp \
primitives/block.h \
primitives/txwitness.cpp \
primitives/txwitness.h \
primitives/transaction.cpp \
primitives/transaction.h \
primitives/pak.cpp \
Expand Down
3 changes: 2 additions & 1 deletion src/bench/block_assemble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ static void AssembleBlock(benchmark::State& state)
for (size_t b{0}; b < NUM_BLOCKS; ++b) {
CMutableTransaction tx;
tx.vin.push_back(MineBlock(SCRIPT_PUB));
tx.vin.back().scriptWitness = witness;
tx.witness.vtxinwit.resize(1);
tx.witness.vtxinwit.back().scriptWitness = witness;
tx.vout.emplace_back(1337, SCRIPT_PUB);
if (NUM_BLOCKS - b >= COINBASE_MATURITY)
txs.at(b) = MakeTransactionRef(tx);
Expand Down
34 changes: 23 additions & 11 deletions src/bench/mempool_eviction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <list>
#include <vector>
#include <primitives/transaction.h>

static void AddTx(const CTransactionRef& tx, const CAmount& nFee, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
{
Expand All @@ -30,15 +31,17 @@ static void MempoolEviction(benchmark::State& state)
CMutableTransaction tx1 = CMutableTransaction();
tx1.vin.resize(1);
tx1.vin[0].scriptSig = CScript() << OP_1;
tx1.vin[0].scriptWitness.stack.push_back({1});
tx1.witness.vtxinwit.resize(1);
tx1.witness.vtxinwit[0].scriptWitness.stack.push_back({1});
tx1.vout.resize(1);
tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL;
tx1.vout[0].nValue = 10 * COIN;

CMutableTransaction tx2 = CMutableTransaction();
tx2.vin.resize(1);
tx2.vin[0].scriptSig = CScript() << OP_2;
tx2.vin[0].scriptWitness.stack.push_back({2});
tx2.witness.vtxinwit.resize(1);
tx2.witness.vtxinwit[0].scriptWitness.stack.push_back({2});
tx2.vout.resize(1);
tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL;
tx2.vout[0].nValue = 10 * COIN;
Expand All @@ -47,7 +50,8 @@ static void MempoolEviction(benchmark::State& state)
tx3.vin.resize(1);
tx3.vin[0].prevout = COutPoint(tx2.GetHash(), 0);
tx3.vin[0].scriptSig = CScript() << OP_2;
tx3.vin[0].scriptWitness.stack.push_back({3});
tx3.witness.vtxinwit.resize(1);
tx3.witness.vtxinwit[0].scriptWitness.stack.push_back({3});
tx3.vout.resize(1);
tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL;
tx3.vout[0].nValue = 10 * COIN;
Expand All @@ -56,10 +60,12 @@ static void MempoolEviction(benchmark::State& state)
tx4.vin.resize(2);
tx4.vin[0].prevout.SetNull();
tx4.vin[0].scriptSig = CScript() << OP_4;
tx4.vin[0].scriptWitness.stack.push_back({4});
tx4.witness.vtxinwit.resize(1);
tx4.witness.vtxinwit[0].scriptWitness.stack.push_back({4});
tx4.vin[1].prevout.SetNull();
tx4.vin[1].scriptSig = CScript() << OP_4;
tx4.vin[1].scriptWitness.stack.push_back({4});
tx4.witness.vtxinwit.resize(2);
tx4.witness.vtxinwit[1].scriptWitness.stack.push_back({4});
tx4.vout.resize(2);
tx4.vout[0].scriptPubKey = CScript() << OP_4 << OP_EQUAL;
tx4.vout[0].nValue = 10 * COIN;
Expand All @@ -70,10 +76,12 @@ static void MempoolEviction(benchmark::State& state)
tx5.vin.resize(2);
tx5.vin[0].prevout = COutPoint(tx4.GetHash(), 0);
tx5.vin[0].scriptSig = CScript() << OP_4;
tx5.vin[0].scriptWitness.stack.push_back({4});
tx5.witness.vtxinwit.resize(1);
tx5.witness.vtxinwit[0].scriptWitness.stack.push_back({4});
tx5.vin[1].prevout.SetNull();
tx5.vin[1].scriptSig = CScript() << OP_5;
tx5.vin[1].scriptWitness.stack.push_back({5});
tx5.witness.vtxinwit.resize(2);
tx5.witness.vtxinwit[1].scriptWitness.stack.push_back({5});
tx5.vout.resize(2);
tx5.vout[0].scriptPubKey = CScript() << OP_5 << OP_EQUAL;
tx5.vout[0].nValue = 10 * COIN;
Expand All @@ -84,10 +92,12 @@ static void MempoolEviction(benchmark::State& state)
tx6.vin.resize(2);
tx6.vin[0].prevout = COutPoint(tx4.GetHash(), 1);
tx6.vin[0].scriptSig = CScript() << OP_4;
tx6.vin[0].scriptWitness.stack.push_back({4});
tx6.witness.vtxinwit.resize(1);
tx6.witness.vtxinwit[0].scriptWitness.stack.push_back({4});
tx6.vin[1].prevout.SetNull();
tx6.vin[1].scriptSig = CScript() << OP_6;
tx6.vin[1].scriptWitness.stack.push_back({6});
tx6.witness.vtxinwit.resize(2);
tx6.witness.vtxinwit[1].scriptWitness.stack.push_back({6});
tx6.vout.resize(2);
tx6.vout[0].scriptPubKey = CScript() << OP_6 << OP_EQUAL;
tx6.vout[0].nValue = 10 * COIN;
Expand All @@ -98,10 +108,12 @@ static void MempoolEviction(benchmark::State& state)
tx7.vin.resize(2);
tx7.vin[0].prevout = COutPoint(tx5.GetHash(), 0);
tx7.vin[0].scriptSig = CScript() << OP_5;
tx7.vin[0].scriptWitness.stack.push_back({5});
tx7.witness.vtxinwit.resize(1);
tx7.witness.vtxinwit[0].scriptWitness.stack.push_back({5});
tx7.vin[1].prevout = COutPoint(tx6.GetHash(), 0);
tx7.vin[1].scriptSig = CScript() << OP_6;
tx7.vin[1].scriptWitness.stack.push_back({6});
tx7.witness.vtxinwit.resize(2);
tx7.witness.vtxinwit[1].scriptWitness.stack.push_back({6});
tx7.vout.resize(2);
tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL;
tx7.vout[0].nValue = 10 * COIN;
Expand Down
5 changes: 3 additions & 2 deletions src/bench/verify_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ static void VerifyScriptBench(benchmark::State& state)
CScript witScriptPubkey = CScript() << OP_DUP << OP_HASH160 << ToByteVector(pubkeyHash) << OP_EQUALVERIFY << OP_CHECKSIG;
const CMutableTransaction& txCredit = BuildCreditingTransaction(scriptPubKey);
CMutableTransaction txSpend = BuildSpendingTransaction(scriptSig, txCredit);
CScriptWitness& witness = txSpend.vin[0].scriptWitness;
txSpend.witness.vtxinwit.resize(1);
CScriptWitness& witness = txSpend.witness.vtxinwit[0].scriptWitness;
witness.stack.emplace_back();
key.Sign(SignatureHash(witScriptPubkey, txSpend, 0, SIGHASH_ALL, txCredit.vout[0].nValue, SigVersion::WITNESS_V0), witness.stack.back());
witness.stack.back().push_back(static_cast<unsigned char>(SIGHASH_ALL));
Expand All @@ -86,7 +87,7 @@ static void VerifyScriptBench(benchmark::State& state)
bool success = VerifyScript(
txSpend.vin[0].scriptSig,
txCredit.vout[0].scriptPubKey,
&txSpend.vin[0].scriptWitness,
&txSpend.witness.vtxinwit[0].scriptWitness,
flags,
MutableTransactionSignatureChecker(&txSpend, 0, txCredit.vout[0].nValue),
&err);
Expand Down
2 changes: 1 addition & 1 deletion src/bitcoin-tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
if (!fHashSingle || (i < mergedTx.vout.size()))
ProduceSignature(keystore, MutableTransactionSignatureCreator(&mergedTx, i, amount, nHashType), prevPubKey, sigdata);

UpdateInput(txin, sigdata);
UpdateTransaction(mergedTx, i, sigdata);
}

tx = mergedTx;
Expand Down
6 changes: 4 additions & 2 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <chainparamsseeds.h>
#include <consensus/merkle.h>
#include <primitives/transaction.h>
#include <tinyformat.h>
#include <util.h>
#include <utilstrencodings.h>
Expand Down Expand Up @@ -523,9 +524,10 @@ class CCustomParams : public CRegTestParams {
consensus.max_block_signature_size = gArgs.GetArg("-con_max_block_sig_size", 74);
g_signed_blocks = gArgs.GetBoolArg("-con_signed_blocks", true);

// Note: This global is needed to avoid circular dependency
// Defaults to true for custom chains.
// Note: These globals are needed to avoid circular dependencies.
// Default to true for custom chains.
g_con_blockheightinheader = args.GetBoolArg("-con_blockheightinheader", true);
g_con_elementswitness = args.GetBoolArg("-con_elementswitness", true);

// No subsidy for custom chains by default
consensus.genesis_subsidy = args.GetArg("-con_blocksubsidy", 0);
Expand Down
1 change: 1 addition & 0 deletions src/chainparamsbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ void SetupChainParamsBaseOptions()
gArgs.AddArg("-con_mandatorycoinbase", "All non-zero valued coinbase outputs must go to this scriptPubKey, if set.", false, OptionsCategory::ELEMENTS);
gArgs.AddArg("-con_blocksubsidy", "Defines the amount of block subsidy to start with, at genesis block.", false, OptionsCategory::ELEMENTS);
gArgs.AddArg("-con_connect_coinbase", "Connect outputs in genesis block to utxo database.", false, OptionsCategory::ELEMENTS);
gArgs.AddArg("-con_elementswitness", "Use Elements-like instead of Core-like witness encoding. This is required for CA/CT. (default: true)", false, OptionsCategory::ELEMENTS);
gArgs.AddArg("-con_blockheightinheader", "Whether the chain includes the block height directly in the header, for easier validation of block height in low-resource environments. (default: true)", false, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-con_genesis_style=<style>", "Use genesis style <style> (default: elements). Results in genesis block compatibility with various networks. Allowed values: elements, bitcoin", true, OptionsCategory::ELEMENTS);
gArgs.AddArg("-con_signed_blocks", "Signed blockchain. Uses input of `-signblockscript` to define what signatures are necessary to solve it.", false, OptionsCategory::CHAINPARAMS);
Expand Down
7 changes: 5 additions & 2 deletions src/consensus/merkle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@ uint256 BlockWitnessMerkleRoot(const CBlock& block, bool* mutated)
leaves.resize(block.vtx.size());
leaves[0].SetNull(); // The witness hash of the coinbase is 0.
for (size_t s = 1; s < block.vtx.size(); s++) {
leaves[s] = block.vtx[s]->GetWitnessHash();
if (g_con_elementswitness) {
leaves[s] = block.vtx[s]->GetWitnessOnlyHash();
} else {
leaves[s] = block.vtx[s]->GetWitnessHash();
}
}
return ComputeMerkleRoot(std::move(leaves), mutated);
}

1 change: 0 additions & 1 deletion src/consensus/merkle.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include <stdint.h>
#include <vector>

#include <primitives/transaction.h>
#include <primitives/block.h>
#include <uint256.h>

Expand Down
21 changes: 11 additions & 10 deletions src/consensus/tx_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,20 +159,21 @@ int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& i

for (unsigned int i = 0; i < tx.vin.size(); i++)
{
std::string err;
if (tx.vin[i].m_is_pegin && !IsValidPeginWitness(tx.vin[i].m_pegin_witness, tx.vin[i].prevout, err, true)) {
continue;
}

CTxOut prevout;
if (tx.vin[i].m_is_pegin) {
prevout = GetPeginOutputFromWitness(tx.vin[i].m_pegin_witness);
std::string err;
if (tx.witness.vtxinwit.size() <= i || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, tx.vin[i].prevout, err, true)) {
continue;
}
prevout = GetPeginOutputFromWitness(tx.witness.vtxinwit[i].m_pegin_witness);
} else {
const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout);
assert(!coin.IsSpent());
prevout = coin.out;
}
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, &tx.vin[i].scriptWitness, flags);

const CScriptWitness* pScriptWitness = tx.witness.vtxinwit.size() > i ? &tx.witness.vtxinwit[i].scriptWitness : NULL;
nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, prevout.scriptPubKey, pScriptWitness, flags);
}
return nSigOps;
}
Expand Down Expand Up @@ -241,10 +242,10 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
if (tx.vin[i].m_is_pegin) {
// Check existence and validity of pegin witness
std::string err;
if (!IsValidPeginWitness(tx.vin[i].m_pegin_witness, prevout, err, true)) {
if (tx.witness.vtxinwit.size() <= i || !IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, prevout, err, true)) {
return state.DoS(0, false, REJECT_PEGIN, "bad-pegin-witness");
}
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.vin[i].m_pegin_witness.stack[2]), prevout);
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.witness.vtxinwit[i].m_pegin_witness.stack[2]), prevout);
if (inputs.IsPeginSpent(pegin)) {
return state.Invalid(false, REJECT_INVALID, "bad-txns-double-pegin", strprintf("Double-pegin of %s:%d", prevout.hash.ToString(), prevout.n));
}
Expand All @@ -255,7 +256,7 @@ bool CheckTxInputs(const CTransaction& tx, CValidationState& state, const CCoins
setPeginsSpent.insert(pegin);

// Tally the input amount.
const CTxOut out = GetPeginOutputFromWitness(tx.vin[i].m_pegin_witness);
const CTxOut out = GetPeginOutputFromWitness(tx.witness.vtxinwit[i].m_pegin_witness);
if (!MoneyRange(out.nValue)) {
return state.DoS(100, false, REJECT_INVALID, "bad-txns-pegin-inputvalue-outofrange");
}
Expand Down
10 changes: 8 additions & 2 deletions src/consensus/validation.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,16 @@ static inline int64_t GetBlockWeight(const CBlock& block)
{
return ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(block, PROTOCOL_VERSION);
}
static inline int64_t GetTransactionInputWeight(const CTxIn& txin)

static inline int64_t GetTransactionInputWeight(const CTransaction& tx, const size_t nIn)
{
// scriptWitness size is added here because witnesses and txins are split up in segwit serialization.
return ::GetSerializeSize(txin, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1) + ::GetSerializeSize(txin, PROTOCOL_VERSION) + ::GetSerializeSize(txin.scriptWitness.stack, PROTOCOL_VERSION);
assert(tx.witness.vtxinwit.size() > nIn);
//TODO(rebase) only count CA/CT witnesses when g_con_elementswitness is true
return ::GetSerializeSize(tx.vin[nIn], PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * (WITNESS_SCALE_FACTOR - 1)
+ ::GetSerializeSize(tx.vin[nIn], PROTOCOL_VERSION)
+ ::GetSerializeSize(tx.witness.vtxinwit[nIn].scriptWitness.stack, PROTOCOL_VERSION)
+ ::GetSerializeSize(tx.witness.vtxinwit[nIn].m_pegin_witness.stack, PROTOCOL_VERSION);
}

#endif // BITCOIN_CONSENSUS_VALIDATION_H
34 changes: 31 additions & 3 deletions src/core_memusage.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,37 @@ static inline size_t RecursiveDynamicUsage(const COutPoint& out) {
}

static inline size_t RecursiveDynamicUsage(const CTxIn& in) {
size_t mem = RecursiveDynamicUsage(in.scriptSig) + RecursiveDynamicUsage(in.prevout) + memusage::DynamicUsage(in.scriptWitness.stack);
for (std::vector<std::vector<unsigned char> >::const_iterator it = in.scriptWitness.stack.begin(); it != in.scriptWitness.stack.end(); it++) {
mem += memusage::DynamicUsage(*it);
size_t mem = RecursiveDynamicUsage(in.scriptSig) + RecursiveDynamicUsage(in.prevout);
return mem;
}

static inline size_t RecursiveDynamicUsage(const CScriptWitness& scriptWit) {
size_t mem = memusage::DynamicUsage(scriptWit.stack);
for (std::vector<std::vector<unsigned char> >::const_iterator it = scriptWit.stack.begin(); it != scriptWit.stack.end(); it++) {
mem += memusage::DynamicUsage(*it);
}
return mem;
}

static inline size_t RecursiveDynamicUsage(const CTxInWitness& txInWit) {
size_t mem = RecursiveDynamicUsage(txInWit.scriptWitness);
mem += RecursiveDynamicUsage(txInWit.m_pegin_witness);
return mem;
}

static inline size_t RecursiveDynamicUsage(const CTxOutWitness& txOutWit) {
size_t mem = memusage::DynamicUsage(txOutWit.vchRangeproof);
mem += memusage::DynamicUsage(txOutWit.vchSurjectionproof);
return mem;
}

static inline size_t RecursiveDynamicUsage(const CTxWitness& wit) {
size_t mem = memusage::DynamicUsage(wit.vtxinwit) + memusage::DynamicUsage(wit.vtxoutwit);
for (const auto& txInWit: wit.vtxinwit) {
mem += RecursiveDynamicUsage(txInWit);
}
for (const auto& txOutWit: wit.vtxoutwit) {
mem += RecursiveDynamicUsage(txOutWit);
}
return mem;
}
Expand Down
21 changes: 14 additions & 7 deletions src/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
{
entry.pushKV("txid", tx.GetHash().GetHex());
entry.pushKV("hash", tx.GetWitnessHash().GetHex());
if (g_con_elementswitness) {
entry.pushKV("wtxid", tx.GetWitnessHash().GetHex());
entry.pushKV("withash", tx.GetWitnessOnlyHash().GetHex());
}
entry.pushKV("version", tx.nVersion);
entry.pushKV("size", (int)::GetSerializeSize(tx, PROTOCOL_VERSION));
entry.pushKV("vsize", (GetTransactionWeight(tx) + WITNESS_SCALE_FACTOR - 1) / WITNESS_SCALE_FACTOR);
Expand All @@ -220,19 +224,22 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry,
o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()));
in.pushKV("scriptSig", o);

if (!tx.vin[i].scriptWitness.IsNull()) {
UniValue txinwitness(UniValue::VARR);
for (const auto& item : tx.vin[i].scriptWitness.stack) {
txinwitness.push_back(HexStr(item.begin(), item.end()));
if (tx.witness.vtxinwit.size() > i) {
const CScriptWitness &scriptWitness = tx.witness.vtxinwit[i].scriptWitness;
if (!scriptWitness.IsNull()) {
UniValue txinwitness(UniValue::VARR);
for (const auto &item : scriptWitness.stack) {
txinwitness.push_back(HexStr(item.begin(), item.end()));
}
in.pushKV("txinwitness", txinwitness);
}
in.pushKV("txinwitness", txinwitness);
}

// ELEMENTS:
in.pushKV("is_pegin", txin.m_is_pegin);
if (!tx.vin[i].m_pegin_witness.IsNull()) {
if (tx.witness.vtxinwit.size() > i && !tx.witness.vtxinwit[i].m_pegin_witness.IsNull()) {
UniValue pegin_witness(UniValue::VARR);
for (const auto& item : tx.vin[i].m_pegin_witness.stack) {
for (const auto& item : tx.witness.vtxinwit[i].m_pegin_witness.stack) {
pegin_witness.push_back(HexStr(item.begin(), item.end()));
}
in.pushKV("pegin_witness", pegin_witness);
Expand Down
28 changes: 28 additions & 0 deletions src/crypto/sha256.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,23 @@ CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
}
return *this;
}
//
//void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
//{
// static const unsigned char pad[64] = {0x80};
// unsigned char sizedesc[8];
// WriteBE64(sizedesc, bytes << 3);
// Write(pad, 1 + ((119 - (bytes % 64)) % 64));
// Write(sizedesc, 8);
// WriteBE32(hash, s[0]);
// WriteBE32(hash + 4, s[1]);
// WriteBE32(hash + 8, s[2]);
// WriteBE32(hash + 12, s[3]);
// WriteBE32(hash + 16, s[4]);
// WriteBE32(hash + 20, s[5]);
// WriteBE32(hash + 24, s[6]);
// WriteBE32(hash + 28, s[7]);
//}

void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
{
Expand All @@ -678,6 +695,11 @@ void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
WriteBE64(sizedesc, bytes << 3);
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
Write(sizedesc, 8);
Midstate(hash, NULL, NULL);
}

void CSHA256::Midstate(unsigned char hash[OUTPUT_SIZE], uint64_t* len, unsigned char *buffer)
{
WriteBE32(hash, s[0]);
WriteBE32(hash + 4, s[1]);
WriteBE32(hash + 8, s[2]);
Expand All @@ -686,6 +708,12 @@ void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
WriteBE32(hash + 20, s[5]);
WriteBE32(hash + 24, s[6]);
WriteBE32(hash + 28, s[7]);
if (len) {
*len = bytes << 3;
}
if (buffer) {
memcpy(buffer, buf, bytes % 64);
}
}

CSHA256& CSHA256::Reset()
Expand Down
Loading

0 comments on commit fd9bdc6

Please sign in to comment.