Bitcoin Core 29.99.0
P2P Digital Currency
descriptor.cpp
Go to the documentation of this file.
1// Copyright (c) 2018-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 <script/descriptor.h>
6
7#include <hash.h>
8#include <key_io.h>
9#include <pubkey.h>
10#include <musig.h>
11#include <script/miniscript.h>
12#include <script/parsing.h>
13#include <script/script.h>
15#include <script/solver.h>
16#include <uint256.h>
17
18#include <common/args.h>
19#include <span.h>
20#include <util/bip32.h>
21#include <util/check.h>
22#include <util/strencodings.h>
23#include <util/vector.h>
24
25#include <algorithm>
26#include <memory>
27#include <numeric>
28#include <optional>
29#include <string>
30#include <vector>
31
32using util::Split;
33
34namespace {
35
37// Checksum //
39
40// This section implements a checksum algorithm for descriptors with the
41// following properties:
42// * Mistakes in a descriptor string are measured in "symbol errors". The higher
43// the number of symbol errors, the harder it is to detect:
44// * An error substituting a character from 0123456789()[],'/*abcdefgh@:$%{} for
45// another in that set always counts as 1 symbol error.
46// * Note that hex encoded keys are covered by these characters. Xprvs and
47// xpubs use other characters too, but already have their own checksum
48// mechanism.
49// * Function names like "multi()" use other characters, but mistakes in
50// these would generally result in an unparsable descriptor.
51// * A case error always counts as 1 symbol error.
52// * Any other 1 character substitution error counts as 1 or 2 symbol errors.
53// * Any 1 symbol error is always detected.
54// * Any 2 or 3 symbol error in a descriptor of up to 49154 characters is always detected.
55// * Any 4 symbol error in a descriptor of up to 507 characters is always detected.
56// * Any 5 symbol error in a descriptor of up to 77 characters is always detected.
57// * Is optimized to minimize the chance a 5 symbol error in a descriptor up to 387 characters is undetected
58// * Random errors have a chance of 1 in 2**40 of being undetected.
59//
60// These properties are achieved by expanding every group of 3 (non checksum) characters into
61// 4 GF(32) symbols, over which a cyclic code is defined.
62
63/*
64 * Interprets c as 8 groups of 5 bits which are the coefficients of a degree 8 polynomial over GF(32),
65 * multiplies that polynomial by x, computes its remainder modulo a generator, and adds the constant term val.
66 *
67 * This generator is G(x) = x^8 + {30}x^7 + {23}x^6 + {15}x^5 + {14}x^4 + {10}x^3 + {6}x^2 + {12}x + {9}.
68 * It is chosen to define an cyclic error detecting code which is selected by:
69 * - Starting from all BCH codes over GF(32) of degree 8 and below, which by construction guarantee detecting
70 * 3 errors in windows up to 19000 symbols.
71 * - Taking all those generators, and for degree 7 ones, extend them to degree 8 by adding all degree-1 factors.
72 * - Selecting just the set of generators that guarantee detecting 4 errors in a window of length 512.
73 * - Selecting one of those with best worst-case behavior for 5 errors in windows of length up to 512.
74 *
75 * The generator and the constants to implement it can be verified using this Sage code:
76 * B = GF(2) # Binary field
77 * BP.<b> = B[] # Polynomials over the binary field
78 * F_mod = b**5 + b**3 + 1
79 * F.<f> = GF(32, modulus=F_mod, repr='int') # GF(32) definition
80 * FP.<x> = F[] # Polynomials over GF(32)
81 * E_mod = x**3 + x + F.fetch_int(8)
82 * E.<e> = F.extension(E_mod) # Extension field definition
83 * alpha = e**2743 # Choice of an element in extension field
84 * for p in divisors(E.order() - 1): # Verify alpha has order 32767.
85 * assert((alpha**p == 1) == (p % 32767 == 0))
86 * G = lcm([(alpha**i).minpoly() for i in [1056,1057,1058]] + [x + 1])
87 * print(G) # Print out the generator
88 * for i in [1,2,4,8,16]: # Print out {1,2,4,8,16}*(G mod x^8), packed in hex integers.
89 * v = 0
90 * for coef in reversed((F.fetch_int(i)*(G % x**8)).coefficients(sparse=True)):
91 * v = v*32 + coef.integer_representation()
92 * print("0x%x" % v)
93 */
94uint64_t PolyMod(uint64_t c, int val)
95{
96 uint8_t c0 = c >> 35;
97 c = ((c & 0x7ffffffff) << 5) ^ val;
98 if (c0 & 1) c ^= 0xf5dee51989;
99 if (c0 & 2) c ^= 0xa9fdca3312;
100 if (c0 & 4) c ^= 0x1bab10e32d;
101 if (c0 & 8) c ^= 0x3706b1677a;
102 if (c0 & 16) c ^= 0x644d626ffd;
103 return c;
104}
105
106std::string DescriptorChecksum(const std::span<const char>& span)
107{
121 static const std::string INPUT_CHARSET =
122 "0123456789()[],'/*abcdefgh@:$%{}"
123 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
124 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
125
127 static const std::string CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
128
129 uint64_t c = 1;
130 int cls = 0;
131 int clscount = 0;
132 for (auto ch : span) {
133 auto pos = INPUT_CHARSET.find(ch);
134 if (pos == std::string::npos) return "";
135 c = PolyMod(c, pos & 31); // Emit a symbol for the position inside the group, for every character.
136 cls = cls * 3 + (pos >> 5); // Accumulate the group numbers
137 if (++clscount == 3) {
138 // Emit an extra symbol representing the group numbers, for every 3 characters.
139 c = PolyMod(c, cls);
140 cls = 0;
141 clscount = 0;
142 }
143 }
144 if (clscount > 0) c = PolyMod(c, cls);
145 for (int j = 0; j < 8; ++j) c = PolyMod(c, 0); // Shift further to determine the checksum.
146 c ^= 1; // Prevent appending zeroes from not affecting the checksum.
147
148 std::string ret(8, ' ');
149 for (int j = 0; j < 8; ++j) ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
150 return ret;
151}
152
153std::string AddChecksum(const std::string& str) { return str + "#" + DescriptorChecksum(str); }
154
156// Internal representation //
158
159typedef std::vector<uint32_t> KeyPath;
160
162struct PubkeyProvider
163{
164protected:
167 uint32_t m_expr_index;
168
169public:
170 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
171
172 virtual ~PubkeyProvider() = default;
173
177 bool operator<(PubkeyProvider& other) const {
179
180 std::optional<CPubKey> a = GetPubKey(0, dummy, dummy);
181 std::optional<CPubKey> b = other.GetPubKey(0, dummy, dummy);
182
183 return a < b;
184 }
185
191 virtual std::optional<CPubKey> GetPubKey(int pos, const SigningProvider& arg, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const = 0;
192
194 virtual bool IsRange() const = 0;
195
197 virtual size_t GetSize() const = 0;
198
199 enum class StringType {
200 PUBLIC,
201 COMPAT // string calculation that mustn't change over time to stay compatible with previous software versions
202 };
203
205 virtual std::string ToString(StringType type=StringType::PUBLIC) const = 0;
206
208 virtual bool ToPrivateString(const SigningProvider& arg, std::string& out) const = 0;
209
213 virtual bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache = nullptr) const = 0;
214
216 virtual void GetPrivKey(int pos, const SigningProvider& arg, FlatSigningProvider& out) const = 0;
217
219 virtual std::optional<CPubKey> GetRootPubKey() const = 0;
221 virtual std::optional<CExtPubKey> GetRootExtPubKey() const = 0;
222
224 virtual std::unique_ptr<PubkeyProvider> Clone() const = 0;
225
227 virtual bool IsBIP32() const = 0;
228};
229
230class OriginPubkeyProvider final : public PubkeyProvider
231{
232 KeyOriginInfo m_origin;
233 std::unique_ptr<PubkeyProvider> m_provider;
234 bool m_apostrophe;
235
236 std::string OriginString(StringType type, bool normalized=false) const
237 {
238 // If StringType==COMPAT, always use the apostrophe to stay compatible with previous versions
239 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
240 return HexStr(m_origin.fingerprint) + FormatHDKeypath(m_origin.path, use_apostrophe);
241 }
242
243public:
244 OriginPubkeyProvider(uint32_t exp_index, KeyOriginInfo info, std::unique_ptr<PubkeyProvider> provider, bool apostrophe) : PubkeyProvider(exp_index), m_origin(std::move(info)), m_provider(std::move(provider)), m_apostrophe(apostrophe) {}
245 std::optional<CPubKey> GetPubKey(int pos, const SigningProvider& arg, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
246 {
247 std::optional<CPubKey> pub = m_provider->GetPubKey(pos, arg, out, read_cache, write_cache);
248 if (!pub) return std::nullopt;
249 Assert(out.pubkeys.contains(pub->GetID()));
250 auto& [pubkey, suborigin] = out.origins[pub->GetID()];
251 Assert(pubkey == *pub); // m_provider must have a valid origin by this point.
252 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), suborigin.fingerprint);
253 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
254 return pub;
255 }
256 bool IsRange() const override { return m_provider->IsRange(); }
257 size_t GetSize() const override { return m_provider->GetSize(); }
258 bool IsBIP32() const override { return m_provider->IsBIP32(); }
259 std::string ToString(StringType type) const override { return "[" + OriginString(type) + "]" + m_provider->ToString(type); }
260 bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
261 {
262 std::string sub;
263 if (!m_provider->ToPrivateString(arg, sub)) return false;
264 ret = "[" + OriginString(StringType::PUBLIC) + "]" + std::move(sub);
265 return true;
266 }
267 bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
268 {
269 std::string sub;
270 if (!m_provider->ToNormalizedString(arg, sub, cache)) return false;
271 // If m_provider is a BIP32PubkeyProvider, we may get a string formatted like a OriginPubkeyProvider
272 // In that case, we need to strip out the leading square bracket and fingerprint from the substring,
273 // and append that to our own origin string.
274 if (sub[0] == '[') {
275 sub = sub.substr(9);
276 ret = "[" + OriginString(StringType::PUBLIC, /*normalized=*/true) + std::move(sub);
277 } else {
278 ret = "[" + OriginString(StringType::PUBLIC, /*normalized=*/true) + "]" + std::move(sub);
279 }
280 return true;
281 }
282 void GetPrivKey(int pos, const SigningProvider& arg, FlatSigningProvider& out) const override
283 {
284 m_provider->GetPrivKey(pos, arg, out);
285 }
286 std::optional<CPubKey> GetRootPubKey() const override
287 {
288 return m_provider->GetRootPubKey();
289 }
290 std::optional<CExtPubKey> GetRootExtPubKey() const override
291 {
292 return m_provider->GetRootExtPubKey();
293 }
294 std::unique_ptr<PubkeyProvider> Clone() const override
295 {
296 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
297 }
298};
299
301class ConstPubkeyProvider final : public PubkeyProvider
302{
303 CPubKey m_pubkey;
304 bool m_xonly;
305
306 std::optional<CKey> GetPrivKey(const SigningProvider& arg) const
307 {
308 CKey key;
309 if (!(m_xonly ? arg.GetKeyByXOnly(XOnlyPubKey(m_pubkey), key) :
310 arg.GetKey(m_pubkey.GetID(), key))) return std::nullopt;
311 return key;
312 }
313
314public:
315 ConstPubkeyProvider(uint32_t exp_index, const CPubKey& pubkey, bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
316 std::optional<CPubKey> GetPubKey(int pos, const SigningProvider&, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
317 {
318 KeyOriginInfo info;
319 CKeyID keyid = m_pubkey.GetID();
320 std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint);
321 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
322 out.pubkeys.emplace(keyid, m_pubkey);
323 return m_pubkey;
324 }
325 bool IsRange() const override { return false; }
326 size_t GetSize() const override { return m_pubkey.size(); }
327 bool IsBIP32() const override { return false; }
328 std::string ToString(StringType type) const override { return m_xonly ? HexStr(m_pubkey).substr(2) : HexStr(m_pubkey); }
329 bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
330 {
331 std::optional<CKey> key = GetPrivKey(arg);
332 if (!key) return false;
333 ret = EncodeSecret(*key);
334 return true;
335 }
336 bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
337 {
338 ret = ToString(StringType::PUBLIC);
339 return true;
340 }
341 void GetPrivKey(int pos, const SigningProvider& arg, FlatSigningProvider& out) const override
342 {
343 std::optional<CKey> key = GetPrivKey(arg);
344 if (!key) return;
345 out.keys.emplace(key->GetPubKey().GetID(), *key);
346 }
347 std::optional<CPubKey> GetRootPubKey() const override
348 {
349 return m_pubkey;
350 }
351 std::optional<CExtPubKey> GetRootExtPubKey() const override
352 {
353 return std::nullopt;
354 }
355 std::unique_ptr<PubkeyProvider> Clone() const override
356 {
357 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
358 }
359};
360
361enum class DeriveType {
362 NO,
363 UNHARDENED,
364 HARDENED,
365};
366
368class BIP32PubkeyProvider final : public PubkeyProvider
369{
370 // Root xpub, path, and final derivation step type being used, if any
371 CExtPubKey m_root_extkey;
372 KeyPath m_path;
373 DeriveType m_derive;
374 // Whether ' or h is used in harded derivation
375 bool m_apostrophe;
376
377 bool GetExtKey(const SigningProvider& arg, CExtKey& ret) const
378 {
379 CKey key;
380 if (!arg.GetKey(m_root_extkey.pubkey.GetID(), key)) return false;
381 ret.nDepth = m_root_extkey.nDepth;
382 std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint + sizeof(ret.vchFingerprint), ret.vchFingerprint);
383 ret.nChild = m_root_extkey.nChild;
384 ret.chaincode = m_root_extkey.chaincode;
385 ret.key = key;
386 return true;
387 }
388
389 // Derives the last xprv
390 bool GetDerivedExtKey(const SigningProvider& arg, CExtKey& xprv, CExtKey& last_hardened) const
391 {
392 if (!GetExtKey(arg, xprv)) return false;
393 for (auto entry : m_path) {
394 if (!xprv.Derive(xprv, entry)) return false;
395 if (entry >> 31) {
396 last_hardened = xprv;
397 }
398 }
399 return true;
400 }
401
402 bool IsHardened() const
403 {
404 if (m_derive == DeriveType::HARDENED) return true;
405 for (auto entry : m_path) {
406 if (entry >> 31) return true;
407 }
408 return false;
409 }
410
411public:
412 BIP32PubkeyProvider(uint32_t exp_index, const CExtPubKey& extkey, KeyPath path, DeriveType derive, bool apostrophe) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(std::move(path)), m_derive(derive), m_apostrophe(apostrophe) {}
413 bool IsRange() const override { return m_derive != DeriveType::NO; }
414 size_t GetSize() const override { return 33; }
415 bool IsBIP32() const override { return true; }
416 std::optional<CPubKey> GetPubKey(int pos, const SigningProvider& arg, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
417 {
418 KeyOriginInfo info;
419 CKeyID keyid = m_root_extkey.pubkey.GetID();
420 std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint);
421 info.path = m_path;
422 if (m_derive == DeriveType::UNHARDENED) info.path.push_back((uint32_t)pos);
423 if (m_derive == DeriveType::HARDENED) info.path.push_back(((uint32_t)pos) | 0x80000000L);
424
425 // Derive keys or fetch them from cache
426 CExtPubKey final_extkey = m_root_extkey;
427 CExtPubKey parent_extkey = m_root_extkey;
428 CExtPubKey last_hardened_extkey;
429 bool der = true;
430 if (read_cache) {
431 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
432 if (m_derive == DeriveType::HARDENED) return std::nullopt;
433 // Try to get the derivation parent
434 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey)) return std::nullopt;
435 final_extkey = parent_extkey;
436 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
437 }
438 } else if (IsHardened()) {
439 CExtKey xprv;
440 CExtKey lh_xprv;
441 if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return std::nullopt;
442 parent_extkey = xprv.Neuter();
443 if (m_derive == DeriveType::UNHARDENED) der = xprv.Derive(xprv, pos);
444 if (m_derive == DeriveType::HARDENED) der = xprv.Derive(xprv, pos | 0x80000000UL);
445 final_extkey = xprv.Neuter();
446 if (lh_xprv.key.IsValid()) {
447 last_hardened_extkey = lh_xprv.Neuter();
448 }
449 } else {
450 for (auto entry : m_path) {
451 if (!parent_extkey.Derive(parent_extkey, entry)) return std::nullopt;
452 }
453 final_extkey = parent_extkey;
454 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
455 assert(m_derive != DeriveType::HARDENED);
456 }
457 if (!der) return std::nullopt;
458
459 out.origins.emplace(final_extkey.pubkey.GetID(), std::make_pair(final_extkey.pubkey, info));
460 out.pubkeys.emplace(final_extkey.pubkey.GetID(), final_extkey.pubkey);
461
462 if (write_cache) {
463 // Only cache parent if there is any unhardened derivation
464 if (m_derive != DeriveType::HARDENED) {
465 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
466 // Cache last hardened xpub if we have it
467 if (last_hardened_extkey.pubkey.IsValid()) {
468 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
469 }
470 } else if (info.path.size() > 0) {
471 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
472 }
473 }
474
475 return final_extkey.pubkey;
476 }
477 std::string ToString(StringType type, bool normalized) const
478 {
479 // If StringType==COMPAT, always use the apostrophe to stay compatible with previous versions
480 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
481 std::string ret = EncodeExtPubKey(m_root_extkey) + FormatHDKeypath(m_path, /*apostrophe=*/use_apostrophe);
482 if (IsRange()) {
483 ret += "/*";
484 if (m_derive == DeriveType::HARDENED) ret += use_apostrophe ? '\'' : 'h';
485 }
486 return ret;
487 }
488 std::string ToString(StringType type=StringType::PUBLIC) const override
489 {
490 return ToString(type, /*normalized=*/false);
491 }
492 bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
493 {
494 CExtKey key;
495 if (!GetExtKey(arg, key)) return false;
496 out = EncodeExtKey(key) + FormatHDKeypath(m_path, /*apostrophe=*/m_apostrophe);
497 if (IsRange()) {
498 out += "/*";
499 if (m_derive == DeriveType::HARDENED) out += m_apostrophe ? '\'' : 'h';
500 }
501 return true;
502 }
503 bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override
504 {
505 if (m_derive == DeriveType::HARDENED) {
506 out = ToString(StringType::PUBLIC, /*normalized=*/true);
507
508 return true;
509 }
510 // Step backwards to find the last hardened step in the path
511 int i = (int)m_path.size() - 1;
512 for (; i >= 0; --i) {
513 if (m_path.at(i) >> 31) {
514 break;
515 }
516 }
517 // Either no derivation or all unhardened derivation
518 if (i == -1) {
519 out = ToString();
520 return true;
521 }
522 // Get the path to the last hardened stup
523 KeyOriginInfo origin;
524 int k = 0;
525 for (; k <= i; ++k) {
526 // Add to the path
527 origin.path.push_back(m_path.at(k));
528 }
529 // Build the remaining path
530 KeyPath end_path;
531 for (; k < (int)m_path.size(); ++k) {
532 end_path.push_back(m_path.at(k));
533 }
534 // Get the fingerprint
535 CKeyID id = m_root_extkey.pubkey.GetID();
536 std::copy(id.begin(), id.begin() + 4, origin.fingerprint);
537
538 CExtPubKey xpub;
539 CExtKey lh_xprv;
540 // If we have the cache, just get the parent xpub
541 if (cache != nullptr) {
542 cache->GetCachedLastHardenedExtPubKey(m_expr_index, xpub);
543 }
544 if (!xpub.pubkey.IsValid()) {
545 // Cache miss, or nor cache, or need privkey
546 CExtKey xprv;
547 if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
548 xpub = lh_xprv.Neuter();
549 }
550 assert(xpub.pubkey.IsValid());
551
552 // Build the string
553 std::string origin_str = HexStr(origin.fingerprint) + FormatHDKeypath(origin.path);
554 out = "[" + origin_str + "]" + EncodeExtPubKey(xpub) + FormatHDKeypath(end_path);
555 if (IsRange()) {
556 out += "/*";
557 assert(m_derive == DeriveType::UNHARDENED);
558 }
559 return true;
560 }
561 void GetPrivKey(int pos, const SigningProvider& arg, FlatSigningProvider& out) const override
562 {
563 CExtKey extkey;
564 CExtKey dummy;
565 if (!GetDerivedExtKey(arg, extkey, dummy)) return;
566 if (m_derive == DeriveType::UNHARDENED && !extkey.Derive(extkey, pos)) return;
567 if (m_derive == DeriveType::HARDENED && !extkey.Derive(extkey, pos | 0x80000000UL)) return;
568 out.keys.emplace(extkey.key.GetPubKey().GetID(), extkey.key);
569 }
570 std::optional<CPubKey> GetRootPubKey() const override
571 {
572 return std::nullopt;
573 }
574 std::optional<CExtPubKey> GetRootExtPubKey() const override
575 {
576 return m_root_extkey;
577 }
578 std::unique_ptr<PubkeyProvider> Clone() const override
579 {
580 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey, m_path, m_derive, m_apostrophe);
581 }
582};
583
585class MuSigPubkeyProvider final : public PubkeyProvider
586{
587private:
589 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
591 const KeyPath m_path;
593 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
594 mutable std::optional<CPubKey> m_aggregate_pubkey;
595 const DeriveType m_derive;
596 const bool m_ranged_participants;
597
598 bool IsRangedDerivation() const { return m_derive != DeriveType::NO; }
599
600public:
601 MuSigPubkeyProvider(
602 uint32_t exp_index,
603 std::vector<std::unique_ptr<PubkeyProvider>> providers,
604 KeyPath path,
605 DeriveType derive
606 )
607 : PubkeyProvider(exp_index),
608 m_participants(std::move(providers)),
609 m_path(std::move(path)),
610 m_derive(derive),
611 m_ranged_participants(std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) { return pubkey->IsRange(); }))
612 {
613 if (!Assume(!(m_ranged_participants && IsRangedDerivation()))) {
614 throw std::runtime_error("musig(): Cannot have both ranged participants and ranged derivation");
615 }
616 if (!Assume(m_derive != DeriveType::HARDENED)) {
617 throw std::runtime_error("musig(): Cannot have hardened derivation");
618 }
619 }
620
621 std::optional<CPubKey> GetPubKey(int pos, const SigningProvider& arg, FlatSigningProvider& out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
622 {
624 // If the participants are not ranged, we can compute and cache the aggregate pubkey by creating a PubkeyProvider for it
625 if (!m_aggregate_provider && !m_ranged_participants) {
626 // Retrieve the pubkeys from the providers
627 std::vector<CPubKey> pubkeys;
628 for (const auto& prov : m_participants) {
629 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
630 if (!pubkey.has_value()) {
631 return std::nullopt;
632 }
633 pubkeys.push_back(pubkey.value());
634 }
635 std::sort(pubkeys.begin(), pubkeys.end());
636
637 // Aggregate the pubkey
638 m_aggregate_pubkey = MuSig2AggregatePubkeys(pubkeys);
639 if (!Assume(m_aggregate_pubkey.has_value())) return std::nullopt;
640
641 // Make our pubkey provider
642 if (IsRangedDerivation() || !m_path.empty()) {
643 // Make the synthetic xpub and construct the BIP32PubkeyProvider
644 CExtPubKey extpub;
645 extpub.nDepth = 0;
646 std::memset(extpub.vchFingerprint, 0, 4);
647 extpub.nChild = 0;
648 extpub.chaincode = MUSIG_CHAINCODE;
649 extpub.pubkey = m_aggregate_pubkey.value();
650
651 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub, m_path, m_derive, /*apostrophe=*/false);
652 } else {
653 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(), /*xonly=*/false);
654 }
655 }
656
657 // Retrieve all participant pubkeys
658 std::vector<CPubKey> pubkeys;
659 for (const auto& prov : m_participants) {
660 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg, out, read_cache, write_cache);
661 if (!pub) return std::nullopt;
662 pubkeys.emplace_back(*pub);
663 }
664 std::sort(pubkeys.begin(), pubkeys.end());
665
666 CPubKey pubout;
667 if (m_aggregate_provider) {
668 // When we have a cached aggregate key, we are either returning it or deriving from it
669 // Either way, we can passthrough to its GetPubKey
670 // Use a dummy signing provider as private keys do not exist for the aggregate pubkey
671 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy, out, read_cache, write_cache);
672 if (!pub) return std::nullopt;
673 pubout = *pub;
674 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
675 } else {
676 if (!Assume(m_ranged_participants) || !Assume(m_path.empty())) return std::nullopt;
677 // Compute aggregate key from derived participants
678 std::optional<CPubKey> aggregate_pubkey = MuSig2AggregatePubkeys(pubkeys);
679 if (!aggregate_pubkey) return std::nullopt;
680 pubout = *aggregate_pubkey;
681
682 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(), /*xonly=*/false);
683 this_agg_provider->GetPubKey(0, dummy, out, read_cache, write_cache);
684 out.aggregate_pubkeys.emplace(pubout, pubkeys);
685 }
686
687 if (!Assume(pubout.IsValid())) return std::nullopt;
688 return pubout;
689 }
690 bool IsRange() const override { return IsRangedDerivation() || m_ranged_participants; }
691 // musig() expressions can only be used in tr() contexts which have 32 byte xonly pubkeys
692 size_t GetSize() const override { return 32; }
693
694 std::string ToString(StringType type=StringType::PUBLIC) const override
695 {
696 std::string out = "musig(";
697 for (size_t i = 0; i < m_participants.size(); ++i) {
698 const auto& pubkey = m_participants.at(i);
699 if (i) out += ",";
700 out += pubkey->ToString(type);
701 }
702 out += ")";
703 out += FormatHDKeypath(m_path);
704 if (IsRangedDerivation()) {
705 out += "/*";
706 }
707 return out;
708 }
709 bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
710 {
711 bool any_privkeys = false;
712 out = "musig(";
713 for (size_t i = 0; i < m_participants.size(); ++i) {
714 const auto& pubkey = m_participants.at(i);
715 if (i) out += ",";
716 std::string tmp;
717 if (pubkey->ToPrivateString(arg, tmp)) {
718 any_privkeys = true;
719 out += tmp;
720 } else {
721 out += pubkey->ToString();
722 }
723 }
724 out += ")";
725 out += FormatHDKeypath(m_path);
726 if (IsRangedDerivation()) {
727 out += "/*";
728 }
729 if (!any_privkeys) out.clear();
730 return any_privkeys;
731 }
732 bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache = nullptr) const override
733 {
734 out = "musig(";
735 for (size_t i = 0; i < m_participants.size(); ++i) {
736 const auto& pubkey = m_participants.at(i);
737 if (i) out += ",";
738 std::string tmp;
739 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
740 return false;
741 }
742 out += tmp;
743 }
744 out += ")";
745 out += FormatHDKeypath(m_path);
746 if (IsRangedDerivation()) {
747 out += "/*";
748 }
749 return true;
750 }
751
752 void GetPrivKey(int pos, const SigningProvider& arg, FlatSigningProvider& out) const override
753 {
754 // Get the private keys for any participants that we have
755 // If there is participant derivation, it will be done.
756 // If there is not, then the participant privkeys will be included directly
757 for (const auto& prov : m_participants) {
758 prov->GetPrivKey(pos, arg, out);
759 }
760 }
761
762 // Get RootPubKey and GetRootExtPubKey are used to return the single pubkey underlying the pubkey provider
763 // to be presented to the user in gethdkeys. As this is a multisig construction, there is no single underlying
764 // pubkey hence nothing should be returned.
765 // While the aggregate pubkey could be returned as the root (ext)pubkey, it is not a pubkey that anyone should
766 // be using by itself in a descriptor as it is unspendable without knowing its participants.
767 std::optional<CPubKey> GetRootPubKey() const override
768 {
769 return std::nullopt;
770 }
771 std::optional<CExtPubKey> GetRootExtPubKey() const override
772 {
773 return std::nullopt;
774 }
775
776 std::unique_ptr<PubkeyProvider> Clone() const override
777 {
778 std::vector<std::unique_ptr<PubkeyProvider>> providers;
779 providers.reserve(m_participants.size());
780 for (const std::unique_ptr<PubkeyProvider>& p : m_participants) {
781 providers.emplace_back(p->Clone());
782 }
783 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers), m_path, m_derive);
784 }
785 bool IsBIP32() const override
786 {
787 // musig() can only be a BIP 32 key if all participants are bip32 too
788 return std::all_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) { return pubkey->IsBIP32(); });
789 }
790};
791
793class DescriptorImpl : public Descriptor
794{
795protected:
797 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
799 const std::string m_name;
800
805 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
806
808 virtual std::string ToStringExtra() const { return ""; }
809
820 virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts, FlatSigningProvider& out) const = 0;
821
822public:
823 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args() {}
824 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl> script, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args(Vector(std::move(script))) {}
825 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::vector<std::unique_ptr<DescriptorImpl>> scripts, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args(std::move(scripts)) {}
826
827 enum class StringType
828 {
829 PUBLIC,
830 PRIVATE,
831 NORMALIZED,
832 COMPAT, // string calculation that mustn't change over time to stay compatible with previous software versions
833 };
834
835 // NOLINTNEXTLINE(misc-no-recursion)
836 bool IsSolvable() const override
837 {
838 for (const auto& arg : m_subdescriptor_args) {
839 if (!arg->IsSolvable()) return false;
840 }
841 return true;
842 }
843
844 // NOLINTNEXTLINE(misc-no-recursion)
845 bool IsRange() const final
846 {
847 for (const auto& pubkey : m_pubkey_args) {
848 if (pubkey->IsRange()) return true;
849 }
850 for (const auto& arg : m_subdescriptor_args) {
851 if (arg->IsRange()) return true;
852 }
853 return false;
854 }
855
856 // NOLINTNEXTLINE(misc-no-recursion)
857 virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const
858 {
859 size_t pos = 0;
860 for (const auto& scriptarg : m_subdescriptor_args) {
861 if (pos++) ret += ",";
862 std::string tmp;
863 if (!scriptarg->ToStringHelper(arg, tmp, type, cache)) return false;
864 ret += tmp;
865 }
866 return true;
867 }
868
869 // NOLINTNEXTLINE(misc-no-recursion)
870 virtual bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type, const DescriptorCache* cache = nullptr) const
871 {
872 std::string extra = ToStringExtra();
873 size_t pos = extra.size() > 0 ? 1 : 0;
874 std::string ret = m_name + "(" + extra;
875 for (const auto& pubkey : m_pubkey_args) {
876 if (pos++) ret += ",";
877 std::string tmp;
878 switch (type) {
879 case StringType::NORMALIZED:
880 if (!pubkey->ToNormalizedString(*arg, tmp, cache)) return false;
881 break;
882 case StringType::PRIVATE:
883 if (!pubkey->ToPrivateString(*arg, tmp)) return false;
884 break;
885 case StringType::PUBLIC:
886 tmp = pubkey->ToString();
887 break;
888 case StringType::COMPAT:
889 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
890 break;
891 }
892 ret += tmp;
893 }
894 std::string subscript;
895 if (!ToStringSubScriptHelper(arg, subscript, type, cache)) return false;
896 if (pos && subscript.size()) ret += ',';
897 out = std::move(ret) + std::move(subscript) + ")";
898 return true;
899 }
900
901 std::string ToString(bool compat_format) const final
902 {
903 std::string ret;
904 ToStringHelper(nullptr, ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
905 return AddChecksum(ret);
906 }
907
908 bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
909 {
910 bool ret = ToStringHelper(&arg, out, StringType::PRIVATE);
911 out = AddChecksum(out);
912 return ret;
913 }
914
915 bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override final
916 {
917 bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED, cache);
918 out = AddChecksum(out);
919 return ret;
920 }
921
922 // NOLINTNEXTLINE(misc-no-recursion)
923 bool ExpandHelper(int pos, const SigningProvider& arg, const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache) const
924 {
925 FlatSigningProvider subprovider;
926 std::vector<CPubKey> pubkeys;
927 pubkeys.reserve(m_pubkey_args.size());
928
929 // Construct temporary data in `pubkeys`, `subscripts`, and `subprovider` to avoid producing output in case of failure.
930 for (const auto& p : m_pubkey_args) {
931 std::optional<CPubKey> pubkey = p->GetPubKey(pos, arg, subprovider, read_cache, write_cache);
932 if (!pubkey) return false;
933 pubkeys.push_back(pubkey.value());
934 }
935 std::vector<CScript> subscripts;
936 for (const auto& subarg : m_subdescriptor_args) {
937 std::vector<CScript> outscripts;
938 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache)) return false;
939 assert(outscripts.size() == 1);
940 subscripts.emplace_back(std::move(outscripts[0]));
941 }
942 out.Merge(std::move(subprovider));
943
944 output_scripts = MakeScripts(pubkeys, std::span{subscripts}, out);
945 return true;
946 }
947
948 bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache = nullptr) const final
949 {
950 return ExpandHelper(pos, provider, nullptr, output_scripts, out, write_cache);
951 }
952
953 bool ExpandFromCache(int pos, const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const final
954 {
955 return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &read_cache, output_scripts, out, nullptr);
956 }
957
958 // NOLINTNEXTLINE(misc-no-recursion)
959 void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final
960 {
961 for (const auto& p : m_pubkey_args) {
962 p->GetPrivKey(pos, provider, out);
963 }
964 for (const auto& arg : m_subdescriptor_args) {
965 arg->ExpandPrivate(pos, provider, out);
966 }
967 }
968
969 std::optional<OutputType> GetOutputType() const override { return std::nullopt; }
970
971 std::optional<int64_t> ScriptSize() const override { return {}; }
972
978 virtual std::optional<int64_t> MaxSatSize(bool use_max_sig) const { return {}; }
979
980 std::optional<int64_t> MaxSatisfactionWeight(bool) const override { return {}; }
981
982 std::optional<int64_t> MaxSatisfactionElems() const override { return {}; }
983
984 // NOLINTNEXTLINE(misc-no-recursion)
985 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs) const override
986 {
987 for (const auto& p : m_pubkey_args) {
988 std::optional<CPubKey> pub = p->GetRootPubKey();
989 if (pub) pubkeys.insert(*pub);
990 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
991 if (ext_pub) ext_pubs.insert(*ext_pub);
992 }
993 for (const auto& arg : m_subdescriptor_args) {
994 arg->GetPubKeys(pubkeys, ext_pubs);
995 }
996 }
997
998 virtual std::unique_ptr<DescriptorImpl> Clone() const = 0;
999};
1000
1002class AddressDescriptor final : public DescriptorImpl
1003{
1004 const CTxDestination m_destination;
1005protected:
1006 std::string ToStringExtra() const override { return EncodeDestination(m_destination); }
1007 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }
1008public:
1009 AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, "addr"), m_destination(std::move(destination)) {}
1010 bool IsSolvable() const final { return false; }
1011
1012 std::optional<OutputType> GetOutputType() const override
1013 {
1014 return OutputTypeFromDestination(m_destination);
1015 }
1016 bool IsSingleType() const final { return true; }
1017 bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }
1018
1019 std::optional<int64_t> ScriptSize() const override { return GetScriptForDestination(m_destination).size(); }
1020 std::unique_ptr<DescriptorImpl> Clone() const override
1021 {
1022 return std::make_unique<AddressDescriptor>(m_destination);
1023 }
1024};
1025
1027class RawDescriptor final : public DescriptorImpl
1028{
1029 const CScript m_script;
1030protected:
1031 std::string ToStringExtra() const override { return HexStr(m_script); }
1032 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&) const override { return Vector(m_script); }
1033public:
1034 RawDescriptor(CScript script) : DescriptorImpl({}, "raw"), m_script(std::move(script)) {}
1035 bool IsSolvable() const final { return false; }
1036
1037 std::optional<OutputType> GetOutputType() const override
1038 {
1039 CTxDestination dest;
1040 ExtractDestination(m_script, dest);
1041 return OutputTypeFromDestination(dest);
1042 }
1043 bool IsSingleType() const final { return true; }
1044 bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }
1045
1046 std::optional<int64_t> ScriptSize() const override { return m_script.size(); }
1047
1048 std::unique_ptr<DescriptorImpl> Clone() const override
1049 {
1050 return std::make_unique<RawDescriptor>(m_script);
1051 }
1052};
1053
1055class PKDescriptor final : public DescriptorImpl
1056{
1057private:
1058 const bool m_xonly;
1059protected:
1060 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override
1061 {
1062 if (m_xonly) {
1064 return Vector(std::move(script));
1065 } else {
1066 return Vector(GetScriptForRawPubKey(keys[0]));
1067 }
1068 }
1069public:
1070 PKDescriptor(std::unique_ptr<PubkeyProvider> prov, bool xonly = false) : DescriptorImpl(Vector(std::move(prov)), "pk"), m_xonly(xonly) {}
1071 bool IsSingleType() const final { return true; }
1072
1073 std::optional<int64_t> ScriptSize() const override {
1074 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1075 }
1076
1077 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1078 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1079 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1080 }
1081
1082 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1083 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
1084 }
1085
1086 std::optional<int64_t> MaxSatisfactionElems() const override { return 1; }
1087
1088 std::unique_ptr<DescriptorImpl> Clone() const override
1089 {
1090 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1091 }
1092};
1093
1095class PKHDescriptor final : public DescriptorImpl
1096{
1097protected:
1098 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override
1099 {
1100 CKeyID id = keys[0].GetID();
1102 }
1103public:
1104 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "pkh") {}
1105 std::optional<OutputType> GetOutputType() const override { return OutputType::LEGACY; }
1106 bool IsSingleType() const final { return true; }
1107
1108 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 1 + 20 + 1 + 1; }
1109
1110 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1111 const auto sig_size = use_max_sig ? 72 : 71;
1112 return 1 + sig_size + 1 + m_pubkey_args[0]->GetSize();
1113 }
1114
1115 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1116 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
1117 }
1118
1119 std::optional<int64_t> MaxSatisfactionElems() const override { return 2; }
1120
1121 std::unique_ptr<DescriptorImpl> Clone() const override
1122 {
1123 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1124 }
1125};
1126
1128class WPKHDescriptor final : public DescriptorImpl
1129{
1130protected:
1131 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override
1132 {
1133 CKeyID id = keys[0].GetID();
1135 }
1136public:
1137 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "wpkh") {}
1138 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
1139 bool IsSingleType() const final { return true; }
1140
1141 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 20; }
1142
1143 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1144 const auto sig_size = use_max_sig ? 72 : 71;
1145 return (1 + sig_size + 1 + 33);
1146 }
1147
1148 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1149 return MaxSatSize(use_max_sig);
1150 }
1151
1152 std::optional<int64_t> MaxSatisfactionElems() const override { return 2; }
1153
1154 std::unique_ptr<DescriptorImpl> Clone() const override
1155 {
1156 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1157 }
1158};
1159
1161class ComboDescriptor final : public DescriptorImpl
1162{
1163protected:
1164 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider& out) const override
1165 {
1166 std::vector<CScript> ret;
1167 CKeyID id = keys[0].GetID();
1168 ret.emplace_back(GetScriptForRawPubKey(keys[0])); // P2PK
1169 ret.emplace_back(GetScriptForDestination(PKHash(id))); // P2PKH
1170 if (keys[0].IsCompressed()) {
1172 out.scripts.emplace(CScriptID(p2wpkh), p2wpkh);
1173 ret.emplace_back(p2wpkh);
1174 ret.emplace_back(GetScriptForDestination(ScriptHash(p2wpkh))); // P2SH-P2WPKH
1175 }
1176 return ret;
1177 }
1178public:
1179 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "combo") {}
1180 bool IsSingleType() const final { return false; }
1181 std::unique_ptr<DescriptorImpl> Clone() const override
1182 {
1183 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1184 }
1185};
1186
1188class MultisigDescriptor final : public DescriptorImpl
1189{
1190 const int m_threshold;
1191 const bool m_sorted;
1192protected:
1193 std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
1194 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override {
1195 if (m_sorted) {
1196 std::vector<CPubKey> sorted_keys(keys);
1197 std::sort(sorted_keys.begin(), sorted_keys.end());
1198 return Vector(GetScriptForMultisig(m_threshold, sorted_keys));
1199 }
1200 return Vector(GetScriptForMultisig(m_threshold, keys));
1201 }
1202public:
1203 MultisigDescriptor(int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers, bool sorted = false) : DescriptorImpl(std::move(providers), sorted ? "sortedmulti" : "multi"), m_threshold(threshold), m_sorted(sorted) {}
1204 bool IsSingleType() const final { return true; }
1205
1206 std::optional<int64_t> ScriptSize() const override {
1207 const auto n_keys = m_pubkey_args.size();
1208 auto op = [](int64_t acc, const std::unique_ptr<PubkeyProvider>& pk) { return acc + 1 + pk->GetSize();};
1209 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1210 return 1 + BuildScript(n_keys).size() + BuildScript(m_threshold).size() + pubkeys_size;
1211 }
1212
1213 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1214 const auto sig_size = use_max_sig ? 72 : 71;
1215 return (1 + (1 + sig_size) * m_threshold);
1216 }
1217
1218 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1219 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
1220 }
1221
1222 std::optional<int64_t> MaxSatisfactionElems() const override { return 1 + m_threshold; }
1223
1224 std::unique_ptr<DescriptorImpl> Clone() const override
1225 {
1226 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1227 providers.reserve(m_pubkey_args.size());
1228 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), providers.begin(), [](const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1229 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1230 }
1231};
1232
1234class MultiADescriptor final : public DescriptorImpl
1235{
1236 const int m_threshold;
1237 const bool m_sorted;
1238protected:
1239 std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
1240 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override {
1241 CScript ret;
1242 std::vector<XOnlyPubKey> xkeys;
1243 xkeys.reserve(keys.size());
1244 for (const auto& key : keys) xkeys.emplace_back(key);
1245 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1246 ret << ToByteVector(xkeys[0]) << OP_CHECKSIG;
1247 for (size_t i = 1; i < keys.size(); ++i) {
1248 ret << ToByteVector(xkeys[i]) << OP_CHECKSIGADD;
1249 }
1250 ret << m_threshold << OP_NUMEQUAL;
1251 return Vector(std::move(ret));
1252 }
1253public:
1254 MultiADescriptor(int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers, bool sorted = false) : DescriptorImpl(std::move(providers), sorted ? "sortedmulti_a" : "multi_a"), m_threshold(threshold), m_sorted(sorted) {}
1255 bool IsSingleType() const final { return true; }
1256
1257 std::optional<int64_t> ScriptSize() const override {
1258 const auto n_keys = m_pubkey_args.size();
1259 return (1 + 32 + 1) * n_keys + BuildScript(m_threshold).size() + 1;
1260 }
1261
1262 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1263 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1264 }
1265
1266 std::optional<int64_t> MaxSatisfactionElems() const override { return m_pubkey_args.size(); }
1267
1268 std::unique_ptr<DescriptorImpl> Clone() const override
1269 {
1270 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1271 providers.reserve(m_pubkey_args.size());
1272 for (const auto& arg : m_pubkey_args) {
1273 providers.push_back(arg->Clone());
1274 }
1275 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1276 }
1277};
1278
1280class SHDescriptor final : public DescriptorImpl
1281{
1282protected:
1283 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1284 {
1285 auto ret = Vector(GetScriptForDestination(ScriptHash(scripts[0])));
1286 if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
1287 return ret;
1288 }
1289
1290 bool IsSegwit() const { return m_subdescriptor_args[0]->GetOutputType() == OutputType::BECH32; }
1291
1292public:
1293 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "sh") {}
1294
1295 std::optional<OutputType> GetOutputType() const override
1296 {
1297 assert(m_subdescriptor_args.size() == 1);
1298 if (IsSegwit()) return OutputType::P2SH_SEGWIT;
1299 return OutputType::LEGACY;
1300 }
1301 bool IsSingleType() const final { return true; }
1302
1303 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 20 + 1; }
1304
1305 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1306 if (const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1307 if (const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1308 // The subscript is never witness data.
1309 const auto subscript_weight = (1 + *subscript_size) * WITNESS_SCALE_FACTOR;
1310 // The weight depends on whether the inner descriptor is satisfied using the witness stack.
1311 if (IsSegwit()) return subscript_weight + *sat_size;
1312 return subscript_weight + *sat_size * WITNESS_SCALE_FACTOR;
1313 }
1314 }
1315 return {};
1316 }
1317
1318 std::optional<int64_t> MaxSatisfactionElems() const override {
1319 if (const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems()) return 1 + *sub_elems;
1320 return {};
1321 }
1322
1323 std::unique_ptr<DescriptorImpl> Clone() const override
1324 {
1325 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1326 }
1327};
1328
1330class WSHDescriptor final : public DescriptorImpl
1331{
1332protected:
1333 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1334 {
1336 if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
1337 return ret;
1338 }
1339public:
1340 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "wsh") {}
1341 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
1342 bool IsSingleType() const final { return true; }
1343
1344 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1345
1346 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1347 if (const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1348 if (const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1349 return GetSizeOfCompactSize(*subscript_size) + *subscript_size + *sat_size;
1350 }
1351 }
1352 return {};
1353 }
1354
1355 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1356 return MaxSatSize(use_max_sig);
1357 }
1358
1359 std::optional<int64_t> MaxSatisfactionElems() const override {
1360 if (const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems()) return 1 + *sub_elems;
1361 return {};
1362 }
1363
1364 std::unique_ptr<DescriptorImpl> Clone() const override
1365 {
1366 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1367 }
1368};
1369
1371class TRDescriptor final : public DescriptorImpl
1372{
1373 std::vector<int> m_depths;
1374protected:
1375 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1376 {
1377 TaprootBuilder builder;
1378 assert(m_depths.size() == scripts.size());
1379 for (size_t pos = 0; pos < m_depths.size(); ++pos) {
1380 builder.Add(m_depths[pos], scripts[pos], TAPROOT_LEAF_TAPSCRIPT);
1381 }
1382 if (!builder.IsComplete()) return {};
1383 assert(keys.size() == 1);
1384 XOnlyPubKey xpk(keys[0]);
1385 if (!xpk.IsFullyValid()) return {};
1386 builder.Finalize(xpk);
1387 WitnessV1Taproot output = builder.GetOutput();
1388 out.tr_trees[output] = builder;
1389 return Vector(GetScriptForDestination(output));
1390 }
1391 bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const override
1392 {
1393 if (m_depths.empty()) return true;
1394 std::vector<bool> path;
1395 for (size_t pos = 0; pos < m_depths.size(); ++pos) {
1396 if (pos) ret += ',';
1397 while ((int)path.size() <= m_depths[pos]) {
1398 if (path.size()) ret += '{';
1399 path.push_back(false);
1400 }
1401 std::string tmp;
1402 if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)) return false;
1403 ret += tmp;
1404 while (!path.empty() && path.back()) {
1405 if (path.size() > 1) ret += '}';
1406 path.pop_back();
1407 }
1408 if (!path.empty()) path.back() = true;
1409 }
1410 return true;
1411 }
1412public:
1413 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1414 DescriptorImpl(Vector(std::move(internal_key)), std::move(descs), "tr"), m_depths(std::move(depths))
1415 {
1416 assert(m_subdescriptor_args.size() == m_depths.size());
1417 }
1418 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32M; }
1419 bool IsSingleType() const final { return true; }
1420
1421 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1422
1423 std::optional<int64_t> MaxSatisfactionWeight(bool) const override {
1424 // FIXME: We assume keypath spend, which can lead to very large underestimations.
1425 return 1 + 65;
1426 }
1427
1428 std::optional<int64_t> MaxSatisfactionElems() const override {
1429 // FIXME: See above, we assume keypath spend.
1430 return 1;
1431 }
1432
1433 std::unique_ptr<DescriptorImpl> Clone() const override
1434 {
1435 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1436 subdescs.reserve(m_subdescriptor_args.size());
1437 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), subdescs.begin(), [](const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1438 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1439 }
1440};
1441
1442/* We instantiate Miniscript here with a simple integer as key type.
1443 * The value of these key integers are an index in the
1444 * DescriptorImpl::m_pubkey_args vector.
1445 */
1446
1450class ScriptMaker {
1452 const std::vector<CPubKey>& m_keys;
1454 const miniscript::MiniscriptContext m_script_ctx;
1455
1459 uint160 GetHash160(uint32_t key) const {
1460 if (miniscript::IsTapscript(m_script_ctx)) {
1461 return Hash160(XOnlyPubKey{m_keys[key]});
1462 }
1463 return m_keys[key].GetID();
1464 }
1465
1466public:
1467 ScriptMaker(const std::vector<CPubKey>& keys LIFETIMEBOUND, const miniscript::MiniscriptContext script_ctx) : m_keys(keys), m_script_ctx{script_ctx} {}
1468
1469 std::vector<unsigned char> ToPKBytes(uint32_t key) const {
1470 // In Tapscript keys always serialize as x-only, whether an x-only key was used in the descriptor or not.
1471 if (!miniscript::IsTapscript(m_script_ctx)) {
1472 return {m_keys[key].begin(), m_keys[key].end()};
1473 }
1474 const XOnlyPubKey xonly_pubkey{m_keys[key]};
1475 return {xonly_pubkey.begin(), xonly_pubkey.end()};
1476 }
1477
1478 std::vector<unsigned char> ToPKHBytes(uint32_t key) const {
1479 auto id = GetHash160(key);
1480 return {id.begin(), id.end()};
1481 }
1482};
1483
1487class StringMaker {
1489 const SigningProvider* m_arg;
1491 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1493 bool m_private;
1494
1495public:
1496 StringMaker(const SigningProvider* arg LIFETIMEBOUND, const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys LIFETIMEBOUND, bool priv)
1497 : m_arg(arg), m_pubkeys(pubkeys), m_private(priv) {}
1498
1499 std::optional<std::string> ToString(uint32_t key) const
1500 {
1501 std::string ret;
1502 if (m_private) {
1503 if (!m_pubkeys[key]->ToPrivateString(*m_arg, ret)) return {};
1504 } else {
1505 ret = m_pubkeys[key]->ToString();
1506 }
1507 return ret;
1508 }
1509};
1510
1511class MiniscriptDescriptor final : public DescriptorImpl
1512{
1513private:
1515
1516protected:
1517 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1518 FlatSigningProvider& provider) const override
1519 {
1520 const auto script_ctx{m_node->GetMsCtx()};
1521 for (const auto& key : keys) {
1522 if (miniscript::IsTapscript(script_ctx)) {
1523 provider.pubkeys.emplace(Hash160(XOnlyPubKey{key}), key);
1524 } else {
1525 provider.pubkeys.emplace(key.GetID(), key);
1526 }
1527 }
1528 return Vector(m_node->ToScript(ScriptMaker(keys, script_ctx)));
1529 }
1530
1531public:
1532 MiniscriptDescriptor(std::vector<std::unique_ptr<PubkeyProvider>> providers, miniscript::NodeRef<uint32_t> node)
1533 : DescriptorImpl(std::move(providers), "?"), m_node(std::move(node)) {}
1534
1535 bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type,
1536 const DescriptorCache* cache = nullptr) const override
1537 {
1538 if (const auto res = m_node->ToString(StringMaker(arg, m_pubkey_args, type == StringType::PRIVATE))) {
1539 out = *res;
1540 return true;
1541 }
1542 return false;
1543 }
1544
1545 bool IsSolvable() const override { return true; }
1546 bool IsSingleType() const final { return true; }
1547
1548 std::optional<int64_t> ScriptSize() const override { return m_node->ScriptSize(); }
1549
1550 std::optional<int64_t> MaxSatSize(bool) const override {
1551 // For Miniscript we always assume high-R ECDSA signatures.
1552 return m_node->GetWitnessSize();
1553 }
1554
1555 std::optional<int64_t> MaxSatisfactionElems() const override {
1556 return m_node->GetStackSize();
1557 }
1558
1559 std::unique_ptr<DescriptorImpl> Clone() const override
1560 {
1561 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1562 providers.reserve(m_pubkey_args.size());
1563 for (const auto& arg : m_pubkey_args) {
1564 providers.push_back(arg->Clone());
1565 }
1566 return std::make_unique<MiniscriptDescriptor>(std::move(providers), m_node->Clone());
1567 }
1568};
1569
1571class RawTRDescriptor final : public DescriptorImpl
1572{
1573protected:
1574 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1575 {
1576 assert(keys.size() == 1);
1577 XOnlyPubKey xpk(keys[0]);
1578 if (!xpk.IsFullyValid()) return {};
1579 WitnessV1Taproot output{xpk};
1580 return Vector(GetScriptForDestination(output));
1581 }
1582public:
1583 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(Vector(std::move(output_key)), "rawtr") {}
1584 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32M; }
1585 bool IsSingleType() const final { return true; }
1586
1587 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1588
1589 std::optional<int64_t> MaxSatisfactionWeight(bool) const override {
1590 // We can't know whether there is a script path, so assume key path spend.
1591 return 1 + 65;
1592 }
1593
1594 std::optional<int64_t> MaxSatisfactionElems() const override {
1595 // See above, we assume keypath spend.
1596 return 1;
1597 }
1598
1599 std::unique_ptr<DescriptorImpl> Clone() const override
1600 {
1601 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1602 }
1603};
1604
1606// Parser //
1608
1609enum class ParseScriptContext {
1610 TOP,
1611 P2SH,
1612 P2WPKH,
1613 P2WSH,
1614 P2TR,
1615 MUSIG,
1616};
1617
1618std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem, bool& apostrophe, std::string& error, bool& has_hardened)
1619{
1620 bool hardened = false;
1621 if (elem.size() > 0) {
1622 const char last = elem[elem.size() - 1];
1623 if (last == '\'' || last == 'h') {
1624 elem = elem.first(elem.size() - 1);
1625 hardened = true;
1626 apostrophe = last == '\'';
1627 }
1628 }
1629 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1630 if (!p) {
1631 error = strprintf("Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1632 return std::nullopt;
1633 } else if (*p > 0x7FFFFFFFUL) {
1634 error = strprintf("Key path value %u is out of range", *p);
1635 return std::nullopt;
1636 }
1637 has_hardened = has_hardened || hardened;
1638
1639 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1640}
1641
1652[[nodiscard]] bool ParseKeyPath(const std::vector<std::span<const char>>& split, std::vector<KeyPath>& out, bool& apostrophe, std::string& error, bool allow_multipath, bool& has_hardened)
1653{
1654 KeyPath path;
1655 struct MultipathSubstitutes {
1656 size_t placeholder_index;
1657 std::vector<uint32_t> values;
1658 };
1659 std::optional<MultipathSubstitutes> substitutes;
1660 has_hardened = false;
1661
1662 for (size_t i = 1; i < split.size(); ++i) {
1663 const std::span<const char>& elem = split[i];
1664
1665 // Check if element contains multipath specifier
1666 if (!elem.empty() && elem.front() == '<' && elem.back() == '>') {
1667 if (!allow_multipath) {
1668 error = strprintf("Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1669 return false;
1670 }
1671 if (substitutes) {
1672 error = "Multiple multipath key path specifiers found";
1673 return false;
1674 }
1675
1676 // Parse each possible value
1677 std::vector<std::span<const char>> nums = Split(std::span(elem.begin()+1, elem.end()-1), ";");
1678 if (nums.size() < 2) {
1679 error = "Multipath key path specifiers must have at least two items";
1680 return false;
1681 }
1682
1683 substitutes.emplace();
1684 std::unordered_set<uint32_t> seen_substitutes;
1685 for (const auto& num : nums) {
1686 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1687 if (!op_num) return false;
1688 auto [_, inserted] = seen_substitutes.insert(*op_num);
1689 if (!inserted) {
1690 error = strprintf("Duplicated key path value %u in multipath specifier", *op_num);
1691 return false;
1692 }
1693 substitutes->values.emplace_back(*op_num);
1694 }
1695
1696 path.emplace_back(); // Placeholder for multipath segment
1697 substitutes->placeholder_index = path.size() - 1;
1698 } else {
1699 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1700 if (!op_num) return false;
1701 path.emplace_back(*op_num);
1702 }
1703 }
1704
1705 if (!substitutes) {
1706 out.emplace_back(std::move(path));
1707 } else {
1708 // Replace the multipath placeholder with each value while generating paths
1709 for (uint32_t substitute : substitutes->values) {
1710 KeyPath branch_path = path;
1711 branch_path[substitutes->placeholder_index] = substitute;
1712 out.emplace_back(std::move(branch_path));
1713 }
1714 }
1715 return true;
1716}
1717
1718[[nodiscard]] bool ParseKeyPath(const std::vector<std::span<const char>>& split, std::vector<KeyPath>& out, bool& apostrophe, std::string& error, bool allow_multipath)
1719{
1720 bool dummy;
1721 return ParseKeyPath(split, out, apostrophe, error, allow_multipath, /*has_hardened=*/dummy);
1722}
1723
1724static DeriveType ParseDeriveType(std::vector<std::span<const char>>& split, bool& apostrophe)
1725{
1726 DeriveType type = DeriveType::NO;
1727 if (std::ranges::equal(split.back(), std::span{"*"}.first(1))) {
1728 split.pop_back();
1729 type = DeriveType::UNHARDENED;
1730 } else if (std::ranges::equal(split.back(), std::span{"*'"}.first(2)) || std::ranges::equal(split.back(), std::span{"*h"}.first(2))) {
1731 apostrophe = std::ranges::equal(split.back(), std::span{"*'"}.first(2));
1732 split.pop_back();
1733 type = DeriveType::HARDENED;
1734 }
1735 return type;
1736}
1737
1739std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_index, const std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, bool& apostrophe, std::string& error)
1740{
1741 std::vector<std::unique_ptr<PubkeyProvider>> ret;
1742 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1743 auto split = Split(sp, '/');
1744 std::string str(split[0].begin(), split[0].end());
1745 if (str.size() == 0) {
1746 error = "No key provided";
1747 return {};
1748 }
1749 if (IsSpace(str.front()) || IsSpace(str.back())) {
1750 error = strprintf("Key '%s' is invalid due to whitespace", str);
1751 return {};
1752 }
1753 if (split.size() == 1) {
1754 if (IsHex(str)) {
1755 std::vector<unsigned char> data = ParseHex(str);
1756 CPubKey pubkey(data);
1757 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1758 error = "Hybrid public keys are not allowed";
1759 return {};
1760 }
1761 if (pubkey.IsFullyValid()) {
1762 if (permit_uncompressed || pubkey.IsCompressed()) {
1763 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, false));
1764 return ret;
1765 } else {
1766 error = "Uncompressed keys are not allowed";
1767 return {};
1768 }
1769 } else if (data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1770 unsigned char fullkey[33] = {0x02};
1771 std::copy(data.begin(), data.end(), fullkey + 1);
1772 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1773 if (pubkey.IsFullyValid()) {
1774 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, true));
1775 return ret;
1776 }
1777 }
1778 error = strprintf("Pubkey '%s' is invalid", str);
1779 return {};
1780 }
1781 CKey key = DecodeSecret(str);
1782 if (key.IsValid()) {
1783 if (permit_uncompressed || key.IsCompressed()) {
1784 CPubKey pubkey = key.GetPubKey();
1785 out.keys.emplace(pubkey.GetID(), key);
1786 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1787 return ret;
1788 } else {
1789 error = "Uncompressed keys are not allowed";
1790 return {};
1791 }
1792 }
1793 }
1794 CExtKey extkey = DecodeExtKey(str);
1795 CExtPubKey extpubkey = DecodeExtPubKey(str);
1796 if (!extkey.key.IsValid() && !extpubkey.pubkey.IsValid()) {
1797 error = strprintf("key '%s' is not valid", str);
1798 return {};
1799 }
1800 std::vector<KeyPath> paths;
1801 DeriveType type = ParseDeriveType(split, apostrophe);
1802 if (!ParseKeyPath(split, paths, apostrophe, error, /*allow_multipath=*/true)) return {};
1803 if (extkey.key.IsValid()) {
1804 extpubkey = extkey.Neuter();
1805 out.keys.emplace(extpubkey.pubkey.GetID(), extkey.key);
1806 }
1807 for (auto& path : paths) {
1808 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
1809 }
1810 return ret;
1811}
1812
1814// NOLINTNEXTLINE(misc-no-recursion)
1815std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index, const std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
1816{
1817 std::vector<std::unique_ptr<PubkeyProvider>> ret;
1818
1819 using namespace script;
1820
1821 // musig cannot be nested inside of an origin
1822 std::span<const char> span = sp;
1823 if (Const("musig(", span, /*skip=*/false)) {
1824 if (ctx != ParseScriptContext::P2TR) {
1825 error = "musig() is only allowed in tr() and rawtr()";
1826 return {};
1827 }
1828
1829 // Split the span on the end parentheses. The end parentheses must
1830 // be included in the resulting span so that Expr is happy.
1831 auto split = Split(sp, ')', /*include_sep=*/true);
1832 if (split.size() > 2) {
1833 error = "Too many ')' in musig() expression";
1834 return {};
1835 }
1836 std::span<const char> expr(split.at(0).begin(), split.at(0).end());
1837 if (!Func("musig", expr)) {
1838 error = "Invalid musig() expression";
1839 return {};
1840 }
1841
1842 // Parse the participant pubkeys
1843 bool any_ranged = false;
1844 bool all_bip32 = true;
1845 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
1846 bool any_key_parsed = true;
1847 size_t max_multipath_len = 0;
1848 while (expr.size()) {
1849 if (!any_key_parsed && !Const(",", expr)) {
1850 error = strprintf("musig(): expected ',', got '%c'", expr[0]);
1851 return {};
1852 }
1853 any_key_parsed = false;
1854 auto arg = Expr(expr);
1855 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG, out, error);
1856 if (pk.empty()) {
1857 error = strprintf("musig(): %s", error);
1858 return {};
1859 }
1860
1861 any_ranged = any_ranged || pk.at(0)->IsRange();
1862 all_bip32 = all_bip32 && pk.at(0)->IsBIP32();
1863
1864 max_multipath_len = std::max(max_multipath_len, pk.size());
1865
1866 providers.emplace_back(std::move(pk));
1867 key_exp_index++;
1868 }
1869 if (any_key_parsed) {
1870 error = "musig(): Must contain key expressions";
1871 return {};
1872 }
1873
1874 // Parse any derivation
1875 DeriveType deriv_type = DeriveType::NO;
1876 std::vector<KeyPath> derivation_multipaths;
1877 if (split.size() == 2 && Const("/", split.at(1), /*skip=*/false)) {
1878 if (!all_bip32) {
1879 error = "musig(): derivation requires all participants to be xpubs or xprvs";
1880 return {};
1881 }
1882 if (any_ranged) {
1883 error = "musig(): Cannot have ranged participant keys if musig() also has derivation";
1884 return {};
1885 }
1886 bool dummy = false;
1887 auto deriv_split = Split(split.at(1), '/');
1888 deriv_type = ParseDeriveType(deriv_split, dummy);
1889 if (deriv_type == DeriveType::HARDENED) {
1890 error = "musig(): Cannot have hardened child derivation";
1891 return {};
1892 }
1893 bool has_hardened = false;
1894 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error, /*allow_multipath=*/true, has_hardened)) {
1895 error = "musig(): " + error;
1896 return {};
1897 }
1898 if (has_hardened) {
1899 error = "musig(): cannot have hardened derivation steps";
1900 return {};
1901 }
1902 } else {
1903 derivation_multipaths.emplace_back();
1904 }
1905
1906 // Makes sure that all providers vectors in providers are the given length, or exactly length 1
1907 // Length 1 vectors have the single provider cloned until it matches the given length.
1908 const auto& clone_providers = [&providers](size_t length) -> bool {
1909 for (auto& multipath_providers : providers) {
1910 if (multipath_providers.size() == 1) {
1911 for (size_t i = 1; i < length; ++i) {
1912 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
1913 }
1914 } else if (multipath_providers.size() != length) {
1915 return false;
1916 }
1917 }
1918 return true;
1919 };
1920
1921 // Emplace the final MuSigPubkeyProvider into ret with the pubkey providers from the specified provider vectors index
1922 // and the path from the specified path index
1923 const auto& emplace_final_provider = [&ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](size_t vec_idx, size_t path_idx) -> void {
1924 KeyPath& path = derivation_multipaths.at(path_idx);
1925 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
1926 pubs.reserve(providers.size());
1927 for (auto& vec : providers) {
1928 pubs.emplace_back(std::move(vec.at(vec_idx)));
1929 }
1930 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
1931 };
1932
1933 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
1934 error = "musig(): Cannot have multipath participant keys if musig() is also multipath";
1935 return {};
1936 } else if (max_multipath_len > 1) {
1937 if (!clone_providers(max_multipath_len)) {
1938 error = strprintf("musig(): Multipath derivation paths have mismatched lengths");
1939 return {};
1940 }
1941 for (size_t i = 0; i < max_multipath_len; ++i) {
1942 // Final MuSigPubkeyProvider uses participant pubkey providers at each multipath position, and the first (and only) path
1943 emplace_final_provider(i, 0);
1944 }
1945 } else if (derivation_multipaths.size() > 1) {
1946 // All key provider vectors should be length 1. Clone them until they have the same length as paths
1947 if (!Assume(clone_providers(derivation_multipaths.size()))) {
1948 error = "musig(): Multipath derivation path with multipath participants is disallowed"; // This error is unreachable due to earlier check
1949 return {};
1950 }
1951 for (size_t i = 0; i < derivation_multipaths.size(); ++i) {
1952 // Final MuSigPubkeyProvider uses cloned participant pubkey providers, and the multipath derivation paths
1953 emplace_final_provider(i, i);
1954 }
1955 } else {
1956 // No multipath derivation, MuSigPubkeyProvider uses the first (and only) participant pubkey providers, and the first (and only) path
1957 emplace_final_provider(0, 0);
1958 }
1959 return ret;
1960 }
1961
1962 auto origin_split = Split(sp, ']');
1963 if (origin_split.size() > 2) {
1964 error = "Multiple ']' characters found for a single pubkey";
1965 return {};
1966 }
1967 // This is set if either the origin or path suffix contains a hardened derivation.
1968 bool apostrophe = false;
1969 if (origin_split.size() == 1) {
1970 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, apostrophe, error);
1971 }
1972 if (origin_split[0].empty() || origin_split[0][0] != '[') {
1973 error = strprintf("Key origin start '[ character expected but not found, got '%c' instead",
1974 origin_split[0].empty() ? ']' : origin_split[0][0]);
1975 return {};
1976 }
1977 auto slash_split = Split(origin_split[0].subspan(1), '/');
1978 if (slash_split[0].size() != 8) {
1979 error = strprintf("Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
1980 return {};
1981 }
1982 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
1983 if (!IsHex(fpr_hex)) {
1984 error = strprintf("Fingerprint '%s' is not hex", fpr_hex);
1985 return {};
1986 }
1987 auto fpr_bytes = ParseHex(fpr_hex);
1988 KeyOriginInfo info;
1989 static_assert(sizeof(info.fingerprint) == 4, "Fingerprint must be 4 bytes");
1990 assert(fpr_bytes.size() == 4);
1991 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
1992 std::vector<KeyPath> path;
1993 if (!ParseKeyPath(slash_split, path, apostrophe, error, /*allow_multipath=*/false)) return {};
1994 info.path = path.at(0);
1995 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx, out, apostrophe, error);
1996 if (providers.empty()) return {};
1997 ret.reserve(providers.size());
1998 for (auto& prov : providers) {
1999 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(key_exp_index, info, std::move(prov), apostrophe));
2000 }
2001 return ret;
2002}
2003
2004std::unique_ptr<PubkeyProvider> InferPubkey(const CPubKey& pubkey, ParseScriptContext ctx, const SigningProvider& provider)
2005{
2006 // Key cannot be hybrid
2007 if (!pubkey.IsValidNonHybrid()) {
2008 return nullptr;
2009 }
2010 // Uncompressed is only allowed in TOP and P2SH contexts
2011 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.IsCompressed()) {
2012 return nullptr;
2013 }
2014 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey, false);
2015 KeyOriginInfo info;
2016 if (provider.GetKeyOrigin(pubkey.GetID(), info)) {
2017 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider), /*apostrophe=*/false);
2018 }
2019 return key_provider;
2020}
2021
2022std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(const XOnlyPubKey& xkey, ParseScriptContext ctx, const SigningProvider& provider)
2023{
2024 CPubKey pubkey{xkey.GetEvenCorrespondingCPubKey()};
2025 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey, true);
2026 KeyOriginInfo info;
2027 if (provider.GetKeyOriginByXOnly(xkey, info)) {
2028 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider), /*apostrophe=*/false);
2029 }
2030 return key_provider;
2031}
2032
2036struct KeyParser {
2038 using Key = uint32_t;
2040 FlatSigningProvider* m_out;
2042 const SigningProvider* m_in;
2044 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2046 mutable std::string m_key_parsing_error;
2048 const miniscript::MiniscriptContext m_script_ctx;
2050 uint32_t m_offset;
2051
2053 miniscript::MiniscriptContext ctx, uint32_t offset = 0)
2054 : m_out(out), m_in(in), m_script_ctx(ctx), m_offset(offset) {}
2055
2056 bool KeyCompare(const Key& a, const Key& b) const {
2057 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2058 }
2059
2060 ParseScriptContext ParseContext() const {
2061 switch (m_script_ctx) {
2062 case miniscript::MiniscriptContext::P2WSH: return ParseScriptContext::P2WSH;
2063 case miniscript::MiniscriptContext::TAPSCRIPT: return ParseScriptContext::P2TR;
2064 }
2065 assert(false);
2066 }
2067
2068 template<typename I> std::optional<Key> FromString(I begin, I end) const
2069 {
2070 assert(m_out);
2071 Key key = m_keys.size();
2072 uint32_t exp_index = m_offset + key;
2073 auto pk = ParsePubkey(exp_index, {&*begin, &*end}, ParseContext(), *m_out, m_key_parsing_error);
2074 if (pk.empty()) return {};
2075 m_keys.emplace_back(std::move(pk));
2076 return key;
2077 }
2078
2079 std::optional<std::string> ToString(const Key& key) const
2080 {
2081 return m_keys.at(key).at(0)->ToString();
2082 }
2083
2084 template<typename I> std::optional<Key> FromPKBytes(I begin, I end) const
2085 {
2086 assert(m_in);
2087 Key key = m_keys.size();
2088 if (miniscript::IsTapscript(m_script_ctx) && end - begin == 32) {
2089 XOnlyPubKey pubkey;
2090 std::copy(begin, end, pubkey.begin());
2091 if (auto pubkey_provider = InferXOnlyPubkey(pubkey, ParseContext(), *m_in)) {
2092 m_keys.emplace_back();
2093 m_keys.back().push_back(std::move(pubkey_provider));
2094 return key;
2095 }
2096 } else if (!miniscript::IsTapscript(m_script_ctx)) {
2097 CPubKey pubkey(begin, end);
2098 if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) {
2099 m_keys.emplace_back();
2100 m_keys.back().push_back(std::move(pubkey_provider));
2101 return key;
2102 }
2103 }
2104 return {};
2105 }
2106
2107 template<typename I> std::optional<Key> FromPKHBytes(I begin, I end) const
2108 {
2109 assert(end - begin == 20);
2110 assert(m_in);
2111 uint160 hash;
2112 std::copy(begin, end, hash.begin());
2113 CKeyID keyid(hash);
2114 CPubKey pubkey;
2115 if (m_in->GetPubKey(keyid, pubkey)) {
2116 if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) {
2117 Key key = m_keys.size();
2118 m_keys.emplace_back();
2119 m_keys.back().push_back(std::move(pubkey_provider));
2120 return key;
2121 }
2122 }
2123 return {};
2124 }
2125
2126 miniscript::MiniscriptContext MsContext() const {
2127 return m_script_ctx;
2128 }
2129};
2130
2132// NOLINTNEXTLINE(misc-no-recursion)
2133std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
2134{
2135 using namespace script;
2136 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2137 std::vector<std::unique_ptr<DescriptorImpl>> ret;
2138 auto expr = Expr(sp);
2139 if (Func("pk", expr)) {
2140 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2141 if (pubkeys.empty()) {
2142 error = strprintf("pk(): %s", error);
2143 return {};
2144 }
2145 ++key_exp_index;
2146 for (auto& pubkey : pubkeys) {
2147 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2148 }
2149 return ret;
2150 }
2151 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && Func("pkh", expr)) {
2152 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2153 if (pubkeys.empty()) {
2154 error = strprintf("pkh(): %s", error);
2155 return {};
2156 }
2157 ++key_exp_index;
2158 for (auto& pubkey : pubkeys) {
2159 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2160 }
2161 return ret;
2162 }
2163 if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
2164 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2165 if (pubkeys.empty()) {
2166 error = strprintf("combo(): %s", error);
2167 return {};
2168 }
2169 ++key_exp_index;
2170 for (auto& pubkey : pubkeys) {
2171 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2172 }
2173 return ret;
2174 } else if (Func("combo", expr)) {
2175 error = "Can only have combo() at top level";
2176 return {};
2177 }
2178 const bool multi = Func("multi", expr);
2179 const bool sortedmulti = !multi && Func("sortedmulti", expr);
2180 const bool multi_a = !(multi || sortedmulti) && Func("multi_a", expr);
2181 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) && Func("sortedmulti_a", expr);
2182 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2183 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2184 auto threshold = Expr(expr);
2185 uint32_t thres;
2186 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers; // List of multipath expanded pubkeys
2187 if (const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2188 thres = *maybe_thres;
2189 } else {
2190 error = strprintf("Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2191 return {};
2192 }
2193 size_t script_size = 0;
2194 size_t max_providers_len = 0;
2195 while (expr.size()) {
2196 if (!Const(",", expr)) {
2197 error = strprintf("Multi: expected ',', got '%c'", expr[0]);
2198 return {};
2199 }
2200 auto arg = Expr(expr);
2201 auto pks = ParsePubkey(key_exp_index, arg, ctx, out, error);
2202 if (pks.empty()) {
2203 error = strprintf("Multi: %s", error);
2204 return {};
2205 }
2206 script_size += pks.at(0)->GetSize() + 1;
2207 max_providers_len = std::max(max_providers_len, pks.size());
2208 providers.emplace_back(std::move(pks));
2209 key_exp_index++;
2210 }
2211 if ((multi || sortedmulti) && (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTISIG)) {
2212 error = strprintf("Cannot have %u keys in multisig; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTISIG);
2213 return {};
2214 } else if ((multi_a || sortedmulti_a) && (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTI_A)) {
2215 error = strprintf("Cannot have %u keys in multi_a; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTI_A);
2216 return {};
2217 } else if (thres < 1) {
2218 error = strprintf("Multisig threshold cannot be %d, must be at least 1", thres);
2219 return {};
2220 } else if (thres > providers.size()) {
2221 error = strprintf("Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2222 return {};
2223 }
2224 if (ctx == ParseScriptContext::TOP) {
2225 if (providers.size() > 3) {
2226 error = strprintf("Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2227 return {};
2228 }
2229 }
2230 if (ctx == ParseScriptContext::P2SH) {
2231 // This limits the maximum number of compressed pubkeys to 15.
2232 if (script_size + 3 > MAX_SCRIPT_ELEMENT_SIZE) {
2233 error = strprintf("P2SH script is too large, %d bytes is larger than %d bytes", script_size + 3, MAX_SCRIPT_ELEMENT_SIZE);
2234 return {};
2235 }
2236 }
2237
2238 // Make sure all vecs are of the same length, or exactly length 1
2239 // For length 1 vectors, clone key providers until vector is the same length
2240 for (auto& vec : providers) {
2241 if (vec.size() == 1) {
2242 for (size_t i = 1; i < max_providers_len; ++i) {
2243 vec.emplace_back(vec.at(0)->Clone());
2244 }
2245 } else if (vec.size() != max_providers_len) {
2246 error = strprintf("multi(): Multipath derivation paths have mismatched lengths");
2247 return {};
2248 }
2249 }
2250
2251 // Build the final descriptors vector
2252 for (size_t i = 0; i < max_providers_len; ++i) {
2253 // Build final pubkeys vectors by retrieving the i'th subscript for each vector in subscripts
2254 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2255 pubs.reserve(providers.size());
2256 for (auto& pub : providers) {
2257 pubs.emplace_back(std::move(pub.at(i)));
2258 }
2259 if (multi || sortedmulti) {
2260 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2261 } else {
2262 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2263 }
2264 }
2265 return ret;
2266 } else if (multi || sortedmulti) {
2267 error = "Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2268 return {};
2269 } else if (multi_a || sortedmulti_a) {
2270 error = "Can only have multi_a/sortedmulti_a inside tr()";
2271 return {};
2272 }
2273 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wpkh", expr)) {
2274 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH, out, error);
2275 if (pubkeys.empty()) {
2276 error = strprintf("wpkh(): %s", error);
2277 return {};
2278 }
2279 key_exp_index++;
2280 for (auto& pubkey : pubkeys) {
2281 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2282 }
2283 return ret;
2284 } else if (Func("wpkh", expr)) {
2285 error = "Can only have wpkh() at top level or inside sh()";
2286 return {};
2287 }
2288 if (ctx == ParseScriptContext::TOP && Func("sh", expr)) {
2289 auto descs = ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error);
2290 if (descs.empty() || expr.size()) return {};
2291 std::vector<std::unique_ptr<DescriptorImpl>> ret;
2292 ret.reserve(descs.size());
2293 for (auto& desc : descs) {
2294 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2295 }
2296 return ret;
2297 } else if (Func("sh", expr)) {
2298 error = "Can only have sh() at top level";
2299 return {};
2300 }
2301 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wsh", expr)) {
2302 auto descs = ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out, error);
2303 if (descs.empty() || expr.size()) return {};
2304 for (auto& desc : descs) {
2305 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2306 }
2307 return ret;
2308 } else if (Func("wsh", expr)) {
2309 error = "Can only have wsh() at top level or inside sh()";
2310 return {};
2311 }
2312 if (ctx == ParseScriptContext::TOP && Func("addr", expr)) {
2313 CTxDestination dest = DecodeDestination(std::string(expr.begin(), expr.end()));
2314 if (!IsValidDestination(dest)) {
2315 error = "Address is not valid";
2316 return {};
2317 }
2318 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2319 return ret;
2320 } else if (Func("addr", expr)) {
2321 error = "Can only have addr() at top level";
2322 return {};
2323 }
2324 if (ctx == ParseScriptContext::TOP && Func("tr", expr)) {
2325 auto arg = Expr(expr);
2326 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
2327 if (internal_keys.empty()) {
2328 error = strprintf("tr(): %s", error);
2329 return {};
2330 }
2331 size_t max_providers_len = internal_keys.size();
2332 ++key_exp_index;
2333 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2334 std::vector<int> depths;
2335 if (expr.size()) {
2336 if (!Const(",", expr)) {
2337 error = strprintf("tr: expected ',', got '%c'", expr[0]);
2338 return {};
2339 }
2343 std::vector<bool> branches;
2344 // Loop over all provided scripts. In every iteration exactly one script will be processed.
2345 // Use a do-loop because inside this if-branch we expect at least one script.
2346 do {
2347 // First process all open braces.
2348 while (Const("{", expr)) {
2349 branches.push_back(false); // new left branch
2350 if (branches.size() > TAPROOT_CONTROL_MAX_NODE_COUNT) {
2351 error = strprintf("tr() supports at most %i nesting levels", TAPROOT_CONTROL_MAX_NODE_COUNT);
2352 return {};
2353 }
2354 }
2355 // Process the actual script expression.
2356 auto sarg = Expr(expr);
2357 subscripts.emplace_back(ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR, out, error));
2358 if (subscripts.back().empty()) return {};
2359 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2360 depths.push_back(branches.size());
2361 // Process closing braces; one is expected for every right branch we were in.
2362 while (branches.size() && branches.back()) {
2363 if (!Const("}", expr)) {
2364 error = strprintf("tr(): expected '}' after script expression");
2365 return {};
2366 }
2367 branches.pop_back(); // move up one level after encountering '}'
2368 }
2369 // If after that, we're at the end of a left branch, expect a comma.
2370 if (branches.size() && !branches.back()) {
2371 if (!Const(",", expr)) {
2372 error = strprintf("tr(): expected ',' after script expression");
2373 return {};
2374 }
2375 branches.back() = true; // And now we're in a right branch.
2376 }
2377 } while (branches.size());
2378 // After we've explored a whole tree, we must be at the end of the expression.
2379 if (expr.size()) {
2380 error = strprintf("tr(): expected ')' after script expression");
2381 return {};
2382 }
2383 }
2385
2386 // Make sure all vecs are of the same length, or exactly length 1
2387 // For length 1 vectors, clone subdescs until vector is the same length
2388 for (auto& vec : subscripts) {
2389 if (vec.size() == 1) {
2390 for (size_t i = 1; i < max_providers_len; ++i) {
2391 vec.emplace_back(vec.at(0)->Clone());
2392 }
2393 } else if (vec.size() != max_providers_len) {
2394 error = strprintf("tr(): Multipath subscripts have mismatched lengths");
2395 return {};
2396 }
2397 }
2398
2399 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2400 error = strprintf("tr(): Multipath internal key mismatches multipath subscripts lengths");
2401 return {};
2402 }
2403
2404 while (internal_keys.size() < max_providers_len) {
2405 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2406 }
2407
2408 // Build the final descriptors vector
2409 for (size_t i = 0; i < max_providers_len; ++i) {
2410 // Build final subscripts vectors by retrieving the i'th subscript for each vector in subscripts
2411 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2412 this_subs.reserve(subscripts.size());
2413 for (auto& subs : subscripts) {
2414 this_subs.emplace_back(std::move(subs.at(i)));
2415 }
2416 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2417 }
2418 return ret;
2419
2420
2421 } else if (Func("tr", expr)) {
2422 error = "Can only have tr at top level";
2423 return {};
2424 }
2425 if (ctx == ParseScriptContext::TOP && Func("rawtr", expr)) {
2426 auto arg = Expr(expr);
2427 if (expr.size()) {
2428 error = strprintf("rawtr(): only one key expected.");
2429 return {};
2430 }
2431 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
2432 if (output_keys.empty()) {
2433 error = strprintf("rawtr(): %s", error);
2434 return {};
2435 }
2436 ++key_exp_index;
2437 for (auto& pubkey : output_keys) {
2438 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2439 }
2440 return ret;
2441 } else if (Func("rawtr", expr)) {
2442 error = "Can only have rawtr at top level";
2443 return {};
2444 }
2445 if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
2446 std::string str(expr.begin(), expr.end());
2447 if (!IsHex(str)) {
2448 error = "Raw script is not hex";
2449 return {};
2450 }
2451 auto bytes = ParseHex(str);
2452 ret.emplace_back(std::make_unique<RawDescriptor>(CScript(bytes.begin(), bytes.end())));
2453 return ret;
2454 } else if (Func("raw", expr)) {
2455 error = "Can only have raw() at top level";
2456 return {};
2457 }
2458 // Process miniscript expressions.
2459 {
2460 const auto script_ctx{ctx == ParseScriptContext::P2WSH ? miniscript::MiniscriptContext::P2WSH : miniscript::MiniscriptContext::TAPSCRIPT};
2461 KeyParser parser(/*out = */&out, /* in = */nullptr, /* ctx = */script_ctx, key_exp_index);
2462 auto node = miniscript::FromString(std::string(expr.begin(), expr.end()), parser);
2463 if (parser.m_key_parsing_error != "") {
2464 error = std::move(parser.m_key_parsing_error);
2465 return {};
2466 }
2467 if (node) {
2468 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2469 error = "Miniscript expressions can only be used in wsh or tr.";
2470 return {};
2471 }
2472 if (!node->IsSane() || node->IsNotSatisfiable()) {
2473 // Try to find the first insane sub for better error reporting.
2474 auto insane_node = node.get();
2475 if (const auto sub = node->FindInsaneSub()) insane_node = sub;
2476 if (const auto str = insane_node->ToString(parser)) error = *str;
2477 if (!insane_node->IsValid()) {
2478 error += " is invalid";
2479 } else if (!node->IsSane()) {
2480 error += " is not sane";
2481 if (!insane_node->IsNonMalleable()) {
2482 error += ": malleable witnesses exist";
2483 } else if (insane_node == node.get() && !insane_node->NeedsSignature()) {
2484 error += ": witnesses without signature exist";
2485 } else if (!insane_node->CheckTimeLocksMix()) {
2486 error += ": contains mixes of timelocks expressed in blocks and seconds";
2487 } else if (!insane_node->CheckDuplicateKey()) {
2488 error += ": contains duplicate public keys";
2489 } else if (!insane_node->ValidSatisfactions()) {
2490 error += ": needs witnesses that may exceed resource limits";
2491 }
2492 } else {
2493 error += " is not satisfiable";
2494 }
2495 return {};
2496 }
2497 // A signature check is required for a miniscript to be sane. Therefore no sane miniscript
2498 // may have an empty list of public keys.
2499 CHECK_NONFATAL(!parser.m_keys.empty());
2500 key_exp_index += parser.m_keys.size();
2501 // Make sure all vecs are of the same length, or exactly length 1
2502 // For length 1 vectors, clone subdescs until vector is the same length
2503 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2504 [](const std::vector<std::unique_ptr<PubkeyProvider>>& a, const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2505 return a.size() < b.size();
2506 })->size();
2507
2508 for (auto& vec : parser.m_keys) {
2509 if (vec.size() == 1) {
2510 for (size_t i = 1; i < num_multipath; ++i) {
2511 vec.emplace_back(vec.at(0)->Clone());
2512 }
2513 } else if (vec.size() != num_multipath) {
2514 error = strprintf("Miniscript: Multipath derivation paths have mismatched lengths");
2515 return {};
2516 }
2517 }
2518
2519 // Build the final descriptors vector
2520 for (size_t i = 0; i < num_multipath; ++i) {
2521 // Build final pubkeys vectors by retrieving the i'th subscript for each vector in subscripts
2522 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2523 pubs.reserve(parser.m_keys.size());
2524 for (auto& pub : parser.m_keys) {
2525 pubs.emplace_back(std::move(pub.at(i)));
2526 }
2527 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs), node->Clone()));
2528 }
2529 return ret;
2530 }
2531 }
2532 if (ctx == ParseScriptContext::P2SH) {
2533 error = "A function is needed within P2SH";
2534 return {};
2535 } else if (ctx == ParseScriptContext::P2WSH) {
2536 error = "A function is needed within P2WSH";
2537 return {};
2538 }
2539 error = strprintf("'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2540 return {};
2541}
2542
2543std::unique_ptr<DescriptorImpl> InferMultiA(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
2544{
2545 auto match = MatchMultiA(script);
2546 if (!match) return {};
2547 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2548 keys.reserve(match->second.size());
2549 for (const auto keyspan : match->second) {
2550 if (keyspan.size() != 32) return {};
2551 auto key = InferXOnlyPubkey(XOnlyPubKey{keyspan}, ctx, provider);
2552 if (!key) return {};
2553 keys.push_back(std::move(key));
2554 }
2555 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
2556}
2557
2558// NOLINTNEXTLINE(misc-no-recursion)
2559std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
2560{
2561 if (ctx == ParseScriptContext::P2TR && script.size() == 34 && script[0] == 32 && script[33] == OP_CHECKSIG) {
2562 XOnlyPubKey key{std::span{script}.subspan(1, 32)};
2563 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider), true);
2564 }
2565
2566 if (ctx == ParseScriptContext::P2TR) {
2567 auto ret = InferMultiA(script, ctx, provider);
2568 if (ret) return ret;
2569 }
2570
2571 std::vector<std::vector<unsigned char>> data;
2572 TxoutType txntype = Solver(script, data);
2573
2574 if (txntype == TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2575 CPubKey pubkey(data[0]);
2576 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2577 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2578 }
2579 }
2580 if (txntype == TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2581 uint160 hash(data[0]);
2582 CKeyID keyid(hash);
2583 CPubKey pubkey;
2584 if (provider.GetPubKey(keyid, pubkey)) {
2585 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2586 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2587 }
2588 }
2589 }
2590 if (txntype == TxoutType::WITNESS_V0_KEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) {
2591 uint160 hash(data[0]);
2592 CKeyID keyid(hash);
2593 CPubKey pubkey;
2594 if (provider.GetPubKey(keyid, pubkey)) {
2595 if (auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
2596 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2597 }
2598 }
2599 }
2600 if (txntype == TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2601 bool ok = true;
2602 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2603 for (size_t i = 1; i + 1 < data.size(); ++i) {
2604 CPubKey pubkey(data[i]);
2605 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2606 providers.push_back(std::move(pubkey_provider));
2607 } else {
2608 ok = false;
2609 break;
2610 }
2611 }
2612 if (ok) return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers));
2613 }
2614 if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
2615 uint160 hash(data[0]);
2616 CScriptID scriptid(hash);
2617 CScript subscript;
2618 if (provider.GetCScript(scriptid, subscript)) {
2619 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
2620 if (sub) return std::make_unique<SHDescriptor>(std::move(sub));
2621 }
2622 }
2623 if (txntype == TxoutType::WITNESS_V0_SCRIPTHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) {
2624 CScriptID scriptid{RIPEMD160(data[0])};
2625 CScript subscript;
2626 if (provider.GetCScript(scriptid, subscript)) {
2627 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
2628 if (sub) return std::make_unique<WSHDescriptor>(std::move(sub));
2629 }
2630 }
2631 if (txntype == TxoutType::WITNESS_V1_TAPROOT && ctx == ParseScriptContext::TOP) {
2632 // Extract x-only pubkey from output.
2633 XOnlyPubKey pubkey;
2634 std::copy(data[0].begin(), data[0].end(), pubkey.begin());
2635 // Request spending data.
2636 TaprootSpendData tap;
2637 if (provider.GetTaprootSpendData(pubkey, tap)) {
2638 // If found, convert it back to tree form.
2639 auto tree = InferTaprootTree(tap, pubkey);
2640 if (tree) {
2641 // If that works, try to infer subdescriptors for all leaves.
2642 bool ok = true;
2643 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2644 std::vector<int> depths;
2645 for (const auto& [depth, script, leaf_ver] : *tree) {
2646 std::unique_ptr<DescriptorImpl> subdesc;
2647 if (leaf_ver == TAPROOT_LEAF_TAPSCRIPT) {
2648 subdesc = InferScript(CScript(script.begin(), script.end()), ParseScriptContext::P2TR, provider);
2649 }
2650 if (!subdesc) {
2651 ok = false;
2652 break;
2653 } else {
2654 subscripts.push_back(std::move(subdesc));
2655 depths.push_back(depth);
2656 }
2657 }
2658 if (ok) {
2659 auto key = InferXOnlyPubkey(tap.internal_key, ParseScriptContext::P2TR, provider);
2660 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2661 }
2662 }
2663 }
2664 // If the above doesn't work, construct a rawtr() descriptor with just the encoded x-only pubkey.
2665 if (pubkey.IsFullyValid()) {
2666 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2667 if (key) {
2668 return std::make_unique<RawTRDescriptor>(std::move(key));
2669 }
2670 }
2671 }
2672
2673 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2674 const auto script_ctx{ctx == ParseScriptContext::P2WSH ? miniscript::MiniscriptContext::P2WSH : miniscript::MiniscriptContext::TAPSCRIPT};
2675 KeyParser parser(/* out = */nullptr, /* in = */&provider, /* ctx = */script_ctx);
2676 auto node = miniscript::FromScript(script, parser);
2677 if (node && node->IsSane()) {
2678 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2679 keys.reserve(parser.m_keys.size());
2680 for (auto& key : parser.m_keys) {
2681 keys.emplace_back(std::move(key.at(0)));
2682 }
2683 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(node));
2684 }
2685 }
2686
2687 // The following descriptors are all top-level only descriptors.
2688 // So if we are not at the top level, return early.
2689 if (ctx != ParseScriptContext::TOP) return nullptr;
2690
2691 CTxDestination dest;
2692 if (ExtractDestination(script, dest)) {
2693 if (GetScriptForDestination(dest) == script) {
2694 return std::make_unique<AddressDescriptor>(std::move(dest));
2695 }
2696 }
2697
2698 return std::make_unique<RawDescriptor>(script);
2699}
2700
2701
2702} // namespace
2703
2705bool CheckChecksum(std::span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr)
2706{
2707 auto check_split = Split(sp, '#');
2708 if (check_split.size() > 2) {
2709 error = "Multiple '#' symbols";
2710 return false;
2711 }
2712 if (check_split.size() == 1 && require_checksum){
2713 error = "Missing checksum";
2714 return false;
2715 }
2716 if (check_split.size() == 2) {
2717 if (check_split[1].size() != 8) {
2718 error = strprintf("Expected 8 character checksum, not %u characters", check_split[1].size());
2719 return false;
2720 }
2721 }
2722 auto checksum = DescriptorChecksum(check_split[0]);
2723 if (checksum.empty()) {
2724 error = "Invalid characters in payload";
2725 return false;
2726 }
2727 if (check_split.size() == 2) {
2728 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2729 error = strprintf("Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2730 return false;
2731 }
2732 }
2733 if (out_checksum) *out_checksum = std::move(checksum);
2734 sp = check_split[0];
2735 return true;
2736}
2737
2738std::vector<std::unique_ptr<Descriptor>> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
2739{
2740 std::span<const char> sp{descriptor};
2741 if (!CheckChecksum(sp, require_checksum, error)) return {};
2742 uint32_t key_exp_index = 0;
2743 auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
2744 if (sp.size() == 0 && !ret.empty()) {
2745 std::vector<std::unique_ptr<Descriptor>> descs;
2746 descs.reserve(ret.size());
2747 for (auto& r : ret) {
2748 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2749 }
2750 return descs;
2751 }
2752 return {};
2753}
2754
2755std::string GetDescriptorChecksum(const std::string& descriptor)
2756{
2757 std::string ret;
2758 std::string error;
2759 std::span<const char> sp{descriptor};
2760 if (!CheckChecksum(sp, false, error, &ret)) return "";
2761 return ret;
2762}
2763
2764std::unique_ptr<Descriptor> InferDescriptor(const CScript& script, const SigningProvider& provider)
2765{
2766 return InferScript(script, ParseScriptContext::TOP, provider);
2767}
2768
2770{
2771 std::string desc_str = desc.ToString(/*compat_format=*/true);
2772 uint256 id;
2773 CSHA256().Write((unsigned char*)desc_str.data(), desc_str.size()).Finalize(id.begin());
2774 return id;
2775}
2776
2777void DescriptorCache::CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
2778{
2779 m_parent_xpubs[key_exp_pos] = xpub;
2780}
2781
2782void DescriptorCache::CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey& xpub)
2783{
2784 auto& xpubs = m_derived_xpubs[key_exp_pos];
2785 xpubs[der_index] = xpub;
2786}
2787
2788void DescriptorCache::CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
2789{
2790 m_last_hardened_xpubs[key_exp_pos] = xpub;
2791}
2792
2793bool DescriptorCache::GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
2794{
2795 const auto& it = m_parent_xpubs.find(key_exp_pos);
2796 if (it == m_parent_xpubs.end()) return false;
2797 xpub = it->second;
2798 return true;
2799}
2800
2801bool DescriptorCache::GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey& xpub) const
2802{
2803 const auto& key_exp_it = m_derived_xpubs.find(key_exp_pos);
2804 if (key_exp_it == m_derived_xpubs.end()) return false;
2805 const auto& der_it = key_exp_it->second.find(der_index);
2806 if (der_it == key_exp_it->second.end()) return false;
2807 xpub = der_it->second;
2808 return true;
2809}
2810
2812{
2813 const auto& it = m_last_hardened_xpubs.find(key_exp_pos);
2814 if (it == m_last_hardened_xpubs.end()) return false;
2815 xpub = it->second;
2816 return true;
2817}
2818
2820{
2821 DescriptorCache diff;
2822 for (const auto& parent_xpub_pair : other.GetCachedParentExtPubKeys()) {
2823 CExtPubKey xpub;
2824 if (GetCachedParentExtPubKey(parent_xpub_pair.first, xpub)) {
2825 if (xpub != parent_xpub_pair.second) {
2826 throw std::runtime_error(std::string(__func__) + ": New cached parent xpub does not match already cached parent xpub");
2827 }
2828 continue;
2829 }
2830 CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
2831 diff.CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
2832 }
2833 for (const auto& derived_xpub_map_pair : other.GetCachedDerivedExtPubKeys()) {
2834 for (const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
2835 CExtPubKey xpub;
2836 if (GetCachedDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, xpub)) {
2837 if (xpub != derived_xpub_pair.second) {
2838 throw std::runtime_error(std::string(__func__) + ": New cached derived xpub does not match already cached derived xpub");
2839 }
2840 continue;
2841 }
2842 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2843 diff.CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2844 }
2845 }
2846 for (const auto& lh_xpub_pair : other.GetCachedLastHardenedExtPubKeys()) {
2847 CExtPubKey xpub;
2848 if (GetCachedLastHardenedExtPubKey(lh_xpub_pair.first, xpub)) {
2849 if (xpub != lh_xpub_pair.second) {
2850 throw std::runtime_error(std::string(__func__) + ": New cached last hardened xpub does not match already cached last hardened xpub");
2851 }
2852 continue;
2853 }
2854 CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
2855 diff.CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
2856 }
2857 return diff;
2858}
2859
2861{
2862 return m_parent_xpubs;
2863}
2864
2865std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDerivedExtPubKeys() const
2866{
2867 return m_derived_xpubs;
2868}
2869
2871{
2872 return m_last_hardened_xpubs;
2873}
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
Definition: addresstype.cpp:49
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:143
#define LIFETIMEBOUND
Definition: attributes.h:16
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
Definition: bip32.cpp:51
int ret
node::NodeContext m_node
Definition: bitcoin-gui.cpp:42
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:102
#define Assert(val)
Identity function.
Definition: check.h:106
#define Assume(val)
Assume is the identity function.
Definition: check.h:118
An encapsulated private key.
Definition: key.h:35
unsigned int size() const
Simple read-only vector-like interface.
Definition: key.h:117
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:123
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:126
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:182
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:24
An encapsulated public key.
Definition: pubkey.h:34
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:204
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:164
bool IsValid() const
Definition: pubkey.h:189
bool IsValidNonHybrid() const noexcept
Check if a public key is a syntactically valid compressed or uncompressed key.
Definition: pubkey.h:195
A hasher class for SHA-256.
Definition: sha256.h:14
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:725
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:699
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:413
A reference to a CScript: the Hash160 of its serialization.
Definition: script.h:602
Cache for single descriptor's derived extended pubkeys.
Definition: descriptor.h:19
bool GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached parent xpub.
std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
ExtPubKeyMap m_last_hardened_xpubs
Map key expression index -> last hardened xpub.
Definition: descriptor.h:26
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a last hardened xpub.
bool GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey &xpub) const
Retrieve a cached xpub derived at an index.
std::unordered_map< uint32_t, ExtPubKeyMap > m_derived_xpubs
Map key expression index -> map of (key derivation index -> xpub)
Definition: descriptor.h:22
bool GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached last hardened xpub.
ExtPubKeyMap m_parent_xpubs
Map key expression index -> parent xpub.
Definition: descriptor.h:24
An interface to be implemented by keystores that support signing.
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
virtual bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
bool GetKeyOriginByXOnly(const XOnlyPubKey &pubkey, KeyOriginInfo &info) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const
Utility class to construct Taproot outputs from internal key and script tree.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
TaprootBuilder & Add(int depth, std::span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
const unsigned char * begin() const
Definition: pubkey.h:299
static constexpr size_t size()
Definition: pubkey.h:297
CPubKey GetEvenCorrespondingCPubKey() const
Definition: pubkey.cpp:223
bool IsFullyValid() const
Determine if this pubkey is fully valid.
Definition: pubkey.cpp:230
constexpr unsigned char * begin()
Definition: uint256.h:101
size_type size() const
Definition: prevector.h:255
160-bit opaque blob.
Definition: uint256.h:184
256-bit opaque blob.
Definition: uint256.h:196
static const int WITNESS_SCALE_FACTOR
Definition: consensus.h:21
CScript ParseScript(const std::string &s)
Definition: core_read.cpp:63
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:92
uint160 RIPEMD160(std::span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
Definition: hash.h:222
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: hex_base.cpp:29
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
Definition: interpreter.h:232
static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
Definition: interpreter.h:235
std::string EncodeExtKey(const CExtKey &key)
Definition: key_io.cpp:283
CExtPubKey DecodeExtPubKey(const std::string &str)
Definition: key_io.cpp:244
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
Definition: key_io.cpp:299
std::string EncodeSecret(const CKey &key)
Definition: key_io.cpp:231
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:294
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:213
std::string EncodeExtPubKey(const CExtPubKey &key)
Definition: key_io.cpp:257
CExtKey DecodeExtKey(const std::string &str)
Definition: key_io.cpp:267
std::optional< CPubKey > MuSig2AggregatePubkeys(const std::vector< CPubKey > &pubkeys)
Compute the full aggregate pubkey from the given participant pubkeys in their current order.
Definition: musig.cpp:46
constexpr uint256 MUSIG_CHAINCODE
Definition: musig.h:17
NodeRef< typename Ctx::Key > FromString(const std::string &str, const Ctx &ctx)
Definition: miniscript.h:2641
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
Definition: miniscript.h:245
NodeRef< typename Ctx::Key > FromScript(const CScript &script, const Ctx &ctx)
Definition: miniscript.h:2646
std::unique_ptr< const Node< Key > > NodeRef
Definition: miniscript.h:192
Definition: messages.h:20
std::span< const char > Expr(std::span< const char > &sp)
Extract the expression that sp begins with.
Definition: parsing.cpp:33
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
Definition: parsing.cpp:24
bool Const(const std::string &str, std::span< const char > &sp, bool skip)
Parse a constant.
Definition: parsing.cpp:15
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
Definition: subprocess.h:315
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:245
std::vector< T > Split(const std::span< const char > &sp, std::string_view separators, bool include_sep=false)
Split a string on any char found in separators, returning a vector.
Definition: string.h:115
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
Definition: spend.cpp:250
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
Definition: spend.cpp:49
bool operator<(const CNetAddr &a, const CNetAddr &b)
Definition: netaddress.cpp:612
std::optional< OutputType > OutputTypeFromDestination(const CTxDestination &dest)
Get the OutputType for a CTxDestination.
Definition: outputtype.cpp:80
const char * name
Definition: rest.cpp:50
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
bool CheckChecksum(std::span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
std::vector< std::unique_ptr< Descriptor > > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
Definition: descriptor.h:16
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
Definition: script.h:28
@ OP_CHECKSIG
Definition: script.h:190
@ OP_NUMEQUAL
Definition: script.h:171
@ OP_CHECKSIGADD
Definition: script.h:210
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
Definition: script.h:37
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
Definition: script.h:616
static const int MAX_PUBKEYS_PER_MULTISIG
Definition: script.h:34
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:67
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
Definition: serialize.h:288
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
Definition: sign.cpp:109
std::optional< std::vector< std::tuple< int, std::vector< unsigned char >, int > > > InferTaprootTree(const TaprootSpendData &spenddata, const XOnlyPubKey &output)
Given a TaprootSpendData and the output key, reconstruct its script tree.
const SigningProvider & DUMMY_SIGNING_PROVIDER
void PolyMod(const std::vector< typename F::Elem > &mod, std::vector< typename F::Elem > &val, const F &field)
Compute the remainder of a polynomial division of val by mod, putting the result in mod.
Definition: sketch_impl.h:18
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: solver.cpp:141
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: solver.cpp:218
std::optional< std::pair< int, std::vector< std::span< const unsigned char > > > > MatchMultiA(const CScript &script)
Definition: solver.cpp:107
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: solver.cpp:213
TxoutType
Definition: solver.h:22
@ WITNESS_V1_TAPROOT
@ WITNESS_V0_SCRIPTHASH
@ WITNESS_V0_KEYHASH
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Definition: strencodings.h:68
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Definition: strencodings.h:165
Definition: key.h:227
CExtPubKey Neuter() const
Definition: key.cpp:380
bool Derive(CExtKey &out, unsigned int nChild) const
Definition: key.cpp:359
CKey key
Definition: key.h:232
ChainCode chaincode
Definition: pubkey.h:351
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition: pubkey.cpp:412
unsigned char vchFingerprint[4]
Definition: pubkey.h:349
unsigned char nDepth
Definition: pubkey.h:348
CPubKey pubkey
Definition: pubkey.h:352
unsigned int nChild
Definition: pubkey.h:350
Interface for parsed descriptor objects.
Definition: descriptor.h:98
virtual std::optional< int64_t > MaxSatisfactionElems() const =0
Get the maximum size number of stack elements for satisfying this descriptor.
virtual void GetPubKeys(std::set< CPubKey > &pubkeys, std::set< CExtPubKey > &ext_pubs) const =0
Return all (extended) public keys for this descriptor, including any from subdescriptors.
virtual bool ToNormalizedString(const SigningProvider &provider, std::string &out, const DescriptorCache *cache=nullptr) const =0
Convert the descriptor to a normalized string.
virtual std::optional< int64_t > MaxSatisfactionWeight(bool use_max_sig) const =0
Get the maximum size of a satisfaction for this descriptor, in weight units.
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
virtual std::optional< OutputType > GetOutputType() const =0
virtual bool Expand(int pos, const SigningProvider &provider, std::vector< CScript > &output_scripts, FlatSigningProvider &out, DescriptorCache *write_cache=nullptr) const =0
Expand a descriptor at a specified position.
virtual bool IsRange() const =0
Whether the expansion of this descriptor depends on the position.
virtual std::optional< int64_t > ScriptSize() const =0
Get the size of the scriptPubKey for this descriptor.
virtual bool IsSolvable() const =0
Whether this descriptor has all information about signing ignoring lack of private keys.
virtual void ExpandPrivate(int pos, const SigningProvider &provider, FlatSigningProvider &out) const =0
Expand the private key for a descriptor at a specified position, if possible.
virtual bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
virtual bool ExpandFromCache(int pos, const DescriptorCache &read_cache, std::vector< CScript > &output_scripts, FlatSigningProvider &out) const =0
Expand a descriptor at a specified position using cached expansion data.
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
std::map< CKeyID, CPubKey > pubkeys
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
Definition: keyorigin.h:13
std::vector< uint32_t > path
Definition: keyorigin.h:14
XOnlyPubKey internal_key
The BIP341 internal key.
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
consteval auto _(util::TranslatedLiteral str)
Definition: translation.h:79
bool IsHex(std::string_view str)
assert(!tx.IsCoinBase())
std::vector< std::common_type_t< Args... > > Vector(Args &&... args)
Construct a vector with the specified elements.
Definition: vector.h:23