Bitcoin Core  26.99.0
P2P Digital Currency
descriptor.cpp
Go to the documentation of this file.
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 
6 
8  // The data to use as a private key or a seed for an xprv.
9  std::array<std::byte, 32> key_data{std::byte{1}};
10  // Generate keys of all kinds and store them in the keys array.
11  for (size_t i{0}; i < TOTAL_KEYS_GENERATED; i++) {
12  key_data[31] = std::byte(i);
13 
14  // If this is a "raw" key, generate a normal privkey. Otherwise generate
15  // an extended one.
17  CKey privkey;
18  privkey.Set(UCharCast(key_data.begin()), UCharCast(key_data.end()), !IdIsUnCompPubKey(i));
19  if (IdIsCompPubKey(i) || IdIsUnCompPubKey(i)) {
20  CPubKey pubkey{privkey.GetPubKey()};
21  keys_str[i] = HexStr(pubkey);
22  } else if (IdIsXOnlyPubKey(i)) {
23  const XOnlyPubKey pubkey{privkey.GetPubKey()};
24  keys_str[i] = HexStr(pubkey);
25  } else {
26  keys_str[i] = EncodeSecret(privkey);
27  }
28  } else {
29  CExtKey ext_privkey;
30  ext_privkey.SetSeed(key_data);
31  if (IdIsXprv(i)) {
32  keys_str[i] = EncodeExtKey(ext_privkey);
33  } else {
34  const CExtPubKey ext_pubkey{ext_privkey.Neuter()};
35  keys_str[i] = EncodeExtPubKey(ext_pubkey);
36  }
37  }
38  }
39 }
40 
41 std::optional<uint8_t> MockedDescriptorConverter::IdxFromHex(std::string_view hex_characters) const {
42  if (hex_characters.size() != 2) return {};
43  auto idx = ParseHex(hex_characters);
44  if (idx.size() != 1) return {};
45  return idx[0];
46 }
47 
48 std::optional<std::string> MockedDescriptorConverter::GetDescriptor(std::string_view mocked_desc) const {
49  // The smallest fragment would be "pk(%00)"
50  if (mocked_desc.size() < 7) return {};
51 
52  // The actual descriptor string to be returned.
53  std::string desc;
54  desc.reserve(mocked_desc.size());
55 
56  // Replace all occurrences of '%' followed by two hex characters with the corresponding key.
57  for (size_t i = 0; i < mocked_desc.size();) {
58  if (mocked_desc[i] == '%') {
59  if (i + 3 >= mocked_desc.size()) return {};
60  if (const auto idx = IdxFromHex(mocked_desc.substr(i + 1, 2))) {
61  desc += keys_str[*idx];
62  i += 3;
63  } else {
64  return {};
65  }
66  } else {
67  desc += mocked_desc[i++];
68  }
69  }
70 
71  return desc;
72 }
73 
74 bool HasDeepDerivPath(const FuzzBufferType& buff, const int max_depth)
75 {
76  auto depth{0};
77  for (const auto& ch: buff) {
78  if (ch == ',') {
79  // A comma is always present between two key expressions, so we use that as a delimiter.
80  depth = 0;
81  } else if (ch == '/') {
82  if (++depth > max_depth) return true;
83  }
84  }
85  return false;
86 }
An encapsulated private key.
Definition: key.h:33
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:188
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:99
An encapsulated public key.
Definition: pubkey.h:34
bool IdIsUnCompPubKey(uint8_t idx) const
Definition: descriptor.h:33
bool IdIsXOnlyPubKey(uint8_t idx) const
Definition: descriptor.h:34
void Init()
When initializing the target, populate the list of keys.
Definition: descriptor.cpp:7
static constexpr size_t TOTAL_KEYS_GENERATED
How many keys we'll generate in total.
Definition: descriptor.h:26
std::optional< std::string > GetDescriptor(std::string_view mocked_desc) const
Get an actual descriptor string from a descriptor string whose keys were mocked.
Definition: descriptor.cpp:48
bool IdIsXprv(uint8_t idx) const
Definition: descriptor.h:37
bool IdIsCompPubKey(uint8_t idx) const
Definition: descriptor.h:32
std::array< std::string, TOTAL_KEYS_GENERATED > keys_str
256 keys of various types.
Definition: descriptor.h:28
bool IdIsConstPrivKey(uint8_t idx) const
Definition: descriptor.h:35
std::optional< uint8_t > IdxFromHex(std::string_view hex_characters) const
Parse an id in the keys vectors from a 2-characters hex string.
Definition: descriptor.cpp:41
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:98
std::string EncodeExtKey(const CExtKey &key)
Definition: key_io.cpp:276
std::string EncodeSecret(const CKey &key)
Definition: key_io.cpp:227
std::string EncodeExtPubKey(const CExtPubKey &key)
Definition: key_io.cpp:253
unsigned char * UCharCast(char *c)
Definition: span.h:288
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Definition: strencodings.h:65
Definition: key.h:210
CExtPubKey Neuter() const
Definition: key.cpp:400
void SetSeed(Span< const std::byte > seed)
Definition: key.cpp:388
bool HasDeepDerivPath(const FuzzBufferType &buff, const int max_depth)
Whether the buffer, if it represents a valid descriptor, contains a derivation path deeper than a giv...
Definition: descriptor.cpp:74
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.