2014-08-27 17:22:33 +02:00
// Copyright (c) 2009-2010 Satoshi Nakamoto
2018-07-27 00:36:45 +02:00
// Copyright (c) 2009-2018 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.
2014-11-03 16:16:40 +01:00
# ifndef BITCOIN_SCRIPT_SIGN_H
# define BITCOIN_SCRIPT_SIGN_H
2014-08-27 17:22:33 +02:00
2018-06-28 01:53:48 +02:00
# include <boost/optional.hpp>
# include <hash.h>
# include <pubkey.h>
2017-11-10 01:57:53 +01:00
# include <script/interpreter.h>
2018-06-28 01:53:48 +02:00
# include <streams.h>
2014-08-27 17:22:33 +02:00
2018-03-18 03:19:09 +01:00
class CKey ;
2014-11-04 19:06:20 +01:00
class CKeyID ;
2014-08-27 17:22:33 +02:00
class CScript ;
2018-03-18 03:19:09 +01:00
class CScriptID ;
2014-08-27 17:22:33 +02:00
class CTransaction ;
2014-09-09 10:00:42 +02:00
2014-08-27 17:22:33 +02:00
struct CMutableTransaction ;
2018-07-20 08:15:53 +02:00
struct KeyOriginInfo
{
2018-11-06 15:23:37 +01:00
unsigned char fingerprint [ 4 ] ; //!< First 32 bits of the Hash160 of the public key at the root of the path
2018-07-20 08:15:53 +02:00
std : : vector < uint32_t > path ;
2018-10-13 19:45:15 +02:00
friend bool operator = = ( const KeyOriginInfo & a , const KeyOriginInfo & b )
{
return std : : equal ( std : : begin ( a . fingerprint ) , std : : end ( a . fingerprint ) , std : : begin ( b . fingerprint ) ) & & a . path = = b . path ;
}
2018-11-06 15:23:37 +01:00
ADD_SERIALIZE_METHODS ;
template < typename Stream , typename Operation >
inline void SerializationOp ( Stream & s , Operation ser_action )
{
READWRITE ( fingerprint ) ;
READWRITE ( path ) ;
}
void clear ( )
{
memset ( fingerprint , 0 , 4 ) ;
path . clear ( ) ;
}
2018-07-20 08:15:53 +02:00
} ;
2018-03-18 03:19:09 +01:00
/** An interface to be implemented by keystores that support signing. */
class SigningProvider
{
public :
virtual ~ SigningProvider ( ) { }
2018-06-08 06:12:25 +02:00
virtual bool GetCScript ( const CScriptID & scriptid , CScript & script ) const { return false ; }
virtual bool GetPubKey ( const CKeyID & address , CPubKey & pubkey ) const { return false ; }
virtual bool GetKey ( const CKeyID & address , CKey & key ) const { return false ; }
2018-07-18 21:24:36 +02:00
virtual bool GetKeyOrigin ( const CKeyID & keyid , KeyOriginInfo & info ) const { return false ; }
2018-03-18 03:19:09 +01:00
} ;
2018-06-08 06:12:25 +02:00
extern const SigningProvider & DUMMY_SIGNING_PROVIDER ;
2018-07-20 09:04:02 +02:00
class HidingSigningProvider : public SigningProvider
2018-06-29 04:05:05 +02:00
{
private :
2018-07-20 09:04:02 +02:00
const bool m_hide_secret ;
const bool m_hide_origin ;
2018-06-29 04:05:05 +02:00
const SigningProvider * m_provider ;
public :
2018-07-20 09:04:02 +02:00
HidingSigningProvider ( const SigningProvider * provider , bool hide_secret , bool hide_origin ) : m_hide_secret ( hide_secret ) , m_hide_origin ( hide_origin ) , m_provider ( provider ) { }
bool GetCScript ( const CScriptID & scriptid , CScript & script ) const override ;
bool GetPubKey ( const CKeyID & keyid , CPubKey & pubkey ) const override ;
bool GetKey ( const CKeyID & keyid , CKey & key ) const override ;
bool GetKeyOrigin ( const CKeyID & keyid , KeyOriginInfo & info ) const override ;
2018-06-29 04:05:05 +02:00
} ;
2018-07-13 00:03:55 +02:00
struct FlatSigningProvider final : public SigningProvider
{
std : : map < CScriptID , CScript > scripts ;
std : : map < CKeyID , CPubKey > pubkeys ;
2019-04-04 21:45:32 +02:00
std : : map < CKeyID , std : : pair < CPubKey , KeyOriginInfo > > origins ;
2018-07-13 00:03:55 +02:00
std : : map < CKeyID , CKey > keys ;
bool GetCScript ( const CScriptID & scriptid , CScript & script ) const override ;
bool GetPubKey ( const CKeyID & keyid , CPubKey & pubkey ) const override ;
2018-07-18 21:24:36 +02:00
bool GetKeyOrigin ( const CKeyID & keyid , KeyOriginInfo & info ) const override ;
2018-07-13 00:03:55 +02:00
bool GetKey ( const CKeyID & keyid , CKey & key ) const override ;
} ;
FlatSigningProvider Merge ( const FlatSigningProvider & a , const FlatSigningProvider & b ) ;
2018-03-27 22:15:10 +02:00
/** Interface for signature creators. */
2014-11-04 19:06:20 +01:00
class BaseSignatureCreator {
public :
virtual ~ BaseSignatureCreator ( ) { }
virtual const BaseSignatureChecker & Checker ( ) const = 0 ;
/** Create a singular (non-script) signature. */
2018-03-27 22:15:10 +02:00
virtual bool CreateSig ( const SigningProvider & provider , std : : vector < unsigned char > & vchSig , const CKeyID & keyid , const CScript & scriptCode , SigVersion sigversion ) const = 0 ;
2014-11-04 19:06:20 +01:00
} ;
/** A signature creator for transactions. */
2018-05-20 22:47:14 +02:00
class MutableTransactionSignatureCreator : public BaseSignatureCreator {
const CMutableTransaction * txTo ;
2014-11-04 19:06:20 +01:00
unsigned int nIn ;
int nHashType ;
2015-12-27 19:49:08 +01:00
CAmount amount ;
2018-05-20 22:47:14 +02:00
const MutableTransactionSignatureChecker checker ;
2014-11-04 19:06:20 +01:00
public :
2018-05-20 22:47:14 +02:00
MutableTransactionSignatureCreator ( const CMutableTransaction * txToIn , unsigned int nInIn , const CAmount & amountIn , int nHashTypeIn = SIGHASH_ALL ) ;
2017-06-20 21:58:56 +02:00
const BaseSignatureChecker & Checker ( ) const override { return checker ; }
2018-03-27 22:15:10 +02:00
bool CreateSig ( const SigningProvider & provider , std : : vector < unsigned char > & vchSig , const CKeyID & keyid , const CScript & scriptCode , SigVersion sigversion ) const override ;
2016-03-31 14:54:58 +02:00
} ;
2018-08-08 01:59:53 +02:00
/** A signature creator that just produces 71-byte empty signatures. */
2018-03-27 22:34:39 +02:00
extern const BaseSignatureCreator & DUMMY_SIGNATURE_CREATOR ;
2018-08-08 01:59:53 +02:00
/** A signature creator that just produces 72-byte empty signatures. */
extern const BaseSignatureCreator & DUMMY_MAXIMUM_SIGNATURE_CREATOR ;
2016-03-31 14:54:58 +02:00
2018-07-04 02:18:52 +02:00
typedef std : : pair < CPubKey , std : : vector < unsigned char > > SigPair ;
// This struct contains information from a transaction input and also contains signatures for that input.
// The information contained here can be used to create a signature and is also filled by ProduceSignature
// in order to construct final scriptSigs and scriptWitnesses.
2016-03-31 14:54:58 +02:00
struct SignatureData {
2018-07-04 02:18:52 +02:00
bool complete = false ; ///< Stores whether the scriptSig and scriptWitness are complete
2018-06-28 01:56:30 +02:00
bool witness = false ; ///< Stores whether the input this SigData corresponds to is a witness input
2018-07-04 02:18:52 +02:00
CScript scriptSig ; ///< The scriptSig of an input. Contains complete signatures or the traditional partial signatures format
CScript redeem_script ; ///< The redeemScript (if any) for the input
CScript witness_script ; ///< The witnessScript (if any) for the input. witnessScripts are used in P2WSH outputs.
CScriptWitness scriptWitness ; ///< The scriptWitness of an input. Contains complete signatures or the traditional partial signatures format. scriptWitness is part of a transaction input per BIP 144.
std : : map < CKeyID , SigPair > signatures ; ///< BIP 174 style partial signatures for the input. May contain all signatures necessary for producing a final scriptSig or scriptWitness.
2018-07-20 03:47:24 +02:00
std : : map < CKeyID , std : : pair < CPubKey , KeyOriginInfo > > misc_pubkeys ;
2018-08-01 02:57:15 +02:00
std : : vector < CKeyID > missing_pubkeys ; ///< KeyIDs of pubkeys 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)
uint256 missing_witness_script ; ///< SHA256 of the missing witnessScript (if any)
2016-03-31 14:54:58 +02:00
SignatureData ( ) { }
explicit SignatureData ( const CScript & script ) : scriptSig ( script ) { }
2018-06-08 06:12:25 +02:00
void MergeSignatureData ( SignatureData sigdata ) ;
2015-05-01 15:21:06 +02:00
} ;
2018-07-19 02:52:43 +02:00
// Takes a stream and multiple arguments and serializes them as if first serialized into a vector and then into the stream
2018-06-28 01:53:48 +02:00
// The resulting output into the stream has the total serialized length of all of the objects followed by all objects concatenated with each other.
template < typename Stream , typename . . . X >
void SerializeToVector ( Stream & s , const X & . . . args )
{
2018-06-15 02:48:30 +02:00
WriteCompactSize ( s , GetSerializeSizeMany ( s . GetVersion ( ) , args . . . ) ) ;
2018-07-19 02:52:43 +02:00
SerializeMany ( s , args . . . ) ;
2018-06-28 01:53:48 +02:00
}
// Takes a stream and multiple arguments and unserializes them first as a vector then each object individually in the order provided in the arguments
template < typename Stream , typename . . . X >
void UnserializeFromVector ( Stream & s , X & . . . args )
{
2018-07-19 02:52:43 +02:00
size_t expected_size = ReadCompactSize ( s ) ;
size_t remaining_before = s . size ( ) ;
UnserializeMany ( s , args . . . ) ;
size_t remaining_after = s . size ( ) ;
if ( remaining_after + expected_size ! = remaining_before ) {
2018-06-28 01:53:48 +02:00
throw std : : ios_base : : failure ( " Size of value was not the stated size " ) ;
}
}
// Deserialize HD keypaths into a map
template < typename Stream >
2018-07-20 08:15:53 +02:00
void DeserializeHDKeypaths ( Stream & s , const std : : vector < unsigned char > & key , std : : map < CPubKey , KeyOriginInfo > & hd_keypaths )
2018-06-28 01:53:48 +02:00
{
// Make sure that the key is the size of pubkey + 1
if ( key . size ( ) ! = CPubKey : : PUBLIC_KEY_SIZE + 1 & & key . size ( ) ! = CPubKey : : COMPRESSED_PUBLIC_KEY_SIZE + 1 ) {
throw std : : ios_base : : failure ( " Size of key was not the expected size for the type BIP32 keypath " ) ;
}
// Read in the pubkey from key
CPubKey pubkey ( key . begin ( ) + 1 , key . end ( ) ) ;
if ( ! pubkey . IsFullyValid ( ) ) {
throw std : : ios_base : : failure ( " Invalid pubkey " ) ;
}
if ( hd_keypaths . count ( pubkey ) > 0 ) {
throw std : : ios_base : : failure ( " Duplicate Key, pubkey derivation path already provided " ) ;
}
// Read in key path
uint64_t value_len = ReadCompactSize ( s ) ;
2018-07-20 08:15:53 +02:00
if ( value_len % 4 | | value_len = = 0 ) {
throw std : : ios_base : : failure ( " Invalid length for HD key path " ) ;
}
KeyOriginInfo keypath ;
s > > keypath . fingerprint ;
for ( unsigned int i = 4 ; i < value_len ; i + = sizeof ( uint32_t ) ) {
2018-06-28 01:53:48 +02:00
uint32_t index ;
s > > index ;
2018-07-20 08:15:53 +02:00
keypath . path . push_back ( index ) ;
2018-06-28 01:53:48 +02:00
}
// Add to map
2018-07-20 08:15:53 +02:00
hd_keypaths . emplace ( pubkey , std : : move ( keypath ) ) ;
2018-06-28 01:53:48 +02:00
}
// Serialize HD keypaths to a stream from a map
template < typename Stream >
2018-07-20 08:15:53 +02:00
void SerializeHDKeypaths ( Stream & s , const std : : map < CPubKey , KeyOriginInfo > & hd_keypaths , uint8_t type )
2018-06-28 01:53:48 +02:00
{
for ( auto keypath_pair : hd_keypaths ) {
2018-11-08 16:33:05 +01:00
if ( ! keypath_pair . first . IsValid ( ) ) {
throw std : : ios_base : : failure ( " Invalid CPubKey being serialized " ) ;
}
2018-06-28 01:53:48 +02:00
SerializeToVector ( s , type , MakeSpan ( keypath_pair . first ) ) ;
2018-07-20 08:15:53 +02:00
WriteCompactSize ( s , ( keypath_pair . second . path . size ( ) + 1 ) * sizeof ( uint32_t ) ) ;
s < < keypath_pair . second . fingerprint ;
for ( const auto & path : keypath_pair . second . path ) {
2018-06-28 01:53:48 +02:00
s < < path ;
}
}
}
2014-11-04 19:06:20 +01:00
/** Produce a script signature using a generic signature creator. */
2018-03-27 22:15:10 +02:00
bool ProduceSignature ( const SigningProvider & provider , const BaseSignatureCreator & creator , const CScript & scriptPubKey , SignatureData & sigdata ) ;
2014-11-04 19:06:20 +01:00
/** Produce a script signature for a transaction. */
2018-03-18 03:19:09 +01:00
bool SignSignature ( const SigningProvider & provider , const CScript & fromPubKey , CMutableTransaction & txTo , unsigned int nIn , const CAmount & amount , int nHashType ) ;
bool SignSignature ( const SigningProvider & provider , const CTransaction & txFrom , CMutableTransaction & txTo , unsigned int nIn , int nHashType ) ;
2014-08-27 17:22:33 +02:00
2018-07-04 02:18:52 +02:00
/** Extract signature data from a transaction input, and insert it. */
SignatureData DataFromTransaction ( const CMutableTransaction & tx , unsigned int nIn , const CTxOut & txout ) ;
2018-03-05 22:37:24 +01:00
void UpdateInput ( CTxIn & input , const SignatureData & data ) ;
2014-08-27 17:22:33 +02:00
2017-12-01 01:48:31 +01:00
/* Check whether we know how to sign for an output like this, assuming we
* have all private keys . While this function does not need private keys , the passed
2018-03-18 03:19:09 +01:00
* provider is used to look up public keys and redeemscripts by hash .
2017-12-01 01:48:31 +01:00
* Solvability is unrelated to whether we consider this output to be ours . */
2018-03-18 03:19:09 +01:00
bool IsSolvable ( const SigningProvider & provider , const CScript & script ) ;
2017-12-01 01:48:31 +01:00
2014-11-03 16:16:40 +01:00
# endif // BITCOIN_SCRIPT_SIGN_H