Coverage Report

Created: 2025-03-18 19:34

/root/bitcoin/src/test/fuzz/script_sign.cpp
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2020-2021 The Bitcoin Core developers
2
// Distributed under the MIT software license, see the accompanying
3
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5
#include <chainparams.h>
6
#include <key.h>
7
#include <psbt.h>
8
#include <pubkey.h>
9
#include <script/keyorigin.h>
10
#include <script/sign.h>
11
#include <script/signingprovider.h>
12
#include <streams.h>
13
#include <test/fuzz/FuzzedDataProvider.h>
14
#include <test/fuzz/fuzz.h>
15
#include <test/fuzz/util.h>
16
#include <test/util/transaction_utils.h>
17
#include <util/chaintype.h>
18
#include <util/translation.h>
19
20
#include <cassert>
21
#include <cstdint>
22
#include <iostream>
23
#include <map>
24
#include <optional>
25
#include <string>
26
#include <vector>
27
28
void initialize_script_sign()
29
0
{
30
0
    static ECC_Context ecc_context{};
31
0
    SelectParams(ChainType::REGTEST);
32
0
}
33
34
FUZZ_TARGET(script_sign, .init = initialize_script_sign)
35
0
{
36
0
    FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
37
0
    const std::vector<uint8_t> key = ConsumeRandomLengthByteVector(fuzzed_data_provider, 128);
38
39
0
    {
40
0
        DataStream random_data_stream{ConsumeDataStream(fuzzed_data_provider)};
41
0
        std::map<CPubKey, KeyOriginInfo> hd_keypaths;
42
0
        try {
43
0
            DeserializeHDKeypaths(random_data_stream, key, hd_keypaths);
44
0
        } catch (const std::ios_base::failure&) {
45
0
        }
46
0
        DataStream serialized{};
47
0
        SerializeHDKeypaths(serialized, hd_keypaths, CompactSizeWriter(fuzzed_data_provider.ConsumeIntegral<uint8_t>()));
48
0
    }
49
50
0
    {
51
0
        std::map<CPubKey, KeyOriginInfo> hd_keypaths;
52
0
        LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 10000) {
53
0
            const std::optional<CPubKey> pub_key = ConsumeDeserializable<CPubKey>(fuzzed_data_provider);
54
0
            if (!pub_key) {
  Branch (54:17): [True: 0, False: 0]
55
0
                break;
56
0
            }
57
0
            const std::optional<KeyOriginInfo> key_origin_info = ConsumeDeserializable<KeyOriginInfo>(fuzzed_data_provider);
58
0
            if (!key_origin_info) {
  Branch (58:17): [True: 0, False: 0]
59
0
                break;
60
0
            }
61
0
            hd_keypaths[*pub_key] = *key_origin_info;
62
0
        }
63
0
        DataStream serialized{};
64
0
        try {
65
0
            SerializeHDKeypaths(serialized, hd_keypaths, CompactSizeWriter(fuzzed_data_provider.ConsumeIntegral<uint8_t>()));
66
0
        } catch (const std::ios_base::failure&) {
67
0
        }
68
0
        std::map<CPubKey, KeyOriginInfo> deserialized_hd_keypaths;
69
0
        try {
70
0
            DeserializeHDKeypaths(serialized, key, hd_keypaths);
71
0
        } catch (const std::ios_base::failure&) {
72
0
        }
73
0
        assert(hd_keypaths.size() >= deserialized_hd_keypaths.size());
74
0
    }
75
76
0
    {
77
0
        SignatureData signature_data_1{ConsumeScript(fuzzed_data_provider)};
78
0
        SignatureData signature_data_2{ConsumeScript(fuzzed_data_provider)};
79
0
        signature_data_1.MergeSignatureData(signature_data_2);
80
0
    }
81
82
0
    FillableSigningProvider provider;
83
0
    CKey k = ConsumePrivateKey(fuzzed_data_provider);
84
0
    if (k.IsValid()) {
  Branch (84:9): [True: 0, False: 0]
85
0
        provider.AddKey(k);
86
0
    }
