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;
1491 : m_arg(arg), m_pubkeys(pubkeys), m_private(priv) {}
1493 std::optional<std::string>
ToString(uint32_t key)
const
1497 if (!m_pubkeys[key]->ToPrivateString(*m_arg,
ret))
return {};
1499 ret = m_pubkeys[key]->ToString();
1505class MiniscriptDescriptor final :
public DescriptorImpl
1511 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1514 const auto script_ctx{
m_node->GetMsCtx()};
1515 for (
const auto& key : keys) {
1519 provider.
pubkeys.emplace(key.GetID(), key);
1522 return Vector(
m_node->ToScript(ScriptMaker(keys, script_ctx)));
1529 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1532 if (
const auto res =
m_node->ToString(StringMaker(arg, m_pubkey_args, type == StringType::PRIVATE))) {
1539 bool IsSolvable()
const override {
return true; }
1540 bool IsSingleType() const final {
return true; }
1542 std::optional<int64_t> ScriptSize()
const override {
return m_node->ScriptSize(); }
1544 std::optional<int64_t> MaxSatSize(
bool)
const override {
1546 return m_node->GetWitnessSize();
1549 std::optional<int64_t> MaxSatisfactionElems()
const override {
1550 return m_node->GetStackSize();
1553 std::unique_ptr<DescriptorImpl> Clone()
const override
1555 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1556 providers.reserve(m_pubkey_args.size());
1557 for (
const auto& arg : m_pubkey_args) {
1558 providers.push_back(arg->Clone());
1560 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node->Clone());
1565class RawTRDescriptor final :
public DescriptorImpl
1568 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1570 assert(keys.size() == 1);
1572 if (!xpk.IsFullyValid())
return {};
1577 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1579 bool IsSingleType() const final {
return true; }
1581 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1583 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1588 std::optional<int64_t> MaxSatisfactionElems()
const override {
1593 std::unique_ptr<DescriptorImpl> Clone()
const override
1595 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1603enum class ParseScriptContext {
1612std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem,
bool& apostrophe, std::string& error,
bool& has_hardened)
1614 bool hardened =
false;
1615 if (elem.size() > 0) {
1616 const char last = elem[elem.size() - 1];
1617 if (last ==
'\'' || last ==
'h') {
1618 elem = elem.first(elem.size() - 1);
1620 apostrophe = last ==
'\'';
1623 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1625 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1626 return std::nullopt;
1627 }
else if (*p > 0x7FFFFFFFUL) {
1628 error =
strprintf(
"Key path value %u is out of range", *p);
1629 return std::nullopt;
1631 has_hardened = has_hardened || hardened;
1633 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1647[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath,
bool& has_hardened)
1650 struct MultipathSubstitutes {
1651 size_t placeholder_index;
1652 std::vector<uint32_t>
values;
1654 std::optional<MultipathSubstitutes> substitutes;
1655 has_hardened =
false;
1657 for (
size_t i = 1; i <
split.size(); ++i) {
1658 const std::span<const char>& elem =
split[i];
1661 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1662 if (!allow_multipath) {
1663 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1667 error =
"Multiple multipath key path specifiers found";
1672 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1673 if (nums.size() < 2) {
1674 error =
"Multipath key path specifiers must have at least two items";
1678 substitutes.emplace();
1679 std::unordered_set<uint32_t> seen_substitutes;
1680 for (
const auto& num : nums) {
1681 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1682 if (!op_num)
return false;
1683 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1685 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1688 substitutes->values.emplace_back(*op_num);
1691 path.emplace_back();
1692 substitutes->placeholder_index = path.size() - 1;
1694 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1695 if (!op_num)
return false;
1696 path.emplace_back(*op_num);
1701 out.emplace_back(std::move(path));
1704 for (uint32_t substitute : substitutes->values) {
1705 KeyPath branch_path = path;
1706 branch_path[substitutes->placeholder_index] = substitute;
1707 out.emplace_back(std::move(branch_path));
1713[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1716 return ParseKeyPath(
split,
out, apostrophe, error, allow_multipath, dummy);
1719static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1721 DeriveType type = DeriveType::NO;
1722 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1724 type = DeriveType::UNHARDENED;
1725 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1726 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1728 type = DeriveType::HARDENED;
1734std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkeyInner(uint32_t key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out,
bool& apostrophe, std::string& error)
1736 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1737 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1739 std::string str(
split[0].begin(),
split[0].end());
1740 if (str.size() == 0) {
1741 error =
"No key provided";
1745 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1748 if (
split.size() == 1) {
1752 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1753 error =
"Hybrid public keys are not allowed";
1756 if (pubkey.IsFullyValid()) {
1757 if (permit_uncompressed || pubkey.IsCompressed()) {
1758 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1761 error =
"Uncompressed keys are not allowed";
1764 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1765 unsigned char fullkey[33] = {0x02};
1766 std::copy(
data.begin(),
data.end(), fullkey + 1);
1767 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1768 if (pubkey.IsFullyValid()) {
1769 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
1773 error =
strprintf(
"Pubkey '%s' is invalid", str);
1780 out.keys.emplace(pubkey.
GetID(), key);
1781 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1784 error =
"Uncompressed keys are not allowed";
1792 error =
strprintf(
"key '%s' is not valid", str);
1795 std::vector<KeyPath> paths;
1796 DeriveType type = ParseDeriveType(
split, apostrophe);
1797 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
1799 extpubkey = extkey.
Neuter();
1802 for (
auto& path : paths) {
1803 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
1810std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
1812 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1817 std::span<const char> span = sp;
1818 if (
Const(
"musig(", span,
false)) {
1819 if (ctx != ParseScriptContext::P2TR) {
1820 error =
"musig() is only allowed in tr() and rawtr()";
1827 if (
split.size() > 2) {
1828 error =
"Too many ')' in musig() expression";
1831 std::span<const char> expr(
split.at(0).begin(),
split.at(0).end());
1832 if (!
Func(
"musig", expr)) {
1833 error =
"Invalid musig() expression";
1838 bool any_ranged =
false;
1839 bool all_bip32 =
true;
1840 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
1841 bool any_key_parsed =
false;
1842 size_t max_multipath_len = 0;
1843 while (expr.size()) {
1844 if (any_key_parsed && !
Const(
",", expr)) {
1845 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
1848 auto arg =
Expr(expr);
1849 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG,
out, error);
1851 error =
strprintf(
"musig(): %s", error);
1854 any_key_parsed =
true;
1856 any_ranged = any_ranged ||
pk.at(0)->IsRange();
1857 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
1859 max_multipath_len = std::max(max_multipath_len,
pk.size());
1861 providers.emplace_back(std::move(
pk));
1864 if (!any_key_parsed) {
1865 error =
"musig(): Must contain key expressions";
1870 DeriveType deriv_type = DeriveType::NO;
1871 std::vector<KeyPath> derivation_multipaths;
1874 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
1878 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
1883 deriv_type = ParseDeriveType(deriv_split, dummy);
1884 if (deriv_type == DeriveType::HARDENED) {
1885 error =
"musig(): Cannot have hardened child derivation";
1888 bool has_hardened =
false;
1889 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
1890 error =
"musig(): " + error;
1894 error =
"musig(): cannot have hardened derivation steps";
1898 derivation_multipaths.emplace_back();
1903 const auto& clone_providers = [&providers](
size_t length) ->
bool {
1904 for (
auto& multipath_providers : providers) {
1905 if (multipath_providers.size() == 1) {
1906 for (
size_t i = 1; i < length; ++i) {
1907 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
1909 }
else if (multipath_providers.size() != length) {
1918 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
1919 KeyPath& path = derivation_multipaths.at(path_idx);
1920 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
1921 pubs.reserve(providers.size());
1922 for (
auto& vec : providers) {
1923 pubs.emplace_back(std::move(vec.at(vec_idx)));
1925 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
1928 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
1929 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
1931 }
else if (max_multipath_len > 1) {
1932 if (!clone_providers(max_multipath_len)) {
1933 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
1936 for (
size_t i = 0; i < max_multipath_len; ++i) {
1938 emplace_final_provider(i, 0);
1940 }
else if (derivation_multipaths.size() > 1) {
1942 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
1943 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
1946 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
1948 emplace_final_provider(i, i);
1952 emplace_final_provider(0, 0);
1957 auto origin_split =
Split(sp,
']');
1958 if (origin_split.size() > 2) {
1959 error =
"Multiple ']' characters found for a single pubkey";
1963 bool apostrophe =
false;
1964 if (origin_split.size() == 1) {
1965 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
1967 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
1968 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
1969 origin_split[0].empty() ?
']' : origin_split[0][0]);
1972 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
1973 if (slash_split[0].size() != 8) {
1974 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
1977 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
1978 if (!
IsHex(fpr_hex)) {
1979 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
1982 auto fpr_bytes =
ParseHex(fpr_hex);
1984 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
1985 assert(fpr_bytes.size() == 4);
1986 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
1987 std::vector<KeyPath> path;
1988 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
1989 info.
path = path.at(0);
1990 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
1991 if (providers.empty())
return {};
1992 ret.reserve(providers.size());
1993 for (
auto& prov : providers) {
1994 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(key_exp_index, info, std::move(prov), apostrophe));
1999std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext ctx,
const SigningProvider& provider)
2006 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2009 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2012 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2014 return key_provider;
2017std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(
const XOnlyPubKey& xkey, ParseScriptContext ctx,
const SigningProvider& provider)
2020 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2023 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2025 return key_provider;
2033 using Key = uint32_t;
2039 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2041 mutable std::string m_key_parsing_error;
2049 : m_out(
out), m_in(in), m_script_ctx(ctx), m_offset(offset) {}
2051 bool KeyCompare(
const Key& a,
const Key& b)
const {
2052 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2056 switch (m_script_ctx) {
2063 template<
typename I> std::optional<Key>
FromString(I begin, I end)
const
2066 Key key = m_keys.
size();
2067 uint32_t exp_index = m_offset + key;
2068 auto pk = ParsePubkey(exp_index, {&*begin, &*end},
ParseContext(), *m_out, m_key_parsing_error);
2069 if (
pk.empty())
return {};
2070 m_keys.emplace_back(std::move(
pk));
2074 std::optional<std::string>
ToString(
const Key& key)
const
2076 return m_keys.at(key).at(0)->ToString();
2079 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2082 Key key = m_keys.size();
2085 std::copy(begin, end, pubkey.
begin());
2086 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2087 m_keys.emplace_back();
2088 m_keys.back().push_back(std::move(pubkey_provider));
2093 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2094 m_keys.emplace_back();
2095 m_keys.back().push_back(std::move(pubkey_provider));
2102 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2104 assert(end - begin == 20);
2107 std::copy(begin, end, hash.
begin());
2111 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2112 Key key = m_keys.
size();
2113 m_keys.emplace_back();
2114 m_keys.back().push_back(std::move(pubkey_provider));
2122 return m_script_ctx;
2128std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2131 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2132 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2133 auto expr =
Expr(sp);
2134 if (
Func(
"pk", expr)) {
2135 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2136 if (pubkeys.empty()) {
2141 for (
auto& pubkey : pubkeys) {
2142 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2146 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2147 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2148 if (pubkeys.empty()) {
2153 for (
auto& pubkey : pubkeys) {
2154 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2158 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2159 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2160 if (pubkeys.empty()) {
2161 error =
strprintf(
"combo(): %s", error);
2165 for (
auto& pubkey : pubkeys) {
2166 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2169 }
else if (
Func(
"combo", expr)) {
2170 error =
"Can only have combo() at top level";
2173 const bool multi =
Func(
"multi", expr);
2174 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2175 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2176 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2177 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2178 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2179 auto threshold =
Expr(expr);
2181 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2182 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2183 thres = *maybe_thres;
2185 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2188 size_t script_size = 0;
2189 size_t max_providers_len = 0;
2190 while (expr.size()) {
2191 if (!
Const(
",", expr)) {
2192 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2195 auto arg =
Expr(expr);
2196 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2201 script_size += pks.at(0)->GetSize() + 1;
2202 max_providers_len = std::max(max_providers_len, pks.size());
2203 providers.emplace_back(std::move(pks));
2212 }
else if (thres < 1) {
2213 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2215 }
else if (thres > providers.size()) {
2216 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2219 if (ctx == ParseScriptContext::TOP) {
2220 if (providers.size() > 3) {
2221 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2225 if (ctx == ParseScriptContext::P2SH) {
2235 for (
auto& vec : providers) {
2236 if (vec.size() == 1) {
2237 for (
size_t i = 1; i < max_providers_len; ++i) {
2238 vec.emplace_back(vec.at(0)->Clone());
2240 }
else if (vec.size() != max_providers_len) {
2241 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2247 for (
size_t i = 0; i < max_providers_len; ++i) {
2249 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2250 pubs.reserve(providers.size());
2251 for (
auto& pub : providers) {
2252 pubs.emplace_back(std::move(pub.at(i)));
2254 if (multi || sortedmulti) {
2255 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2257 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2261 }
else if (multi || sortedmulti) {
2262 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2264 }
else if (multi_a || sortedmulti_a) {
2265 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2268 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2269 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
2270 if (pubkeys.empty()) {
2275 for (
auto& pubkey : pubkeys) {
2276 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2279 }
else if (
Func(
"wpkh", expr)) {
2280 error =
"Can only have wpkh() at top level or inside sh()";
2283 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2284 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
2285 if (descs.empty() || expr.size())
return {};
2286 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2287 ret.reserve(descs.size());
2288 for (
auto& desc : descs) {
2289 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2292 }
else if (
Func(
"sh", expr)) {
2293 error =
"Can only have sh() at top level";
2296 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2297 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
2298 if (descs.empty() || expr.size())
return {};
2299 for (
auto& desc : descs) {
2300 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2303 }
else if (
Func(
"wsh", expr)) {
2304 error =
"Can only have wsh() at top level or inside sh()";
2307 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2310 error =
"Address is not valid";
2313 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2315 }
else if (
Func(
"addr", expr)) {
2316 error =
"Can only have addr() at top level";
2319 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2320 auto arg =
Expr(expr);
2321 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2322 if (internal_keys.empty()) {
2326 size_t max_providers_len = internal_keys.size();
2328 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2329 std::vector<int> depths;
2331 if (!
Const(
",", expr)) {
2332 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2338 std::vector<bool> branches;
2343 while (
Const(
"{", expr)) {
2344 branches.push_back(
false);
2351 auto sarg =
Expr(expr);
2352 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
2353 if (subscripts.back().empty())
return {};
2354 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2355 depths.push_back(branches.size());
2357 while (branches.size() && branches.back()) {
2358 if (!
Const(
"}", expr)) {
2359 error =
strprintf(
"tr(): expected '}' after script expression");
2362 branches.pop_back();
2365 if (branches.size() && !branches.back()) {
2366 if (!
Const(
",", expr)) {
2367 error =
strprintf(
"tr(): expected ',' after script expression");
2370 branches.back() =
true;
2372 }
while (branches.size());
2375 error =
strprintf(
"tr(): expected ')' after script expression");
2383 for (
auto& vec : subscripts) {
2384 if (vec.size() == 1) {
2385 for (
size_t i = 1; i < max_providers_len; ++i) {
2386 vec.emplace_back(vec.at(0)->Clone());
2388 }
else if (vec.size() != max_providers_len) {
2389 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2394 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2395 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2399 while (internal_keys.size() < max_providers_len) {
2400 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2404 for (
size_t i = 0; i < max_providers_len; ++i) {
2406 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2407 this_subs.reserve(subscripts.size());
2408 for (
auto& subs : subscripts) {
2409 this_subs.emplace_back(std::move(subs.at(i)));
2411 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2416 }
else if (
Func(
"tr", expr)) {
2417 error =
"Can only have tr at top level";
2420 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2421 auto arg =
Expr(expr);
2423 error =
strprintf(
"rawtr(): only one key expected.");
2426 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2427 if (output_keys.empty()) {
2428 error =
strprintf(
"rawtr(): %s", error);
2432 for (
auto& pubkey : output_keys) {
2433 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2436 }
else if (
Func(
"rawtr", expr)) {
2437 error =
"Can only have rawtr at top level";
2440 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2441 std::string str(expr.begin(), expr.end());
2443 error =
"Raw script is not hex";
2447 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2449 }
else if (
Func(
"raw", expr)) {
2450 error =
"Can only have raw() at top level";
2456 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2458 if (parser.m_key_parsing_error !=
"") {
2459 error = std::move(parser.m_key_parsing_error);
2463 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2464 error =
"Miniscript expressions can only be used in wsh or tr.";
2467 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2469 auto insane_node =
node.get();
2470 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2471 if (
const auto str = insane_node->ToString(parser)) error = *str;
2472 if (!insane_node->IsValid()) {
2473 error +=
" is invalid";
2474 }
else if (!
node->IsSane()) {
2475 error +=
" is not sane";
2476 if (!insane_node->IsNonMalleable()) {
2477 error +=
": malleable witnesses exist";
2478 }
else if (insane_node ==
node.get() && !insane_node->NeedsSignature()) {
2479 error +=
": witnesses without signature exist";
2480 }
else if (!insane_node->CheckTimeLocksMix()) {
2481 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2482 }
else if (!insane_node->CheckDuplicateKey()) {
2483 error +=
": contains duplicate public keys";
2484 }
else if (!insane_node->ValidSatisfactions()) {
2485 error +=
": needs witnesses that may exceed resource limits";
2488 error +=
" is not satisfiable";
2495 key_exp_index += parser.m_keys.size();
2498 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2499 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2500 return a.size() < b.size();
2503 for (
auto& vec : parser.m_keys) {
2504 if (vec.size() == 1) {
2505 for (
size_t i = 1; i < num_multipath; ++i) {
2506 vec.emplace_back(vec.at(0)->Clone());
2508 }
else if (vec.size() != num_multipath) {
2509 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2515 for (
size_t i = 0; i < num_multipath; ++i) {
2517 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2518 pubs.reserve(parser.m_keys.size());
2519 for (
auto& pub : parser.m_keys) {
2520 pubs.emplace_back(std::move(pub.at(i)));
2522 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2527 if (ctx == ParseScriptContext::P2SH) {
2528 error =
"A function is needed within P2SH";
2530 }
else if (ctx == ParseScriptContext::P2WSH) {
2531 error =
"A function is needed within P2WSH";
2534 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2541 if (!match)
return {};
2542 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2543 keys.reserve(match->second.size());
2544 for (
const auto keyspan : match->second) {
2545 if (keyspan.size() != 32)
return {};
2546 auto key = InferXOnlyPubkey(
XOnlyPubKey{keyspan}, ctx, provider);
2547 if (!key)
return {};
2548 keys.push_back(std::move(key));
2550 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
2558 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider),
true);
2561 if (ctx == ParseScriptContext::P2TR) {
2562 auto ret = InferMultiA(
script, ctx, provider);
2566 std::vector<std::vector<unsigned char>>
data;
2569 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2571 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2572 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2575 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2579 if (provider.
GetPubKey(keyid, pubkey)) {
2580 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2581 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2589 if (provider.
GetPubKey(keyid, pubkey)) {
2590 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
2591 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2595 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2597 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2598 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2600 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2601 providers.push_back(std::move(pubkey_provider));
2607 if (ok)
return std::make_unique<MultisigDescriptor>((
int)
data[0][0], std::move(providers));
2613 if (provider.
GetCScript(scriptid, subscript)) {
2614 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
2615 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2621 if (provider.
GetCScript(scriptid, subscript)) {
2622 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
2623 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2638 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2639 std::vector<int> depths;
2640 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2641 std::unique_ptr<DescriptorImpl> subdesc;
2643 subdesc = InferScript(
CScript(
script.begin(),
script.end()), ParseScriptContext::P2TR, provider);
2649 subscripts.push_back(std::move(subdesc));
2650 depths.push_back(depth);
2654 auto key = InferXOnlyPubkey(tap.
internal_key, ParseScriptContext::P2TR, provider);
2655 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2661 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2663 return std::make_unique<RawTRDescriptor>(std::move(key));
2668 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2670 KeyParser parser(
nullptr, &provider, script_ctx);
2673 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2674 keys.reserve(parser.m_keys.size());
2675 for (
auto& key : parser.m_keys) {
2676 keys.emplace_back(std::move(key.at(0)));
2678 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(
node));
2684 if (ctx != ParseScriptContext::TOP)
return nullptr;
2689 return std::make_unique<AddressDescriptor>(std::move(dest));
2693 return std::make_unique<RawDescriptor>(
script);
2700bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2702 auto check_split =
Split(sp,
'#');
2703 if (check_split.size() > 2) {
2704 error =
"Multiple '#' symbols";
2707 if (check_split.size() == 1 && require_checksum){
2708 error =
"Missing checksum";
2711 if (check_split.size() == 2) {
2712 if (check_split[1].size() != 8) {
2713 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2717 auto checksum = DescriptorChecksum(check_split[0]);
2718 if (checksum.empty()) {
2719 error =
"Invalid characters in payload";
2722 if (check_split.size() == 2) {
2723 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2724 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2728 if (out_checksum) *out_checksum = std::move(checksum);
2729 sp = check_split[0];
2735 if (!
CheckChecksum(descriptor, require_checksum, error))
return {};
2736 uint32_t key_exp_index = 0;
2737 auto ret =
ParseScript(key_exp_index, descriptor, ParseScriptContext::TOP,
out, error);
2738 if (descriptor.empty() && !
ret.empty()) {
2739 std::vector<std::unique_ptr<Descriptor>> descs;
2740 descs.reserve(
ret.size());
2741 for (
auto& r :
ret) {
2742 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2753 std::span<const char> sp{descriptor};
2760 return InferScript(
script, ParseScriptContext::TOP, provider);
2765 std::string desc_str = desc.
ToString(
true);
2779 xpubs[der_index] = xpub;
2799 const auto& der_it = key_exp_it->second.find(der_index);
2800 if (der_it == key_exp_it->second.end())
return false;
2801 xpub = der_it->second;
2819 if (xpub != parent_xpub_pair.second) {
2820 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
2828 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
2831 if (xpub != derived_xpub_pair.second) {
2832 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
2836 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2837 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2843 if (xpub != lh_xpub_pair.second) {
2844 throw std::runtime_error(std::string(__func__) +
": New cached last hardened xpub does not match already cached last hardened xpub");
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::vector< std::unique_ptr< Descriptor > > Parse(std::span< const char > descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
bool CheckChecksum(std::span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
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.