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