2014-08-27 17:22:33 +02:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2021-12-30 19:36:57 +02:00
// Copyright (c) 2009-2021 The Bitcoin Core developers
2014-09-09 10:00:42 +02:00
// Distributed under the MIT software license, see the accompanying
2014-08-27 17:22:33 +02:00
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2017-11-10 13:57:53 +13:00
# include <script/sign.h>
2014-08-27 17:22:33 +02:00
2021-09-11 10:29:00 +08:00
# include <consensus/amount.h>
2017-11-10 13:57:53 +13:00
# include <key.h>
# include <policy/policy.h>
# include <primitives/transaction.h>
2019-07-25 11:26:20 -04:00
# include <script/keyorigin.h>
2019-06-06 22:52:24 +02:00
# include <script/signingprovider.h>
2017-11-10 13:57:53 +13:00
# include <script/standard.h>
# include <uint256.h>
2021-06-23 17:28:54 -04:00
# include <util/translation.h>
2021-02-27 20:33:22 -08:00
# include <util/vector.h>
2014-08-27 17:22:33 +02:00
2015-10-29 07:11:24 +01:00
typedef std : : vector < unsigned char > valtype ;
2014-08-27 17:22:33 +02:00
2021-09-21 15:03:22 +02:00
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 } ,
2021-02-17 18:57:19 -08:00
m_txdata ( nullptr )
{
}
2021-09-21 15:03:22 +02:00
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 } } ,
2021-02-17 18:57:19 -08:00
m_txdata ( txdata )
{
}
2014-11-04 10:06:20 -08:00
2018-05-20 22:47:14 +02:00
bool MutableTransactionSignatureCreator : : CreateSig ( const SigningProvider & provider , std : : vector < unsigned char > & vchSig , const CKeyID & address , const CScript & scriptCode , SigVersion sigversion ) const
2014-08-27 17:22:33 +02:00
{
2021-02-27 20:33:22 -08:00
assert ( sigversion = = SigVersion : : BASE | | sigversion = = SigVersion : : WITNESS_V0 ) ;
2014-08-27 17:22:33 +02:00
CKey key ;
2018-03-27 13:15:10 -07:00
if ( ! provider . GetKey ( address , key ) )
2014-08-27 17:22:33 +02:00
return false ;
2016-10-02 01:19:33 +08:00
// Signing with uncompressed keys is disabled in witness scripts
2018-03-09 15:03:40 +01:00
if ( sigversion = = SigVersion : : WITNESS_V0 & & ! key . IsCompressed ( ) )
2016-10-02 01:19:33 +08:00
return false ;
2021-02-17 18:57:19 -08:00
// Signing without known amount does not work in witness scripts.
if ( sigversion = = SigVersion : : WITNESS_V0 & & ! MoneyRange ( amount ) ) return false ;
2021-03-01 18:10:13 -08:00
2021-03-04 14:27:20 -08:00
// 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 ) ;
2014-08-27 17:22:33 +02:00
if ( ! key . Sign ( hash , vchSig ) )
return false ;
2021-03-04 14:27:20 -08:00
vchSig . push_back ( ( unsigned char ) hashtype ) ;
2014-11-04 10:06:20 -08:00
return true ;
}
2014-08-27 17:22:33 +02:00
2021-02-27 20:33:22 -08:00
bool MutableTransactionSignatureCreator : : CreateSchnorrSig ( const SigningProvider & provider , std : : vector < unsigned char > & sig , const XOnlyPubKey & pubkey , const uint256 * leaf_hash , const uint256 * merkle_root , SigVersion sigversion ) const
{
assert ( sigversion = = SigVersion : : TAPROOT | | sigversion = = SigVersion : : TAPSCRIPT ) ;
CKey key ;
2021-06-28 15:00:33 -04:00
if ( ! provider . GetKeyByXOnly ( pubkey , key ) ) return false ;
2021-02-27 20:33:22 -08:00
// BIP341/BIP342 signing needs lots of precomputed transaction data. While some
// (non-SIGHASH_DEFAULT) sighash modes exist that can work with just some subset
// of data present, for now, only support signing when everything is provided.
if ( ! m_txdata | | ! m_txdata - > m_bip341_taproot_ready | | ! m_txdata - > m_spent_outputs_ready ) return false ;
ScriptExecutionData execdata ;
execdata . m_annex_init = true ;
execdata . m_annex_present = false ; // Only support annex-less signing for now.
if ( sigversion = = SigVersion : : TAPSCRIPT ) {
execdata . m_codeseparator_pos_init = true ;
execdata . m_codeseparator_pos = 0xFFFFFFFF ; // Only support non-OP_CODESEPARATOR BIP342 signing for now.
if ( ! leaf_hash ) return false ; // BIP342 signing needs leaf hash.
execdata . m_tapleaf_hash_init = true ;
execdata . m_tapleaf_hash = * leaf_hash ;
}
uint256 hash ;
if ( ! SignatureHashSchnorr ( hash , execdata , * txTo , nIn , nHashType , sigversion , * m_txdata , MissingDataBehavior : : FAIL ) ) return false ;
sig . resize ( 64 ) ;
2021-10-28 13:46:52 -04:00
// Use uint256{} as aux_rnd for now.
if ( ! key . SignSchnorr ( hash , sig , merkle_root , { } ) ) return false ;
2021-02-27 20:33:22 -08:00
if ( nHashType ) sig . push_back ( nHashType ) ;
return true ;
}
2018-06-07 21:12:25 -07:00
static bool GetCScript ( const SigningProvider & provider , const SignatureData & sigdata , const CScriptID & scriptid , CScript & script )
{
if ( provider . GetCScript ( scriptid , script ) ) {
return true ;
}
// Look for scripts in SignatureData
if ( CScriptID ( sigdata . redeem_script ) = = scriptid ) {
script = sigdata . redeem_script ;
return true ;
} else if ( CScriptID ( sigdata . witness_script ) = = scriptid ) {
script = sigdata . witness_script ;
return true ;
}
return false ;
}
2018-11-13 10:42:10 -05:00
static bool GetPubKey ( const SigningProvider & provider , const SignatureData & sigdata , const CKeyID & address , CPubKey & pubkey )
2018-06-07 21:12:25 -07:00
{
// Look for pubkey in all partial sigs
const auto it = sigdata . signatures . find ( address ) ;
if ( it ! = sigdata . signatures . end ( ) ) {
pubkey = it - > second . first ;
return true ;
}
2018-06-27 16:56:30 -07:00
// Look for pubkey in pubkey list
const auto & pk_it = sigdata . misc_pubkeys . find ( address ) ;
if ( pk_it ! = sigdata . misc_pubkeys . end ( ) ) {
2018-07-19 18:47:24 -07:00
pubkey = pk_it - > second . first ;
return true ;
}
// Query the underlying provider
2018-11-07 10:50:32 -05:00
return provider . GetPubKey ( address , pubkey ) ;
2018-06-07 21:12:25 -07:00
}
2018-10-06 03:33:24 -07:00
static bool CreateSig ( const BaseSignatureCreator & creator , SignatureData & sigdata , const SigningProvider & provider , std : : vector < unsigned char > & sig_out , const CPubKey & pubkey , const CScript & scriptcode , SigVersion sigversion )
2018-06-07 21:12:25 -07:00
{
2018-10-06 03:33:24 -07:00
CKeyID keyid = pubkey . GetID ( ) ;
2018-06-07 21:12:25 -07:00
const auto it = sigdata . signatures . find ( keyid ) ;
if ( it ! = sigdata . signatures . end ( ) ) {
sig_out = it - > second . second ;
return true ;
}
2018-10-06 03:33:24 -07:00
KeyOriginInfo info ;
if ( provider . GetKeyOrigin ( keyid , info ) ) {
sigdata . misc_pubkeys . emplace ( keyid , std : : make_pair ( pubkey , std : : move ( info ) ) ) ;
}
2018-06-07 21:12:25 -07:00
if ( creator . CreateSig ( provider , sig_out , keyid , scriptcode , sigversion ) ) {
auto i = sigdata . signatures . emplace ( keyid , SigPair ( pubkey , sig_out ) ) ;
assert ( i . second ) ;
return true ;
}
2018-07-31 17:57:15 -07:00
// Could not make signature or signature not found, add keyid to missing
sigdata . missing_sigs . push_back ( keyid ) ;
2018-06-07 21:12:25 -07:00
return false ;
}
2021-02-27 20:33:22 -08:00
static bool CreateTaprootScriptSig ( const BaseSignatureCreator & creator , SignatureData & sigdata , const SigningProvider & provider , std : : vector < unsigned char > & sig_out , const XOnlyPubKey & pubkey , const uint256 & leaf_hash , SigVersion sigversion )
{
auto lookup_key = std : : make_pair ( pubkey , leaf_hash ) ;
auto it = sigdata . taproot_script_sigs . find ( lookup_key ) ;
if ( it ! = sigdata . taproot_script_sigs . end ( ) ) {
sig_out = it - > second ;
}
if ( creator . CreateSchnorrSig ( provider , sig_out , pubkey , & leaf_hash , nullptr , sigversion ) ) {
sigdata . taproot_script_sigs [ lookup_key ] = sig_out ;
return true ;
}
return false ;
}
static bool SignTaprootScript ( const SigningProvider & provider , const BaseSignatureCreator & creator , SignatureData & sigdata , int leaf_version , const CScript & script , std : : vector < valtype > & result )
{
// Only BIP342 tapscript signing is supported for now.
if ( leaf_version ! = TAPROOT_LEAF_TAPSCRIPT ) return false ;
SigVersion sigversion = SigVersion : : TAPSCRIPT ;
uint256 leaf_hash = ( CHashWriter ( HASHER_TAPLEAF ) < < uint8_t ( leaf_version ) < < script ) . GetSHA256 ( ) ;
// <xonly pubkey> OP_CHECKSIG
if ( script . size ( ) = = 34 & & script [ 33 ] = = OP_CHECKSIG & & script [ 0 ] = = 0x20 ) {
2021-11-01 16:32:53 -04:00
XOnlyPubKey pubkey { Span { script } . subspan ( 1 , 32 ) } ;
2021-02-27 20:33:22 -08:00
std : : vector < unsigned char > sig ;
if ( CreateTaprootScriptSig ( creator , sigdata , provider , sig , pubkey , leaf_hash , sigversion ) ) {
result = Vector ( std : : move ( sig ) ) ;
return true ;
}
2022-01-10 18:12:14 -05:00
return false ;
}
// multi_a scripts (<key> OP_CHECKSIG <key> OP_CHECKSIGADD <key> OP_CHECKSIGADD <k> OP_NUMEQUAL)
if ( auto match = MatchMultiA ( script ) ) {
std : : vector < std : : vector < unsigned char > > sigs ;
int good_sigs = 0 ;
for ( size_t i = 0 ; i < match - > second . size ( ) ; + + i ) {
XOnlyPubKey pubkey { * ( match - > second . rbegin ( ) + i ) } ;
std : : vector < unsigned char > sig ;
bool good_sig = CreateTaprootScriptSig ( creator , sigdata , provider , sig , pubkey , leaf_hash , sigversion ) ;
if ( good_sig & & good_sigs < match - > first ) {
+ + good_sigs ;
sigs . push_back ( std : : move ( sig ) ) ;
} else {
sigs . emplace_back ( ) ;
}
}
if ( good_sigs = = match - > first ) {
result = std : : move ( sigs ) ;
return true ;
}
return false ;
2021-02-27 20:33:22 -08:00
}
return false ;
}
static bool SignTaproot ( const SigningProvider & provider , const BaseSignatureCreator & creator , const WitnessV1Taproot & output , SignatureData & sigdata , std : : vector < valtype > & result )
{
TaprootSpendData spenddata ;
// Gather information about this output.
if ( provider . GetTaprootSpendData ( output , spenddata ) ) {
sigdata . tr_spenddata . Merge ( spenddata ) ;
}
// Try key path spending.
{
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 ) ) {
sigdata . taproot_key_path_sig = sig ;
}
}
if ( sigdata . taproot_key_path_sig . size ( ) ) {
result = Vector ( sigdata . taproot_key_path_sig ) ;
return true ;
}
}
// Try script path spending.
std : : vector < std : : vector < unsigned char > > smallest_result_stack ;
for ( const auto & [ key , control_blocks ] : sigdata . tr_spenddata . scripts ) {
const auto & [ script , leaf_ver ] = key ;
std : : vector < std : : vector < unsigned char > > result_stack ;
if ( SignTaprootScript ( provider , creator , sigdata , leaf_ver , script , result_stack ) ) {
result_stack . emplace_back ( std : : begin ( script ) , std : : end ( script ) ) ; // Push the script
result_stack . push_back ( * control_blocks . begin ( ) ) ; // Push the smallest control block
if ( smallest_result_stack . size ( ) = = 0 | |
GetSerializeSize ( result_stack , PROTOCOL_VERSION ) < GetSerializeSize ( smallest_result_stack , PROTOCOL_VERSION ) ) {
smallest_result_stack = std : : move ( result_stack ) ;
}
}
}
if ( smallest_result_stack . size ( ) ! = 0 ) {
result = std : : move ( smallest_result_stack ) ;
return true ;
}
return false ;
}
2014-11-10 14:40:01 +08:00
/**
2014-11-04 10:06:20 -08:00
* Sign scriptPubKey using signature made with creator .
2014-11-10 14:40:01 +08:00
* Signatures are returned in scriptSigRet ( or returns false if scriptPubKey can ' t be signed ) ,
2020-05-30 09:16:05 -04:00
* unless whichTypeRet is TxoutType : : SCRIPTHASH , in which case scriptSigRet is the redemption script .
2014-11-10 14:40:01 +08:00
* Returns false if scriptPubKey could not be completely satisfied .
*/
2018-03-27 13:15:10 -07:00
static bool SignStep ( const SigningProvider & provider , const BaseSignatureCreator & creator , const CScript & scriptPubKey ,
2020-05-30 09:16:05 -04:00
std : : vector < valtype > & ret , TxoutType & whichTypeRet , SigVersion sigversion , SignatureData & sigdata )
2014-08-27 17:22:33 +02:00
{
2016-03-31 14:54:58 +02:00
CScript scriptRet ;
uint160 h160 ;
ret . clear ( ) ;
2018-06-09 12:06:25 -07:00
std : : vector < unsigned char > sig ;
2014-08-27 17:22:33 +02:00
2017-01-04 14:42:14 +09:00
std : : vector < valtype > vSolutions ;
2018-06-10 22:19:07 -07:00
whichTypeRet = Solver ( scriptPubKey , vSolutions ) ;
2014-08-27 17:22:33 +02:00
2020-10-21 13:57:24 +02:00
switch ( whichTypeRet ) {
2020-05-30 09:16:05 -04:00
case TxoutType : : NONSTANDARD :
case TxoutType : : NULL_DATA :
case TxoutType : : WITNESS_UNKNOWN :
2014-08-27 17:22:33 +02:00
return false ;
2020-05-30 09:16:05 -04:00
case TxoutType : : PUBKEY :
2018-10-06 03:33:24 -07:00
if ( ! CreateSig ( creator , sigdata , provider , sig , CPubKey ( vSolutions [ 0 ] ) , scriptPubKey , sigversion ) ) return false ;
2018-06-09 12:06:25 -07:00
ret . push_back ( std : : move ( sig ) ) ;
2014-08-27 17:22:33 +02:00
return true ;
2020-05-30 09:16:05 -04:00
case TxoutType : : PUBKEYHASH : {
2018-06-09 12:06:25 -07:00
CKeyID keyID = CKeyID ( uint160 ( vSolutions [ 0 ] ) ) ;
CPubKey pubkey ;
2018-07-31 17:57:15 -07:00
if ( ! GetPubKey ( provider , sigdata , keyID , pubkey ) ) {
// Pubkey could not be found, add to missing
sigdata . missing_pubkeys . push_back ( keyID ) ;
return false ;
}
2018-10-06 03:33:24 -07:00
if ( ! CreateSig ( creator , sigdata , provider , sig , pubkey , scriptPubKey , sigversion ) ) return false ;
ret . push_back ( std : : move ( sig ) ) ;
2018-06-09 12:06:25 -07:00
ret . push_back ( ToByteVector ( pubkey ) ) ;
return true ;
}
2020-05-30 09:16:05 -04:00
case TxoutType : : SCRIPTHASH :
2018-07-31 17:57:15 -07:00
h160 = uint160 ( vSolutions [ 0 ] ) ;
2020-01-14 22:48:34 -08:00
if ( GetCScript ( provider , sigdata , CScriptID { h160 } , scriptRet ) ) {
2016-03-31 14:54:58 +02:00
ret . push_back ( std : : vector < unsigned char > ( scriptRet . begin ( ) , scriptRet . end ( ) ) ) ;
return true ;
}
2018-07-31 17:57:15 -07:00
// Could not find redeemScript, add to missing
sigdata . missing_redeem_script = h160 ;
2016-03-31 14:54:58 +02:00
return false ;
2014-08-27 17:22:33 +02:00
2020-05-30 09:16:05 -04:00
case TxoutType : : MULTISIG : {
2018-06-09 12:06:25 -07:00
size_t required = vSolutions . front ( ) [ 0 ] ;
2016-03-31 14:54:58 +02:00
ret . push_back ( valtype ( ) ) ; // workaround CHECKMULTISIG bug
2018-06-09 12:06:25 -07:00
for ( size_t i = 1 ; i < vSolutions . size ( ) - 1 ; + + i ) {
CPubKey pubkey = CPubKey ( vSolutions [ i ] ) ;
2019-07-03 16:58:28 -04:00
// We need to always call CreateSig in order to fill sigdata with all
// possible signatures that we can create. This will allow further PSBT
// processing to work as it needs all possible signature and pubkey pairs
if ( CreateSig ( creator , sigdata , provider , sig , pubkey , scriptPubKey , sigversion ) ) {
if ( ret . size ( ) < required + 1 ) {
ret . push_back ( std : : move ( sig ) ) ;
}
2018-06-09 12:06:25 -07:00
}
}
bool ok = ret . size ( ) = = required + 1 ;
for ( size_t i = 0 ; i + ret . size ( ) < required + 1 ; + + i ) {
ret . push_back ( valtype ( ) ) ;
}
return ok ;
}
2020-05-30 09:16:05 -04:00
case TxoutType : : WITNESS_V0_KEYHASH :
2016-03-31 14:54:58 +02:00
ret . push_back ( vSolutions [ 0 ] ) ;
return true ;
2020-05-30 09:16:05 -04:00
case TxoutType : : WITNESS_V0_SCRIPTHASH :
2021-04-30 20:03:35 +02:00
CRIPEMD160 ( ) . Write ( vSolutions [ 0 ] . data ( ) , vSolutions [ 0 ] . size ( ) ) . Finalize ( h160 . begin ( ) ) ;
2020-01-14 22:48:34 -08:00
if ( GetCScript ( provider , sigdata , CScriptID { h160 } , scriptRet ) ) {
2016-03-31 14:54:58 +02:00
ret . push_back ( std : : vector < unsigned char > ( scriptRet . begin ( ) , scriptRet . end ( ) ) ) ;
return true ;
}
2018-07-31 17:57:15 -07:00
// Could not find witnessScript, add to missing
sigdata . missing_witness_script = uint256 ( vSolutions [ 0 ] ) ;
2016-03-31 14:54:58 +02:00
return false ;
2021-02-27 20:33:22 -08:00
case TxoutType : : WITNESS_V1_TAPROOT :
return SignTaproot ( provider , creator , WitnessV1Taproot ( XOnlyPubKey { vSolutions [ 0 ] } ) , sigdata , ret ) ;
2020-10-21 13:57:24 +02:00
} // no default case, so the compiler can warn about missing cases
assert ( false ) ;
2014-08-27 17:22:33 +02:00
}
2017-01-04 14:42:14 +09:00
static CScript PushAll ( const std : : vector < valtype > & values )
2014-08-27 17:22:33 +02:00
{
2016-03-31 14:54:58 +02:00
CScript result ;
2017-06-02 03:18:57 +02:00
for ( const valtype & v : values ) {
2016-03-31 14:54:58 +02:00
if ( v . size ( ) = = 0 ) {
result < < OP_0 ;
} else if ( v . size ( ) = = 1 & & v [ 0 ] > = 1 & & v [ 0 ] < = 16 ) {
result < < CScript : : EncodeOP_N ( v [ 0 ] ) ;
2018-04-25 16:49:39 -07:00
} else if ( v . size ( ) = = 1 & & v [ 0 ] = = 0x81 ) {
result < < OP_1NEGATE ;
2016-03-31 14:54:58 +02:00
} else {
result < < v ;
}
}
return result ;
}
2018-03-27 13:15:10 -07:00
bool ProduceSignature ( const SigningProvider & provider , const BaseSignatureCreator & creator , const CScript & fromPubKey , SignatureData & sigdata )
2016-03-31 14:54:58 +02:00
{
2018-07-03 17:18:52 -07:00
if ( sigdata . complete ) return true ;
2016-03-31 14:54:58 +02:00
std : : vector < valtype > result ;
2020-05-30 09:16:05 -04:00
TxoutType whichType ;
2018-06-07 21:12:25 -07:00
bool solved = SignStep ( provider , creator , fromPubKey , result , whichType , SigVersion : : BASE , sigdata ) ;
2016-03-31 14:54:58 +02:00
bool P2SH = false ;
CScript subscript ;
2014-08-27 17:22:33 +02:00
2020-05-30 09:16:05 -04:00
if ( solved & & whichType = = TxoutType : : SCRIPTHASH )
2014-08-27 17:22:33 +02:00
{
2016-03-31 14:54:58 +02:00
// Solver returns the subscript that needs to be evaluated;
2014-08-27 17:22:33 +02:00
// the final scriptSig is the signatures from that
// and then the serialized subscript:
2017-12-13 15:16:23 -05:00
subscript = CScript ( result [ 0 ] . begin ( ) , result [ 0 ] . end ( ) ) ;
2018-06-07 21:12:25 -07:00
sigdata . redeem_script = subscript ;
2020-05-30 09:16:05 -04:00
solved = solved & & SignStep ( provider , creator , subscript , result , whichType , SigVersion : : BASE , sigdata ) & & whichType ! = TxoutType : : SCRIPTHASH ;
2016-03-31 14:54:58 +02:00
P2SH = true ;
}
2014-08-27 17:22:33 +02:00
2020-05-30 09:16:05 -04:00
if ( solved & & whichType = = TxoutType : : WITNESS_V0_KEYHASH )
2016-03-31 14:54:58 +02:00
{
CScript witnessscript ;
witnessscript < < OP_DUP < < OP_HASH160 < < ToByteVector ( result [ 0 ] ) < < OP_EQUALVERIFY < < OP_CHECKSIG ;
2020-05-30 09:16:05 -04:00
TxoutType subType ;
2018-06-07 21:12:25 -07:00
solved = solved & & SignStep ( provider , creator , witnessscript , result , subType , SigVersion : : WITNESS_V0 , sigdata ) ;
2016-03-31 14:54:58 +02:00
sigdata . scriptWitness . stack = result ;
2018-06-27 16:56:30 -07:00
sigdata . witness = true ;
2016-03-31 14:54:58 +02:00
result . clear ( ) ;
}
2020-05-30 09:16:05 -04:00
else if ( solved & & whichType = = TxoutType : : WITNESS_V0_SCRIPTHASH )
2016-03-31 14:54:58 +02:00
{
CScript witnessscript ( result [ 0 ] . begin ( ) , result [ 0 ] . end ( ) ) ;
2018-06-07 21:12:25 -07:00
sigdata . witness_script = witnessscript ;
2020-05-30 09:16:05 -04:00
TxoutType subType ;
solved = solved & & SignStep ( provider , creator , witnessscript , result , subType , SigVersion : : WITNESS_V0 , sigdata ) & & subType ! = TxoutType : : SCRIPTHASH & & subType ! = TxoutType : : WITNESS_V0_SCRIPTHASH & & subType ! = TxoutType : : WITNESS_V0_KEYHASH ;
2016-03-31 14:54:58 +02:00
result . push_back ( std : : vector < unsigned char > ( witnessscript . begin ( ) , witnessscript . end ( ) ) ) ;
sigdata . scriptWitness . stack = result ;
2018-06-27 16:56:30 -07:00
sigdata . witness = true ;
2016-03-31 14:54:58 +02:00
result . clear ( ) ;
2021-02-27 20:33:22 -08:00
} else if ( whichType = = TxoutType : : WITNESS_V1_TAPROOT & & ! P2SH ) {
sigdata . witness = true ;
if ( solved ) {
sigdata . scriptWitness . stack = std : : move ( result ) ;
}
result . clear ( ) ;
2020-05-30 09:16:05 -04:00
} else if ( solved & & whichType = = TxoutType : : WITNESS_UNKNOWN ) {
2018-06-27 16:56:30 -07:00
sigdata . witness = true ;
2014-08-27 17:22:33 +02:00
}
2021-02-27 20:26:54 -08:00
if ( ! sigdata . witness ) sigdata . scriptWitness . stack . clear ( ) ;
2016-03-31 14:54:58 +02:00
if ( P2SH ) {
result . push_back ( std : : vector < unsigned char > ( subscript . begin ( ) , subscript . end ( ) ) ) ;
}
sigdata . scriptSig = PushAll ( result ) ;
2014-08-27 17:22:33 +02:00
// Test solution
2018-07-03 17:18:52 -07:00
sigdata . complete = solved & & VerifyScript ( sigdata . scriptSig , fromPubKey , & sigdata . scriptWitness , STANDARD_SCRIPT_VERIFY_FLAGS , creator . Checker ( ) ) ;
return sigdata . complete ;
}
2018-07-15 12:19:12 -04:00
namespace {
2021-02-12 14:18:50 -05:00
class SignatureExtractorChecker final : public DeferringSignatureChecker
2018-07-03 17:18:52 -07:00
{
private :
SignatureData & sigdata ;
public :
2021-02-12 14:18:50 -05:00
SignatureExtractorChecker ( SignatureData & sigdata , BaseSignatureChecker & checker ) : DeferringSignatureChecker ( checker ) , sigdata ( sigdata ) { }
2020-09-11 14:33:23 -07:00
bool CheckECDSASignature ( const std : : vector < unsigned char > & scriptSig , const std : : vector < unsigned char > & vchPubKey , const CScript & scriptCode , SigVersion sigversion ) const override
2018-07-15 12:19:12 -04:00
{
2021-02-12 14:18:50 -05:00
if ( m_checker . CheckECDSASignature ( scriptSig , vchPubKey , scriptCode , sigversion ) ) {
2018-07-15 12:19:12 -04:00
CPubKey pubkey ( vchPubKey ) ;
sigdata . signatures . emplace ( pubkey . GetID ( ) , SigPair ( pubkey , scriptSig ) ) ;
return true ;
}
return false ;
2018-07-03 17:18:52 -07:00
}
2018-07-15 12:19:12 -04:00
} ;
2018-07-03 17:18:52 -07:00
struct Stacks
{
std : : vector < valtype > script ;
std : : vector < valtype > witness ;
2018-07-05 23:43:54 -04:00
Stacks ( ) = delete ;
Stacks ( const Stacks & ) = delete ;
2018-07-03 17:18:52 -07:00
explicit Stacks ( const SignatureData & data ) : witness ( data . scriptWitness . stack ) {
EvalScript ( script , data . scriptSig , SCRIPT_VERIFY_STRICTENC , BaseSignatureChecker ( ) , SigVersion : : BASE ) ;
}
} ;
2016-03-31 14:54:58 +02:00
}
2018-07-03 17:18:52 -07:00
// Extracts signatures and scripts from incomplete scriptSigs. Please do not extend this, use PSBT instead
SignatureData DataFromTransaction ( const CMutableTransaction & tx , unsigned int nIn , const CTxOut & txout )
2016-03-31 14:54:58 +02:00
{
SignatureData data ;
assert ( tx . vin . size ( ) > nIn ) ;
data . scriptSig = tx . vin [ nIn ] . scriptSig ;
2016-08-04 02:49:16 +02:00
data . scriptWitness = tx . vin [ nIn ] . scriptWitness ;
2018-07-03 17:18:52 -07:00
Stacks stack ( data ) ;
// Get signatures
2021-03-01 18:07:14 -08:00
MutableTransactionSignatureChecker tx_checker ( & tx , nIn , txout . nValue , MissingDataBehavior : : FAIL ) ;
2018-07-03 17:18:52 -07:00
SignatureExtractorChecker extractor_checker ( data , tx_checker ) ;
if ( VerifyScript ( data . scriptSig , txout . scriptPubKey , & data . scriptWitness , STANDARD_SCRIPT_VERIFY_FLAGS , extractor_checker ) ) {
data . complete = true ;
return data ;
}
// Get scripts
std : : vector < std : : vector < unsigned char > > solutions ;
2020-05-30 09:16:05 -04:00
TxoutType script_type = Solver ( txout . scriptPubKey , solutions ) ;
2018-07-03 17:18:52 -07:00
SigVersion sigversion = SigVersion : : BASE ;
CScript next_script = txout . scriptPubKey ;
2020-05-30 09:16:05 -04:00
if ( script_type = = TxoutType : : SCRIPTHASH & & ! stack . script . empty ( ) & & ! stack . script . back ( ) . empty ( ) ) {
2018-07-03 17:18:52 -07:00
// Get the redeemScript
CScript redeem_script ( stack . script . back ( ) . begin ( ) , stack . script . back ( ) . end ( ) ) ;
data . redeem_script = redeem_script ;
next_script = std : : move ( redeem_script ) ;
// Get redeemScript type
2018-06-10 22:19:07 -07:00
script_type = Solver ( next_script , solutions ) ;
2018-07-03 17:18:52 -07:00
stack . script . pop_back ( ) ;
}
2020-05-30 09:16:05 -04:00
if ( script_type = = TxoutType : : WITNESS_V0_SCRIPTHASH & & ! stack . witness . empty ( ) & & ! stack . witness . back ( ) . empty ( ) ) {
2018-07-03 17:18:52 -07:00
// Get the witnessScript
CScript witness_script ( stack . witness . back ( ) . begin ( ) , stack . witness . back ( ) . end ( ) ) ;
data . witness_script = witness_script ;
next_script = std : : move ( witness_script ) ;
// Get witnessScript type
2018-06-10 22:19:07 -07:00
script_type = Solver ( next_script , solutions ) ;
2018-07-03 17:18:52 -07:00
stack . witness . pop_back ( ) ;
stack . script = std : : move ( stack . witness ) ;
stack . witness . clear ( ) ;
sigversion = SigVersion : : WITNESS_V0 ;
}
2020-05-30 09:16:05 -04:00
if ( script_type = = TxoutType : : MULTISIG & & ! stack . script . empty ( ) ) {
2018-07-03 17:18:52 -07:00
// Build a map of pubkey -> signature by matching sigs to pubkeys:
assert ( solutions . size ( ) > 1 ) ;
unsigned int num_pubkeys = solutions . size ( ) - 2 ;
unsigned int last_success_key = 0 ;
for ( const valtype & sig : stack . script ) {
for ( unsigned int i = last_success_key ; i < num_pubkeys ; + + i ) {
const valtype & pubkey = solutions [ i + 1 ] ;
// We either have a signature for this pubkey, or we have found a signature and it is valid
2020-09-11 14:33:23 -07:00
if ( data . signatures . count ( CPubKey ( pubkey ) . GetID ( ) ) | | extractor_checker . CheckECDSASignature ( sig , pubkey , next_script , sigversion ) ) {
2018-07-03 17:18:52 -07:00
last_success_key = i + 1 ;
break ;
}
}
}
}
2016-03-31 14:54:58 +02:00
return data ;
}
2018-03-05 16:37:24 -05:00
void UpdateInput ( CTxIn & input , const SignatureData & data )
{
input . scriptSig = data . scriptSig ;
input . scriptWitness = data . scriptWitness ;
}
2018-06-07 21:12:25 -07:00
void SignatureData : : MergeSignatureData ( SignatureData sigdata )
{
if ( complete ) return ;
if ( sigdata . complete ) {
* this = std : : move ( sigdata ) ;
return ;
}
if ( redeem_script . empty ( ) & & ! sigdata . redeem_script . empty ( ) ) {
redeem_script = sigdata . redeem_script ;
}
if ( witness_script . empty ( ) & & ! sigdata . witness_script . empty ( ) ) {
witness_script = sigdata . witness_script ;
}
signatures . insert ( std : : make_move_iterator ( sigdata . signatures . begin ( ) ) , std : : make_move_iterator ( sigdata . signatures . end ( ) ) ) ;
}
2018-03-17 19:19:09 -07:00
bool SignSignature ( const SigningProvider & provider , const CScript & fromPubKey , CMutableTransaction & txTo , unsigned int nIn , const CAmount & amount , int nHashType )
2014-11-04 10:06:20 -08:00
{
assert ( nIn < txTo . vin . size ( ) ) ;
2018-05-20 22:47:14 +02:00
MutableTransactionSignatureCreator creator ( & txTo , nIn , amount , nHashType ) ;
2014-11-04 10:06:20 -08:00
2016-03-31 14:54:58 +02:00
SignatureData sigdata ;
2018-03-27 13:15:10 -07:00
bool ret = ProduceSignature ( provider , creator , fromPubKey , sigdata ) ;
2018-05-17 17:54:18 -07:00
UpdateInput ( txTo . vin . at ( nIn ) , sigdata ) ;
2016-03-31 14:54:58 +02:00
return ret ;
2014-08-27 17:22:33 +02:00
}
2018-03-17 19:19:09 -07:00
bool SignSignature ( const SigningProvider & provider , const CTransaction & txFrom , CMutableTransaction & txTo , unsigned int nIn , int nHashType )
2014-08-27 17:22:33 +02:00
{
assert ( nIn < txTo . vin . size ( ) ) ;
2020-12-06 16:11:39 +00:00
const CTxIn & txin = txTo . vin [ nIn ] ;
2014-08-27 17:22:33 +02:00
assert ( txin . prevout . n < txFrom . vout . size ( ) ) ;
const CTxOut & txout = txFrom . vout [ txin . prevout . n ] ;
2018-03-17 19:19:09 -07:00
return SignSignature ( provider , txout . scriptPubKey , txTo , nIn , txout . nValue , nHashType ) ;
2014-08-27 17:22:33 +02:00
}
2015-05-01 15:21:06 +02:00
namespace {
/** Dummy signature checker which accepts all signatures. */
2018-03-27 13:34:39 -07:00
class DummySignatureChecker final : public BaseSignatureChecker
2015-05-01 15:21:06 +02:00
{
public :
DummySignatureChecker ( ) { }
2020-09-11 14:33:23 -07:00
bool CheckECDSASignature ( const std : : vector < unsigned char > & scriptSig , const std : : vector < unsigned char > & vchPubKey , const CScript & scriptCode , SigVersion sigversion ) const override { return true ; }
2022-01-19 12:32:06 -08:00
bool CheckSchnorrSignature ( Span < const unsigned char > sig , Span < const unsigned char > pubkey , SigVersion sigversion , ScriptExecutionData & execdata , ScriptError * serror ) const override { return true ; }
2018-03-27 13:34:39 -07:00
} ;
const DummySignatureChecker DUMMY_CHECKER ;
2015-05-01 15:21:06 +02:00
2018-03-27 13:34:39 -07:00
class DummySignatureCreator final : public BaseSignatureCreator {
2018-08-07 16:59:53 -07:00
private :
char m_r_len = 32 ;
char m_s_len = 32 ;
2018-03-27 13:34:39 -07:00
public :
2018-08-07 16:59:53 -07:00
DummySignatureCreator ( char r_len , char s_len ) : m_r_len ( r_len ) , m_s_len ( s_len ) { }
2018-03-27 13:34:39 -07:00
const BaseSignatureChecker & Checker ( ) const override { return DUMMY_CHECKER ; }
bool CreateSig ( const SigningProvider & provider , std : : vector < unsigned char > & vchSig , const CKeyID & keyid , const CScript & scriptCode , SigVersion sigversion ) const override
2015-05-01 15:21:06 +02:00
{
2018-03-27 13:34:39 -07:00
// Create a dummy signature that is a valid DER-encoding
2018-08-07 16:59:53 -07:00
vchSig . assign ( m_r_len + m_s_len + 7 , ' \000 ' ) ;
2018-03-27 13:34:39 -07:00
vchSig [ 0 ] = 0x30 ;
2018-08-07 16:59:53 -07:00
vchSig [ 1 ] = m_r_len + m_s_len + 4 ;
2018-03-27 13:34:39 -07:00
vchSig [ 2 ] = 0x02 ;
2018-08-07 16:59:53 -07:00
vchSig [ 3 ] = m_r_len ;
2018-03-27 13:34:39 -07:00
vchSig [ 4 ] = 0x01 ;
2018-08-07 16:59:53 -07:00
vchSig [ 4 + m_r_len ] = 0x02 ;
vchSig [ 5 + m_r_len ] = m_s_len ;
vchSig [ 6 + m_r_len ] = 0x01 ;
vchSig [ 6 + m_r_len + m_s_len ] = SIGHASH_ALL ;
2015-05-01 15:21:06 +02:00
return true ;
}
2021-02-27 20:33:22 -08:00
bool CreateSchnorrSig ( const SigningProvider & provider , std : : vector < unsigned char > & sig , const XOnlyPubKey & pubkey , const uint256 * leaf_hash , const uint256 * tweak , SigVersion sigversion ) const override
{
sig . assign ( 64 , ' \000 ' ) ;
return true ;
}
2015-05-01 15:21:06 +02:00
} ;
2018-07-12 15:03:55 -07:00
2015-05-01 15:21:06 +02:00
}
2018-08-07 16:59:53 -07:00
const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR = DummySignatureCreator ( 32 , 32 ) ;
const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR = DummySignatureCreator ( 33 , 32 ) ;
2017-11-30 16:48:31 -08:00
2018-03-17 19:19:09 -07:00
bool IsSolvable ( const SigningProvider & provider , const CScript & script )
2017-11-30 16:48:31 -08:00
{
// This check is to make sure that the script we created can actually be solved for and signed by us
// if we were to have the private keys. This is just to make sure that the script is valid and that,
// if found in a transaction, we would still accept and relay that transaction. In particular,
// it will reject witness outputs that require signing with an uncompressed public key.
SignatureData sigs ;
// Make sure that STANDARD_SCRIPT_VERIFY_FLAGS includes SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, the most
// important property this function is designed to test for.
static_assert ( STANDARD_SCRIPT_VERIFY_FLAGS & SCRIPT_VERIFY_WITNESS_PUBKEYTYPE , " IsSolvable requires standard script flags to include WITNESS_PUBKEYTYPE " ) ;
2018-03-27 13:34:39 -07:00
if ( ProduceSignature ( provider , DUMMY_SIGNATURE_CREATOR , script , sigs ) ) {
2017-11-30 16:48:31 -08:00
// VerifyScript check is just defensive, and should never fail.
2018-06-26 17:19:31 +02:00
bool verified = VerifyScript ( sigs . scriptSig , script , & sigs . scriptWitness , STANDARD_SCRIPT_VERIFY_FLAGS , DUMMY_CHECKER ) ;
assert ( verified ) ;
2017-11-30 16:48:31 -08:00
return true ;
}
return false ;
}
2018-06-27 16:53:48 -07:00
2019-02-16 14:18:54 -08:00
bool IsSegWitOutput ( const SigningProvider & provider , const CScript & script )
{
2021-07-09 09:58:34 -07:00
int version ;
valtype program ;
if ( script . IsWitnessProgram ( version , program ) ) return true ;
if ( script . IsPayToScriptHash ( ) ) {
std : : vector < valtype > solutions ;
auto whichtype = Solver ( script , solutions ) ;
if ( whichtype = = TxoutType : : SCRIPTHASH ) {
auto h160 = uint160 ( solutions [ 0 ] ) ;
CScript subscript ;
if ( provider . GetCScript ( CScriptID { h160 } , subscript ) ) {
if ( subscript . IsWitnessProgram ( version , program ) ) return true ;
}
2019-02-16 14:18:54 -08:00
}
}
return false ;
}
2020-02-10 19:19:59 -05:00
2021-06-23 17:28:54 -04:00
bool SignTransaction ( CMutableTransaction & mtx , const SigningProvider * keystore , const std : : map < COutPoint , Coin > & coins , int nHashType , std : : map < int , bilingual_str > & input_errors )
2020-02-10 19:19:59 -05:00
{
bool fHashSingle = ( ( nHashType & ~ SIGHASH_ANYONECANPAY ) = = SIGHASH_SINGLE ) ;
// Use CTransaction for the constant parts of the
// transaction to avoid rehashing.
const CTransaction txConst ( mtx ) ;
2021-02-27 20:30:18 -08:00
PrecomputedTransactionData txdata ;
std : : vector < CTxOut > spent_outputs ;
2021-06-17 17:25:07 -07:00
for ( unsigned int i = 0 ; i < mtx . vin . size ( ) ; + + i ) {
2021-02-27 20:30:18 -08:00
CTxIn & txin = mtx . vin [ i ] ;
auto coin = coins . find ( txin . prevout ) ;
if ( coin = = coins . end ( ) | | coin - > second . IsSpent ( ) ) {
2022-04-02 16:01:40 +01:00
txdata . Init ( txConst , /*spent_outputs=*/ { } , /*force=*/ true ) ;
2021-06-17 17:25:07 -07:00
break ;
2021-02-27 20:30:18 -08:00
} else {
2021-06-17 17:25:07 -07:00
spent_outputs . emplace_back ( coin - > second . out . nValue , coin - > second . out . scriptPubKey ) ;
2021-02-27 20:30:18 -08:00
}
}
2021-06-17 17:25:07 -07:00
if ( spent_outputs . size ( ) = = mtx . vin . size ( ) ) {
2021-02-27 20:30:18 -08:00
txdata . Init ( txConst , std : : move ( spent_outputs ) , true ) ;
}
2020-02-10 19:19:59 -05:00
// Sign what we can:
2021-06-17 17:25:07 -07:00
for ( unsigned int i = 0 ; i < mtx . vin . size ( ) ; + + i ) {
2020-02-10 19:19:59 -05:00
CTxIn & txin = mtx . vin [ i ] ;
auto coin = coins . find ( txin . prevout ) ;
if ( coin = = coins . end ( ) | | coin - > second . IsSpent ( ) ) {
2021-06-23 17:28:54 -04:00
input_errors [ i ] = _ ( " Input not found or already spent " ) ;
2020-02-10 19:19:59 -05:00
continue ;
}
const CScript & prevPubKey = coin - > second . out . scriptPubKey ;
const CAmount & amount = coin - > second . out . nValue ;
SignatureData sigdata = DataFromTransaction ( mtx , i , coin - > second . out ) ;
// Only sign SIGHASH_SINGLE if there's a corresponding output:
if ( ! fHashSingle | | ( i < mtx . vout . size ( ) ) ) {
2021-02-27 20:30:18 -08:00
ProduceSignature ( * keystore , MutableTransactionSignatureCreator ( & mtx , i , amount , & txdata , nHashType ) , prevPubKey , sigdata ) ;
2020-02-10 19:19:59 -05:00
}
UpdateInput ( txin , sigdata ) ;
// amount must be specified for valid segwit signature
if ( amount = = MAX_MONEY & & ! txin . scriptWitness . IsNull ( ) ) {
2021-06-23 17:28:54 -04:00
input_errors [ i ] = _ ( " Missing amount " ) ;
2020-02-10 19:19:59 -05:00
continue ;
}
ScriptError serror = SCRIPT_ERR_OK ;
2021-02-27 20:30:18 -08:00
if ( ! VerifyScript ( txin . scriptSig , prevPubKey , & txin . scriptWitness , STANDARD_SCRIPT_VERIFY_FLAGS , TransactionSignatureChecker ( & txConst , i , amount , txdata , MissingDataBehavior : : FAIL ) , & serror ) ) {
2020-02-10 19:19:59 -05:00
if ( serror = = SCRIPT_ERR_INVALID_STACK_OPERATION ) {
// Unable to sign input and verification failed (possible attempt to partially sign).
2021-06-23 17:28:54 -04:00
input_errors [ i ] = Untranslated ( " Unable to sign input, invalid stack size (possibly missing key) " ) ;
2020-02-10 19:19:59 -05:00
} else if ( serror = = SCRIPT_ERR_SIG_NULLFAIL ) {
// Verification failed (possibly due to insufficient signatures).
2021-06-23 17:28:54 -04:00
input_errors [ i ] = Untranslated ( " CHECK(MULTI)SIG failing with non-zero signature (possibly need more signatures) " ) ;
2020-02-10 19:19:59 -05:00
} else {
2021-06-23 17:28:54 -04:00
input_errors [ i ] = Untranslated ( ScriptErrorString ( serror ) ) ;
2020-02-10 19:19:59 -05:00
}
2020-02-11 19:24:14 -05:00
} else {
// If this input succeeds, make sure there is no error set for it
input_errors . erase ( i ) ;
2020-02-10 19:19:59 -05:00
}
}
return input_errors . empty ( ) ;
}