aboutsummaryrefslogtreecommitdiff
path: root/src/script/sign.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/sign.cpp')
-rw-r--r--src/script/sign.cpp50
1 files changed, 37 insertions, 13 deletions
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index d77515f16c..3b8071d9d1 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -18,16 +18,16 @@
typedef std::vector<unsigned char> valtype;
-MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* tx, unsigned int input_idx, const CAmount& amount, int hash_type)
- : txTo{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount}, checker{txTo, nIn, amount, MissingDataBehavior::FAIL},
+MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction& tx, unsigned int input_idx, const CAmount& amount, int hash_type)
+ : m_txto{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount}, checker{&m_txto, nIn, amount, MissingDataBehavior::FAIL},
m_txdata(nullptr)
{
}
-MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction* tx, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, int hash_type)
- : txTo{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount},
- checker{txdata ? MutableTransactionSignatureChecker{txTo, nIn, amount, *txdata, MissingDataBehavior::FAIL} :
- MutableTransactionSignatureChecker{txTo, nIn, amount, MissingDataBehavior::FAIL}},
+MutableTransactionSignatureCreator::MutableTransactionSignatureCreator(const CMutableTransaction& tx, unsigned int input_idx, const CAmount& amount, const PrecomputedTransactionData* txdata, int hash_type)
+ : m_txto{tx}, nIn{input_idx}, nHashType{hash_type}, amount{amount},
+ checker{txdata ? MutableTransactionSignatureChecker{&m_txto, nIn, amount, *txdata, MissingDataBehavior::FAIL} :
+ MutableTransactionSignatureChecker{&m_txto, nIn, amount, MissingDataBehavior::FAIL}},
m_txdata(txdata)
{
}
@@ -50,7 +50,7 @@ bool MutableTransactionSignatureCreator::CreateSig(const SigningProvider& provid
// BASE/WITNESS_V0 signatures don't support explicit SIGHASH_DEFAULT, use SIGHASH_ALL instead.
const int hashtype = nHashType == SIGHASH_DEFAULT ? SIGHASH_ALL : nHashType;
- uint256 hash = SignatureHash(scriptCode, *txTo, nIn, hashtype, amount, sigversion, m_txdata);
+ uint256 hash = SignatureHash(scriptCode, m_txto, nIn, hashtype, amount, sigversion, m_txdata);
if (!key.Sign(hash, vchSig))
return false;
vchSig.push_back((unsigned char)hashtype);
@@ -80,7 +80,7 @@ bool MutableTransactionSignatureCreator::CreateSchnorrSig(const SigningProvider&
execdata.m_tapleaf_hash = *leaf_hash;
}
uint256 hash;
- if (!SignatureHashSchnorr(hash, execdata, *txTo, nIn, nHashType, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return false;
+ if (!SignatureHashSchnorr(hash, execdata, m_txto, nIn, nHashType, sigversion, *m_txdata, MissingDataBehavior::FAIL)) return false;
sig.resize(64);
// Use uint256{} as aux_rnd for now.
if (!key.SignSchnorr(hash, sig, merkle_root, {})) return false;
@@ -150,6 +150,7 @@ static bool CreateTaprootScriptSig(const BaseSignatureCreator& creator, Signatur
auto it = sigdata.taproot_script_sigs.find(lookup_key);
if (it != sigdata.taproot_script_sigs.end()) {
sig_out = it->second;
+ return true;
}
if (creator.CreateSchnorrSig(provider, sig_out, pubkey, &leaf_hash, nullptr, sigversion)) {
sigdata.taproot_script_sigs[lookup_key] = sig_out;
@@ -164,11 +165,22 @@ static bool SignTaprootScript(const SigningProvider& provider, const BaseSignatu
if (leaf_version != TAPROOT_LEAF_TAPSCRIPT) return false;
SigVersion sigversion = SigVersion::TAPSCRIPT;
- uint256 leaf_hash = (CHashWriter(HASHER_TAPLEAF) << uint8_t(leaf_version) << script).GetSHA256();
+ uint256 leaf_hash = (HashWriter{HASHER_TAPLEAF} << uint8_t(leaf_version) << script).GetSHA256();
// <xonly pubkey> OP_CHECKSIG
if (script.size() == 34 && script[33] == OP_CHECKSIG && script[0] == 0x20) {
XOnlyPubKey pubkey{Span{script}.subspan(1, 32)};
+
+ KeyOriginInfo info;
+ if (provider.GetKeyOriginByXOnly(pubkey, info)) {
+ auto it = sigdata.taproot_misc_pubkeys.find(pubkey);
+ if (it == sigdata.taproot_misc_pubkeys.end()) {
+ sigdata.taproot_misc_pubkeys.emplace(pubkey, std::make_pair(std::set<uint256>({leaf_hash}), info));
+ } else {
+ it->second.first.insert(leaf_hash);
+ }
+ }
+
std::vector<unsigned char> sig;
if (CreateTaprootScriptSig(creator, sigdata, provider, sig, pubkey, leaf_hash, sigversion)) {
result = Vector(std::move(sig));
@@ -205,17 +217,29 @@ static bool SignTaprootScript(const SigningProvider& provider, const BaseSignatu
static bool SignTaproot(const SigningProvider& provider, const BaseSignatureCreator& creator, const WitnessV1Taproot& output, SignatureData& sigdata, std::vector<valtype>& result)
{
TaprootSpendData spenddata;
+ TaprootBuilder builder;
// Gather information about this output.
if (provider.GetTaprootSpendData(output, spenddata)) {
sigdata.tr_spenddata.Merge(spenddata);
}
+ if (provider.GetTaprootBuilder(output, builder)) {
+ sigdata.tr_builder = builder;
+ }
// Try key path spending.
{
+ KeyOriginInfo info;
+ if (provider.GetKeyOriginByXOnly(sigdata.tr_spenddata.internal_key, info)) {
+ auto it = sigdata.taproot_misc_pubkeys.find(sigdata.tr_spenddata.internal_key);
+ if (it == sigdata.taproot_misc_pubkeys.end()) {
+ sigdata.taproot_misc_pubkeys.emplace(sigdata.tr_spenddata.internal_key, std::make_pair(std::set<uint256>(), info));
+ }
+ }
+
std::vector<unsigned char> sig;
if (sigdata.taproot_key_path_sig.size() == 0) {
- if (creator.CreateSchnorrSig(provider, sig, spenddata.internal_key, nullptr, &spenddata.merkle_root, SigVersion::TAPROOT)) {
+ if (creator.CreateSchnorrSig(provider, sig, sigdata.tr_spenddata.internal_key, nullptr, &sigdata.tr_spenddata.merkle_root, SigVersion::TAPROOT)) {
sigdata.taproot_key_path_sig = sig;
}
}
@@ -540,7 +564,7 @@ bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, C
{
assert(nIn < txTo.vin.size());
- MutableTransactionSignatureCreator creator(&txTo, nIn, amount, nHashType);
+ MutableTransactionSignatureCreator creator(txTo, nIn, amount, nHashType);
SignatureData sigdata;
bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
@@ -563,7 +587,7 @@ namespace {
class DummySignatureChecker final : public BaseSignatureChecker
{
public:
- DummySignatureChecker() {}
+ DummySignatureChecker() = default;
bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override { return true; }
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror) const override { return true; }
};
@@ -679,7 +703,7 @@ bool SignTransaction(CMutableTransaction& mtx, const SigningProvider* keystore,
SignatureData sigdata = DataFromTransaction(mtx, i, coin->second.out);
// Only sign SIGHASH_SINGLE if there's a corresponding output:
if (!fHashSingle || (i < mtx.vout.size())) {
- ProduceSignature(*keystore, MutableTransactionSignatureCreator(&mtx, i, amount, &txdata, nHashType), prevPubKey, sigdata);
+ ProduceSignature(*keystore, MutableTransactionSignatureCreator(mtx, i, amount, &txdata, nHashType), prevPubKey, sigdata);
}
UpdateInput(txin, sigdata);