mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 02:25:40 +01:00
script/sign: signing support for Miniscripts with hash preimage challenges
Preimages must be externally provided (typically, via a PSBT).
This commit is contained in:
parent
a2f81b6a8f
commit
560e62b1e2
@ -382,6 +382,17 @@ static CScript PushAll(const std::vector<valtype>& values)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename M, typename K, typename V>
|
||||||
|
miniscript::Availability MsLookupHelper(const M& map, const K& key, V& value)
|
||||||
|
{
|
||||||
|
auto it = map.find(key);
|
||||||
|
if (it != map.end()) {
|
||||||
|
value = it->second;
|
||||||
|
return miniscript::Availability::YES;
|
||||||
|
}
|
||||||
|
return miniscript::Availability::NO;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Context for solving a Miniscript.
|
* Context for solving a Miniscript.
|
||||||
* If enough material (access to keys, hash preimages, ..) is given, produces a valid satisfaction.
|
* If enough material (access to keys, hash preimages, ..) is given, produces a valid satisfaction.
|
||||||
@ -443,11 +454,18 @@ struct Satisfier {
|
|||||||
|
|
||||||
|
|
||||||
//! Hash preimage satisfactions.
|
//! Hash preimage satisfactions.
|
||||||
// TODO
|
miniscript::Availability SatSHA256(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const {
|
||||||
miniscript::Availability SatSHA256(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return miniscript::Availability::NO; }
|
return MsLookupHelper(m_sig_data.sha256_preimages, hash, preimage);
|
||||||
miniscript::Availability SatRIPEMD160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return miniscript::Availability::NO; }
|
}
|
||||||
miniscript::Availability SatHASH256(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return miniscript::Availability::NO; }
|
miniscript::Availability SatRIPEMD160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const {
|
||||||
miniscript::Availability SatHASH160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const { return miniscript::Availability::NO; }
|
return MsLookupHelper(m_sig_data.ripemd160_preimages, hash, preimage);
|
||||||
|
}
|
||||||
|
miniscript::Availability SatHASH256(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const {
|
||||||
|
return MsLookupHelper(m_sig_data.hash256_preimages, hash, preimage);
|
||||||
|
}
|
||||||
|
miniscript::Availability SatHASH160(const std::vector<unsigned char>& hash, std::vector<unsigned char>& preimage) const {
|
||||||
|
return MsLookupHelper(m_sig_data.hash160_preimages, hash, preimage);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
|
bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& fromPubKey, SignatureData& sigdata)
|
||||||
@ -645,26 +663,25 @@ void SignatureData::MergeSignatureData(SignatureData sigdata)
|
|||||||
signatures.insert(std::make_move_iterator(sigdata.signatures.begin()), std::make_move_iterator(sigdata.signatures.end()));
|
signatures.insert(std::make_move_iterator(sigdata.signatures.begin()), std::make_move_iterator(sigdata.signatures.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType)
|
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType, SignatureData& sig_data)
|
||||||
{
|
{
|
||||||
assert(nIn < txTo.vin.size());
|
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, sig_data);
|
||||||
bool ret = ProduceSignature(provider, creator, fromPubKey, sigdata);
|
UpdateInput(txTo.vin.at(nIn), sig_data);
|
||||||
UpdateInput(txTo.vin.at(nIn), sigdata);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
|
bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType, SignatureData& sig_data)
|
||||||
{
|
{
|
||||||
assert(nIn < txTo.vin.size());
|
assert(nIn < txTo.vin.size());
|
||||||
const CTxIn& txin = txTo.vin[nIn];
|
const CTxIn& txin = txTo.vin[nIn];
|
||||||
assert(txin.prevout.n < txFrom.vout.size());
|
assert(txin.prevout.n < txFrom.vout.size());
|
||||||
const CTxOut& txout = txFrom.vout[txin.prevout.n];
|
const CTxOut& txout = txFrom.vout[txin.prevout.n];
|
||||||
|
|
||||||
return SignSignature(provider, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType);
|
return SignSignature(provider, txout.scriptPubKey, txTo, nIn, txout.nValue, nHashType, sig_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -82,6 +82,10 @@ struct SignatureData {
|
|||||||
std::vector<CKeyID> missing_sigs; ///< KeyIDs of pubkeys for signatures which could not be found
|
std::vector<CKeyID> missing_sigs; ///< KeyIDs of pubkeys for signatures which could not be found
|
||||||
uint160 missing_redeem_script; ///< ScriptID of the missing redeemScript (if any)
|
uint160 missing_redeem_script; ///< ScriptID of the missing redeemScript (if any)
|
||||||
uint256 missing_witness_script; ///< SHA256 of the missing witnessScript (if any)
|
uint256 missing_witness_script; ///< SHA256 of the missing witnessScript (if any)
|
||||||
|
std::map<std::vector<uint8_t>, std::vector<uint8_t>> sha256_preimages; ///< Mapping from a SHA256 hash to its preimage provided to solve a Script
|
||||||
|
std::map<std::vector<uint8_t>, std::vector<uint8_t>> hash256_preimages; ///< Mapping from a HASH256 hash to its preimage provided to solve a Script
|
||||||
|
std::map<std::vector<uint8_t>, std::vector<uint8_t>> ripemd160_preimages; ///< Mapping from a RIPEMD160 hash to its preimage provided to solve a Script
|
||||||
|
std::map<std::vector<uint8_t>, std::vector<uint8_t>> hash160_preimages; ///< Mapping from a HASH160 hash to its preimage provided to solve a Script
|
||||||
|
|
||||||
SignatureData() {}
|
SignatureData() {}
|
||||||
explicit SignatureData(const CScript& script) : scriptSig(script) {}
|
explicit SignatureData(const CScript& script) : scriptSig(script) {}
|
||||||
@ -91,9 +95,24 @@ struct SignatureData {
|
|||||||
/** Produce a script signature using a generic signature creator. */
|
/** Produce a script signature using a generic signature creator. */
|
||||||
bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata);
|
bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, SignatureData& sigdata);
|
||||||
|
|
||||||
/** Produce a script signature for a transaction. */
|
/**
|
||||||
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo, unsigned int nIn, const CAmount& amount, int nHashType);
|
* Produce a satisfying script (scriptSig or witness).
|
||||||
bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType);
|
*
|
||||||
|
* @param provider Utility containing the information necessary to solve a script.
|
||||||
|
* @param fromPubKey The script to produce a satisfaction for.
|
||||||
|
* @param txTo The spending transaction.
|
||||||
|
* @param nIn The index of the input in `txTo` refering the output being spent.
|
||||||
|
* @param amount The value of the output being spent.
|
||||||
|
* @param nHashType Signature hash type.
|
||||||
|
* @param sig_data Additional data provided to solve a script. Filled with the resulting satisfying
|
||||||
|
* script and whether the satisfaction is complete.
|
||||||
|
*
|
||||||
|
* @return True if the produced script is entirely satisfying `fromPubKey`.
|
||||||
|
**/
|
||||||
|
bool SignSignature(const SigningProvider &provider, const CScript& fromPubKey, CMutableTransaction& txTo,
|
||||||
|
unsigned int nIn, const CAmount& amount, int nHashType, SignatureData& sig_data);
|
||||||
|
bool SignSignature(const SigningProvider &provider, const CTransaction& txFrom, CMutableTransaction& txTo,
|
||||||
|
unsigned int nIn, int nHashType, SignatureData& sig_data);
|
||||||
|
|
||||||
/** Extract signature data from a transaction input, and insert it. */
|
/** Extract signature data from a transaction input, and insert it. */
|
||||||
SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout);
|
SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nIn, const CTxOut& txout);
|
||||||
|
@ -130,7 +130,8 @@ std::set<std::pair<CPubKey, KeyOriginInfo>> GetKeyOriginData(const FlatSigningPr
|
|||||||
void DoCheck(const std::string& prv, const std::string& pub, const std::string& norm_pub, int flags,
|
void DoCheck(const std::string& prv, const std::string& pub, const std::string& norm_pub, int flags,
|
||||||
const std::vector<std::vector<std::string>>& scripts, const std::optional<OutputType>& type,
|
const std::vector<std::vector<std::string>>& scripts, const std::optional<OutputType>& type,
|
||||||
const std::set<std::vector<uint32_t>>& paths = ONLY_EMPTY, bool replace_apostrophe_with_h_in_prv=false,
|
const std::set<std::vector<uint32_t>>& paths = ONLY_EMPTY, bool replace_apostrophe_with_h_in_prv=false,
|
||||||
bool replace_apostrophe_with_h_in_pub=false, uint32_t spender_nlocktime=0, uint32_t spender_nsequence=CTxIn::SEQUENCE_FINAL)
|
bool replace_apostrophe_with_h_in_pub=false, uint32_t spender_nlocktime=0, uint32_t spender_nsequence=CTxIn::SEQUENCE_FINAL,
|
||||||
|
std::map<std::vector<uint8_t>, std::vector<uint8_t>> preimages={})
|
||||||
{
|
{
|
||||||
FlatSigningProvider keys_priv, keys_pub;
|
FlatSigningProvider keys_priv, keys_pub;
|
||||||
std::set<std::vector<uint32_t>> left_paths = paths;
|
std::set<std::vector<uint32_t>> left_paths = paths;
|
||||||
@ -317,6 +318,11 @@ void DoCheck(const std::string& prv, const std::string& pub, const std::string&
|
|||||||
txdata.Init(spend, std::move(utxos), /*force=*/true);
|
txdata.Init(spend, std::move(utxos), /*force=*/true);
|
||||||
MutableTransactionSignatureCreator creator{spend, 0, CAmount{0}, &txdata, SIGHASH_DEFAULT};
|
MutableTransactionSignatureCreator creator{spend, 0, CAmount{0}, &txdata, SIGHASH_DEFAULT};
|
||||||
SignatureData sigdata;
|
SignatureData sigdata;
|
||||||
|
// We assume there is no collision between the hashes (eg h1=SHA256(SHA256(x)) and h2=SHA256(x))
|
||||||
|
sigdata.sha256_preimages = preimages;
|
||||||
|
sigdata.hash256_preimages = preimages;
|
||||||
|
sigdata.ripemd160_preimages = preimages;
|
||||||
|
sigdata.hash160_preimages = preimages;
|
||||||
const auto prod_sig_res = ProduceSignature(FlatSigningProvider{keys_priv}.Merge(FlatSigningProvider{script_provider}), creator, spks[n], sigdata);
|
const auto prod_sig_res = ProduceSignature(FlatSigningProvider{keys_priv}.Merge(FlatSigningProvider{script_provider}), creator, spks[n], sigdata);
|
||||||
BOOST_CHECK_MESSAGE(prod_sig_res == !(flags & SIGNABLE_FAILS), prv);
|
BOOST_CHECK_MESSAGE(prod_sig_res == !(flags & SIGNABLE_FAILS), prv);
|
||||||
}
|
}
|
||||||
@ -349,7 +355,7 @@ void DoCheck(const std::string& prv, const std::string& pub, const std::string&
|
|||||||
void Check(const std::string& prv, const std::string& pub, const std::string& norm_pub, int flags,
|
void Check(const std::string& prv, const std::string& pub, const std::string& norm_pub, int flags,
|
||||||
const std::vector<std::vector<std::string>>& scripts, const std::optional<OutputType>& type,
|
const std::vector<std::vector<std::string>>& scripts, const std::optional<OutputType>& type,
|
||||||
const std::set<std::vector<uint32_t>>& paths = ONLY_EMPTY, uint32_t spender_nlocktime=0,
|
const std::set<std::vector<uint32_t>>& paths = ONLY_EMPTY, uint32_t spender_nlocktime=0,
|
||||||
uint32_t spender_nsequence=CTxIn::SEQUENCE_FINAL)
|
uint32_t spender_nsequence=CTxIn::SEQUENCE_FINAL, std::map<std::vector<uint8_t>, std::vector<uint8_t>> preimages={})
|
||||||
{
|
{
|
||||||
bool found_apostrophes_in_prv = false;
|
bool found_apostrophes_in_prv = false;
|
||||||
bool found_apostrophes_in_pub = false;
|
bool found_apostrophes_in_pub = false;
|
||||||
@ -357,14 +363,14 @@ void Check(const std::string& prv, const std::string& pub, const std::string& no
|
|||||||
// Do not replace apostrophes with 'h' in prv and pub
|
// Do not replace apostrophes with 'h' in prv and pub
|
||||||
DoCheck(prv, pub, norm_pub, flags, scripts, type, paths, /*replace_apostrophe_with_h_in_prv=*/false,
|
DoCheck(prv, pub, norm_pub, flags, scripts, type, paths, /*replace_apostrophe_with_h_in_prv=*/false,
|
||||||
/*replace_apostrophe_with_h_in_pub=*/false, /*spender_nlocktime=*/spender_nlocktime,
|
/*replace_apostrophe_with_h_in_pub=*/false, /*spender_nlocktime=*/spender_nlocktime,
|
||||||
/*spender_nsequence=*/spender_nsequence);
|
/*spender_nsequence=*/spender_nsequence, /*preimages=*/preimages);
|
||||||
|
|
||||||
// Replace apostrophes with 'h' in prv but not in pub, if apostrophes are found in prv
|
// Replace apostrophes with 'h' in prv but not in pub, if apostrophes are found in prv
|
||||||
if (prv.find('\'') != std::string::npos) {
|
if (prv.find('\'') != std::string::npos) {
|
||||||
found_apostrophes_in_prv = true;
|
found_apostrophes_in_prv = true;
|
||||||
DoCheck(prv, pub, norm_pub, flags, scripts, type, paths, /*replace_apostrophe_with_h_in_prv=*/true,
|
DoCheck(prv, pub, norm_pub, flags, scripts, type, paths, /*replace_apostrophe_with_h_in_prv=*/true,
|
||||||
/*replace_apostrophe_with_h_in_pub=*/false, /*spender_nlocktime=*/spender_nlocktime,
|
/*replace_apostrophe_with_h_in_pub=*/false, /*spender_nlocktime=*/spender_nlocktime,
|
||||||
/*spender_nsequence=*/spender_nsequence);
|
/*spender_nsequence=*/spender_nsequence, /*preimages=*/preimages);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace apostrophes with 'h' in pub but not in prv, if apostrophes are found in pub
|
// Replace apostrophes with 'h' in pub but not in prv, if apostrophes are found in pub
|
||||||
@ -372,14 +378,14 @@ void Check(const std::string& prv, const std::string& pub, const std::string& no
|
|||||||
found_apostrophes_in_pub = true;
|
found_apostrophes_in_pub = true;
|
||||||
DoCheck(prv, pub, norm_pub, flags, scripts, type, paths, /*replace_apostrophe_with_h_in_prv=*/false,
|
DoCheck(prv, pub, norm_pub, flags, scripts, type, paths, /*replace_apostrophe_with_h_in_prv=*/false,
|
||||||
/*replace_apostrophe_with_h_in_pub=*/true, /*spender_nlocktime=*/spender_nlocktime,
|
/*replace_apostrophe_with_h_in_pub=*/true, /*spender_nlocktime=*/spender_nlocktime,
|
||||||
/*spender_nsequence=*/spender_nsequence);
|
/*spender_nsequence=*/spender_nsequence, /*preimages=*/preimages);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace apostrophes with 'h' both in prv and in pub, if apostrophes are found in both
|
// Replace apostrophes with 'h' both in prv and in pub, if apostrophes are found in both
|
||||||
if (found_apostrophes_in_prv && found_apostrophes_in_pub) {
|
if (found_apostrophes_in_prv && found_apostrophes_in_pub) {
|
||||||
DoCheck(prv, pub, norm_pub, flags, scripts, type, paths, /*replace_apostrophe_with_h_in_prv=*/true,
|
DoCheck(prv, pub, norm_pub, flags, scripts, type, paths, /*replace_apostrophe_with_h_in_prv=*/true,
|
||||||
/*replace_apostrophe_with_h_in_pub=*/true, /*spender_nlocktime=*/spender_nlocktime,
|
/*replace_apostrophe_with_h_in_pub=*/true, /*spender_nlocktime=*/spender_nlocktime,
|
||||||
/*spender_nsequence=*/spender_nsequence);
|
/*spender_nsequence=*/spender_nsequence, /*preimages=*/preimages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,6 +563,19 @@ BOOST_AUTO_TEST_CASE(descriptor_test)
|
|||||||
Check("sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0),n:older(2)))))", "sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0),n:older(2)))))", "sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0),n:older(2)))))", SIGNABLE_FAILS, {{"a914099f400961f930d4c16c3b33c0e2a58ef53ac38f87"}}, OutputType::P2SH_SEGWIT, {{},{0}}, /*spender_nlocktime=*/999, /*spender_nsequence=*/2);
|
Check("sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0),n:older(2)))))", "sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0),n:older(2)))))", "sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0),n:older(2)))))", SIGNABLE_FAILS, {{"a914099f400961f930d4c16c3b33c0e2a58ef53ac38f87"}}, OutputType::P2SH_SEGWIT, {{},{0}}, /*spender_nlocktime=*/999, /*spender_nsequence=*/2);
|
||||||
// But if both are set to (at least) the required value, we'll succeed.
|
// But if both are set to (at least) the required value, we'll succeed.
|
||||||
Check("sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0),n:older(2)))))", "sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0),n:older(2)))))", "sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0),n:older(2)))))", SIGNABLE, {{"a914099f400961f930d4c16c3b33c0e2a58ef53ac38f87"}}, OutputType::P2SH_SEGWIT, {{},{0}}, /*spender_nlocktime=*/1000, /*spender_nsequence=*/2);
|
Check("sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0),n:older(2)))))", "sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0),n:older(2)))))", "sh(wsh(thresh(2,ndv:after(1000),a:and_n(multi(1,xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0),n:older(2)))))", SIGNABLE, {{"a914099f400961f930d4c16c3b33c0e2a58ef53ac38f87"}}, OutputType::P2SH_SEGWIT, {{},{0}}, /*spender_nlocktime=*/1000, /*spender_nsequence=*/2);
|
||||||
|
// We can't sign for a script requiring a ripemd160 preimage without providing it.
|
||||||
|
Check("wsh(and_v(v:ripemd160(ff9aa1829c90d26e73301383f549e1497b7d6325),pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc)))", "wsh(and_v(v:ripemd160(ff9aa1829c90d26e73301383f549e1497b7d6325),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", "wsh(and_v(v:ripemd160(ff9aa1829c90d26e73301383f549e1497b7d6325),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", SIGNABLE_FAILS, {{"002001549deda34cbc4a5982263191380f522695a2ddc2f99fc3a65c736264bd6cab"}}, OutputType::BECH32, {{}}, /*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, {});
|
||||||
|
// But if we provide it, we can.
|
||||||
|
Check("wsh(and_v(v:ripemd160(ff9aa1829c90d26e73301383f549e1497b7d6325),pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc)))", "wsh(and_v(v:ripemd160(ff9aa1829c90d26e73301383f549e1497b7d6325),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", "wsh(and_v(v:ripemd160(ff9aa1829c90d26e73301383f549e1497b7d6325),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", SIGNABLE, {{"002001549deda34cbc4a5982263191380f522695a2ddc2f99fc3a65c736264bd6cab"}}, OutputType::BECH32, {{}}, /*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, {{ParseHex("ff9aa1829c90d26e73301383f549e1497b7d6325"), ParseHex("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")}});
|
||||||
|
// Same for sha256
|
||||||
|
Check("wsh(and_v(v:sha256(7426ba0604c3f8682c7016b44673f85c5bd9da2fa6c1080810cf53ae320c9863),pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc)))", "wsh(and_v(v:sha256(7426ba0604c3f8682c7016b44673f85c5bd9da2fa6c1080810cf53ae320c9863),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", "wsh(and_v(v:sha256(7426ba0604c3f8682c7016b44673f85c5bd9da2fa6c1080810cf53ae320c9863),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", SIGNABLE_FAILS, {{"002071f7283dbbb9a55ed43a54cda16ba0efd0f16dc48fe200f299e57bb5d7be8dd4"}}, OutputType::BECH32, {{}}, /*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, {});
|
||||||
|
Check("wsh(and_v(v:sha256(7426ba0604c3f8682c7016b44673f85c5bd9da2fa6c1080810cf53ae320c9863),pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc)))", "wsh(and_v(v:sha256(7426ba0604c3f8682c7016b44673f85c5bd9da2fa6c1080810cf53ae320c9863),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", "wsh(and_v(v:sha256(7426ba0604c3f8682c7016b44673f85c5bd9da2fa6c1080810cf53ae320c9863),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", SIGNABLE, {{"002071f7283dbbb9a55ed43a54cda16ba0efd0f16dc48fe200f299e57bb5d7be8dd4"}}, OutputType::BECH32, {{}}, /*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, {{ParseHex("7426ba0604c3f8682c7016b44673f85c5bd9da2fa6c1080810cf53ae320c9863"), ParseHex("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")}});
|
||||||
|
// Same for hash160
|
||||||
|
Check("wsh(and_v(v:hash160(292e2df59e3a22109200beed0cdc84b12e66793e),pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc)))", "wsh(and_v(v:hash160(292e2df59e3a22109200beed0cdc84b12e66793e),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", "wsh(and_v(v:hash160(292e2df59e3a22109200beed0cdc84b12e66793e),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", SIGNABLE_FAILS, {{"00209b9d5b45735d0e15df5b41d6594602d3de472262f7b75edc6cf5f3e3fa4e3ae4"}}, OutputType::BECH32, {{}}, /*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, {});
|
||||||
|
Check("wsh(and_v(v:hash160(292e2df59e3a22109200beed0cdc84b12e66793e),pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc)))", "wsh(and_v(v:hash160(292e2df59e3a22109200beed0cdc84b12e66793e),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", "wsh(and_v(v:hash160(292e2df59e3a22109200beed0cdc84b12e66793e),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", SIGNABLE, {{"00209b9d5b45735d0e15df5b41d6594602d3de472262f7b75edc6cf5f3e3fa4e3ae4"}}, OutputType::BECH32, {{}}, /*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, {{ParseHex("292e2df59e3a22109200beed0cdc84b12e66793e"), ParseHex("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")}});
|
||||||
|
// Same for hash256
|
||||||
|
Check("wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc)))", "wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", "wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", SIGNABLE_FAILS, {{"0020cf62bf97baf977aec69cbc290c372899f913337a9093e8f066ab59b8657a365c"}}, OutputType::BECH32, {{}}, /*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, {});
|
||||||
|
Check("wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc)))", "wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", "wsh(and_v(v:hash256(ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588),pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL)))", SIGNABLE, {{"0020cf62bf97baf977aec69cbc290c372899f913337a9093e8f066ab59b8657a365c"}}, OutputType::BECH32, {{}}, /*spender_nlocktime=*/0, /*spender_nsequence=*/CTxIn::SEQUENCE_FINAL, {{ParseHex("ae253ca2a54debcac7ecf414f6734f48c56421a08bb59182ff9f39a6fffdb588"), ParseHex("000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")}});
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -109,10 +109,12 @@ FUZZ_TARGET_INIT(script_sign, initialize_script_sign)
|
|||||||
CMutableTransaction script_tx_to = tx_to;
|
CMutableTransaction script_tx_to = tx_to;
|
||||||
CMutableTransaction sign_transaction_tx_to = tx_to;
|
CMutableTransaction sign_transaction_tx_to = tx_to;
|
||||||
if (n_in < tx_to.vin.size() && tx_to.vin[n_in].prevout.n < tx_from.vout.size()) {
|
if (n_in < tx_to.vin.size() && tx_to.vin[n_in].prevout.n < tx_from.vout.size()) {
|
||||||
(void)SignSignature(provider, tx_from, tx_to, n_in, fuzzed_data_provider.ConsumeIntegral<int>());
|
SignatureData empty;
|
||||||
|
(void)SignSignature(provider, tx_from, tx_to, n_in, fuzzed_data_provider.ConsumeIntegral<int>(), empty);
|
||||||
}
|
}
|
||||||
if (n_in < script_tx_to.vin.size()) {
|
if (n_in < script_tx_to.vin.size()) {
|
||||||
(void)SignSignature(provider, ConsumeScript(fuzzed_data_provider), script_tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>());
|
SignatureData empty;
|
||||||
|
(void)SignSignature(provider, ConsumeScript(fuzzed_data_provider), script_tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>(), empty);
|
||||||
MutableTransactionSignatureCreator signature_creator{tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>()};
|
MutableTransactionSignatureCreator signature_creator{tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>()};
|
||||||
std::vector<unsigned char> vch_sig;
|
std::vector<unsigned char> vch_sig;
|
||||||
CKeyID address;
|
CKeyID address;
|
||||||
|
@ -217,7 +217,8 @@ BOOST_AUTO_TEST_CASE(multisig_Sign)
|
|||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
|
SignatureData empty;
|
||||||
|
BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL, empty), strprintf("SignSignature %d", i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,8 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
|||||||
tx.vout.resize(1);
|
tx.vout.resize(1);
|
||||||
tx.vout[0].nValue = 1*CENT;
|
tx.vout[0].nValue = 1*CENT;
|
||||||
tx.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
|
tx.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
|
||||||
BOOST_CHECK(SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL));
|
SignatureData empty;
|
||||||
|
BOOST_CHECK(SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL, empty));
|
||||||
|
|
||||||
orphanage.AddTx(MakeTransactionRef(tx), i);
|
orphanage.AddTx(MakeTransactionRef(tx), i);
|
||||||
}
|
}
|
||||||
@ -108,7 +109,8 @@ BOOST_AUTO_TEST_CASE(DoS_mapOrphans)
|
|||||||
tx.vin[j].prevout.n = j;
|
tx.vin[j].prevout.n = j;
|
||||||
tx.vin[j].prevout.hash = txPrev->GetHash();
|
tx.vin[j].prevout.hash = txPrev->GetHash();
|
||||||
}
|
}
|
||||||
BOOST_CHECK(SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL));
|
SignatureData empty;
|
||||||
|
BOOST_CHECK(SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL, empty));
|
||||||
// Re-use same signature for other inputs
|
// Re-use same signature for other inputs
|
||||||
// (they don't have to be valid for this test)
|
// (they don't have to be valid for this test)
|
||||||
for (unsigned int j = 1; j < tx.vin.size(); j++)
|
for (unsigned int j = 1; j < tx.vin.size(); j++)
|
||||||
|
@ -102,7 +102,8 @@ BOOST_AUTO_TEST_CASE(sign)
|
|||||||
}
|
}
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
|
SignatureData empty;
|
||||||
|
BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL, empty), strprintf("SignSignature %d", i));
|
||||||
}
|
}
|
||||||
// All of the above should be OK, and the txTos have valid signatures
|
// All of the above should be OK, and the txTos have valid signatures
|
||||||
// Check to make sure signature verification fails if we use the wrong ScriptSig:
|
// Check to make sure signature verification fails if we use the wrong ScriptSig:
|
||||||
@ -197,7 +198,8 @@ BOOST_AUTO_TEST_CASE(set)
|
|||||||
}
|
}
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
|
SignatureData empty;
|
||||||
|
BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL, empty), strprintf("SignSignature %d", i));
|
||||||
BOOST_CHECK_MESSAGE(IsStandardTx(CTransaction(txTo[i]), reason), strprintf("txTo[%d].IsStandard", i));
|
BOOST_CHECK_MESSAGE(IsStandardTx(CTransaction(txTo[i]), reason), strprintf("txTo[%d].IsStandard", i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,9 +336,12 @@ BOOST_AUTO_TEST_CASE(AreInputsStandard)
|
|||||||
txTo.vin[i].prevout.n = i;
|
txTo.vin[i].prevout.n = i;
|
||||||
txTo.vin[i].prevout.hash = txFrom.GetHash();
|
txTo.vin[i].prevout.hash = txFrom.GetHash();
|
||||||
}
|
}
|
||||||
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL));
|
SignatureData empty;
|
||||||
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 1, SIGHASH_ALL));
|
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, empty));
|
||||||
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 2, SIGHASH_ALL));
|
SignatureData empty_b;
|
||||||
|
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 1, SIGHASH_ALL, empty_b));
|
||||||
|
SignatureData empty_c;
|
||||||
|
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 2, SIGHASH_ALL, empty_c));
|
||||||
// SignSignature doesn't know how to sign these. We're
|
// SignSignature doesn't know how to sign these. We're
|
||||||
// not testing validating signatures, so just create
|
// not testing validating signatures, so just create
|
||||||
// dummy signatures that DO include the correct P2SH scripts:
|
// dummy signatures that DO include the correct P2SH scripts:
|
||||||
|
@ -1191,7 +1191,8 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
|
|||||||
BOOST_CHECK(combined.scriptSig.empty());
|
BOOST_CHECK(combined.scriptSig.empty());
|
||||||
|
|
||||||
// Single signature case:
|
// Single signature case:
|
||||||
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL)); // changes scriptSig
|
SignatureData dummy;
|
||||||
|
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, dummy)); // changes scriptSig
|
||||||
scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
|
scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
|
||||||
combined = CombineSignatures(txFrom.vout[0], txTo, scriptSig, empty);
|
combined = CombineSignatures(txFrom.vout[0], txTo, scriptSig, empty);
|
||||||
BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
|
BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
|
||||||
@ -1199,7 +1200,8 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
|
|||||||
BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
|
BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
|
||||||
SignatureData scriptSigCopy = scriptSig;
|
SignatureData scriptSigCopy = scriptSig;
|
||||||
// Signing again will give a different, valid signature:
|
// Signing again will give a different, valid signature:
|
||||||
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL));
|
SignatureData dummy_b;
|
||||||
|
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, dummy_b));
|
||||||
scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
|
scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
|
||||||
combined = CombineSignatures(txFrom.vout[0], txTo, scriptSigCopy, scriptSig);
|
combined = CombineSignatures(txFrom.vout[0], txTo, scriptSigCopy, scriptSig);
|
||||||
BOOST_CHECK(combined.scriptSig == scriptSigCopy.scriptSig || combined.scriptSig == scriptSig.scriptSig);
|
BOOST_CHECK(combined.scriptSig == scriptSigCopy.scriptSig || combined.scriptSig == scriptSig.scriptSig);
|
||||||
@ -1208,14 +1210,16 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
|
|||||||
CScript pkSingle; pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG;
|
CScript pkSingle; pkSingle << ToByteVector(keys[0].GetPubKey()) << OP_CHECKSIG;
|
||||||
BOOST_CHECK(keystore.AddCScript(pkSingle));
|
BOOST_CHECK(keystore.AddCScript(pkSingle));
|
||||||
scriptPubKey = GetScriptForDestination(ScriptHash(pkSingle));
|
scriptPubKey = GetScriptForDestination(ScriptHash(pkSingle));
|
||||||
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL));
|
SignatureData dummy_c;
|
||||||
|
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, dummy_c));
|
||||||
scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
|
scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
|
||||||
combined = CombineSignatures(txFrom.vout[0], txTo, scriptSig, empty);
|
combined = CombineSignatures(txFrom.vout[0], txTo, scriptSig, empty);
|
||||||
BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
|
BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
|
||||||
combined = CombineSignatures(txFrom.vout[0], txTo, empty, scriptSig);
|
combined = CombineSignatures(txFrom.vout[0], txTo, empty, scriptSig);
|
||||||
BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
|
BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
|
||||||
scriptSigCopy = scriptSig;
|
scriptSigCopy = scriptSig;
|
||||||
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL));
|
SignatureData dummy_d;
|
||||||
|
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, dummy_d));
|
||||||
scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
|
scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
|
||||||
combined = CombineSignatures(txFrom.vout[0], txTo, scriptSigCopy, scriptSig);
|
combined = CombineSignatures(txFrom.vout[0], txTo, scriptSigCopy, scriptSig);
|
||||||
BOOST_CHECK(combined.scriptSig == scriptSigCopy.scriptSig || combined.scriptSig == scriptSig.scriptSig);
|
BOOST_CHECK(combined.scriptSig == scriptSigCopy.scriptSig || combined.scriptSig == scriptSig.scriptSig);
|
||||||
@ -1223,7 +1227,8 @@ BOOST_AUTO_TEST_CASE(script_combineSigs)
|
|||||||
// Hardest case: Multisig 2-of-3
|
// Hardest case: Multisig 2-of-3
|
||||||
scriptPubKey = GetScriptForMultisig(2, pubkeys);
|
scriptPubKey = GetScriptForMultisig(2, pubkeys);
|
||||||
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
|
BOOST_CHECK(keystore.AddCScript(scriptPubKey));
|
||||||
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL));
|
SignatureData dummy_e;
|
||||||
|
BOOST_CHECK(SignSignature(keystore, CTransaction(txFrom), txTo, 0, SIGHASH_ALL, dummy_e));
|
||||||
scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
|
scriptSig = DataFromTransaction(txTo, 0, txFrom.vout[0]);
|
||||||
combined = CombineSignatures(txFrom.vout[0], txTo, scriptSig, empty);
|
combined = CombineSignatures(txFrom.vout[0], txTo, scriptSig, empty);
|
||||||
BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
|
BOOST_CHECK(combined.scriptSig == scriptSig.scriptSig);
|
||||||
|
@ -435,7 +435,8 @@ static void CreateCreditAndSpend(const FillableSigningProvider& keystore, const
|
|||||||
inputm.vout.resize(1);
|
inputm.vout.resize(1);
|
||||||
inputm.vout[0].nValue = 1;
|
inputm.vout[0].nValue = 1;
|
||||||
inputm.vout[0].scriptPubKey = CScript();
|
inputm.vout[0].scriptPubKey = CScript();
|
||||||
bool ret = SignSignature(keystore, *output, inputm, 0, SIGHASH_ALL);
|
SignatureData empty;
|
||||||
|
bool ret = SignSignature(keystore, *output, inputm, 0, SIGHASH_ALL, empty);
|
||||||
assert(ret == success);
|
assert(ret == success);
|
||||||
CDataStream ssin(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ssin(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ssin << inputm;
|
ssin << inputm;
|
||||||
@ -519,7 +520,8 @@ BOOST_AUTO_TEST_CASE(test_big_witness_transaction)
|
|||||||
|
|
||||||
// sign all inputs
|
// sign all inputs
|
||||||
for(uint32_t i = 0; i < mtx.vin.size(); i++) {
|
for(uint32_t i = 0; i < mtx.vin.size(); i++) {
|
||||||
bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, i, 1000, sigHashes.at(i % sigHashes.size()));
|
SignatureData empty;
|
||||||
|
bool hashSigned = SignSignature(keystore, scriptPubKey, mtx, i, 1000, sigHashes.at(i % sigHashes.size()), empty);
|
||||||
assert(hashSigned);
|
assert(hashSigned);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user