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