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;
795 std::vector<std::string> m_warnings;
796
801 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
802
804 virtual std::string ToStringExtra() const { return ""; }
805
816 virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts, FlatSigningProvider& out) const = 0;
817
818public:
819 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args() {}
820 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))) {}
821 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)) {}
822
823 enum class StringType
824 {
825 PUBLIC,
826 PRIVATE,
827 NORMALIZED,
828 COMPAT, // string calculation that mustn't change over time to stay compatible with previous software versions
829 };
830
831 // NOLINTNEXTLINE(misc-no-recursion)
832 bool IsSolvable() const override
833 {
834 for (const auto& arg : m_subdescriptor_args) {
835 if (!arg->IsSolvable()) return false;
836 }
837 return true;
838 }
839
840 // NOLINTNEXTLINE(misc-no-recursion)
841 bool IsRange() const final
842 {
843 for (const auto& pubkey : m_pubkey_args) {
844 if (pubkey->IsRange()) return true;
845 }
846 for (const auto& arg : m_subdescriptor_args) {
847 if (arg->IsRange()) return true;
848 }
849 return false;
850 }
851
852 // NOLINTNEXTLINE(misc-no-recursion)
853 virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const
854 {
855 size_t pos = 0;
856 for (const auto& scriptarg : m_subdescriptor_args) {
857 if (pos++) ret += ",";
858 std::string tmp;
859 if (!scriptarg->ToStringHelper(arg, tmp, type, cache)) return false;
860 ret += tmp;
861 }
862 return true;
863 }
864
865 // NOLINTNEXTLINE(misc-no-recursion)
866 virtual bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type, const DescriptorCache* cache = nullptr) const
867 {
868 std::string extra = ToStringExtra();
869 size_t pos = extra.size() > 0 ? 1 : 0;
870 std::string ret = m_name + "(" + extra;
871 for (const auto& pubkey : m_pubkey_args) {
872 if (pos++) ret += ",";
873 std::string tmp;
874 switch (type) {
875 case StringType::NORMALIZED:
876 if (!pubkey->ToNormalizedString(*arg, tmp, cache)) return false;
877 break;
878 case StringType::PRIVATE:
879 if (!pubkey->ToPrivateString(*arg, tmp)) return false;
880 break;
881 case StringType::PUBLIC:
882 tmp = pubkey->ToString();
883 break;
884 case StringType::COMPAT:
885 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
886 break;
887 }
888 ret += tmp;
889 }
890 std::string subscript;
891 if (!ToStringSubScriptHelper(arg, subscript, type, cache)) return false;
892 if (pos && subscript.size()) ret += ',';
893 out = std::move(ret) + std::move(subscript) + ")";
894 return true;
895 }
896
897 std::string ToString(bool compat_format) const final
898 {
899 std::string ret;
900 ToStringHelper(nullptr, ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
901 return AddChecksum(ret);
902 }
903
904 bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
905 {
906 bool ret = ToStringHelper(&arg, out, StringType::PRIVATE);
907 out = AddChecksum(out);
908 return ret;
909 }
910
911 bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override final
912 {
913 bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED, cache);
914 out = AddChecksum(out);
915 return ret;
916 }
917
918 // NOLINTNEXTLINE(misc-no-recursion)
919 bool ExpandHelper(int pos, const SigningProvider& arg, const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache) const
920 {
921 FlatSigningProvider subprovider;
922 std::vector<CPubKey> pubkeys;
923 pubkeys.reserve(m_pubkey_args.size());
924
925 // Construct temporary data in `pubkeys`, `subscripts`, and `subprovider` to avoid producing output in case of failure.
926 for (const auto& p : m_pubkey_args) {
927 std::optional<CPubKey> pubkey = p->GetPubKey(pos, arg, subprovider, read_cache, write_cache);
928 if (!pubkey) return false;
929 pubkeys.push_back(pubkey.value());
930 }
931 std::vector<CScript> subscripts;
932 for (const auto& subarg : m_subdescriptor_args) {
933 std::vector<CScript> outscripts;
934 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache)) return false;
935 assert(outscripts.size() == 1);
936 subscripts.emplace_back(std::move(outscripts[0]));
937 }
938 out.Merge(std::move(subprovider));
939
940 output_scripts = MakeScripts(pubkeys, std::span{subscripts}, out);
941 return true;
942 }
943
944 bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache = nullptr) const final
945 {
946 return ExpandHelper(pos, provider, nullptr, output_scripts, out, write_cache);
947 }
948
949 bool ExpandFromCache(int pos, const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const final
950 {
951 return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &read_cache, output_scripts, out, nullptr);
952 }
953
954 // NOLINTNEXTLINE(misc-no-recursion)
955 void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final
956 {
957 for (const auto& p : m_pubkey_args) {
958 p->GetPrivKey(pos, provider, out);
959 }
960 for (const auto& arg : m_subdescriptor_args) {
961 arg->ExpandPrivate(pos, provider, out);
962 }
963 }
964
965 std::optional<OutputType> GetOutputType() const override { return std::nullopt; }
966
967 std::optional<int64_t> ScriptSize() const override { return {}; }
968
974 virtual std::optional<int64_t> MaxSatSize(bool use_max_sig) const { return {}; }
975
976 std::optional<int64_t> MaxSatisfactionWeight(bool) const override { return {}; }
977
978 std::optional<int64_t> MaxSatisfactionElems() const override { return {}; }
979
980 // NOLINTNEXTLINE(misc-no-recursion)
981 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs) const override
982 {
983 for (const auto& p : m_pubkey_args) {
984 std::optional<CPubKey> pub = p->GetRootPubKey();
985 if (pub) pubkeys.insert(*pub);
986 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
987 if (ext_pub) ext_pubs.insert(*ext_pub);
988 }
989 for (const auto& arg : m_subdescriptor_args) {
990 arg->GetPubKeys(pubkeys, ext_pubs);
991 }
992 }
993
994 virtual std::unique_ptr<DescriptorImpl> Clone() const = 0;
995
996 // NOLINTNEXTLINE(misc-no-recursion)
997 std::vector<std::string> Warnings() const override {
998 std::vector<std::string> all = m_warnings;
999 for (const auto& sub : m_subdescriptor_args) {
1000 auto sub_w = sub->Warnings();
1001 all.insert(all.end(), sub_w.begin(), sub_w.end());
1002 }
1003 return all;
1004 }
1005};
1006
1008class AddressDescriptor final : public DescriptorImpl
1009{
1010 const CTxDestination m_destination;
1011protected:
1012 std::string ToStringExtra() const override { return EncodeDestination(m_destination); }
1013 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }
1014public:
1015 AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, "addr"), m_destination(std::move(destination)) {}
1016 bool IsSolvable() const final { return false; }
1017
1018 std::optional<OutputType> GetOutputType() const override
1019 {
1020 return OutputTypeFromDestination(m_destination);
1021 }
1022 bool IsSingleType() const final { return true; }
1023 bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }
1024
1025 std::optional<int64_t> ScriptSize() const override { return GetScriptForDestination(m_destination).size(); }
1026 std::unique_ptr<DescriptorImpl> Clone() const override
1027 {
1028 return std::make_unique<AddressDescriptor>(m_destination);
1029 }
1030};
1031
1033class RawDescriptor final : public DescriptorImpl
1034{
1035 const CScript m_script;
1036protected:
1037 std::string ToStringExtra() const override { return HexStr(m_script); }
1038 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript>, FlatSigningProvider&) const override { return Vector(m_script); }
1039public:
1040 RawDescriptor(CScript script) : DescriptorImpl({}, "raw"), m_script(std::move(script)) {}
1041 bool IsSolvable() const final { return false; }
1042
1043 std::optional<OutputType> GetOutputType() const override
1044 {
1045 CTxDestination dest;
1046 ExtractDestination(m_script, dest);
1047 return OutputTypeFromDestination(dest);
1048 }
1049 bool IsSingleType() const final { return true; }
1050 bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }
1051
1052 std::optional<int64_t> ScriptSize() const override { return m_script.size(); }
1053
1054 std::unique_ptr<DescriptorImpl> Clone() const override
1055 {
1056 return std::make_unique<RawDescriptor>(m_script);
1057 }
1058};
1059
1061class PKDescriptor final : public DescriptorImpl
1062{
1063private:
1064 const bool m_xonly;
1065protected:
1066 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override
1067 {
1068 if (m_xonly) {
1070 return Vector(std::move(script));
1071 } else {
1072 return Vector(GetScriptForRawPubKey(keys[0]));
1073 }
1074 }
1075public:
1076 PKDescriptor(std::unique_ptr<PubkeyProvider> prov, bool xonly = false) : DescriptorImpl(Vector(std::move(prov)), "pk"), m_xonly(xonly) {}
1077 bool IsSingleType() const final { return true; }
1078
1079 std::optional<int64_t> ScriptSize() const override {
1080 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1081 }
1082
1083 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1084 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1085 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1086 }
1087
1088 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1089 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
1090 }
1091
1092 std::optional<int64_t> MaxSatisfactionElems() const override { return 1; }
1093
1094 std::unique_ptr<DescriptorImpl> Clone() const override
1095 {
1096 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1097 }
1098};
1099
1101class PKHDescriptor final : public DescriptorImpl
1102{
1103protected:
1104 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override
1105 {
1106 CKeyID id = keys[0].GetID();
1108 }
1109public:
1110 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "pkh") {}
1111 std::optional<OutputType> GetOutputType() const override { return OutputType::LEGACY; }
1112 bool IsSingleType() const final { return true; }
1113
1114 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 1 + 20 + 1 + 1; }
1115
1116 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1117 const auto sig_size = use_max_sig ? 72 : 71;
1118 return 1 + sig_size + 1 + m_pubkey_args[0]->GetSize();
1119 }
1120
1121 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1122 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
1123 }
1124
1125 std::optional<int64_t> MaxSatisfactionElems() const override { return 2; }
1126
1127 std::unique_ptr<DescriptorImpl> Clone() const override
1128 {
1129 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1130 }
1131};
1132
1134class WPKHDescriptor final : public DescriptorImpl
1135{
1136protected:
1137 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override
1138 {
1139 CKeyID id = keys[0].GetID();
1141 }
1142public:
1143 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "wpkh") {}
1144 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
1145 bool IsSingleType() const final { return true; }
1146
1147 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 20; }
1148
1149 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1150 const auto sig_size = use_max_sig ? 72 : 71;
1151 return (1 + sig_size + 1 + 33);
1152 }
1153
1154 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1155 return MaxSatSize(use_max_sig);
1156 }
1157
1158 std::optional<int64_t> MaxSatisfactionElems() const override { return 2; }
1159
1160 std::unique_ptr<DescriptorImpl> Clone() const override
1161 {
1162 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1163 }
1164};
1165
1167class ComboDescriptor final : public DescriptorImpl
1168{
1169protected:
1170 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider& out) const override
1171 {
1172 std::vector<CScript> ret;
1173 CKeyID id = keys[0].GetID();
1174 ret.emplace_back(GetScriptForRawPubKey(keys[0])); // P2PK
1175 ret.emplace_back(GetScriptForDestination(PKHash(id))); // P2PKH
1176 if (keys[0].IsCompressed()) {
1178 out.scripts.emplace(CScriptID(p2wpkh), p2wpkh);
1179 ret.emplace_back(p2wpkh);
1180 ret.emplace_back(GetScriptForDestination(ScriptHash(p2wpkh))); // P2SH-P2WPKH
1181 }
1182 return ret;
1183 }
1184public:
1185 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "combo") {}
1186 bool IsSingleType() const final { return false; }
1187 std::unique_ptr<DescriptorImpl> Clone() const override
1188 {
1189 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1190 }
1191};
1192
1194class MultisigDescriptor final : public DescriptorImpl
1195{
1196 const int m_threshold;
1197 const bool m_sorted;
1198protected:
1199 std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
1200 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override {
1201 if (m_sorted) {
1202 std::vector<CPubKey> sorted_keys(keys);
1203 std::sort(sorted_keys.begin(), sorted_keys.end());
1204 return Vector(GetScriptForMultisig(m_threshold, sorted_keys));
1205 }
1206 return Vector(GetScriptForMultisig(m_threshold, keys));
1207 }
1208public:
1209 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) {}
1210 bool IsSingleType() const final { return true; }
1211
1212 std::optional<int64_t> ScriptSize() const override {
1213 const auto n_keys = m_pubkey_args.size();
1214 auto op = [](int64_t acc, const std::unique_ptr<PubkeyProvider>& pk) { return acc + 1 + pk->GetSize();};
1215 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1216 return 1 + BuildScript(n_keys).size() + BuildScript(m_threshold).size() + pubkeys_size;
1217 }
1218
1219 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1220 const auto sig_size = use_max_sig ? 72 : 71;
1221 return (1 + (1 + sig_size) * m_threshold);
1222 }
1223
1224 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1225 return *MaxSatSize(use_max_sig) * WITNESS_SCALE_FACTOR;
1226 }
1227
1228 std::optional<int64_t> MaxSatisfactionElems() const override { return 1 + m_threshold; }
1229
1230 std::unique_ptr<DescriptorImpl> Clone() const override
1231 {
1232 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1233 providers.reserve(m_pubkey_args.size());
1234 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), providers.begin(), [](const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1235 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1236 }
1237};
1238
1240class MultiADescriptor final : public DescriptorImpl
1241{
1242 const int m_threshold;
1243 const bool m_sorted;
1244protected:
1245 std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
1246 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript>, FlatSigningProvider&) const override {
1247 CScript ret;
1248 std::vector<XOnlyPubKey> xkeys;
1249 xkeys.reserve(keys.size());
1250 for (const auto& key : keys) xkeys.emplace_back(key);
1251 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1252 ret << ToByteVector(xkeys[0]) << OP_CHECKSIG;
1253 for (size_t i = 1; i < keys.size(); ++i) {
1254 ret << ToByteVector(xkeys[i]) << OP_CHECKSIGADD;
1255 }
1256 ret << m_threshold << OP_NUMEQUAL;
1257 return Vector(std::move(ret));
1258 }
1259public:
1260 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) {}
1261 bool IsSingleType() const final { return true; }
1262
1263 std::optional<int64_t> ScriptSize() const override {
1264 const auto n_keys = m_pubkey_args.size();
1265 return (1 + 32 + 1) * n_keys + BuildScript(m_threshold).size() + 1;
1266 }
1267
1268 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1269 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1270 }
1271
1272 std::optional<int64_t> MaxSatisfactionElems() const override { return m_pubkey_args.size(); }
1273
1274 std::unique_ptr<DescriptorImpl> Clone() const override
1275 {
1276 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1277 providers.reserve(m_pubkey_args.size());
1278 for (const auto& arg : m_pubkey_args) {
1279 providers.push_back(arg->Clone());
1280 }
1281 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1282 }
1283};
1284
1286class SHDescriptor final : public DescriptorImpl
1287{
1288protected:
1289 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1290 {
1291 auto ret = Vector(GetScriptForDestination(ScriptHash(scripts[0])));
1292 if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
1293 return ret;
1294 }
1295
1296 bool IsSegwit() const { return m_subdescriptor_args[0]->GetOutputType() == OutputType::BECH32; }
1297
1298public:
1299 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "sh") {}
1300
1301 std::optional<OutputType> GetOutputType() const override
1302 {
1303 assert(m_subdescriptor_args.size() == 1);
1304 if (IsSegwit()) return OutputType::P2SH_SEGWIT;
1305 return OutputType::LEGACY;
1306 }
1307 bool IsSingleType() const final { return true; }
1308
1309 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 20 + 1; }
1310
1311 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1312 if (const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1313 if (const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1314 // The subscript is never witness data.
1315 const auto subscript_weight = (1 + *subscript_size) * WITNESS_SCALE_FACTOR;
1316 // The weight depends on whether the inner descriptor is satisfied using the witness stack.
1317 if (IsSegwit()) return subscript_weight + *sat_size;
1318 return subscript_weight + *sat_size * WITNESS_SCALE_FACTOR;
1319 }
1320 }
1321 return {};
1322 }
1323
1324 std::optional<int64_t> MaxSatisfactionElems() const override {
1325 if (const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems()) return 1 + *sub_elems;
1326 return {};
1327 }
1328
1329 std::unique_ptr<DescriptorImpl> Clone() const override
1330 {
1331 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1332 }
1333};
1334
1336class WSHDescriptor final : public DescriptorImpl
1337{
1338protected:
1339 std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1340 {
1342 if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
1343 return ret;
1344 }
1345public:
1346 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "wsh") {}
1347 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32; }
1348 bool IsSingleType() const final { return true; }
1349
1350 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1351
1352 std::optional<int64_t> MaxSatSize(bool use_max_sig) const override {
1353 if (const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1354 if (const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1355 return GetSizeOfCompactSize(*subscript_size) + *subscript_size + *sat_size;
1356 }
1357 }
1358 return {};
1359 }
1360
1361 std::optional<int64_t> MaxSatisfactionWeight(bool use_max_sig) const override {
1362 return MaxSatSize(use_max_sig);
1363 }
1364
1365 std::optional<int64_t> MaxSatisfactionElems() const override {
1366 if (const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems()) return 1 + *sub_elems;
1367 return {};
1368 }
1369
1370 std::unique_ptr<DescriptorImpl> Clone() const override
1371 {
1372 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1373 }
1374};
1375
1377class TRDescriptor final : public DescriptorImpl
1378{
1379 std::vector<int> m_depths;
1380protected:
1381 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1382 {
1383 TaprootBuilder builder;
1384 assert(m_depths.size() == scripts.size());
1385 for (size_t pos = 0; pos < m_depths.size(); ++pos) {
1386 builder.Add(m_depths[pos], scripts[pos], TAPROOT_LEAF_TAPSCRIPT);
1387 }
1388 if (!builder.IsComplete()) return {};
1389 assert(keys.size() == 1);
1390 XOnlyPubKey xpk(keys[0]);
1391 if (!xpk.IsFullyValid()) return {};
1392 builder.Finalize(xpk);
1393 WitnessV1Taproot output = builder.GetOutput();
1394 out.tr_trees[output] = builder;
1395 return Vector(GetScriptForDestination(output));
1396 }
1397 bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const override
1398 {
1399 if (m_depths.empty()) return true;
1400 std::vector<bool> path;
1401 for (size_t pos = 0; pos < m_depths.size(); ++pos) {
1402 if (pos) ret += ',';
1403 while ((int)path.size() <= m_depths[pos]) {
1404 if (path.size()) ret += '{';
1405 path.push_back(false);
1406 }
1407 std::string tmp;
1408 if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)) return false;
1409 ret += tmp;
1410 while (!path.empty() && path.back()) {
1411 if (path.size() > 1) ret += '}';
1412 path.pop_back();
1413 }
1414 if (!path.empty()) path.back() = true;
1415 }
1416 return true;
1417 }
1418public:
1419 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1420 DescriptorImpl(Vector(std::move(internal_key)), std::move(descs), "tr"), m_depths(std::move(depths))
1421 {
1422 assert(m_subdescriptor_args.size() == m_depths.size());
1423 }
1424 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32M; }
1425 bool IsSingleType() const final { return true; }
1426
1427 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1428
1429 std::optional<int64_t> MaxSatisfactionWeight(bool) const override {
1430 // FIXME: We assume keypath spend, which can lead to very large underestimations.
1431 return 1 + 65;
1432 }
1433
1434 std::optional<int64_t> MaxSatisfactionElems() const override {
1435 // FIXME: See above, we assume keypath spend.
1436 return 1;
1437 }
1438
1439 std::unique_ptr<DescriptorImpl> Clone() const override
1440 {
1441 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1442 subdescs.reserve(m_subdescriptor_args.size());
1443 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), subdescs.begin(), [](const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1444 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1445 }
1446};
1447
1448/* We instantiate Miniscript here with a simple integer as key type.
1449 * The value of these key integers are an index in the
1450 * DescriptorImpl::m_pubkey_args vector.
1451 */
1452
1456class ScriptMaker {
1458 const std::vector<CPubKey>& m_keys;
1460 const miniscript::MiniscriptContext m_script_ctx;
1461
1465 uint160 GetHash160(uint32_t key) const {
1466 if (miniscript::IsTapscript(m_script_ctx)) {
1467 return Hash160(XOnlyPubKey{m_keys[key]});
1468 }
1469 return m_keys[key].GetID();
1470 }
1471
1472public:
1473 ScriptMaker(const std::vector<CPubKey>& keys LIFETIMEBOUND, const miniscript::MiniscriptContext script_ctx) : m_keys(keys), m_script_ctx{script_ctx} {}
1474
1475 std::vector<unsigned char> ToPKBytes(uint32_t key) const {
1476 // In Tapscript keys always serialize as x-only, whether an x-only key was used in the descriptor or not.
1477 if (!miniscript::IsTapscript(m_script_ctx)) {
1478 return {m_keys[key].begin(), m_keys[key].end()};
1479 }
1480 const XOnlyPubKey xonly_pubkey{m_keys[key]};
1481 return {xonly_pubkey.begin(), xonly_pubkey.end()};
1482 }
1483
1484 std::vector<unsigned char> ToPKHBytes(uint32_t key) const {
1485 auto id = GetHash160(key);
1486 return {id.begin(), id.end()};
1487 }
1488};
1489
1493class StringMaker {
1495 const SigningProvider* m_arg;
1497 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1499 const DescriptorImpl::StringType m_type;
1500 const DescriptorCache* m_cache;
1501
1502public:
1503 StringMaker(const SigningProvider* arg LIFETIMEBOUND,
1504 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys LIFETIMEBOUND,
1505 DescriptorImpl::StringType type,
1506 const DescriptorCache* cache LIFETIMEBOUND)
1507 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1508
1509 std::optional<std::string> ToString(uint32_t key) const
1510 {
1511 std::string ret;
1512 switch (m_type) {
1513 case DescriptorImpl::StringType::PUBLIC:
1514 ret = m_pubkeys[key]->ToString();
1515 break;
1516 case DescriptorImpl::StringType::PRIVATE:
1517 if (!m_pubkeys[key]->ToPrivateString(*m_arg, ret)) return {};
1518 break;
1519 case DescriptorImpl::StringType::NORMALIZED:
1520 if (!m_pubkeys[key]->ToNormalizedString(*m_arg, ret, m_cache)) return {};
1521 break;
1522 case DescriptorImpl::StringType::COMPAT:
1523 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT);
1524 break;
1525 }
1526 return ret;
1527 }
1528};
1529
1530class MiniscriptDescriptor final : public DescriptorImpl
1531{
1532private:
1534
1535protected:
1536 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1537 FlatSigningProvider& provider) const override
1538 {
1539 const auto script_ctx{m_node->GetMsCtx()};
1540 for (const auto& key : keys) {
1541 if (miniscript::IsTapscript(script_ctx)) {
1542 provider.pubkeys.emplace(Hash160(XOnlyPubKey{key}), key);
1543 } else {
1544 provider.pubkeys.emplace(key.GetID(), key);
1545 }
1546 }
1547 return Vector(m_node->ToScript(ScriptMaker(keys, script_ctx)));
1548 }
1549
1550public:
1551 MiniscriptDescriptor(std::vector<std::unique_ptr<PubkeyProvider>> providers, miniscript::NodeRef<uint32_t> node)
1552 : DescriptorImpl(std::move(providers), "?"), m_node(std::move(node))
1553 {
1554 // Traverse miniscript tree for unsafe use of older()
1556 if (node.fragment == miniscript::Fragment::OLDER) {
1557 const uint32_t raw = node.k;
1558 const uint32_t value_part = raw & ~CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1559 if (value_part > CTxIn::SEQUENCE_LOCKTIME_MASK) {
1560 const bool is_time_based = (raw & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0;
1561 if (is_time_based) {
1562 m_warnings.push_back(strprintf("time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1563 } else {
1564 m_warnings.push_back(strprintf("height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1565 }
1566 }
1567 }
1568 });
1569 }
1570
1571 bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type,
1572 const DescriptorCache* cache = nullptr) const override
1573 {
1574 if (const auto res = m_node->ToString(StringMaker(arg, m_pubkey_args, type, cache))) {
1575 out = *res;
1576 return true;
1577 }
1578 return false;
1579 }
1580
1581 bool IsSolvable() const override { return true; }
1582 bool IsSingleType() const final { return true; }
1583
1584 std::optional<int64_t> ScriptSize() const override { return m_node->ScriptSize(); }
1585
1586 std::optional<int64_t> MaxSatSize(bool) const override {
1587 // For Miniscript we always assume high-R ECDSA signatures.
1588 return m_node->GetWitnessSize();
1589 }
1590
1591 std::optional<int64_t> MaxSatisfactionElems() const override {
1592 return m_node->GetStackSize();
1593 }
1594
1595 std::unique_ptr<DescriptorImpl> Clone() const override
1596 {
1597 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1598 providers.reserve(m_pubkey_args.size());
1599 for (const auto& arg : m_pubkey_args) {
1600 providers.push_back(arg->Clone());
1601 }
1602 return std::make_unique<MiniscriptDescriptor>(std::move(providers), m_node->Clone());
1603 }
1604};
1605
1607class RawTRDescriptor final : public DescriptorImpl
1608{
1609protected:
1610 std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, std::span<const CScript> scripts, FlatSigningProvider& out) const override
1611 {
1612 assert(keys.size() == 1);
1613 XOnlyPubKey xpk(keys[0]);
1614 if (!xpk.IsFullyValid()) return {};
1615 WitnessV1Taproot output{xpk};
1616 return Vector(GetScriptForDestination(output));
1617 }
1618public:
1619 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(Vector(std::move(output_key)), "rawtr") {}
1620 std::optional<OutputType> GetOutputType() const override { return OutputType::BECH32M; }
1621 bool IsSingleType() const final { return true; }
1622
1623 std::optional<int64_t> ScriptSize() const override { return 1 + 1 + 32; }
1624
1625 std::optional<int64_t> MaxSatisfactionWeight(bool) const override {
1626 // We can't know whether there is a script path, so assume key path spend.
1627 return 1 + 65;
1628 }
1629
1630 std::optional<int64_t> MaxSatisfactionElems() const override {
1631 // See above, we assume keypath spend.
1632 return 1;
1633 }
1634
1635 std::unique_ptr<DescriptorImpl> Clone() const override
1636 {
1637 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1638 }
1639};
1640
1642// Parser //
1644
1645enum class ParseScriptContext {
1646 TOP,
1647 P2SH,
1648 P2WPKH,
1649 P2WSH,
1650 P2TR,
1651 MUSIG,
1652};
1653
1654std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem, bool& apostrophe, std::string& error, bool& has_hardened)
1655{
1656 bool hardened = false;
1657 if (elem.size() > 0) {
1658 const char last = elem[elem.size() - 1];
1659 if (last == '\'' || last == 'h') {
1660 elem = elem.first(elem.size() - 1);
1661 hardened = true;
1662 apostrophe = last == '\'';
1663 }
1664 }
1665 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1666 if (!p) {
1667 error = strprintf("Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1668 return std::nullopt;
1669 } else if (*p > 0x7FFFFFFFUL) {
1670 error = strprintf("Key path value %u is out of range", *p);
1671 return std::nullopt;
1672 }
1673 has_hardened = has_hardened || hardened;
1674
1675 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1676}
1677
1689[[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)
1690{
1691 KeyPath path;
1692 struct MultipathSubstitutes {
1693 size_t placeholder_index;
1694 std::vector<uint32_t> values;
1695 };
1696 std::optional<MultipathSubstitutes> substitutes;
1697 has_hardened = false;
1698
1699 for (size_t i = 1; i < split.size(); ++i) {
1700 const std::span<const char>& elem = split[i];
1701
1702 // Check if element contains multipath specifier
1703 if (!elem.empty() && elem.front() == '<' && elem.back() == '>') {
1704 if (!allow_multipath) {
1705 error = strprintf("Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1706 return false;
1707 }
1708 if (substitutes) {
1709 error = "Multiple multipath key path specifiers found";
1710 return false;
1711 }
1712
1713 // Parse each possible value
1714 std::vector<std::span<const char>> nums = Split(std::span(elem.begin()+1, elem.end()-1), ";");
1715 if (nums.size() < 2) {
1716 error = "Multipath key path specifiers must have at least two items";
1717 return false;
1718 }
1719
1720 substitutes.emplace();
1721 std::unordered_set<uint32_t> seen_substitutes;
1722 for (const auto& num : nums) {
1723 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1724 if (!op_num) return false;
1725 auto [_, inserted] = seen_substitutes.insert(*op_num);
1726 if (!inserted) {
1727 error = strprintf("Duplicated key path value %u in multipath specifier", *op_num);
1728 return false;
1729 }
1730 substitutes->values.emplace_back(*op_num);
1731 }
1732
1733 path.emplace_back(); // Placeholder for multipath segment
1734 substitutes->placeholder_index = path.size() - 1;
1735 } else {
1736 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1737 if (!op_num) return false;
1738 path.emplace_back(*op_num);
1739 }
1740 }
1741
1742 if (!substitutes) {
1743 out.emplace_back(std::move(path));
1744 } else {
1745 // Replace the multipath placeholder with each value while generating paths
1746 for (uint32_t substitute : substitutes->values) {
1747 KeyPath branch_path = path;
1748 branch_path[substitutes->placeholder_index] = substitute;
1749 out.emplace_back(std::move(branch_path));
1750 }
1751 }
1752 return true;
1753}
1754
1755[[nodiscard]] bool ParseKeyPath(const std::vector<std::span<const char>>& split, std::vector<KeyPath>& out, bool& apostrophe, std::string& error, bool allow_multipath)
1756{
1757 bool dummy;
1758 return ParseKeyPath(split, out, apostrophe, error, allow_multipath, /*has_hardened=*/dummy);
1759}
1760
1761static DeriveType ParseDeriveType(std::vector<std::span<const char>>& split, bool& apostrophe)
1762{
1763 DeriveType type = DeriveType::NO;
1764 if (std::ranges::equal(split.back(), std::span{"*"}.first(1))) {
1765 split.pop_back();
1766 type = DeriveType::UNHARDENED;
1767 } else if (std::ranges::equal(split.back(), std::span{"*'"}.first(2)) || std::ranges::equal(split.back(), std::span{"*h"}.first(2))) {
1768 apostrophe = std::ranges::equal(split.back(), std::span{"*'"}.first(2));
1769 split.pop_back();
1770 type = DeriveType::HARDENED;
1771 }
1772 return type;
1773}
1774
1776std::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)
1777{
1778 std::vector<std::unique_ptr<PubkeyProvider>> ret;
1779 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1780 auto split = Split(sp, '/');
1781 std::string str(split[0].begin(), split[0].end());
1782 if (str.size() == 0) {
1783 error = "No key provided";
1784 return {};
1785 }
1786 if (IsSpace(str.front()) || IsSpace(str.back())) {
1787 error = strprintf("Key '%s' is invalid due to whitespace", str);
1788 return {};
1789 }
1790 if (split.size() == 1) {
1791 if (IsHex(str)) {
1792 std::vector<unsigned char> data = ParseHex(str);
1793 CPubKey pubkey(data);
1794 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1795 error = "Hybrid public keys are not allowed";
1796 return {};
1797 }
1798 if (pubkey.IsFullyValid()) {
1799 if (permit_uncompressed || pubkey.IsCompressed()) {
1800 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, false));
1801 return ret;
1802 } else {
1803 error = "Uncompressed keys are not allowed";
1804 return {};
1805 }
1806 } else if (data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1807 unsigned char fullkey[33] = {0x02};
1808 std::copy(data.begin(), data.end(), fullkey + 1);
1809 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1810 if (pubkey.IsFullyValid()) {
1811 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, true));
1812 return ret;
1813 }
1814 }
1815 error = strprintf("Pubkey '%s' is invalid", str);
1816 return {};
1817 }
1818 CKey key = DecodeSecret(str);
1819 if (key.IsValid()) {
1820 if (permit_uncompressed || key.IsCompressed()) {
1821 CPubKey pubkey = key.GetPubKey();
1822 out.keys.emplace(pubkey.GetID(), key);
1823 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1824 return ret;
1825 } else {
1826 error = "Uncompressed keys are not allowed";
1827 return {};
1828 }
1829 }
1830 }
1831 CExtKey extkey = DecodeExtKey(str);
1832 CExtPubKey extpubkey = DecodeExtPubKey(str);
1833 if (!extkey.key.IsValid() && !extpubkey.pubkey.IsValid()) {
1834 error = strprintf("key '%s' is not valid", str);
1835 return {};
1836 }
1837 std::vector<KeyPath> paths;
1838 DeriveType type = ParseDeriveType(split, apostrophe);
1839 if (!ParseKeyPath(split, paths, apostrophe, error, /*allow_multipath=*/true)) return {};
1840 if (extkey.key.IsValid()) {
1841 extpubkey = extkey.Neuter();
1842 out.keys.emplace(extpubkey.pubkey.GetID(), extkey.key);
1843 }
1844 for (auto& path : paths) {
1845 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
1846 }
1847 return ret;
1848}
1849
1851// NOLINTNEXTLINE(misc-no-recursion)
1852std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index, const std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
1853{
1854 std::vector<std::unique_ptr<PubkeyProvider>> ret;
1855
1856 using namespace script;
1857
1858 // musig cannot be nested inside of an origin
1859 std::span<const char> span = sp;
1860 if (Const("musig(", span, /*skip=*/false)) {
1861 if (ctx != ParseScriptContext::P2TR) {
1862 error = "musig() is only allowed in tr() and rawtr()";
1863 return {};
1864 }
1865
1866 // Split the span on the end parentheses. The end parentheses must
1867 // be included in the resulting span so that Expr is happy.
1868 auto split = Split(sp, ')', /*include_sep=*/true);
1869 if (split.size() > 2) {
1870 error = "Too many ')' in musig() expression";
1871 return {};
1872 }
1873 std::span<const char> expr(split.at(0).begin(), split.at(0).end());
1874 if (!Func("musig", expr)) {
1875 error = "Invalid musig() expression";
1876 return {};
1877 }
1878
1879 // Parse the participant pubkeys
1880 bool any_ranged = false;
1881 bool all_bip32 = true;
1882 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
1883 bool any_key_parsed = false;
1884 size_t max_multipath_len = 0;
1885 while (expr.size()) {
1886 if (any_key_parsed && !Const(",", expr)) {
1887 error = strprintf("musig(): expected ',', got '%c'", expr[0]);
1888 return {};
1889 }
1890 auto arg = Expr(expr);
1891 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG, out, error);
1892 if (pk.empty()) {
1893 error = strprintf("musig(): %s", error);
1894 return {};
1895 }
1896 any_key_parsed = true;
1897
1898 any_ranged = any_ranged || pk.at(0)->IsRange();
1899 all_bip32 = all_bip32 && pk.at(0)->IsBIP32();
1900
1901 max_multipath_len = std::max(max_multipath_len, pk.size());
1902
1903 providers.emplace_back(std::move(pk));
1904 key_exp_index++;
1905 }
1906 if (!any_key_parsed) {
1907 error = "musig(): Must contain key expressions";
1908 return {};
1909 }
1910
1911 // Parse any derivation
1912 DeriveType deriv_type = DeriveType::NO;
1913 std::vector<KeyPath> derivation_multipaths;
1914 if (split.size() == 2 && Const("/", split.at(1), /*skip=*/false)) {
1915 if (!all_bip32) {
1916 error = "musig(): derivation requires all participants to be xpubs or xprvs";
1917 return {};
1918 }
1919 if (any_ranged) {
1920 error = "musig(): Cannot have ranged participant keys if musig() also has derivation";
1921 return {};
1922 }
1923 bool dummy = false;
1924 auto deriv_split = Split(split.at(1), '/');
1925 deriv_type = ParseDeriveType(deriv_split, dummy);
1926 if (deriv_type == DeriveType::HARDENED) {
1927 error = "musig(): Cannot have hardened child derivation";
1928 return {};
1929 }
1930 bool has_hardened = false;
1931 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error, /*allow_multipath=*/true, has_hardened)) {
1932 error = "musig(): " + error;
1933 return {};
1934 }
1935 if (has_hardened) {
1936 error = "musig(): cannot have hardened derivation steps";
1937 return {};
1938 }
1939 } else {
1940 derivation_multipaths.emplace_back();
1941 }
1942
1943 // Makes sure that all providers vectors in providers are the given length, or exactly length 1
1944 // Length 1 vectors have the single provider cloned until it matches the given length.
1945 const auto& clone_providers = [&providers](size_t length) -> bool {
1946 for (auto& multipath_providers : providers) {
1947 if (multipath_providers.size() == 1) {
1948 for (size_t i = 1; i < length; ++i) {
1949 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
1950 }
1951 } else if (multipath_providers.size() != length) {
1952 return false;
1953 }
1954 }
1955 return true;
1956 };
1957
1958 // Emplace the final MuSigPubkeyProvider into ret with the pubkey providers from the specified provider vectors index
1959 // and the path from the specified path index
1960 const auto& emplace_final_provider = [&ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](size_t vec_idx, size_t path_idx) -> void {
1961 KeyPath& path = derivation_multipaths.at(path_idx);
1962 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
1963 pubs.reserve(providers.size());
1964 for (auto& vec : providers) {
1965 pubs.emplace_back(std::move(vec.at(vec_idx)));
1966 }
1967 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
1968 };
1969
1970 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
1971 error = "musig(): Cannot have multipath participant keys if musig() is also multipath";
1972 return {};
1973 } else if (max_multipath_len > 1) {
1974 if (!clone_providers(max_multipath_len)) {
1975 error = strprintf("musig(): Multipath derivation paths have mismatched lengths");
1976 return {};
1977 }
1978 for (size_t i = 0; i < max_multipath_len; ++i) {
1979 // Final MuSigPubkeyProvider uses participant pubkey providers at each multipath position, and the first (and only) path
1980 emplace_final_provider(i, 0);
1981 }
1982 } else if (derivation_multipaths.size() > 1) {
1983 // All key provider vectors should be length 1. Clone them until they have the same length as paths
1984 if (!Assume(clone_providers(derivation_multipaths.size()))) {
1985 error = "musig(): Multipath derivation path with multipath participants is disallowed"; // This error is unreachable due to earlier check
1986 return {};
1987 }
1988 for (size_t i = 0; i < derivation_multipaths.size(); ++i) {
1989 // Final MuSigPubkeyProvider uses cloned participant pubkey providers, and the multipath derivation paths
1990 emplace_final_provider(i, i);
1991 }
1992 } else {
1993 // No multipath derivation, MuSigPubkeyProvider uses the first (and only) participant pubkey providers, and the first (and only) path
1994 emplace_final_provider(0, 0);
1995 }
1996 return ret;
1997 }
1998
1999 auto origin_split = Split(sp, ']');
2000 if (origin_split.size() > 2) {
2001 error = "Multiple ']' characters found for a single pubkey";
2002 return {};
2003 }
2004 // This is set if either the origin or path suffix contains a hardened derivation.
2005 bool apostrophe = false;
2006 if (origin_split.size() == 1) {
2007 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, apostrophe, error);
2008 }
2009 if (origin_split[0].empty() || origin_split[0][0] != '[') {
2010 error = strprintf("Key origin start '[ character expected but not found, got '%c' instead",
2011 origin_split[0].empty() ? ']' : origin_split[0][0]);
2012 return {};
2013 }
2014 auto slash_split = Split(origin_split[0].subspan(1), '/');
2015 if (slash_split[0].size() != 8) {
2016 error = strprintf("Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
2017 return {};
2018 }
2019 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
2020 if (!IsHex(fpr_hex)) {
2021 error = strprintf("Fingerprint '%s' is not hex", fpr_hex);
2022 return {};
2023 }
2024 auto fpr_bytes = ParseHex(fpr_hex);
2025 KeyOriginInfo info;
2026 static_assert(sizeof(info.fingerprint) == 4, "Fingerprint must be 4 bytes");
2027 assert(fpr_bytes.size() == 4);
2028 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
2029 std::vector<KeyPath> path;
2030 if (!ParseKeyPath(slash_split, path, apostrophe, error, /*allow_multipath=*/false)) return {};
2031 info.path = path.at(0);
2032 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx, out, apostrophe, error);
2033 if (providers.empty()) return {};
2034 ret.reserve(providers.size());
2035 for (auto& prov : providers) {
2036 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(key_exp_index, info, std::move(prov), apostrophe));
2037 }
2038 return ret;
2039}
2040
2041std::unique_ptr<PubkeyProvider> InferPubkey(const CPubKey& pubkey, ParseScriptContext ctx, const SigningProvider& provider)
2042{
2043 // Key cannot be hybrid
2044 if (!pubkey.IsValidNonHybrid()) {
2045 return nullptr;
2046 }
2047 // Uncompressed is only allowed in TOP and P2SH contexts
2048 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.IsCompressed()) {
2049 return nullptr;
2050 }
2051 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey, false);
2052 KeyOriginInfo info;
2053 if (provider.GetKeyOrigin(pubkey.GetID(), info)) {
2054 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider), /*apostrophe=*/false);
2055 }
2056 return key_provider;
2057}
2058
2059std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(const XOnlyPubKey& xkey, ParseScriptContext ctx, const SigningProvider& provider)
2060{
2061 CPubKey pubkey{xkey.GetEvenCorrespondingCPubKey()};
2062 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey, true);
2063 KeyOriginInfo info;
2064 if (provider.GetKeyOriginByXOnly(xkey, info)) {
2065 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider), /*apostrophe=*/false);
2066 }
2067 return key_provider;
2068}
2069
2073struct KeyParser {
2075 using Key = uint32_t;
2077 FlatSigningProvider* m_out;
2079 const SigningProvider* m_in;
2081 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2083 mutable std::string m_key_parsing_error;
2085 const miniscript::MiniscriptContext m_script_ctx;
2087 uint32_t m_offset;
2088
2090 miniscript::MiniscriptContext ctx, uint32_t offset = 0)
2091 : m_out(out), m_in(in), m_script_ctx(ctx), m_offset(offset) {}
2092
2093 bool KeyCompare(const Key& a, const Key& b) const {
2094 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2095 }
2096
2097 ParseScriptContext ParseContext() const {
2098 switch (m_script_ctx) {
2099 case miniscript::MiniscriptContext::P2WSH: return ParseScriptContext::P2WSH;
2100 case miniscript::MiniscriptContext::TAPSCRIPT: return ParseScriptContext::P2TR;
2101 }
2102 assert(false);
2103 }
2104
2105 template<typename I> std::optional<Key> FromString(I begin, I end) const
2106 {
2107 assert(m_out);
2108 Key key = m_keys.size();
2109 uint32_t exp_index = m_offset + key;
2110 auto pk = ParsePubkey(exp_index, {&*begin, &*end}, ParseContext(), *m_out, m_key_parsing_error);
2111 if (pk.empty()) return {};
2112 m_keys.emplace_back(std::move(pk));
2113 return key;
2114 }
2115
2116 std::optional<std::string> ToString(const Key& key) const
2117 {
2118 return m_keys.at(key).at(0)->ToString();
2119 }
2120
2121 template<typename I> std::optional<Key> FromPKBytes(I begin, I end) const
2122 {
2123 assert(m_in);
2124 Key key = m_keys.size();
2125 if (miniscript::IsTapscript(m_script_ctx) && end - begin == 32) {
2126 XOnlyPubKey pubkey;
2127 std::copy(begin, end, pubkey.begin());
2128 if (auto pubkey_provider = InferXOnlyPubkey(pubkey, ParseContext(), *m_in)) {
2129 m_keys.emplace_back();
2130 m_keys.back().push_back(std::move(pubkey_provider));
2131 return key;
2132 }
2133 } else if (!miniscript::IsTapscript(m_script_ctx)) {
2134 CPubKey pubkey(begin, end);
2135 if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) {
2136 m_keys.emplace_back();
2137 m_keys.back().push_back(std::move(pubkey_provider));
2138 return key;
2139 }
2140 }
2141 return {};
2142 }
2143
2144 template<typename I> std::optional<Key> FromPKHBytes(I begin, I end) const
2145 {
2146 assert(end - begin == 20);
2147 assert(m_in);
2148 uint160 hash;
2149 std::copy(begin, end, hash.begin());
2150 CKeyID keyid(hash);
2151 CPubKey pubkey;
2152 if (m_in->GetPubKey(keyid, pubkey)) {
2153 if (auto pubkey_provider = InferPubkey(pubkey, ParseContext(), *m_in)) {
2154 Key key = m_keys.size();
2155 m_keys.emplace_back();
2156 m_keys.back().push_back(std::move(pubkey_provider));
2157 return key;
2158 }
2159 }
2160 return {};
2161 }
2162
2163 miniscript::MiniscriptContext MsContext() const {
2164 return m_script_ctx;
2165 }
2166};
2167
2169// NOLINTNEXTLINE(misc-no-recursion)
2170std::vector<std::unique_ptr<DescriptorImpl>> ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
2171{
2172 using namespace script;
2173 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2174 std::vector<std::unique_ptr<DescriptorImpl>> ret;
2175 auto expr = Expr(sp);
2176 if (Func("pk", expr)) {
2177 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2178 if (pubkeys.empty()) {
2179 error = strprintf("pk(): %s", error);
2180 return {};
2181 }
2182 ++key_exp_index;
2183 for (auto& pubkey : pubkeys) {
2184 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2185 }
2186 return ret;
2187 }
2188 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && Func("pkh", expr)) {
2189 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2190 if (pubkeys.empty()) {
2191 error = strprintf("pkh(): %s", error);
2192 return {};
2193 }
2194 ++key_exp_index;
2195 for (auto& pubkey : pubkeys) {
2196 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2197 }
2198 return ret;
2199 }
2200 if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
2201 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx, out, error);
2202 if (pubkeys.empty()) {
2203 error = strprintf("combo(): %s", error);
2204 return {};
2205 }
2206 ++key_exp_index;
2207 for (auto& pubkey : pubkeys) {
2208 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2209 }
2210 return ret;
2211 } else if (Func("combo", expr)) {
2212 error = "Can only have combo() at top level";
2213 return {};
2214 }
2215 const bool multi = Func("multi", expr);
2216 const bool sortedmulti = !multi && Func("sortedmulti", expr);
2217 const bool multi_a = !(multi || sortedmulti) && Func("multi_a", expr);
2218 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) && Func("sortedmulti_a", expr);
2219 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2220 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2221 auto threshold = Expr(expr);
2222 uint32_t thres;
2223 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers; // List of multipath expanded pubkeys
2224 if (const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2225 thres = *maybe_thres;
2226 } else {
2227 error = strprintf("Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2228 return {};
2229 }
2230 size_t script_size = 0;
2231 size_t max_providers_len = 0;
2232 while (expr.size()) {
2233 if (!Const(",", expr)) {
2234 error = strprintf("Multi: expected ',', got '%c'", expr[0]);
2235 return {};
2236 }
2237 auto arg = Expr(expr);
2238 auto pks = ParsePubkey(key_exp_index, arg, ctx, out, error);
2239 if (pks.empty()) {
2240 error = strprintf("Multi: %s", error);
2241 return {};
2242 }
2243 script_size += pks.at(0)->GetSize() + 1;
2244 max_providers_len = std::max(max_providers_len, pks.size());
2245 providers.emplace_back(std::move(pks));
2246 key_exp_index++;
2247 }
2248 if ((multi || sortedmulti) && (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTISIG)) {
2249 error = strprintf("Cannot have %u keys in multisig; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTISIG);
2250 return {};
2251 } else if ((multi_a || sortedmulti_a) && (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTI_A)) {
2252 error = strprintf("Cannot have %u keys in multi_a; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTI_A);
2253 return {};
2254 } else if (thres < 1) {
2255 error = strprintf("Multisig threshold cannot be %d, must be at least 1", thres);
2256 return {};
2257 } else if (thres > providers.size()) {
2258 error = strprintf("Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2259 return {};
2260 }
2261 if (ctx == ParseScriptContext::TOP) {
2262 if (providers.size() > 3) {
2263 error = strprintf("Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2264 return {};
2265 }
2266 }
2267 if (ctx == ParseScriptContext::P2SH) {
2268 // This limits the maximum number of compressed pubkeys to 15.
2269 if (script_size + 3 > MAX_SCRIPT_ELEMENT_SIZE) {
2270 error = strprintf("P2SH script is too large, %d bytes is larger than %d bytes", script_size + 3, MAX_SCRIPT_ELEMENT_SIZE);
2271 return {};
2272 }
2273 }
2274
2275 // Make sure all vecs are of the same length, or exactly length 1
2276 // For length 1 vectors, clone key providers until vector is the same length
2277 for (auto& vec : providers) {
2278 if (vec.size() == 1) {
2279 for (size_t i = 1; i < max_providers_len; ++i) {
2280 vec.emplace_back(vec.at(0)->Clone());
2281 }
2282 } else if (vec.size() != max_providers_len) {
2283 error = strprintf("multi(): Multipath derivation paths have mismatched lengths");
2284 return {};
2285 }
2286 }
2287
2288 // Build the final descriptors vector
2289 for (size_t i = 0; i < max_providers_len; ++i) {
2290 // Build final pubkeys vectors by retrieving the i'th subscript for each vector in subscripts
2291 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2292 pubs.reserve(providers.size());
2293 for (auto& pub : providers) {
2294 pubs.emplace_back(std::move(pub.at(i)));
2295 }
2296 if (multi || sortedmulti) {
2297 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2298 } else {
2299 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2300 }
2301 }
2302 return ret;
2303 } else if (multi || sortedmulti) {
2304 error = "Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2305 return {};
2306 } else if (multi_a || sortedmulti_a) {
2307 error = "Can only have multi_a/sortedmulti_a inside tr()";
2308 return {};
2309 }
2310 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wpkh", expr)) {
2311 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH, out, error);
2312 if (pubkeys.empty()) {
2313 error = strprintf("wpkh(): %s", error);
2314 return {};
2315 }
2316 key_exp_index++;
2317 for (auto& pubkey : pubkeys) {
2318 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2319 }
2320 return ret;
2321 } else if (Func("wpkh", expr)) {
2322 error = "Can only have wpkh() at top level or inside sh()";
2323 return {};
2324 }
2325 if (ctx == ParseScriptContext::TOP && Func("sh", expr)) {
2326 auto descs = ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error);
2327 if (descs.empty() || expr.size()) return {};
2328 std::vector<std::unique_ptr<DescriptorImpl>> ret;
2329 ret.reserve(descs.size());
2330 for (auto& desc : descs) {
2331 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2332 }
2333 return ret;
2334 } else if (Func("sh", expr)) {
2335 error = "Can only have sh() at top level";
2336 return {};
2337 }
2338 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) && Func("wsh", expr)) {
2339 auto descs = ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH, out, error);
2340 if (descs.empty() || expr.size()) return {};
2341 for (auto& desc : descs) {
2342 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2343 }
2344 return ret;
2345 } else if (Func("wsh", expr)) {
2346 error = "Can only have wsh() at top level or inside sh()";
2347 return {};
2348 }
2349 if (ctx == ParseScriptContext::TOP && Func("addr", expr)) {
2350 CTxDestination dest = DecodeDestination(std::string(expr.begin(), expr.end()));
2351 if (!IsValidDestination(dest)) {
2352 error = "Address is not valid";
2353 return {};
2354 }
2355 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2356 return ret;
2357 } else if (Func("addr", expr)) {
2358 error = "Can only have addr() at top level";
2359 return {};
2360 }
2361 if (ctx == ParseScriptContext::TOP && Func("tr", expr)) {
2362 auto arg = Expr(expr);
2363 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
2364 if (internal_keys.empty()) {
2365 error = strprintf("tr(): %s", error);
2366 return {};
2367 }
2368 size_t max_providers_len = internal_keys.size();
2369 ++key_exp_index;
2370 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2371 std::vector<int> depths;
2372 if (expr.size()) {
2373 if (!Const(",", expr)) {
2374 error = strprintf("tr: expected ',', got '%c'", expr[0]);
2375 return {};
2376 }
2380 std::vector<bool> branches;
2381 // Loop over all provided scripts. In every iteration exactly one script will be processed.
2382 // Use a do-loop because inside this if-branch we expect at least one script.
2383 do {
2384 // First process all open braces.
2385 while (Const("{", expr)) {
2386 branches.push_back(false); // new left branch
2387 if (branches.size() > TAPROOT_CONTROL_MAX_NODE_COUNT) {
2388 error = strprintf("tr() supports at most %i nesting levels", TAPROOT_CONTROL_MAX_NODE_COUNT);
2389 return {};
2390 }
2391 }
2392 // Process the actual script expression.
2393 auto sarg = Expr(expr);
2394 subscripts.emplace_back(ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR, out, error));
2395 if (subscripts.back().empty()) return {};
2396 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2397 depths.push_back(branches.size());
2398 // Process closing braces; one is expected for every right branch we were in.
2399 while (branches.size() && branches.back()) {
2400 if (!Const("}", expr)) {
2401 error = strprintf("tr(): expected '}' after script expression");
2402 return {};
2403 }
2404 branches.pop_back(); // move up one level after encountering '}'
2405 }
2406 // If after that, we're at the end of a left branch, expect a comma.
2407 if (branches.size() && !branches.back()) {
2408 if (!Const(",", expr)) {
2409 error = strprintf("tr(): expected ',' after script expression");
2410 return {};
2411 }
2412 branches.back() = true; // And now we're in a right branch.
2413 }
2414 } while (branches.size());
2415 // After we've explored a whole tree, we must be at the end of the expression.
2416 if (expr.size()) {
2417 error = strprintf("tr(): expected ')' after script expression");
2418 return {};
2419 }
2420 }
2422
2423 // Make sure all vecs are of the same length, or exactly length 1
2424 // For length 1 vectors, clone subdescs until vector is the same length
2425 for (auto& vec : subscripts) {
2426 if (vec.size() == 1) {
2427 for (size_t i = 1; i < max_providers_len; ++i) {
2428 vec.emplace_back(vec.at(0)->Clone());
2429 }
2430 } else if (vec.size() != max_providers_len) {
2431 error = strprintf("tr(): Multipath subscripts have mismatched lengths");
2432 return {};
2433 }
2434 }
2435
2436 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2437 error = strprintf("tr(): Multipath internal key mismatches multipath subscripts lengths");
2438 return {};
2439 }
2440
2441 while (internal_keys.size() < max_providers_len) {
2442 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2443 }
2444
2445 // Build the final descriptors vector
2446 for (size_t i = 0; i < max_providers_len; ++i) {
2447 // Build final subscripts vectors by retrieving the i'th subscript for each vector in subscripts
2448 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2449 this_subs.reserve(subscripts.size());
2450 for (auto& subs : subscripts) {
2451 this_subs.emplace_back(std::move(subs.at(i)));
2452 }
2453 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2454 }
2455 return ret;
2456
2457
2458 } else if (Func("tr", expr)) {
2459 error = "Can only have tr at top level";
2460 return {};
2461 }
2462 if (ctx == ParseScriptContext::TOP && Func("rawtr", expr)) {
2463 auto arg = Expr(expr);
2464 if (expr.size()) {
2465 error = strprintf("rawtr(): only one key expected.");
2466 return {};
2467 }
2468 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR, out, error);
2469 if (output_keys.empty()) {
2470 error = strprintf("rawtr(): %s", error);
2471 return {};
2472 }
2473 ++key_exp_index;
2474 for (auto& pubkey : output_keys) {
2475 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2476 }
2477 return ret;
2478 } else if (Func("rawtr", expr)) {
2479 error = "Can only have rawtr at top level";
2480 return {};
2481 }
2482 if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
2483 std::string str(expr.begin(), expr.end());
2484 if (!IsHex(str)) {
2485 error = "Raw script is not hex";
2486 return {};
2487 }
2488 auto bytes = ParseHex(str);
2489 ret.emplace_back(std::make_unique<RawDescriptor>(CScript(bytes.begin(), bytes.end())));
2490 return ret;
2491 } else if (Func("raw", expr)) {
2492 error = "Can only have raw() at top level";
2493 return {};
2494 }
2495 // Process miniscript expressions.
2496 {
2497 const auto script_ctx{ctx == ParseScriptContext::P2WSH ? miniscript::MiniscriptContext::P2WSH : miniscript::MiniscriptContext::TAPSCRIPT};
2498 KeyParser parser(/*out = */&out, /* in = */nullptr, /* ctx = */script_ctx, key_exp_index);
2499 auto node = miniscript::FromString(std::string(expr.begin(), expr.end()), parser);
2500 if (parser.m_key_parsing_error != "") {
2501 error = std::move(parser.m_key_parsing_error);
2502 return {};
2503 }
2504 if (node) {
2505 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2506 error = "Miniscript expressions can only be used in wsh or tr.";
2507 return {};
2508 }
2509 if (!node->IsSane() || node->IsNotSatisfiable()) {
2510 // Try to find the first insane sub for better error reporting.
2511 auto insane_node = node.get();
2512 if (const auto sub = node->FindInsaneSub()) insane_node = sub;
2513 if (const auto str = insane_node->ToString(parser)) error = *str;
2514 if (!insane_node->IsValid()) {
2515 error += " is invalid";
2516 } else if (!node->IsSane()) {
2517 error += " is not sane";
2518 if (!insane_node->IsNonMalleable()) {
2519 error += ": malleable witnesses exist";
2520 } else if (insane_node == node.get() && !insane_node->NeedsSignature()) {
2521 error += ": witnesses without signature exist";
2522 } else if (!insane_node->CheckTimeLocksMix()) {
2523 error += ": contains mixes of timelocks expressed in blocks and seconds";
2524 } else if (!insane_node->CheckDuplicateKey()) {
2525 error += ": contains duplicate public keys";
2526 } else if (!insane_node->ValidSatisfactions()) {
2527 error += ": needs witnesses that may exceed resource limits";
2528 }
2529 } else {
2530 error += " is not satisfiable";
2531 }
2532 return {};
2533 }
2534 // A signature check is required for a miniscript to be sane. Therefore no sane miniscript
2535 // may have an empty list of public keys.
2536 CHECK_NONFATAL(!parser.m_keys.empty());
2537 key_exp_index += parser.m_keys.size();
2538 // Make sure all vecs are of the same length, or exactly length 1
2539 // For length 1 vectors, clone subdescs until vector is the same length
2540 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2541 [](const std::vector<std::unique_ptr<PubkeyProvider>>& a, const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2542 return a.size() < b.size();
2543 })->size();
2544
2545 for (auto& vec : parser.m_keys) {
2546 if (vec.size() == 1) {
2547 for (size_t i = 1; i < num_multipath; ++i) {
2548 vec.emplace_back(vec.at(0)->Clone());
2549 }
2550 } else if (vec.size() != num_multipath) {
2551 error = strprintf("Miniscript: Multipath derivation paths have mismatched lengths");
2552 return {};
2553 }
2554 }
2555
2556 // Build the final descriptors vector
2557 for (size_t i = 0; i < num_multipath; ++i) {
2558 // Build final pubkeys vectors by retrieving the i'th subscript for each vector in subscripts
2559 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2560 pubs.reserve(parser.m_keys.size());
2561 for (auto& pub : parser.m_keys) {
2562 pubs.emplace_back(std::move(pub.at(i)));
2563 }
2564 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs), node->Clone()));
2565 }
2566 return ret;
2567 }
2568 }
2569 if (ctx == ParseScriptContext::P2SH) {
2570 error = "A function is needed within P2SH";
2571 return {};
2572 } else if (ctx == ParseScriptContext::P2WSH) {
2573 error = "A function is needed within P2WSH";
2574 return {};
2575 }
2576 error = strprintf("'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2577 return {};
2578}
2579
2580std::unique_ptr<DescriptorImpl> InferMultiA(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
2581{
2582 auto match = MatchMultiA(script);
2583 if (!match) return {};
2584 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2585 keys.reserve(match->second.size());
2586 for (const auto keyspan : match->second) {
2587 if (keyspan.size() != 32) return {};
2588 auto key = InferXOnlyPubkey(XOnlyPubKey{keyspan}, ctx, provider);
2589 if (!key) return {};
2590 keys.push_back(std::move(key));
2591 }
2592 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
2593}
2594
2595// NOLINTNEXTLINE(misc-no-recursion)
2596std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
2597{
2598 if (ctx == ParseScriptContext::P2TR && script.size() == 34 && script[0] == 32 && script[33] == OP_CHECKSIG) {
2599 XOnlyPubKey key{std::span{script}.subspan(1, 32)};
2600 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider), true);
2601 }
2602
2603 if (ctx == ParseScriptContext::P2TR) {
2604 auto ret = InferMultiA(script, ctx, provider);
2605 if (ret) return ret;
2606 }
2607
2608 std::vector<std::vector<unsigned char>> data;
2609 TxoutType txntype = Solver(script, data);
2610
2611 if (txntype == TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2612 CPubKey pubkey(data[0]);
2613 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2614 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2615 }
2616 }
2617 if (txntype == TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2618 uint160 hash(data[0]);
2619 CKeyID keyid(hash);
2620 CPubKey pubkey;
2621 if (provider.GetPubKey(keyid, pubkey)) {
2622 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2623 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2624 }
2625 }
2626 }
2627 if (txntype == TxoutType::WITNESS_V0_KEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) {
2628 uint160 hash(data[0]);
2629 CKeyID keyid(hash);
2630 CPubKey pubkey;
2631 if (provider.GetPubKey(keyid, pubkey)) {
2632 if (auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
2633 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2634 }
2635 }
2636 }
2637 if (txntype == TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2638 bool ok = true;
2639 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2640 for (size_t i = 1; i + 1 < data.size(); ++i) {
2641 CPubKey pubkey(data[i]);
2642 if (auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2643 providers.push_back(std::move(pubkey_provider));
2644 } else {
2645 ok = false;
2646 break;
2647 }
2648 }
2649 if (ok) return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers));
2650 }
2651 if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
2652 uint160 hash(data[0]);
2653 CScriptID scriptid(hash);
2654 CScript subscript;
2655 if (provider.GetCScript(scriptid, subscript)) {
2656 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
2657 if (sub) return std::make_unique<SHDescriptor>(std::move(sub));
2658 }
2659 }
2660 if (txntype == TxoutType::WITNESS_V0_SCRIPTHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH)) {
2661 CScriptID scriptid{RIPEMD160(data[0])};
2662 CScript subscript;
2663 if (provider.GetCScript(scriptid, subscript)) {
2664 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
2665 if (sub) return std::make_unique<WSHDescriptor>(std::move(sub));
2666 }
2667 }
2668 if (txntype == TxoutType::WITNESS_V1_TAPROOT && ctx == ParseScriptContext::TOP) {
2669 // Extract x-only pubkey from output.
2670 XOnlyPubKey pubkey;
2671 std::copy(data[0].begin(), data[0].end(), pubkey.begin());
2672 // Request spending data.
2673 TaprootSpendData tap;
2674 if (provider.GetTaprootSpendData(pubkey, tap)) {
2675 // If found, convert it back to tree form.
2676 auto tree = InferTaprootTree(tap, pubkey);
2677 if (tree) {
2678 // If that works, try to infer subdescriptors for all leaves.
2679 bool ok = true;
2680 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2681 std::vector<int> depths;
2682 for (const auto& [depth, script, leaf_ver] : *tree) {
2683 std::unique_ptr<DescriptorImpl> subdesc;
2684 if (leaf_ver == TAPROOT_LEAF_TAPSCRIPT) {
2685 subdesc = InferScript(CScript(script.begin(), script.end()), ParseScriptContext::P2TR, provider);
2686 }
2687 if (!subdesc) {
2688 ok = false;
2689 break;
2690 } else {
2691 subscripts.push_back(std::move(subdesc));
2692 depths.push_back(depth);
2693 }
2694 }
2695 if (ok) {
2696 auto key = InferXOnlyPubkey(tap.internal_key, ParseScriptContext::P2TR, provider);
2697 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2698 }
2699 }
2700 }
2701 // If the above doesn't work, construct a rawtr() descriptor with just the encoded x-only pubkey.
2702 if (pubkey.IsFullyValid()) {
2703 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2704 if (key) {
2705 return std::make_unique<RawTRDescriptor>(std::move(key));
2706 }
2707 }
2708 }
2709
2710 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2711 const auto script_ctx{ctx == ParseScriptContext::P2WSH ? miniscript::MiniscriptContext::P2WSH : miniscript::MiniscriptContext::TAPSCRIPT};
2712 KeyParser parser(/* out = */nullptr, /* in = */&provider, /* ctx = */script_ctx);
2713 auto node = miniscript::FromScript(script, parser);
2714 if (node && node->IsSane()) {
2715 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2716 keys.reserve(parser.m_keys.size());
2717 for (auto& key : parser.m_keys) {
2718 keys.emplace_back(std::move(key.at(0)));
2719 }
2720 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(node));
2721 }
2722 }
2723
2724 // The following descriptors are all top-level only descriptors.
2725 // So if we are not at the top level, return early.
2726 if (ctx != ParseScriptContext::TOP) return nullptr;
2727
2728 CTxDestination dest;
2729 if (ExtractDestination(script, dest)) {
2730 if (GetScriptForDestination(dest) == script) {
2731 return std::make_unique<AddressDescriptor>(std::move(dest));
2732 }
2733 }
2734
2735 return std::make_unique<RawDescriptor>(script);
2736}
2737
2738
2739} // namespace
2740
2742bool CheckChecksum(std::span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr)
2743{
2744 auto check_split = Split(sp, '#');
2745 if (check_split.size() > 2) {
2746 error = "Multiple '#' symbols";
2747 return false;
2748 }
2749 if (check_split.size() == 1 && require_checksum){
2750 error = "Missing checksum";
2751 return false;
2752 }
2753 if (check_split.size() == 2) {
2754 if (check_split[1].size() != 8) {
2755 error = strprintf("Expected 8 character checksum, not %u characters", check_split[1].size());
2756 return false;
2757 }
2758 }
2759 auto checksum = DescriptorChecksum(check_split[0]);
2760 if (checksum.empty()) {
2761 error = "Invalid characters in payload";
2762 return false;
2763 }
2764 if (check_split.size() == 2) {
2765 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2766 error = strprintf("Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2767 return false;
2768 }
2769 }
2770 if (out_checksum) *out_checksum = std::move(checksum);
2771 sp = check_split[0];
2772 return true;
2773}
2774
2775std::vector<std::unique_ptr<Descriptor>> Parse(std::string_view descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
2776{
2777 std::span<const char> sp{descriptor};
2778 if (!CheckChecksum(sp, require_checksum, error)) return {};
2779 uint32_t key_exp_index = 0;
2780 auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
2781 if (sp.empty() && !ret.empty()) {
2782 std::vector<std::unique_ptr<Descriptor>> descs;
2783 descs.reserve(ret.size());
2784 for (auto& r : ret) {
2785 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2786 }
2787 return descs;
2788 }
2789 return {};
2790}
2791
2792std::string GetDescriptorChecksum(const std::string& descriptor)
2793{
2794 std::string ret;
2795 std::string error;
2796 std::span<const char> sp{descriptor};
2797 if (!CheckChecksum(sp, false, error, &ret)) return "";
2798 return ret;
2799}
2800
2801std::unique_ptr<Descriptor> InferDescriptor(const CScript& script, const SigningProvider& provider)
2802{
2803 return InferScript(script, ParseScriptContext::TOP, provider);
2804}
2805
2807{
2808 std::string desc_str = desc.ToString(/*compat_format=*/true);
2809 uint256 id;
2810 CSHA256().Write((unsigned char*)desc_str.data(), desc_str.size()).Finalize(id.begin());
2811 return id;
2812}
2813
2814void DescriptorCache::CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
2815{
2816 m_parent_xpubs[key_exp_pos] = xpub;
2817}
2818
2819void DescriptorCache::CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey& xpub)
2820{
2821 auto& xpubs = m_derived_xpubs[key_exp_pos];
2822 xpubs[der_index] = xpub;
2823}
2824
2825void DescriptorCache::CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
2826{
2827 m_last_hardened_xpubs[key_exp_pos] = xpub;
2828}
2829
2830bool DescriptorCache::GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
2831{
2832 const auto& it = m_parent_xpubs.find(key_exp_pos);
2833 if (it == m_parent_xpubs.end()) return false;
2834 xpub = it->second;
2835 return true;
2836}
2837
2838bool DescriptorCache::GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey& xpub) const
2839{
2840 const auto& key_exp_it = m_derived_xpubs.find(key_exp_pos);
2841 if (key_exp_it == m_derived_xpubs.end()) return false;
2842 const auto& der_it = key_exp_it->second.find(der_index);
2843 if (der_it == key_exp_it->second.end()) return false;
2844 xpub = der_it->second;
2845 return true;
2846}
2847
2849{
2850 const auto& it = m_last_hardened_xpubs.find(key_exp_pos);
2851 if (it == m_last_hardened_xpubs.end()) return false;
2852 xpub = it->second;
2853 return true;
2854}
2855
2857{
2858 DescriptorCache diff;
2859 for (const auto& parent_xpub_pair : other.GetCachedParentExtPubKeys()) {
2860 CExtPubKey xpub;
2861 if (GetCachedParentExtPubKey(parent_xpub_pair.first, xpub)) {
2862 if (xpub != parent_xpub_pair.second) {
2863 throw std::runtime_error(std::string(__func__) + ": New cached parent xpub does not match already cached parent xpub");
2864 }
2865 continue;
2866 }
2867 CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
2868 diff.CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
2869 }
2870 for (const auto& derived_xpub_map_pair : other.GetCachedDerivedExtPubKeys()) {
2871 for (const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
2872 CExtPubKey xpub;
2873 if (GetCachedDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, xpub)) {
2874 if (xpub != derived_xpub_pair.second) {
2875 throw std::runtime_error(std::string(__func__) + ": New cached derived xpub does not match already cached derived xpub");
2876 }
2877 continue;
2878 }
2879 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2880 diff.CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2881 }
2882 }
2883 for (const auto& lh_xpub_pair : other.GetCachedLastHardenedExtPubKeys()) {
2884 CExtPubKey xpub;
2885 if (GetCachedLastHardenedExtPubKey(lh_xpub_pair.first, xpub)) {
2886 if (xpub != lh_xpub_pair.second) {
2887 throw std::runtime_error(std::string(__func__) + ": New cached last hardened xpub does not match already cached last hardened xpub");
2888 }
2889 continue;
2890 }
2891 CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
2892 diff.CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
2893 }
2894 return diff;
2895}
2896
2898{
2899 return m_parent_xpubs;
2900}
2901
2902std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDerivedExtPubKeys() const
2903{
2904 return m_derived_xpubs;
2905}
2906
2908{
2909 return m_last_hardened_xpubs;
2910}
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
Definition: addresstype.cpp:49
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, PayToAnchor, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
Definition: addresstype.h:143
#define LIFETIMEBOUND
Definition: attributes.h:16
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
Definition: bip32.cpp:51
int ret
node::NodeContext m_node
Definition: bitcoin-gui.cpp:43
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:109
#define Assert(val)
Identity function.
Definition: check.h:113
#define Assume(val)
Assume is the identity function.
Definition: check.h:125
An encapsulated private key.
Definition: key.h:36
unsigned int size() const
Simple read-only vector-like interface.
Definition: key.h:118
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:124
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:127
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:183
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:24
An encapsulated public key.
Definition: pubkey.h:34
bool IsCompressed() const
Check whether this is a compressed public key.
Definition: pubkey.h:200
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:160
bool IsValid() const
Definition: pubkey.h:185
bool IsValidNonHybrid() const noexcept
Check if a public key is a syntactically valid compressed or uncompressed key.
Definition: pubkey.h:191
A hasher class for SHA-256.
Definition: sha256.h:14
void Finalize(unsigned char hash[OUTPUT_SIZE])
Definition: sha256.cpp:725
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:699
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:405
A reference to a CScript: the Hash160 of its serialization.
Definition: script.h:594
Cache for single descriptor's derived extended pubkeys.
Definition: descriptor.h:19
bool GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached parent xpub.
std::unordered_map< uint32_t, ExtPubKeyMap > GetCachedDerivedExtPubKeys() const
Retrieve all cached derived xpubs.
ExtPubKeyMap m_last_hardened_xpubs
Map key expression index -> last hardened xpub.
Definition: descriptor.h:26
void CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey &xpub)
Cache an xpub derived at an index.
DescriptorCache MergeAndDiff(const DescriptorCache &other)
Combine another DescriptorCache into this one.
ExtPubKeyMap GetCachedParentExtPubKeys() const
Retrieve all cached parent xpubs.
ExtPubKeyMap GetCachedLastHardenedExtPubKeys() const
Retrieve all cached last hardened xpubs.
void CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a parent xpub.
void CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey &xpub)
Cache a last hardened xpub.
bool GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey &xpub) const
Retrieve a cached xpub derived at an index.
std::unordered_map< uint32_t, ExtPubKeyMap > m_derived_xpubs
Map key expression index -> map of (key derivation index -> xpub)
Definition: descriptor.h:22
bool GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey &xpub) const
Retrieve a cached last hardened xpub.
ExtPubKeyMap m_parent_xpubs
Map key expression index -> parent xpub.
Definition: descriptor.h:24
An interface to be implemented by keystores that support signing.
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
virtual bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
bool GetKeyOriginByXOnly(const XOnlyPubKey &pubkey, KeyOriginInfo &info) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const
Utility class to construct Taproot outputs from internal key and script tree.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
TaprootBuilder & Add(int depth, std::span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
const unsigned char * begin() const
Definition: pubkey.h:295
static constexpr size_t size()
Definition: pubkey.h:293
CPubKey GetEvenCorrespondingCPubKey() const
Definition: pubkey.cpp:223
bool IsFullyValid() const
Determine if this pubkey is fully valid.
Definition: pubkey.cpp:230
constexpr unsigned char * begin()
Definition: uint256.h:100
size_type size() const
Definition: prevector.h:247
160-bit opaque blob.
Definition: uint256.h:183
256-bit opaque blob.
Definition: uint256.h:195
static const int WITNESS_SCALE_FACTOR
Definition: consensus.h:21
CScript ParseScript(const std::string &s)
Definition: core_read.cpp:73
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
Definition: hash.h:92
uint160 RIPEMD160(std::span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
Definition: hash.h:222
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: hex_base.cpp:30
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
Definition: interpreter.h:242
static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
Definition: interpreter.h:245
std::string EncodeExtKey(const CExtKey &key)
Definition: key_io.cpp:283
CExtPubKey DecodeExtPubKey(const std::string &str)
Definition: key_io.cpp:244
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
Definition: key_io.cpp:299
std::string EncodeSecret(const CKey &key)
Definition: key_io.cpp:231
std::string EncodeDestination(const CTxDestination &dest)
Definition: key_io.cpp:294
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:213
std::string EncodeExtPubKey(const CExtPubKey &key)
Definition: key_io.cpp:257
CExtKey DecodeExtKey(const std::string &str)
Definition: key_io.cpp:267
CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey &pubkey)
Construct the BIP 328 synthetic xpub for a pubkey.
Definition: musig.cpp:71
std::optional< CPubKey > MuSig2AggregatePubkeys(const std::vector< CPubKey > &pubkeys, secp256k1_musig_keyagg_cache &keyagg_cache, const std::optional< CPubKey > &expected_aggregate)
Compute the full aggregate pubkey from the given participant pubkeys in their current order.
Definition: musig.cpp:54
NodeRef< typename Ctx::Key > FromString(const std::string &str, const Ctx &ctx)
Definition: miniscript.h:2658
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
Definition: miniscript.h:262
void ForEachNode(const Node< Key > &root, Fn &&fn)
Unordered traversal of a miniscript node tree.
Definition: miniscript.h:202
NodeRef< typename Ctx::Key > FromScript(const CScript &script, const Ctx &ctx)
Definition: miniscript.h:2663
std::unique_ptr< const Node< Key > > NodeRef
Definition: miniscript.h:194
@ OLDER
[n] OP_CHECKSEQUENCEVERIFY
Definition: messages.h:21
std::span< const char > Expr(std::span< const char > &sp)
Extract the expression that sp begins with.
Definition: parsing.cpp:33
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
Definition: parsing.cpp:24
bool Const(const std::string &str, std::span< const char > &sp, bool skip)
Parse a constant.
Definition: parsing.cpp:15
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
Definition: subprocess.h:315
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h: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:48
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
bool CheckChecksum(std::span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
std::vector< std::unique_ptr< Descriptor > > Parse(std::string_view descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
Definition: descriptor.h:16
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
Definition: script.h:28
@ OP_CHECKSIG
Definition: script.h:190
@ OP_NUMEQUAL
Definition: script.h:171
@ OP_CHECKSIGADD
Definition: script.h:210
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
Definition: script.h:37
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
Definition: script.h:608
static const int MAX_PUBKEYS_PER_MULTISIG
Definition: script.h:34
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:67
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
Definition: serialize.h:288
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
Definition: sign.cpp:221
std::optional< std::vector< std::tuple< int, std::vector< unsigned char >, int > > > InferTaprootTree(const TaprootSpendData &spenddata, const XOnlyPubKey &output)
Given a TaprootSpendData and the output key, reconstruct its script tree.
const SigningProvider & DUMMY_SIGNING_PROVIDER
void PolyMod(const std::vector< typename F::Elem > &mod, std::vector< typename F::Elem > &val, const F &field)
Compute the remainder of a polynomial division of val by mod, putting the result in mod.
Definition: sketch_impl.h:18
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
Definition: solver.cpp:141
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
Definition: solver.cpp:218
std::optional< std::pair< int, std::vector< std::span< const unsigned char > > > > MatchMultiA(const CScript &script)
Definition: solver.cpp:107
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: solver.cpp:213
TxoutType
Definition: solver.h:22
@ WITNESS_V1_TAPROOT
@ WITNESS_V0_SCRIPTHASH
@ WITNESS_V0_KEYHASH
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
Definition: strencodings.h: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:342
bool Derive(CExtPubKey &out, unsigned int nChild, uint256 *bip32_tweak_out=nullptr) const
Definition: pubkey.cpp:415
Interface for parsed descriptor objects.
Definition: descriptor.h:98
virtual std::optional< int64_t > MaxSatisfactionElems() const =0
Get the maximum size number of stack elements for satisfying this descriptor.
virtual void GetPubKeys(std::set< CPubKey > &pubkeys, std::set< CExtPubKey > &ext_pubs) const =0
Return all (extended) public keys for this descriptor, including any from subdescriptors.
virtual bool ToNormalizedString(const SigningProvider &provider, std::string &out, const DescriptorCache *cache=nullptr) const =0
Convert the descriptor to a normalized string.
virtual std::optional< int64_t > MaxSatisfactionWeight(bool use_max_sig) const =0
Get the maximum size of a satisfaction for this descriptor, in weight units.
virtual std::vector< std::string > Warnings() const =0
Semantic/safety warnings (includes subdescriptors).
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
virtual std::optional< OutputType > GetOutputType() const =0
virtual bool Expand(int pos, const SigningProvider &provider, std::vector< CScript > &output_scripts, FlatSigningProvider &out, DescriptorCache *write_cache=nullptr) const =0
Expand a descriptor at a specified position.
virtual bool IsRange() const =0
Whether the expansion of this descriptor depends on the position.
virtual std::optional< int64_t > ScriptSize() const =0
Get the size of the scriptPubKey for this descriptor.
virtual bool IsSolvable() const =0
Whether this descriptor has all information about signing ignoring lack of private keys.
virtual void ExpandPrivate(int pos, const SigningProvider &provider, FlatSigningProvider &out) const =0
Expand the private key for a descriptor at a specified position, if possible.
virtual bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
virtual bool 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.
A node in a miniscript expression.
Definition: miniscript.h:521
#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