94uint64_t
PolyMod(uint64_t c,
int val)
97 c = ((c & 0x7ffffffff) << 5) ^ val;
98 if (c0 & 1) c ^= 0xf5dee51989;
99 if (c0 & 2) c ^= 0xa9fdca3312;
100 if (c0 & 4) c ^= 0x1bab10e32d;
101 if (c0 & 8) c ^= 0x3706b1677a;
102 if (c0 & 16) c ^= 0x644d626ffd;
106std::string DescriptorChecksum(
const std::span<const char>& span)
121 static const std::string INPUT_CHARSET =
122 "0123456789()[],'/*abcdefgh@:$%{}"
123 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
124 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
127 static const std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
132 for (
auto ch : span) {
133 auto pos = INPUT_CHARSET.find(ch);
134 if (pos == std::string::npos)
return "";
136 cls = cls * 3 + (pos >> 5);
137 if (++clscount == 3) {
144 if (clscount > 0) c =
PolyMod(c, cls);
145 for (
int j = 0; j < 8; ++j) c =
PolyMod(c, 0);
148 std::string
ret(8,
' ');
149 for (
int j = 0; j < 8; ++j)
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
153std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
159typedef std::vector<uint32_t> KeyPath;
167 uint32_t m_expr_index;
170 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
172 virtual ~PubkeyProvider() =
default;
177 bool operator<(PubkeyProvider& other)
const {
180 std::optional<CPubKey> a =
GetPubKey(0, dummy, dummy);
181 std::optional<CPubKey> b = other.GetPubKey(0, dummy, dummy);
194 virtual bool IsRange()
const = 0;
197 virtual size_t GetSize()
const = 0;
199 enum class StringType {
205 virtual std::string
ToString(StringType type=StringType::PUBLIC)
const = 0;
219 virtual std::optional<CPubKey> GetRootPubKey()
const = 0;
221 virtual std::optional<CExtPubKey> GetRootExtPubKey()
const = 0;
224 virtual std::unique_ptr<PubkeyProvider> Clone()
const = 0;
227 virtual bool IsBIP32()
const = 0;
230class OriginPubkeyProvider final :
public PubkeyProvider
233 std::unique_ptr<PubkeyProvider> m_provider;
236 std::string OriginString(StringType type,
bool normalized=
false)
const
239 bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
244 OriginPubkeyProvider(uint32_t exp_index,
KeyOriginInfo info, std::unique_ptr<PubkeyProvider> provider,
bool apostrophe) : PubkeyProvider(exp_index), m_origin(
std::move(info)), m_provider(
std::move(provider)), m_apostrophe(apostrophe) {}
247 std::optional<CPubKey> pub = m_provider->GetPubKey(pos, arg,
out, read_cache, write_cache);
248 if (!pub)
return std::nullopt;
249 Assert(
out.pubkeys.contains(pub->GetID()));
250 auto& [pubkey, suborigin] =
out.origins[pub->GetID()];
252 std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), suborigin.fingerprint);
253 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
256 bool IsRange()
const override {
return m_provider->IsRange(); }
257 size_t GetSize()
const override {
return m_provider->GetSize(); }
258 bool IsBIP32()
const override {
return m_provider->IsBIP32(); }
259 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
263 if (!m_provider->ToPrivateString(arg, sub))
return false;
264 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
270 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
276 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
278 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
284 m_provider->GetPrivKey(pos, arg,
out);
286 std::optional<CPubKey> GetRootPubKey()
const override
288 return m_provider->GetRootPubKey();
290 std::optional<CExtPubKey> GetRootExtPubKey()
const override
292 return m_provider->GetRootExtPubKey();
294 std::unique_ptr<PubkeyProvider> Clone()
const override
296 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
301class ConstPubkeyProvider final :
public PubkeyProvider
310 arg.
GetKey(m_pubkey.GetID(), key)))
return std::nullopt;
315 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
319 CKeyID keyid = m_pubkey.GetID();
321 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
322 out.pubkeys.emplace(keyid, m_pubkey);
325 bool IsRange()
const override {
return false; }
326 size_t GetSize()
const override {
return m_pubkey.size(); }
327 bool IsBIP32()
const override {
return false; }
328 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
331 std::optional<CKey> key = GetPrivKey(arg);
332 if (!key)
return false;
343 std::optional<CKey> key = GetPrivKey(arg);
345 out.keys.emplace(key->GetPubKey().GetID(), *key);
347 std::optional<CPubKey> GetRootPubKey()
const override
351 std::optional<CExtPubKey> GetRootExtPubKey()
const override
355 std::unique_ptr<PubkeyProvider> Clone()
const override
357 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
361enum class DeriveType {
368class BIP32PubkeyProvider final :
public PubkeyProvider
380 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
381 ret.nDepth = m_root_extkey.nDepth;
382 std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint +
sizeof(
ret.vchFingerprint),
ret.vchFingerprint);
383 ret.nChild = m_root_extkey.nChild;
384 ret.chaincode = m_root_extkey.chaincode;
392 if (!GetExtKey(arg, xprv))
return false;
393 for (
auto entry : m_path) {
394 if (!xprv.
Derive(xprv, entry))
return false;
396 last_hardened = xprv;
402 bool IsHardened()
const
404 if (m_derive == DeriveType::HARDENED)
return true;
405 for (
auto entry : m_path) {
406 if (entry >> 31)
return true;
412 BIP32PubkeyProvider(uint32_t exp_index,
const CExtPubKey& extkey, KeyPath path, DeriveType derive,
bool apostrophe) : PubkeyProvider(exp_index), m_root_extkey(extkey), m_path(
std::move(path)), m_derive(derive), m_apostrophe(apostrophe) {}
413 bool IsRange()
const override {
return m_derive != DeriveType::NO; }
414 size_t GetSize()
const override {
return 33; }
415 bool IsBIP32()
const override {
return true; }
419 CKeyID keyid = m_root_extkey.pubkey.GetID();
422 if (m_derive == DeriveType::UNHARDENED) info.
path.push_back((uint32_t)pos);
423 if (m_derive == DeriveType::HARDENED) info.
path.push_back(((uint32_t)pos) | 0x80000000L);
431 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
432 if (m_derive == DeriveType::HARDENED)
return std::nullopt;
434 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return std::nullopt;
435 final_extkey = parent_extkey;
436 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
438 }
else if (IsHardened()) {
441 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return std::nullopt;
442 parent_extkey = xprv.
Neuter();
443 if (m_derive == DeriveType::UNHARDENED) der = xprv.
Derive(xprv, pos);
444 if (m_derive == DeriveType::HARDENED) der = xprv.
Derive(xprv, pos | 0x80000000UL);
445 final_extkey = xprv.
Neuter();
447 last_hardened_extkey = lh_xprv.
Neuter();
450 for (
auto entry : m_path) {
451 if (!parent_extkey.
Derive(parent_extkey, entry))
return std::nullopt;
453 final_extkey = parent_extkey;
454 if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.
Derive(final_extkey, pos);
455 assert(m_derive != DeriveType::HARDENED);
457 if (!der)
return std::nullopt;
464 if (m_derive != DeriveType::HARDENED) {
465 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
468 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
470 }
else if (info.
path.size() > 0) {
471 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
475 return final_extkey.
pubkey;
477 std::string
ToString(StringType type,
bool normalized)
const
480 const bool use_apostrophe = (!normalized && m_apostrophe) || type == StringType::COMPAT;
484 if (m_derive == DeriveType::HARDENED)
ret += use_apostrophe ?
'\'' :
'h';
488 std::string
ToString(StringType type=StringType::PUBLIC)
const override
495 if (!GetExtKey(arg, key))
return false;
499 if (m_derive == DeriveType::HARDENED)
out += m_apostrophe ?
'\'' :
'h';
505 if (m_derive == DeriveType::HARDENED) {
511 int i = (int)m_path.size() - 1;
512 for (; i >= 0; --i) {
513 if (m_path.at(i) >> 31) {
525 for (;
k <= i; ++
k) {
527 origin.
path.push_back(m_path.at(
k));
531 for (;
k < (int)m_path.size(); ++
k) {
532 end_path.push_back(m_path.at(
k));
535 CKeyID id = m_root_extkey.pubkey.GetID();
536 std::copy(
id.begin(),
id.begin() + 4, origin.
fingerprint);
541 if (cache !=
nullptr) {
547 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
557 assert(m_derive == DeriveType::UNHARDENED);
565 if (!GetDerivedExtKey(arg, extkey, dummy))
return;
566 if (m_derive == DeriveType::UNHARDENED && !extkey.
Derive(extkey, pos))
return;
567 if (m_derive == DeriveType::HARDENED && !extkey.
Derive(extkey, pos | 0x80000000UL))
return;
570 std::optional<CPubKey> GetRootPubKey()
const override
574 std::optional<CExtPubKey> GetRootExtPubKey()
const override
576 return m_root_extkey;
578 std::unique_ptr<PubkeyProvider> Clone()
const override
580 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey, m_path, m_derive, m_apostrophe);
585class MuSigPubkeyProvider final :
public PubkeyProvider
589 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
591 const KeyPath m_path;
593 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
594 mutable std::optional<CPubKey> m_aggregate_pubkey;
595 const DeriveType m_derive;
596 const bool m_ranged_participants;
598 bool IsRangedDerivation()
const {
return m_derive != DeriveType::NO; }
603 std::vector<std::unique_ptr<PubkeyProvider>> providers,
607 : PubkeyProvider(exp_index),
608 m_participants(
std::move(providers)),
609 m_path(
std::move(path)),
611 m_ranged_participants(
std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) {
return pubkey->IsRange(); }))
613 if (!
Assume(!(m_ranged_participants && IsRangedDerivation()))) {
614 throw std::runtime_error(
"musig(): Cannot have both ranged participants and ranged derivation");
616 if (!
Assume(m_derive != DeriveType::HARDENED)) {
617 throw std::runtime_error(
"musig(): Cannot have hardened derivation");
625 if (!m_aggregate_provider && !m_ranged_participants) {
627 std::vector<CPubKey> pubkeys;
628 for (
const auto& prov : m_participants) {
629 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
630 if (!pubkey.has_value()) {
633 pubkeys.push_back(pubkey.value());
635 std::sort(pubkeys.begin(), pubkeys.end());
639 if (!
Assume(m_aggregate_pubkey.has_value()))
return std::nullopt;
642 if (IsRangedDerivation() || !m_path.empty()) {
645 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub, m_path, m_derive,
false);
647 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(),
false);
652 std::vector<CPubKey> pubkeys;
653 for (
const auto& prov : m_participants) {
654 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg,
out, read_cache, write_cache);
655 if (!pub)
return std::nullopt;
656 pubkeys.emplace_back(*pub);
658 std::sort(pubkeys.begin(), pubkeys.end());
661 if (m_aggregate_provider) {
665 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy,
out, read_cache, write_cache);
666 if (!pub)
return std::nullopt;
668 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
670 if (!
Assume(m_ranged_participants) || !
Assume(m_path.empty()))
return std::nullopt;
673 if (!aggregate_pubkey)
return std::nullopt;
674 pubout = *aggregate_pubkey;
676 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(),
false);
677 this_agg_provider->GetPubKey(0, dummy,
out, read_cache, write_cache);
678 out.aggregate_pubkeys.emplace(pubout, pubkeys);
684 bool IsRange()
const override {
return IsRangedDerivation() || m_ranged_participants; }
686 size_t GetSize()
const override {
return 32; }
688 std::string
ToString(StringType type=StringType::PUBLIC)
const override
690 std::string
out =
"musig(";
691 for (
size_t i = 0; i < m_participants.size(); ++i) {
692 const auto& pubkey = m_participants.at(i);
694 out += pubkey->ToString(type);
698 if (IsRangedDerivation()) {
705 bool any_privkeys =
false;
707 for (
size_t i = 0; i < m_participants.size(); ++i) {
708 const auto& pubkey = m_participants.at(i);
711 if (pubkey->ToPrivateString(arg, tmp)) {
715 out += pubkey->ToString();
720 if (IsRangedDerivation()) {
723 if (!any_privkeys)
out.clear();
729 for (
size_t i = 0; i < m_participants.size(); ++i) {
730 const auto& pubkey = m_participants.at(i);
733 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
740 if (IsRangedDerivation()) {
751 for (
const auto& prov : m_participants) {
752 prov->GetPrivKey(pos, arg,
out);
761 std::optional<CPubKey> GetRootPubKey()
const override
765 std::optional<CExtPubKey> GetRootExtPubKey()
const override
770 std::unique_ptr<PubkeyProvider> Clone()
const override
772 std::vector<std::unique_ptr<PubkeyProvider>> providers;
773 providers.reserve(m_participants.size());
774 for (
const std::unique_ptr<PubkeyProvider>& p : m_participants) {
775 providers.emplace_back(p->Clone());
777 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers), m_path, m_derive);
779 bool IsBIP32()
const override
782 return std::all_of(m_participants.begin(), m_participants.end(), [](
const auto& pubkey) { return pubkey->IsBIP32(); });
791 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
793 const std::string m_name;
799 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
802 virtual std::string ToStringExtra()
const {
return ""; }
814 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const = 0;
817 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
818 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::unique_ptr<DescriptorImpl>
script,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args(
Vector(
std::move(
script))) {}
819 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, std::vector<std::unique_ptr<DescriptorImpl>> scripts,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args(
std::move(scripts)) {}
821 enum class StringType
832 for (
const auto& arg : m_subdescriptor_args) {
833 if (!arg->IsSolvable())
return false;
841 for (
const auto& pubkey : m_pubkey_args) {
842 if (pubkey->IsRange())
return true;
844 for (
const auto& arg : m_subdescriptor_args) {
845 if (arg->IsRange())
return true;
854 for (
const auto& scriptarg : m_subdescriptor_args) {
855 if (pos++)
ret +=
",";
857 if (!scriptarg->ToStringHelper(arg, tmp, type, cache))
return false;
866 std::string extra = ToStringExtra();
867 size_t pos = extra.size() > 0 ? 1 : 0;
868 std::string
ret = m_name +
"(" + extra;
869 for (
const auto& pubkey : m_pubkey_args) {
870 if (pos++)
ret +=
",";
873 case StringType::NORMALIZED:
874 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
876 case StringType::PRIVATE:
877 if (!pubkey->ToPrivateString(*arg, tmp))
return false;
879 case StringType::PUBLIC:
880 tmp = pubkey->ToString();
882 case StringType::COMPAT:
883 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
888 std::string subscript;
889 if (!ToStringSubScriptHelper(arg, subscript, type, cache))
return false;
890 if (pos && subscript.size())
ret +=
',';
891 out = std::move(
ret) + std::move(subscript) +
")";
895 std::string
ToString(
bool compat_format)
const final
898 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
899 return AddChecksum(
ret);
904 bool ret = ToStringHelper(&arg,
out, StringType::PRIVATE);
911 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
920 std::vector<CPubKey> pubkeys;
921 pubkeys.reserve(m_pubkey_args.size());
924 for (
const auto& p : m_pubkey_args) {
925 std::optional<CPubKey> pubkey = p->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
926 if (!pubkey)
return false;
927 pubkeys.push_back(pubkey.value());
929 std::vector<CScript> subscripts;
930 for (
const auto& subarg : m_subdescriptor_args) {
931 std::vector<CScript> outscripts;
932 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
933 assert(outscripts.size() == 1);
934 subscripts.emplace_back(std::move(outscripts[0]));
936 out.Merge(std::move(subprovider));
938 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
944 return ExpandHelper(pos, provider,
nullptr, output_scripts,
out, write_cache);
955 for (
const auto& p : m_pubkey_args) {
956 p->GetPrivKey(pos, provider,
out);
958 for (
const auto& arg : m_subdescriptor_args) {
959 arg->ExpandPrivate(pos, provider,
out);
963 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
965 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
972 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
979 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
981 for (
const auto& p : m_pubkey_args) {
982 std::optional<CPubKey> pub = p->GetRootPubKey();
983 if (pub) pubkeys.insert(*pub);
984 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
985 if (ext_pub) ext_pubs.insert(*ext_pub);
987 for (
const auto& arg : m_subdescriptor_args) {
988 arg->GetPubKeys(pubkeys, ext_pubs);
992 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
996class AddressDescriptor final :
public DescriptorImpl
1000 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
1003 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1004 bool IsSolvable() const final {
return false; }
1010 bool IsSingleType() const final {
return true; }
1011 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1014 std::unique_ptr<DescriptorImpl> Clone()
const override
1016 return std::make_unique<AddressDescriptor>(m_destination);
1021class RawDescriptor final :
public DescriptorImpl
1025 std::string ToStringExtra()
const override {
return HexStr(m_script); }
1026 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>,
FlatSigningProvider&)
const override {
return Vector(m_script); }
1029 bool IsSolvable() const final {
return false; }
1037 bool IsSingleType() const final {
return true; }
1038 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1040 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1042 std::unique_ptr<DescriptorImpl> Clone()
const override
1044 return std::make_unique<RawDescriptor>(m_script);
1049class PKDescriptor final :
public DescriptorImpl
1054 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1064 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
1065 bool IsSingleType() const final {
return true; }
1067 std::optional<int64_t> ScriptSize()
const override {
1068 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1071 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1072 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1073 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1076 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1080 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1082 std::unique_ptr<DescriptorImpl> Clone()
const override
1084 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1089class PKHDescriptor final :
public DescriptorImpl
1092 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1094 CKeyID id = keys[0].GetID();
1098 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
1100 bool IsSingleType() const final {
return true; }
1102 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1104 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1105 const auto sig_size = use_max_sig ? 72 : 71;
1106 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1109 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1113 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1115 std::unique_ptr<DescriptorImpl> Clone()
const override
1117 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1122class WPKHDescriptor final :
public DescriptorImpl
1125 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1127 CKeyID id = keys[0].GetID();
1131 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
1133 bool IsSingleType() const final {
return true; }
1135 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1137 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1138 const auto sig_size = use_max_sig ? 72 : 71;
1142 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1143 return MaxSatSize(use_max_sig);
1146 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1148 std::unique_ptr<DescriptorImpl> Clone()
const override
1150 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1155class ComboDescriptor final :
public DescriptorImpl
1158 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&
out)
const override
1160 std::vector<CScript>
ret;
1161 CKeyID id = keys[0].GetID();
1164 if (keys[0].IsCompressed()) {
1167 ret.emplace_back(p2wpkh);
1173 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
1174 bool IsSingleType() const final {
return false; }
1175 std::unique_ptr<DescriptorImpl> Clone()
const override
1177 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1182class MultisigDescriptor final :
public DescriptorImpl
1184 const int m_threshold;
1185 const bool m_sorted;
1187 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1188 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1190 std::vector<CPubKey> sorted_keys(keys);
1191 std::sort(sorted_keys.begin(), sorted_keys.end());
1197 MultisigDescriptor(
int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers,
bool sorted =
false) : DescriptorImpl(
std::move(providers), sorted ?
"sortedmulti" :
"multi"), m_threshold(threshold), m_sorted(sorted) {}
1198 bool IsSingleType() const final {
return true; }
1200 std::optional<int64_t> ScriptSize()
const override {
1201 const auto n_keys = m_pubkey_args.size();
1202 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1203 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1207 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1208 const auto sig_size = use_max_sig ? 72 : 71;
1209 return (1 + (1 +
sig_size) * m_threshold);
1212 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1216 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1218 std::unique_ptr<DescriptorImpl> Clone()
const override
1220 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1221 providers.reserve(m_pubkey_args.size());
1222 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), providers.begin(), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1223 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1228class MultiADescriptor final :
public DescriptorImpl
1230 const int m_threshold;
1231 const bool m_sorted;
1233 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1234 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1236 std::vector<XOnlyPubKey> xkeys;
1237 xkeys.reserve(keys.size());
1238 for (
const auto& key : keys) xkeys.emplace_back(key);
1239 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1241 for (
size_t i = 1; i < keys.size(); ++i) {
1248 MultiADescriptor(
int threshold, std::vector<std::unique_ptr<PubkeyProvider>> providers,
bool sorted =
false) : DescriptorImpl(
std::move(providers), sorted ?
"sortedmulti_a" :
"multi_a"), m_threshold(threshold), m_sorted(sorted) {}
1249 bool IsSingleType() const final {
return true; }
1251 std::optional<int64_t> ScriptSize()
const override {
1252 const auto n_keys = m_pubkey_args.size();
1256 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1257 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1260 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1262 std::unique_ptr<DescriptorImpl> Clone()
const override
1264 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1265 providers.reserve(m_pubkey_args.size());
1266 for (
const auto& arg : m_pubkey_args) {
1267 providers.push_back(arg->Clone());
1269 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1274class SHDescriptor final :
public DescriptorImpl
1277 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1280 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1287 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1291 assert(m_subdescriptor_args.size() == 1);
1295 bool IsSingleType() const final {
return true; }
1297 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1299 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1300 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1301 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1305 if (
IsSegwit())
return subscript_weight + *sat_size;
1312 std::optional<int64_t> MaxSatisfactionElems()
const override {
1313 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1317 std::unique_ptr<DescriptorImpl> Clone()
const override
1319 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1324class WSHDescriptor final :
public DescriptorImpl
1327 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1330 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1334 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1336 bool IsSingleType() const final {
return true; }
1338 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1340 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1341 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1342 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1349 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1350 return MaxSatSize(use_max_sig);
1353 std::optional<int64_t> MaxSatisfactionElems()
const override {
1354 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1358 std::unique_ptr<DescriptorImpl> Clone()
const override
1360 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1365class TRDescriptor final :
public DescriptorImpl
1367 std::vector<int> m_depths;
1369 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1372 assert(m_depths.size() == scripts.size());
1373 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1377 assert(keys.size() == 1);
1379 if (!xpk.IsFullyValid())
return {};
1382 out.tr_trees[output] = builder;
1387 if (m_depths.empty())
return true;
1388 std::vector<bool> path;
1389 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1390 if (pos)
ret +=
',';
1391 while ((
int)path.size() <= m_depths[pos]) {
1392 if (path.size())
ret +=
'{';
1393 path.push_back(
false);
1396 if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache))
return false;
1398 while (!path.empty() && path.back()) {
1399 if (path.size() > 1)
ret +=
'}';
1402 if (!path.empty()) path.back() =
true;
1407 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1408 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1410 assert(m_subdescriptor_args.size() == m_depths.size());
1413 bool IsSingleType() const final {
return true; }
1415 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1417 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1422 std::optional<int64_t> MaxSatisfactionElems()
const override {
1427 std::unique_ptr<DescriptorImpl> Clone()
const override
1429 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1430 subdescs.reserve(m_subdescriptor_args.size());
1431 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), subdescs.begin(), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1432 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1446 const std::vector<CPubKey>& m_keys;
1453 uint160 GetHash160(uint32_t key)
const {
1457 return m_keys[key].GetID();
1463 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1466 return {m_keys[key].begin(), m_keys[key].end()};
1469 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1472 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1473 auto id = GetHash160(key);
1474 return {
id.begin(),
id.end()};
1485 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1487 const DescriptorImpl::StringType m_type;
1492 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys
LIFETIMEBOUND,
1493 DescriptorImpl::StringType type,
1495 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1497 std::optional<std::string>
ToString(uint32_t key)
const
1501 case DescriptorImpl::StringType::PUBLIC:
1502 ret = m_pubkeys[key]->ToString();
1504 case DescriptorImpl::StringType::PRIVATE:
1505 if (!m_pubkeys[key]->ToPrivateString(*m_arg,
ret))
return {};
1507 case DescriptorImpl::StringType::NORMALIZED:
1508 if (!m_pubkeys[key]->ToNormalizedString(*m_arg,
ret, m_cache))
return {};
1510 case DescriptorImpl::StringType::COMPAT:
1511 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::COMPAT);
1518class MiniscriptDescriptor final :
public DescriptorImpl
1524 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1527 const auto script_ctx{
m_node->GetMsCtx()};
1528 for (
const auto& key : keys) {
1532 provider.
pubkeys.emplace(key.GetID(), key);
1535 return Vector(
m_node->ToScript(ScriptMaker(keys, script_ctx)));
1542 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1545 if (
const auto res =
m_node->ToString(StringMaker(arg, m_pubkey_args, type, cache))) {
1552 bool IsSolvable()
const override {
return true; }
1553 bool IsSingleType() const final {
return true; }
1555 std::optional<int64_t> ScriptSize()
const override {
return m_node->ScriptSize(); }
1557 std::optional<int64_t> MaxSatSize(
bool)
const override {
1559 return m_node->GetWitnessSize();
1562 std::optional<int64_t> MaxSatisfactionElems()
const override {
1563 return m_node->GetStackSize();
1566 std::unique_ptr<DescriptorImpl> Clone()
const override
1568 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1569 providers.reserve(m_pubkey_args.size());
1570 for (
const auto& arg : m_pubkey_args) {
1571 providers.push_back(arg->Clone());
1573 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node->Clone());
1578class RawTRDescriptor final :
public DescriptorImpl
1581 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1583 assert(keys.size() == 1);
1585 if (!xpk.IsFullyValid())
return {};
1590 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1592 bool IsSingleType() const final {
return true; }
1594 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1596 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1601 std::optional<int64_t> MaxSatisfactionElems()
const override {
1606 std::unique_ptr<DescriptorImpl> Clone()
const override
1608 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1616enum class ParseScriptContext {
1625std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem,
bool& apostrophe, std::string& error,
bool& has_hardened)
1627 bool hardened =
false;
1628 if (elem.size() > 0) {
1629 const char last = elem[elem.size() - 1];
1630 if (last ==
'\'' || last ==
'h') {
1631 elem = elem.first(elem.size() - 1);
1633 apostrophe = last ==
'\'';
1636 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1638 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1639 return std::nullopt;
1640 }
else if (*p > 0x7FFFFFFFUL) {
1641 error =
strprintf(
"Key path value %u is out of range", *p);
1642 return std::nullopt;
1644 has_hardened = has_hardened || hardened;
1646 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1660[[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)
1663 struct MultipathSubstitutes {
1664 size_t placeholder_index;
1665 std::vector<uint32_t>
values;
1667 std::optional<MultipathSubstitutes> substitutes;
1668 has_hardened =
false;
1670 for (
size_t i = 1; i <
split.size(); ++i) {
1671 const std::span<const char>& elem =
split[i];
1674 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1675 if (!allow_multipath) {
1676 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1680 error =
"Multiple multipath key path specifiers found";
1685 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1686 if (nums.size() < 2) {
1687 error =
"Multipath key path specifiers must have at least two items";
1691 substitutes.emplace();
1692 std::unordered_set<uint32_t> seen_substitutes;
1693 for (
const auto& num : nums) {
1694 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1695 if (!op_num)
return false;
1696 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1698 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1701 substitutes->values.emplace_back(*op_num);
1704 path.emplace_back();
1705 substitutes->placeholder_index = path.size() - 1;
1707 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1708 if (!op_num)
return false;
1709 path.emplace_back(*op_num);
1714 out.emplace_back(std::move(path));
1717 for (uint32_t substitute : substitutes->values) {
1718 KeyPath branch_path = path;
1719 branch_path[substitutes->placeholder_index] = substitute;
1720 out.emplace_back(std::move(branch_path));
1726[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1729 return ParseKeyPath(
split,
out, apostrophe, error, allow_multipath, dummy);
1732static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1734 DeriveType type = DeriveType::NO;
1735 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1737 type = DeriveType::UNHARDENED;
1738 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1739 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1741 type = DeriveType::HARDENED;
1747std::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)
1749 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1750 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1752 std::string str(
split[0].begin(),
split[0].end());
1753 if (str.size() == 0) {
1754 error =
"No key provided";
1758 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1761 if (
split.size() == 1) {
1765 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1766 error =
"Hybrid public keys are not allowed";
1769 if (pubkey.IsFullyValid()) {
1770 if (permit_uncompressed || pubkey.IsCompressed()) {
1771 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1774 error =
"Uncompressed keys are not allowed";
1777 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1778 unsigned char fullkey[33] = {0x02};
1779 std::copy(
data.begin(),
data.end(), fullkey + 1);
1780 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1781 if (pubkey.IsFullyValid()) {
1782 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
1786 error =
strprintf(
"Pubkey '%s' is invalid", str);
1793 out.keys.emplace(pubkey.
GetID(), key);
1794 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1797 error =
"Uncompressed keys are not allowed";
1805 error =
strprintf(
"key '%s' is not valid", str);
1808 std::vector<KeyPath> paths;
1809 DeriveType type = ParseDeriveType(
split, apostrophe);
1810 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
1812 extpubkey = extkey.
Neuter();
1815 for (
auto& path : paths) {
1816 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
1823std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
1825 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1830 std::span<const char> span = sp;
1831 if (
Const(
"musig(", span,
false)) {
1832 if (ctx != ParseScriptContext::P2TR) {
1833 error =
"musig() is only allowed in tr() and rawtr()";
1840 if (
split.size() > 2) {
1841 error =
"Too many ')' in musig() expression";
1844 std::span<const char> expr(
split.at(0).begin(),
split.at(0).end());
1845 if (!
Func(
"musig", expr)) {
1846 error =
"Invalid musig() expression";
1851 bool any_ranged =
false;
1852 bool all_bip32 =
true;
1853 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
1854 bool any_key_parsed =
false;
1855 size_t max_multipath_len = 0;
1856 while (expr.size()) {
1857 if (any_key_parsed && !
Const(
",", expr)) {
1858 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
1861 auto arg =
Expr(expr);
1862 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG,
out, error);
1864 error =
strprintf(
"musig(): %s", error);
1867 any_key_parsed =
true;
1869 any_ranged = any_ranged ||
pk.at(0)->IsRange();
1870 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
1872 max_multipath_len = std::max(max_multipath_len,
pk.size());
1874 providers.emplace_back(std::move(
pk));
1877 if (!any_key_parsed) {
1878 error =
"musig(): Must contain key expressions";
1883 DeriveType deriv_type = DeriveType::NO;
1884 std::vector<KeyPath> derivation_multipaths;
1887 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
1891 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
1896 deriv_type = ParseDeriveType(deriv_split, dummy);
1897 if (deriv_type == DeriveType::HARDENED) {
1898 error =
"musig(): Cannot have hardened child derivation";
1901 bool has_hardened =
false;
1902 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
1903 error =
"musig(): " + error;
1907 error =
"musig(): cannot have hardened derivation steps";
1911 derivation_multipaths.emplace_back();
1916 const auto& clone_providers = [&providers](
size_t length) ->
bool {
1917 for (
auto& multipath_providers : providers) {
1918 if (multipath_providers.size() == 1) {
1919 for (
size_t i = 1; i < length; ++i) {
1920 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
1922 }
else if (multipath_providers.size() != length) {
1931 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
1932 KeyPath& path = derivation_multipaths.at(path_idx);
1933 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
1934 pubs.reserve(providers.size());
1935 for (
auto& vec : providers) {
1936 pubs.emplace_back(std::move(vec.at(vec_idx)));
1938 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
1941 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
1942 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
1944 }
else if (max_multipath_len > 1) {
1945 if (!clone_providers(max_multipath_len)) {
1946 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
1949 for (
size_t i = 0; i < max_multipath_len; ++i) {
1951 emplace_final_provider(i, 0);
1953 }
else if (derivation_multipaths.size() > 1) {
1955 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
1956 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
1959 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
1961 emplace_final_provider(i, i);
1965 emplace_final_provider(0, 0);
1970 auto origin_split =
Split(sp,
']');
1971 if (origin_split.size() > 2) {
1972 error =
"Multiple ']' characters found for a single pubkey";
1976 bool apostrophe =
false;
1977 if (origin_split.size() == 1) {
1978 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
1980 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
1981 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
1982 origin_split[0].empty() ?
']' : origin_split[0][0]);
1985 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
1986 if (slash_split[0].size() != 8) {
1987 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
1990 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
1991 if (!
IsHex(fpr_hex)) {
1992 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
1995 auto fpr_bytes =
ParseHex(fpr_hex);
1997 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
1998 assert(fpr_bytes.size() == 4);
1999 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
2000 std::vector<KeyPath> path;
2001 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
2002 info.
path = path.at(0);
2003 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
2004 if (providers.empty())
return {};
2005 ret.reserve(providers.size());
2006 for (
auto& prov : providers) {
2007 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(key_exp_index, info, std::move(prov), apostrophe));
2012std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext ctx,
const SigningProvider& provider)
2019 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2022 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2025 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2027 return key_provider;
2030std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(
const XOnlyPubKey& xkey, ParseScriptContext ctx,
const SigningProvider& provider)
2033 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2036 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2038 return key_provider;
2046 using Key = uint32_t;
2052 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2054 mutable std::string m_key_parsing_error;
2062 : m_out(
out), m_in(in), m_script_ctx(ctx), m_offset(offset) {}
2064 bool KeyCompare(
const Key& a,
const Key& b)
const {
2065 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2069 switch (m_script_ctx) {
2076 template<
typename I> std::optional<Key>
FromString(I begin, I end)
const
2079 Key key = m_keys.
size();
2080 uint32_t exp_index = m_offset + key;
2081 auto pk = ParsePubkey(exp_index, {&*begin, &*end},
ParseContext(), *m_out, m_key_parsing_error);
2082 if (
pk.empty())
return {};
2083 m_keys.emplace_back(std::move(
pk));
2087 std::optional<std::string>
ToString(
const Key& key)
const
2089 return m_keys.at(key).at(0)->ToString();
2092 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2095 Key key = m_keys.size();
2098 std::copy(begin, end, pubkey.
begin());
2099 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2100 m_keys.emplace_back();
2101 m_keys.back().push_back(std::move(pubkey_provider));
2106 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2107 m_keys.emplace_back();
2108 m_keys.back().push_back(std::move(pubkey_provider));
2115 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2117 assert(end - begin == 20);
2120 std::copy(begin, end, hash.
begin());
2124 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2125 Key key = m_keys.
size();
2126 m_keys.emplace_back();
2127 m_keys.back().push_back(std::move(pubkey_provider));
2135 return m_script_ctx;
2141std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2144 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2145 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2146 auto expr =
Expr(sp);
2147 if (
Func(
"pk", expr)) {
2148 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2149 if (pubkeys.empty()) {
2154 for (
auto& pubkey : pubkeys) {
2155 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2159 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2160 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2161 if (pubkeys.empty()) {
2166 for (
auto& pubkey : pubkeys) {
2167 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2171 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2172 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2173 if (pubkeys.empty()) {
2174 error =
strprintf(
"combo(): %s", error);
2178 for (
auto& pubkey : pubkeys) {
2179 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2182 }
else if (
Func(
"combo", expr)) {
2183 error =
"Can only have combo() at top level";
2186 const bool multi =
Func(
"multi", expr);
2187 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2188 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2189 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2190 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2191 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2192 auto threshold =
Expr(expr);
2194 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2195 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2196 thres = *maybe_thres;
2198 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2201 size_t script_size = 0;
2202 size_t max_providers_len = 0;
2203 while (expr.size()) {
2204 if (!
Const(
",", expr)) {
2205 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2208 auto arg =
Expr(expr);
2209 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2214 script_size += pks.at(0)->GetSize() + 1;
2215 max_providers_len = std::max(max_providers_len, pks.size());
2216 providers.emplace_back(std::move(pks));
2225 }
else if (thres < 1) {
2226 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2228 }
else if (thres > providers.size()) {
2229 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2232 if (ctx == ParseScriptContext::TOP) {
2233 if (providers.size() > 3) {
2234 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2238 if (ctx == ParseScriptContext::P2SH) {
2248 for (
auto& vec : providers) {
2249 if (vec.size() == 1) {
2250 for (
size_t i = 1; i < max_providers_len; ++i) {
2251 vec.emplace_back(vec.at(0)->Clone());
2253 }
else if (vec.size() != max_providers_len) {
2254 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2260 for (
size_t i = 0; i < max_providers_len; ++i) {
2262 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2263 pubs.reserve(providers.size());
2264 for (
auto& pub : providers) {
2265 pubs.emplace_back(std::move(pub.at(i)));
2267 if (multi || sortedmulti) {
2268 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2270 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2274 }
else if (multi || sortedmulti) {
2275 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2277 }
else if (multi_a || sortedmulti_a) {
2278 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2281 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2282 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
2283 if (pubkeys.empty()) {
2288 for (
auto& pubkey : pubkeys) {
2289 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2292 }
else if (
Func(
"wpkh", expr)) {
2293 error =
"Can only have wpkh() at top level or inside sh()";
2296 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2297 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
2298 if (descs.empty() || expr.size())
return {};
2299 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2300 ret.reserve(descs.size());
2301 for (
auto& desc : descs) {
2302 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2305 }
else if (
Func(
"sh", expr)) {
2306 error =
"Can only have sh() at top level";
2309 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2310 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
2311 if (descs.empty() || expr.size())
return {};
2312 for (
auto& desc : descs) {
2313 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2316 }
else if (
Func(
"wsh", expr)) {
2317 error =
"Can only have wsh() at top level or inside sh()";
2320 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2323 error =
"Address is not valid";
2326 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2328 }
else if (
Func(
"addr", expr)) {
2329 error =
"Can only have addr() at top level";
2332 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2333 auto arg =
Expr(expr);
2334 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2335 if (internal_keys.empty()) {
2339 size_t max_providers_len = internal_keys.size();
2341 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2342 std::vector<int> depths;
2344 if (!
Const(
",", expr)) {
2345 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2351 std::vector<bool> branches;
2356 while (
Const(
"{", expr)) {
2357 branches.push_back(
false);
2364 auto sarg =
Expr(expr);
2365 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
2366 if (subscripts.back().empty())
return {};
2367 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2368 depths.push_back(branches.size());
2370 while (branches.size() && branches.back()) {
2371 if (!
Const(
"}", expr)) {
2372 error =
strprintf(
"tr(): expected '}' after script expression");
2375 branches.pop_back();
2378 if (branches.size() && !branches.back()) {
2379 if (!
Const(
",", expr)) {
2380 error =
strprintf(
"tr(): expected ',' after script expression");
2383 branches.back() =
true;
2385 }
while (branches.size());
2388 error =
strprintf(
"tr(): expected ')' after script expression");
2396 for (
auto& vec : subscripts) {
2397 if (vec.size() == 1) {
2398 for (
size_t i = 1; i < max_providers_len; ++i) {
2399 vec.emplace_back(vec.at(0)->Clone());
2401 }
else if (vec.size() != max_providers_len) {
2402 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2407 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2408 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2412 while (internal_keys.size() < max_providers_len) {
2413 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2417 for (
size_t i = 0; i < max_providers_len; ++i) {
2419 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2420 this_subs.reserve(subscripts.size());
2421 for (
auto& subs : subscripts) {
2422 this_subs.emplace_back(std::move(subs.at(i)));
2424 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2429 }
else if (
Func(
"tr", expr)) {
2430 error =
"Can only have tr at top level";
2433 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2434 auto arg =
Expr(expr);
2436 error =
strprintf(
"rawtr(): only one key expected.");
2439 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2440 if (output_keys.empty()) {
2441 error =
strprintf(
"rawtr(): %s", error);
2445 for (
auto& pubkey : output_keys) {
2446 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2449 }
else if (
Func(
"rawtr", expr)) {
2450 error =
"Can only have rawtr at top level";
2453 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2454 std::string str(expr.begin(), expr.end());
2456 error =
"Raw script is not hex";
2460 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2462 }
else if (
Func(
"raw", expr)) {
2463 error =
"Can only have raw() at top level";
2469 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2471 if (parser.m_key_parsing_error !=
"") {
2472 error = std::move(parser.m_key_parsing_error);
2476 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2477 error =
"Miniscript expressions can only be used in wsh or tr.";
2480 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2482 auto insane_node =
node.get();
2483 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2484 if (
const auto str = insane_node->ToString(parser)) error = *str;
2485 if (!insane_node->IsValid()) {
2486 error +=
" is invalid";
2487 }
else if (!
node->IsSane()) {
2488 error +=
" is not sane";
2489 if (!insane_node->IsNonMalleable()) {
2490 error +=
": malleable witnesses exist";
2491 }
else if (insane_node ==
node.get() && !insane_node->NeedsSignature()) {
2492 error +=
": witnesses without signature exist";
2493 }
else if (!insane_node->CheckTimeLocksMix()) {
2494 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2495 }
else if (!insane_node->CheckDuplicateKey()) {
2496 error +=
": contains duplicate public keys";
2497 }
else if (!insane_node->ValidSatisfactions()) {
2498 error +=
": needs witnesses that may exceed resource limits";
2501 error +=
" is not satisfiable";
2508 key_exp_index += parser.m_keys.size();
2511 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2512 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2513 return a.size() < b.size();
2516 for (
auto& vec : parser.m_keys) {
2517 if (vec.size() == 1) {
2518 for (
size_t i = 1; i < num_multipath; ++i) {
2519 vec.emplace_back(vec.at(0)->Clone());
2521 }
else if (vec.size() != num_multipath) {
2522 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2528 for (
size_t i = 0; i < num_multipath; ++i) {
2530 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2531 pubs.reserve(parser.m_keys.size());
2532 for (
auto& pub : parser.m_keys) {
2533 pubs.emplace_back(std::move(pub.at(i)));
2535 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2540 if (ctx == ParseScriptContext::P2SH) {
2541 error =
"A function is needed within P2SH";
2543 }
else if (ctx == ParseScriptContext::P2WSH) {
2544 error =
"A function is needed within P2WSH";
2547 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2554 if (!match)
return {};
2555 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2556 keys.reserve(match->second.size());
2557 for (
const auto keyspan : match->second) {
2558 if (keyspan.size() != 32)
return {};
2559 auto key = InferXOnlyPubkey(
XOnlyPubKey{keyspan}, ctx, provider);
2560 if (!key)
return {};
2561 keys.push_back(std::move(key));
2563 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
2571 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider),
true);
2574 if (ctx == ParseScriptContext::P2TR) {
2575 auto ret = InferMultiA(
script, ctx, provider);
2579 std::vector<std::vector<unsigned char>>
data;
2582 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2584 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2585 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2588 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2592 if (provider.
GetPubKey(keyid, pubkey)) {
2593 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2594 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2602 if (provider.
GetPubKey(keyid, pubkey)) {
2603 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
2604 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2608 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2610 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2611 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2613 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2614 providers.push_back(std::move(pubkey_provider));
2620 if (ok)
return std::make_unique<MultisigDescriptor>((
int)
data[0][0], std::move(providers));
2626 if (provider.
GetCScript(scriptid, subscript)) {
2627 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
2628 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2634 if (provider.
GetCScript(scriptid, subscript)) {
2635 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
2636 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2651 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2652 std::vector<int> depths;
2653 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2654 std::unique_ptr<DescriptorImpl> subdesc;
2656 subdesc = InferScript(
CScript(
script.begin(),
script.end()), ParseScriptContext::P2TR, provider);
2662 subscripts.push_back(std::move(subdesc));
2663 depths.push_back(depth);
2667 auto key = InferXOnlyPubkey(tap.
internal_key, ParseScriptContext::P2TR, provider);
2668 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2674 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2676 return std::make_unique<RawTRDescriptor>(std::move(key));
2681 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2683 KeyParser parser(
nullptr, &provider, script_ctx);
2686 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2687 keys.reserve(parser.m_keys.size());
2688 for (
auto& key : parser.m_keys) {
2689 keys.emplace_back(std::move(key.at(0)));
2691 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(
node));
2697 if (ctx != ParseScriptContext::TOP)
return nullptr;
2702 return std::make_unique<AddressDescriptor>(std::move(dest));
2706 return std::make_unique<RawDescriptor>(
script);
2713bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2715 auto check_split =
Split(sp,
'#');
2716 if (check_split.size() > 2) {
2717 error =
"Multiple '#' symbols";
2720 if (check_split.size() == 1 && require_checksum){
2721 error =
"Missing checksum";
2724 if (check_split.size() == 2) {
2725 if (check_split[1].size() != 8) {
2726 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2730 auto checksum = DescriptorChecksum(check_split[0]);
2731 if (checksum.empty()) {
2732 error =
"Invalid characters in payload";
2735 if (check_split.size() == 2) {
2736 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2737 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2741 if (out_checksum) *out_checksum = std::move(checksum);
2742 sp = check_split[0];
2748 std::span<const char> sp{descriptor};
2750 uint32_t key_exp_index = 0;
2752 if (sp.empty() && !
ret.empty()) {
2753 std::vector<std::unique_ptr<Descriptor>> descs;
2754 descs.reserve(
ret.size());
2755 for (
auto& r :
ret) {
2756 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2767 std::span<const char> sp{descriptor};
2774 return InferScript(
script, ParseScriptContext::TOP, provider);
2779 std::string desc_str = desc.
ToString(
true);
2793 xpubs[der_index] = xpub;
2813 const auto& der_it = key_exp_it->second.find(der_index);
2814 if (der_it == key_exp_it->second.end())
return false;
2815 xpub = der_it->second;
2833 if (xpub != parent_xpub_pair.second) {
2834 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
2842 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
2845 if (xpub != derived_xpub_pair.second) {
2846 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
2850 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2851 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2857 if (xpub != lh_xpub_pair.second) {
2858 throw std::runtime_error(std::string(__func__) +
": New cached last hardened xpub does not match already cached last hardened xpub");
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.
std::string FormatHDKeypath(const std::vector< uint32_t > &path, bool apostrophe)
#define CHECK_NONFATAL(condition)
Identity function.
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the identity function.
An encapsulated private key.
unsigned int size() const
Simple read-only vector-like interface.
bool IsValid() const
Check whether this private key is valid.
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
CPubKey GetPubKey() const
Compute the public key from a private key.
A reference to a CKey: the Hash160 of its serialized public key.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
bool IsValidNonHybrid() const noexcept
Check if a public key is a syntactically valid compressed or uncompressed key.
A hasher class for SHA-256.
void Finalize(unsigned char hash[OUTPUT_SIZE])
CSHA256 & Write(const unsigned char *data, size_t len)
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization.
Cache for single descriptor's derived extended pubkeys.
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.
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)
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.
An interface to be implemented by keystores that support signing.
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
virtual bool GetTaprootSpendData(const XOnlyPubKey &output_key, TaprootSpendData &spenddata) const
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
bool GetKeyOriginByXOnly(const XOnlyPubKey &pubkey, KeyOriginInfo &info) const
virtual bool GetKey(const CKeyID &address, CKey &key) const
virtual bool GetKeyOrigin(const CKeyID &keyid, KeyOriginInfo &info) const
Utility class to construct Taproot outputs from internal key and script tree.
WitnessV1Taproot GetOutput()
Compute scriptPubKey (after Finalize()).
bool IsComplete() const
Return whether there were either no leaves, or the leaves form a Huffman tree.
TaprootBuilder & Add(int depth, std::span< const unsigned char > script, int leaf_version, bool track=true)
Add a new script at a certain depth in the tree.
static bool ValidDepths(const std::vector< int > &depths)
Check if a list of depths is legal (will lead to IsComplete()).
TaprootBuilder & Finalize(const XOnlyPubKey &internal_key)
Finalize the construction.
const unsigned char * begin() const
static constexpr size_t size()
CPubKey GetEvenCorrespondingCPubKey() const
bool IsFullyValid() const
Determine if this pubkey is fully valid.
constexpr unsigned char * begin()
static const int WITNESS_SCALE_FACTOR
CScript ParseScript(const std::string &s)
uint160 Hash160(const T1 &in1)
Compute the 160-bit hash an object.
uint160 RIPEMD160(std::span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
static constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
static constexpr size_t TAPROOT_CONTROL_MAX_NODE_COUNT
std::string EncodeExtKey(const CExtKey &key)
CExtPubKey DecodeExtPubKey(const std::string &str)
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
std::string EncodeSecret(const CKey &key)
std::string EncodeDestination(const CTxDestination &dest)
CKey DecodeSecret(const std::string &str)
std::string EncodeExtPubKey(const CExtPubKey &key)
CExtKey DecodeExtKey(const std::string &str)
CExtPubKey CreateMuSig2SyntheticXpub(const CPubKey &pubkey)
Construct the BIP 328 synthetic xpub for a pubkey.
std::optional< CPubKey > MuSig2AggregatePubkeys(const std::vector< CPubKey > &pubkeys, secp256k1_musig_keyagg_cache &keyagg_cache, const std::optional< CPubKey > &expected_aggregate)
Compute the full aggregate pubkey from the given participant pubkeys in their current order.
NodeRef< typename Ctx::Key > FromString(const std::string &str, const Ctx &ctx)
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
NodeRef< typename Ctx::Key > FromScript(const CScript &script, const Ctx &ctx)
std::unique_ptr< const Node< Key > > NodeRef
std::span< const char > Expr(std::span< const char > &sp)
Extract the expression that sp begins with.
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
bool Const(const std::string &str, std::span< const char > &sp, bool skip)
Parse a constant.
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
std::string ToString(const T &t)
Locale-independent version of std::to_string.
std::vector< T > Split(const std::span< const char > &sp, std::string_view separators, bool include_sep=false)
Split a string on any char found in separators, returning a vector.
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
bool operator<(const CNetAddr &a, const CNetAddr &b)
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.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
bool CheckChecksum(std::span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
std::vector< std::unique_ptr< Descriptor > > Parse(std::string_view descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
static const int MAX_PUBKEYS_PER_MULTISIG
std::vector< unsigned char > ToByteVector(const T &in)
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
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.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
std::optional< std::pair< int, std::vector< std::span< const unsigned char > > > > MatchMultiA(const CScript &script)
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
CExtPubKey Neuter() const
bool Derive(CExtKey &out, unsigned int nChild) const
bool Derive(CExtPubKey &out, unsigned int nChild, uint256 *bip32_tweak_out=nullptr) const
Interface for parsed descriptor objects.
virtual std::optional< int64_t > MaxSatisfactionElems() const =0
Get the maximum size number of stack elements for satisfying this descriptor.
virtual void GetPubKeys(std::set< CPubKey > &pubkeys, std::set< CExtPubKey > &ext_pubs) const =0
Return all (extended) public keys for this descriptor, including any from subdescriptors.
virtual bool ToNormalizedString(const SigningProvider &provider, std::string &out, const DescriptorCache *cache=nullptr) const =0
Convert the descriptor to a normalized string.
virtual std::optional< int64_t > MaxSatisfactionWeight(bool use_max_sig) const =0
Get the maximum size of a satisfaction for this descriptor, in weight units.
virtual std::string ToString(bool compat_format=false) const =0
Convert the descriptor back to a string, undoing parsing.
virtual std::optional< OutputType > GetOutputType() const =0
virtual bool Expand(int pos, const SigningProvider &provider, std::vector< CScript > &output_scripts, FlatSigningProvider &out, DescriptorCache *write_cache=nullptr) const =0
Expand a descriptor at a specified position.
virtual bool IsRange() const =0
Whether the expansion of this descriptor depends on the position.
virtual std::optional< int64_t > ScriptSize() const =0
Get the size of the scriptPubKey for this descriptor.
virtual bool IsSolvable() const =0
Whether this descriptor has all information about signing ignoring lack of private keys.
virtual void ExpandPrivate(int pos, const SigningProvider &provider, FlatSigningProvider &out) const =0
Expand the private key for a descriptor at a specified position, if possible.
virtual bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
virtual bool ExpandFromCache(int pos, const DescriptorCache &read_cache, std::vector< CScript > &output_scripts, FlatSigningProvider &out) const =0
Expand a descriptor at a specified position using cached expansion data.
bool GetPubKey(const CKeyID &keyid, CPubKey &pubkey) const override
std::map< CKeyID, CPubKey > pubkeys
unsigned char fingerprint[4]
First 32 bits of the Hash160 of the public key at the root of the path.
std::vector< uint32_t > path
XOnlyPubKey internal_key
The BIP341 internal key.
consteval auto _(util::TranslatedLiteral str)
bool IsHex(std::string_view str)
std::vector< std::common_type_t< Args... > > Vector(Args &&... args)
Construct a vector with the specified elements.