descriptor.h
1 // Copyright (c) 2023-present 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 #ifndef BITCOIN_TEST_FUZZ_UTIL_DESCRIPTOR_H 6 #define BITCOIN_TEST_FUZZ_UTIL_DESCRIPTOR_H 7 8 #include <key_io.h> 9 #include <util/strencodings.h> 10 #include <script/descriptor.h> 11 #include <test/fuzz/fuzz.h> 12 13 #include <functional> 14 15 /** 16 * Converts a mocked descriptor string to a valid one. Every key in a mocked descriptor key is 17 * represented by 2 hex characters preceded by the '%' character. We parse the two hex characters 18 * as an index in a list of pre-generated keys. This list contains keys of the various types 19 * accepted in descriptor keys expressions. 20 */ 21 class MockedDescriptorConverter { 22 private: 23 //! Types are raw (un)compressed pubkeys, raw xonly pubkeys, raw privkeys (WIF), xpubs, xprvs. 24 static constexpr uint8_t KEY_TYPES_COUNT{6}; 25 //! How many keys we'll generate in total. 26 static constexpr size_t TOTAL_KEYS_GENERATED{std::numeric_limits<uint8_t>::max() + 1}; 27 //! 256 keys of various types. 28 std::array<std::string, TOTAL_KEYS_GENERATED> keys_str; 29 30 public: 31 // We derive the type of key to generate from the 1-byte id parsed from hex. 32 bool IdIsCompPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 0; } 33 bool IdIsUnCompPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 1; } 34 bool IdIsXOnlyPubKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 2; } 35 bool IdIsConstPrivKey(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 3; } 36 bool IdIsXpub(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 4; } 37 bool IdIsXprv(uint8_t idx) const { return idx % KEY_TYPES_COUNT == 5; } 38 39 //! When initializing the target, populate the list of keys. 40 void Init(); 41 42 //! Parse an id in the keys vectors from a 2-characters hex string. 43 std::optional<uint8_t> IdxFromHex(std::string_view hex_characters) const; 44 45 //! Get an actual descriptor string from a descriptor string whose keys were mocked. 46 std::optional<std::string> GetDescriptor(std::string_view mocked_desc) const; 47 }; 48 49 //! Default maximum number of derivation indexes in a single derivation path when limiting its depth. 50 constexpr int MAX_DEPTH{2}; 51 52 /** 53 * Whether the buffer, if it represents a valid descriptor, contains a derivation path deeper than 54 * a given maximum depth. Note this may also be hit for deriv paths in origins. 55 */ 56 bool HasDeepDerivPath(const FuzzBufferType& buff, const int max_depth = MAX_DEPTH); 57 58 #endif // BITCOIN_TEST_FUZZ_UTIL_DESCRIPTOR_H