Branch data Line data Source code
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 : : #include <test/fuzz/util/descriptor.h> 6 : : 7 : 1 : void MockedDescriptorConverter::Init() { 8 : : // The data to use as a private key or a seed for an xprv. 9 : 1 : std::array<std::byte, 32> key_data{std::byte{1}}; 10 : : // Generate keys of all kinds and store them in the keys array. 11 [ + + ]: 257 : for (size_t i{0}; i < TOTAL_KEYS_GENERATED; i++) { 12 : 256 : key_data[31] = std::byte(i); 13 : : 14 : : // If this is a "raw" key, generate a normal privkey. Otherwise generate 15 : : // an extended one. 16 [ + + ][ + + ]: 256 : if (IdIsCompPubKey(i) || IdIsUnCompPubKey(i) || IdIsXOnlyPubKey(i) || IdIsConstPrivKey(i)) { [ + + ][ + + ] 17 : 172 : CKey privkey; 18 [ + - ][ + - ]: 172 : privkey.Set(UCharCast(key_data.begin()), UCharCast(key_data.end()), !IdIsUnCompPubKey(i)); [ + - ][ + - ] 19 [ + - ][ + + ]: 172 : if (IdIsCompPubKey(i) || IdIsUnCompPubKey(i)) { [ + - ][ + + ] 20 [ + - ]: 86 : CPubKey pubkey{privkey.GetPubKey()}; 21 [ + - ][ + - ]: 86 : keys_str[i] = HexStr(pubkey); 22 [ + - ][ + + ]: 172 : } else if (IdIsXOnlyPubKey(i)) { 23 [ + - ][ + - ]: 43 : const XOnlyPubKey pubkey{privkey.GetPubKey()}; 24 [ + - ][ + - ]: 43 : keys_str[i] = HexStr(pubkey); 25 : 43 : } else { 26 [ + - ]: 43 : keys_str[i] = EncodeSecret(privkey); 27 : : } 28 : 172 : } else { 29 : 84 : CExtKey ext_privkey; 30 [ + - ][ + - ]: 84 : ext_privkey.SetSeed(key_data); 31 [ + - ][ + + ]: 84 : if (IdIsXprv(i)) { 32 [ + - ]: 42 : keys_str[i] = EncodeExtKey(ext_privkey); 33 : 42 : } else { 34 [ + - ]: 42 : const CExtPubKey ext_pubkey{ext_privkey.Neuter()}; 35 [ + - ]: 42 : keys_str[i] = EncodeExtPubKey(ext_pubkey); 36 : : } 37 : 84 : } 38 : 256 : } 39 : 1 : } 40 : : 41 : 13279 : std::optional<uint8_t> MockedDescriptorConverter::IdxFromHex(std::string_view hex_characters) const { 42 [ - + ]: 13279 : if (hex_characters.size() != 2) return {}; 43 : 13279 : auto idx = ParseHex(hex_characters); 44 [ + + ]: 13279 : if (idx.size() != 1) return {}; 45 : 13267 : return idx[0]; 46 : 13279 : } 47 : : 48 : 828 : std::optional<std::string> MockedDescriptorConverter::GetDescriptor(std::string_view mocked_desc) const { 49 : : // The smallest fragment would be "pk(%00)" 50 [ + + ]: 828 : if (mocked_desc.size() < 7) return {}; 51 : : 52 : : // The actual descriptor string to be returned. 53 : 826 : std::string desc; 54 [ + - ]: 826 : desc.reserve(mocked_desc.size()); 55 : : 56 : : // Replace all occurrences of '%' followed by two hex characters with the corresponding key. 57 [ + + ]: 387141 : for (size_t i = 0; i < mocked_desc.size();) { 58 [ + + ]: 386329 : if (mocked_desc[i] == '%') { 59 [ + + ]: 13281 : if (i + 3 >= mocked_desc.size()) return {}; 60 [ + - ][ + - ]: 13279 : if (const auto idx = IdxFromHex(mocked_desc.substr(i + 1, 2))) { [ + + ] 61 [ + - ]: 13267 : desc += keys_str[*idx]; 62 : 13267 : i += 3; 63 : 13267 : } else { 64 : 12 : return {}; 65 : : } 66 : 13267 : } else { 67 [ + - ]: 373048 : desc += mocked_desc[i++]; 68 : : } 69 : : } 70 : : 71 : 812 : return desc; 72 : 828 : } 73 : : 74 : 829 : bool HasDeepDerivPath(const FuzzBufferType& buff, const int max_depth) 75 : : { 76 : 829 : auto depth{0}; 77 [ + + ]: 413755 : for (const auto& ch: buff) { 78 [ + + ]: 412927 : if (ch == ',') { 79 : : // A comma is always present between two key expressions, so we use that as a delimiter. 80 : 55127 : depth = 0; 81 [ + + ]: 412927 : } else if (ch == '/') { 82 [ + + ]: 4770 : if (++depth > max_depth) return true; 83 : 4769 : } 84 : : } 85 : 828 : return false; 86 : 829 : }