2021-12-30 19:36:57 +02:00
// Copyright (c) 2020-2021 The Bitcoin Core developers
2020-05-16 18:20:39 +00:00
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# include <chainparams.h>
# include <key.h>
2019-07-25 11:26:20 -04:00
# include <psbt.h>
2020-05-16 18:20:39 +00:00
# include <pubkey.h>
# include <script/keyorigin.h>
# include <script/sign.h>
# include <script/signingprovider.h>
# include <streams.h>
# include <test/fuzz/FuzzedDataProvider.h>
# include <test/fuzz/fuzz.h>
# include <test/fuzz/util.h>
2023-04-17 22:20:59 +02:00
# include <util/chaintype.h>
2021-06-23 17:28:54 -04:00
# include <util/translation.h>
2020-05-16 18:20:39 +00:00
# include <cassert>
# include <cstdint>
# include <iostream>
# include <map>
# include <optional>
# include <string>
# include <vector>
2020-12-03 16:42:49 +01:00
void initialize_script_sign ( )
2020-05-16 18:20:39 +00:00
{
ECC_Start ( ) ;
2023-04-17 22:20:59 +02:00
SelectParams ( ChainType : : REGTEST ) ;
2020-05-16 18:20:39 +00:00
}
2023-07-11 14:33:31 +02:00
FUZZ_TARGET ( script_sign , . init = initialize_script_sign )
2020-05-16 18:20:39 +00:00
{
FuzzedDataProvider fuzzed_data_provider ( buffer . data ( ) , buffer . size ( ) ) ;
const std : : vector < uint8_t > key = ConsumeRandomLengthByteVector ( fuzzed_data_provider , 128 ) ;
{
2023-01-31 18:04:44 +01:00
DataStream stream { ConsumeDataStream ( fuzzed_data_provider ) } ;
CDataStream random_data_stream { stream , SER_NETWORK , INIT_PROTO_VERSION } ; // temporary copy, to be removed along with the version flag SERIALIZE_TRANSACTION_NO_WITNESS
2020-05-16 18:20:39 +00:00
std : : map < CPubKey , KeyOriginInfo > hd_keypaths ;
try {
DeserializeHDKeypaths ( random_data_stream , key , hd_keypaths ) ;
} catch ( const std : : ios_base : : failure & ) {
}
CDataStream serialized { SER_NETWORK , PROTOCOL_VERSION } ;
2019-10-02 15:49:33 -04:00
SerializeHDKeypaths ( serialized , hd_keypaths , CompactSizeWriter ( fuzzed_data_provider . ConsumeIntegral < uint8_t > ( ) ) ) ;
2020-05-16 18:20:39 +00:00
}
{
std : : map < CPubKey , KeyOriginInfo > hd_keypaths ;
2021-10-25 19:48:22 +00:00
LIMITED_WHILE ( fuzzed_data_provider . ConsumeBool ( ) , 10000 ) {
2020-05-16 18:20:39 +00:00
const std : : optional < CPubKey > pub_key = ConsumeDeserializable < CPubKey > ( fuzzed_data_provider ) ;
if ( ! pub_key ) {
break ;
}
const std : : optional < KeyOriginInfo > key_origin_info = ConsumeDeserializable < KeyOriginInfo > ( fuzzed_data_provider ) ;
if ( ! key_origin_info ) {
break ;
}
hd_keypaths [ * pub_key ] = * key_origin_info ;
}
CDataStream serialized { SER_NETWORK , PROTOCOL_VERSION } ;
try {
2019-10-02 15:49:33 -04:00
SerializeHDKeypaths ( serialized , hd_keypaths , CompactSizeWriter ( fuzzed_data_provider . ConsumeIntegral < uint8_t > ( ) ) ) ;
2020-05-16 18:20:39 +00:00
} catch ( const std : : ios_base : : failure & ) {
}
std : : map < CPubKey , KeyOriginInfo > deserialized_hd_keypaths ;
try {
DeserializeHDKeypaths ( serialized , key , hd_keypaths ) ;
} catch ( const std : : ios_base : : failure & ) {
}
assert ( hd_keypaths . size ( ) > = deserialized_hd_keypaths . size ( ) ) ;
}
{
SignatureData signature_data_1 { ConsumeScript ( fuzzed_data_provider ) } ;
SignatureData signature_data_2 { ConsumeScript ( fuzzed_data_provider ) } ;
signature_data_1 . MergeSignatureData ( signature_data_2 ) ;
}
FillableSigningProvider provider ;
2023-09-05 22:38:45 +02:00
CKey k = ConsumePrivateKey ( fuzzed_data_provider ) ;
2020-05-16 18:20:39 +00:00
if ( k . IsValid ( ) ) {
provider . AddKey ( k ) ;
}
{
const std : : optional < CMutableTransaction > mutable_transaction = ConsumeDeserializable < CMutableTransaction > ( fuzzed_data_provider ) ;
const std : : optional < CTxOut > tx_out = ConsumeDeserializable < CTxOut > ( fuzzed_data_provider ) ;
const unsigned int n_in = fuzzed_data_provider . ConsumeIntegral < unsigned int > ( ) ;
if ( mutable_transaction & & tx_out & & mutable_transaction - > vin . size ( ) > n_in ) {
SignatureData signature_data_1 = DataFromTransaction ( * mutable_transaction , n_in , * tx_out ) ;
CTxIn input ;
UpdateInput ( input , signature_data_1 ) ;
const CScript script = ConsumeScript ( fuzzed_data_provider ) ;
SignatureData signature_data_2 { script } ;
signature_data_1 . MergeSignatureData ( signature_data_2 ) ;
}
if ( mutable_transaction ) {
CTransaction tx_from { * mutable_transaction } ;
CMutableTransaction tx_to ;
const std : : optional < CMutableTransaction > opt_tx_to = ConsumeDeserializable < CMutableTransaction > ( fuzzed_data_provider ) ;
if ( opt_tx_to ) {
tx_to = * opt_tx_to ;
}
CMutableTransaction script_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 ( ) ) {
2021-12-04 14:39:24 +01:00
SignatureData empty ;
( void ) SignSignature ( provider , tx_from , tx_to , n_in , fuzzed_data_provider . ConsumeIntegral < int > ( ) , empty ) ;
2020-05-16 18:20:39 +00:00
}
if ( n_in < script_tx_to . vin . size ( ) ) {
2021-12-04 14:39:24 +01:00
SignatureData empty ;
( void ) SignSignature ( provider , ConsumeScript ( fuzzed_data_provider ) , script_tx_to , n_in , ConsumeMoney ( fuzzed_data_provider ) , fuzzed_data_provider . ConsumeIntegral < int > ( ) , empty ) ;
2020-07-01 19:31:53 +02:00
MutableTransactionSignatureCreator signature_creator { tx_to , n_in , ConsumeMoney ( fuzzed_data_provider ) , fuzzed_data_provider . ConsumeIntegral < int > ( ) } ;
2020-05-16 18:20:39 +00:00
std : : vector < unsigned char > vch_sig ;
CKeyID address ;
if ( fuzzed_data_provider . ConsumeBool ( ) ) {
if ( k . IsValid ( ) ) {
address = k . GetPubKey ( ) . GetID ( ) ;
}
} else {
address = CKeyID { ConsumeUInt160 ( fuzzed_data_provider ) } ;
}
( void ) signature_creator . CreateSig ( provider , vch_sig , address , ConsumeScript ( fuzzed_data_provider ) , fuzzed_data_provider . PickValueInArray ( { SigVersion : : BASE , SigVersion : : WITNESS_V0 } ) ) ;
}
std : : map < COutPoint , Coin > coins ;
2021-10-25 19:48:22 +00:00
LIMITED_WHILE ( fuzzed_data_provider . ConsumeBool ( ) , 10000 ) {
2020-05-16 18:20:39 +00:00
const std : : optional < COutPoint > outpoint = ConsumeDeserializable < COutPoint > ( fuzzed_data_provider ) ;
if ( ! outpoint ) {
break ;
}
const std : : optional < Coin > coin = ConsumeDeserializable < Coin > ( fuzzed_data_provider ) ;
if ( ! coin ) {
break ;
}
coins [ * outpoint ] = * coin ;
}
2021-06-23 17:28:54 -04:00
std : : map < int , bilingual_str > input_errors ;
2020-05-16 18:20:39 +00:00
( void ) SignTransaction ( sign_transaction_tx_to , & provider , coins , fuzzed_data_provider . ConsumeIntegral < int > ( ) , input_errors ) ;
}
}
{
SignatureData signature_data_1 ;
( void ) ProduceSignature ( provider , DUMMY_SIGNATURE_CREATOR , ConsumeScript ( fuzzed_data_provider ) , signature_data_1 ) ;
SignatureData signature_data_2 ;
( void ) ProduceSignature ( provider , DUMMY_MAXIMUM_SIGNATURE_CREATOR , ConsumeScript ( fuzzed_data_provider ) , signature_data_2 ) ;
}
}