87
88
0
    {
89
0
        const std::optional<CMutableTransaction> mutable_transaction = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
90
0
        const std::optional<CTxOut> tx_out = ConsumeDeserializable<CTxOut>(fuzzed_data_provider);
91
0
        const unsigned int n_in = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
92
0
        if (mutable_transaction && tx_out && mutable_transaction->vin.size() > n_in) {
  Branch (92:13): [True: 0, False: 0]
  Branch (92:36): [True: 0, False: 0]
  Branch (92:46): [True: 0, False: 0]
93
0
            SignatureData signature_data_1 = DataFromTransaction(*mutable_transaction, n_in, *tx_out);
94
0
            CTxIn input;
95
0
            UpdateInput(input, signature_data_1);
96
0
            const CScript script = ConsumeScript(fuzzed_data_provider);
97
0
            SignatureData signature_data_2{script};
98
0
            signature_data_1.MergeSignatureData(signature_data_2);
99
0
        }
100
0
        if (mutable_transaction) {
  Branch (100:13): [True: 0, False: 0]
101
0
            CTransaction tx_from{*mutable_transaction};
102
0
            CMutableTransaction tx_to;
103
0
            const std::optional<CMutableTransaction> opt_tx_to = ConsumeDeserializable<CMutableTransaction>(fuzzed_data_provider, TX_WITH_WITNESS);
104
0
            if (opt_tx_to) {
  Branch (104:17): [True: 0, False: 0]
105
0
                tx_to = *opt_tx_to;
106
0
            }
107
0
            CMutableTransaction script_tx_to = tx_to;
108
0
            CMutableTransaction sign_transaction_tx_to = tx_to;
109
0
            if (n_in < tx_to.vin.size() && tx_to.vin[n_in].prevout.n < tx_from.vout.size()) {
  Branch (109:17): [True: 0, False: 0]
  Branch (109:44): [True: 0, False: 0]
110
0
                SignatureData empty;
111
0
                (void)SignSignature(provider, tx_from, tx_to, n_in, fuzzed_data_provider.ConsumeIntegral<int>(), empty);
112
0
            }
113
0
            if (n_in < script_tx_to.vin.size()) {
  Branch (113:17): [True: 0, False: 0]
114
0
                SignatureData empty;
115
0
                auto from_pub_key = ConsumeScript(fuzzed_data_provider);
116
0
                auto amount = ConsumeMoney(fuzzed_data_provider);
117
0
                auto n_hash_type = fuzzed_data_provider.ConsumeIntegral<int>();
118
0
                (void)SignSignature(provider, from_pub_key, script_tx_to, n_in, amount, n_hash_type, empty);
119
0
                MutableTransactionSignatureCreator signature_creator{tx_to, n_in, ConsumeMoney(fuzzed_data_provider), fuzzed_data_provider.ConsumeIntegral<int>()};
120
0
                std::vector<unsigned char> vch_sig;
121
0
                CKeyID address;
122
0
                if (fuzzed_data_provider.ConsumeBool()) {
  Branch (122:21): [True: 0, False: 0]
123
0
                    if (k.IsValid()) {
  Branch (123:25): [True: 0, False: 0]
124
0
                        address = k.GetPubKey().GetID();
125
0
                    }
126
0
                } else {
127
0
                    address = CKeyID{ConsumeUInt160(fuzzed_data_provider)};
128
0
                }
129
0
                auto script_code = ConsumeScript(fuzzed_data_provider);
130
0
                auto sigversion = fuzzed_data_provider.PickValueInArray({SigVersion::BASE, SigVersion::WITNESS_V0});
131
0
                (void)signature_creator.CreateSig(provider, vch_sig, address, script_code, sigversion);
132
0
            }
133
0
            std::map<COutPoint, Coin> coins{ConsumeCoins(fuzzed_data_provider)};
134
0
            std::map<int, bilingual_str> input_errors;
135
0
            (void)SignTransaction(sign_transaction_tx_to, &provider, coins, fuzzed_data_provider.ConsumeIntegral<int>(), input_errors);
136
0
        }
137
0
    }
138
139
0
    {
140
0
        SignatureData signature_data_1;
141
0
        (void)ProduceSignature(provider, DUMMY_SIGNATURE_CREATOR, ConsumeScript(fuzzed_data_provider), signature_data_1);
142
0
        SignatureData signature_data_2;
143
0
        (void)ProduceSignature(provider, DUMMY_MAXIMUM_SIGNATURE_CREATOR, ConsumeScript(fuzzed_data_provider), signature_data_2);
144
0
    }
145
0
}