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