46#include <unordered_set>
57 if ((high >> 31) != 0) {
60 if (high >= low + 1000000) {
129uint64_t
PolyMod(uint64_t c,
int val)
131 uint8_t c0 = c >> 35;
132 c = ((c & 0x7ffffffff) << 5) ^ val;
133 if (c0 & 1) c ^= 0xf5dee51989;
134 if (c0 & 2) c ^= 0xa9fdca3312;
135 if (c0 & 4) c ^= 0x1bab10e32d;
136 if (c0 & 8) c ^= 0x3706b1677a;
137 if (c0 & 16) c ^= 0x644d626ffd;
141std::string DescriptorChecksum(
const std::span<const char>& span)
156 static const std::string INPUT_CHARSET =
157 "0123456789()[],'/*abcdefgh@:$%{}"
158 "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
159 "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
162 static const std::string CHECKSUM_CHARSET =
"qpzry9x8gf2tvdw0s3jn54khce6mua7l";
167 for (
auto ch : span) {
168 auto pos = INPUT_CHARSET.find(ch);
169 if (pos == std::string::npos)
return "";
171 cls = cls * 3 + (pos >> 5);
172 if (++clscount == 3) {
179 if (clscount > 0) c =
PolyMod(c, cls);
180 for (
int j = 0; j < 8; ++j) c =
PolyMod(c, 0);
183 std::string
ret(8,
' ');
184 for (
int j = 0; j < 8; ++j)
ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
188std::string AddChecksum(
const std::string& str) {
return str +
"#" + DescriptorChecksum(str); }
194typedef std::vector<uint32_t> KeyPath;
202 const uint32_t m_expr_index;
204 explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
206 virtual ~PubkeyProvider() =
default;
216 virtual bool IsRange()
const = 0;
219 virtual size_t GetSize()
const = 0;
221 enum class StringType {
228 virtual std::string
ToString(StringType type)
const = 0;
249 GetPrivKey(0, arg, tmp_provider);
250 return !tmp_provider.
keys.empty();
254 virtual std::optional<CPubKey> GetRootPubKey()
const = 0;
256 virtual std::optional<CExtPubKey> GetRootExtPubKey()
const = 0;
259 virtual std::unique_ptr<PubkeyProvider> Clone()
const = 0;
262 virtual bool IsBIP32()
const = 0;
265 virtual size_t GetKeyCount()
const {
return 1; }
268 virtual bool CanSelfExpand()
const = 0;
271 static bool DetermineApostropheUse(StringType type,
bool normalized,
bool public_apostrophe)
273 bool use_apostrophe{
false};
275 case StringType::COMPAT:
277 use_apostrophe =
true;
279 case StringType::CANONICAL:
281 use_apostrophe =
false;
283 case StringType::PUBLIC:
284 use_apostrophe = !normalized && public_apostrophe;
287 return use_apostrophe;
291class OriginPubkeyProvider final :
public PubkeyProvider
294 std::unique_ptr<PubkeyProvider> m_provider;
297 std::string OriginString(StringType type,
bool normalized=
false)
const
299 bool use_apostrophe{DetermineApostropheUse(type, normalized, m_apostrophe)};
304 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) {}
310 std::optional<CPubKey> pub = m_provider->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
311 if (!pub)
return std::nullopt;
312 const CKeyID keyid{pub->GetID()};
314 auto& [pubkey, suborigin] = subprovider.
origins[keyid];
316 suborigin.fingerprint = m_origin.fingerprint;
317 suborigin.path.insert(suborigin.path.begin(), m_origin.path.begin(), m_origin.path.end());
318 auto origin{subprovider.
origins.extract(keyid)};
319 out.Merge(std::move(subprovider));
321 out.origins.insert_or_assign(keyid, std::move(origin.mapped()));
324 bool IsRange()
const override {
return m_provider->IsRange(); }
325 size_t GetSize()
const override {
return m_provider->GetSize(); }
326 bool IsBIP32()
const override {
return m_provider->IsBIP32(); }
327 std::string
ToString(StringType type)
const override {
return "[" + OriginString(type) +
"]" + m_provider->ToString(type); }
331 bool has_priv_key{m_provider->ToPrivateString(arg, sub)};
332 ret =
"[" + OriginString(StringType::PUBLIC) +
"]" + std::move(sub);
338 if (!m_provider->ToNormalizedString(arg, sub, cache))
return false;
344 ret =
"[" + OriginString(StringType::PUBLIC,
true) + std::move(sub);
346 ret =
"[" + OriginString(StringType::PUBLIC,
true) +
"]" + std::move(sub);
352 m_provider->GetPrivKey(pos, arg,
out);
354 std::optional<CPubKey> GetRootPubKey()
const override
356 return m_provider->GetRootPubKey();
358 std::optional<CExtPubKey> GetRootExtPubKey()
const override
360 return m_provider->GetRootExtPubKey();
362 std::unique_ptr<PubkeyProvider> Clone()
const override
364 return std::make_unique<OriginPubkeyProvider>(m_expr_index, m_origin, m_provider->Clone(), m_apostrophe);
366 bool CanSelfExpand()
const override {
return m_provider->CanSelfExpand(); }
370class ConstPubkeyProvider final :
public PubkeyProvider
379 arg.
GetKey(m_pubkey.GetID(), key)))
return std::nullopt;
384 ConstPubkeyProvider(uint32_t exp_index,
const CPubKey& pubkey,
bool xonly) : PubkeyProvider(exp_index), m_pubkey(pubkey), m_xonly(xonly) {}
388 CKeyID keyid = m_pubkey.GetID();
390 out.origins.emplace(keyid, std::make_pair(m_pubkey, info));
391 out.pubkeys.emplace(keyid, m_pubkey);
394 bool IsRange()
const override {
return false; }
395 size_t GetSize()
const override {
return m_pubkey.size(); }
396 bool IsBIP32()
const override {
return false; }
397 std::string
ToString(StringType type)
const override {
return m_xonly ?
HexStr(m_pubkey).substr(2) :
HexStr(m_pubkey); }
400 std::optional<CKey> key = GetPrivKey(arg);
415 std::optional<CKey> key = GetPrivKey(arg);
417 out.keys.emplace(key->GetPubKey().GetID(), *key);
419 std::optional<CPubKey> GetRootPubKey()
const override
423 std::optional<CExtPubKey> GetRootExtPubKey()
const override
427 std::unique_ptr<PubkeyProvider> Clone()
const override
429 return std::make_unique<ConstPubkeyProvider>(m_expr_index, m_pubkey, m_xonly);
431 bool CanSelfExpand() const final {
return true; }
434enum class DeriveType {
441class BIP32PubkeyProvider final :
public PubkeyProvider
453 if (!arg.
GetKey(m_root_extkey.pubkey.GetID(), key))
return false;
454 ret.nDepth = m_root_extkey.nDepth;
455 ret.fingerprint = m_root_extkey.fingerprint;
456 ret.nChild = m_root_extkey.nChild;
457 ret.chaincode = m_root_extkey.chaincode;
465 if (!GetExtKey(arg, xprv))
return false;
466 for (
auto entry :
m_path) {
467 if (!xprv.
Derive(xprv, entry))
return false;
469 last_hardened = xprv;
475 bool IsHardened()
const
477 if (m_derive == DeriveType::HARDENED_RANGED)
return true;
482 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) {}
483 bool IsRange()
const override {
return m_derive != DeriveType::NON_RANGED; }
484 size_t GetSize()
const override {
return 33; }
485 bool IsBIP32()
const override {
return true; }
489 info.
fingerprint = m_root_extkey.id_key_fingerprint();
491 if (m_derive == DeriveType::UNHARDENED_RANGED) info.
path.push_back((uint32_t)pos);
500 if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
501 if (m_derive == DeriveType::HARDENED_RANGED)
return std::nullopt;
503 if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey))
return std::nullopt;
504 final_extkey = parent_extkey;
505 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
507 }
else if (IsHardened()) {
510 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return std::nullopt;
511 parent_extkey = xprv.
Neuter();
512 if (m_derive == DeriveType::UNHARDENED_RANGED) der = xprv.
Derive(xprv, pos);
514 final_extkey = xprv.
Neuter();
516 last_hardened_extkey = lh_xprv.
Neuter();
519 for (
auto entry :
m_path) {
520 if (!parent_extkey.
Derive(parent_extkey, entry))
return std::nullopt;
522 final_extkey = parent_extkey;
523 if (m_derive == DeriveType::UNHARDENED_RANGED) der = parent_extkey.
Derive(final_extkey, pos);
524 assert(m_derive != DeriveType::HARDENED_RANGED);
526 if (!der)
return std::nullopt;
533 if (m_derive != DeriveType::HARDENED_RANGED) {
534 write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
537 write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
539 }
else if (info.
path.size() > 0) {
540 write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
544 return final_extkey.
pubkey;
546 std::string
ToString(StringType type,
bool normalized)
const
548 bool use_apostrophe{DetermineApostropheUse(type, normalized, m_apostrophe)};
552 if (m_derive == DeriveType::HARDENED_RANGED)
ret += use_apostrophe ?
'\'' :
'h';
556 std::string
ToString(StringType type)
const override
563 if (!GetExtKey(arg, key)) {
570 if (m_derive == DeriveType::HARDENED_RANGED)
out += m_apostrophe ?
'\'' :
'h';
576 if (m_derive == DeriveType::HARDENED_RANGED) {
582 int i = (int)
m_path.size() - 1;
583 for (; i >= 0; --i) {
596 for (;
k <= i; ++
k) {
602 for (;
k < (int)
m_path.size(); ++
k) {
603 end_path.push_back(
m_path.at(
k));
605 origin.
fingerprint = m_root_extkey.id_key_fingerprint();
610 if (cache !=
nullptr) {
616 if (!GetDerivedExtKey(arg, xprv, lh_xprv))
return false;
626 assert(m_derive == DeriveType::UNHARDENED_RANGED);
634 if (!GetDerivedExtKey(arg, extkey, dummy))
return;
635 if (m_derive == DeriveType::UNHARDENED_RANGED && !extkey.
Derive(extkey, pos))
return;
639 std::optional<CPubKey> GetRootPubKey()
const override
643 std::optional<CExtPubKey> GetRootExtPubKey()
const override
645 return m_root_extkey;
647 std::unique_ptr<PubkeyProvider> Clone()
const override
649 return std::make_unique<BIP32PubkeyProvider>(m_expr_index, m_root_extkey,
m_path, m_derive, m_apostrophe);
651 bool CanSelfExpand()
const override {
return !IsHardened(); }
655class MuSigPubkeyProvider final :
public PubkeyProvider
659 const std::vector<std::unique_ptr<PubkeyProvider>> m_participants;
663 mutable std::unique_ptr<PubkeyProvider> m_aggregate_provider;
664 mutable std::optional<CPubKey> m_aggregate_pubkey;
665 const DeriveType m_derive;
666 const bool m_ranged_participants;
668 bool IsRangedDerivation()
const {
return m_derive != DeriveType::NON_RANGED; }
673 std::vector<std::unique_ptr<PubkeyProvider>> providers,
677 : PubkeyProvider(exp_index),
678 m_participants(
std::move(providers)),
681 m_ranged_participants(
std::any_of(m_participants.begin(), m_participants.end(), [](const auto& pubkey) {
return pubkey->IsRange(); }))
683 if (!
Assume(!(m_ranged_participants && IsRangedDerivation()))) {
684 throw std::runtime_error(
"musig(): Cannot have both ranged participants and ranged derivation");
686 if (!
Assume(m_derive != DeriveType::HARDENED_RANGED)) {
687 throw std::runtime_error(
"musig(): Cannot have hardened derivation");
695 if (!m_aggregate_provider && !m_ranged_participants) {
697 std::vector<CPubKey> pubkeys;
698 for (
const auto& prov : m_participants) {
699 std::optional<CPubKey> pubkey = prov->GetPubKey(0, arg, dummy, read_cache, write_cache);
700 if (!pubkey.has_value()) {
703 pubkeys.push_back(pubkey.value());
705 std::sort(pubkeys.begin(), pubkeys.end());
709 if (!
Assume(m_aggregate_pubkey.has_value()))
return std::nullopt;
712 if (IsRangedDerivation() || !
m_path.empty()) {
715 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub,
m_path, m_derive,
false);
717 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(),
false);
722 std::vector<CPubKey> pubkeys;
723 for (
const auto& prov : m_participants) {
724 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg,
out, read_cache, write_cache);
725 if (!pub)
return std::nullopt;
726 pubkeys.emplace_back(*pub);
728 std::sort(pubkeys.begin(), pubkeys.end());
731 if (m_aggregate_provider) {
735 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy,
out, read_cache, write_cache);
736 if (!pub)
return std::nullopt;
738 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
743 if (!aggregate_pubkey)
return std::nullopt;
744 pubout = *aggregate_pubkey;
746 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(),
false);
747 this_agg_provider->GetPubKey(0, dummy,
out, read_cache, write_cache);
748 out.aggregate_pubkeys.emplace(pubout, pubkeys);
754 bool IsRange()
const override {
return IsRangedDerivation() || m_ranged_participants; }
756 size_t GetSize()
const override {
return 32; }
758 std::string
ToString(StringType type)
const override
760 std::string
out =
"musig(";
761 for (
size_t i = 0; i < m_participants.size(); ++i) {
762 const auto& pubkey = m_participants.at(i);
764 out += pubkey->ToString(type);
768 if (IsRangedDerivation()) {
775 bool any_privkeys =
false;
777 for (
size_t i = 0; i < m_participants.size(); ++i) {
778 const auto& pubkey = m_participants.at(i);
781 if (pubkey->ToPrivateString(arg, tmp)) {
788 if (IsRangedDerivation()) {
796 for (
size_t i = 0; i < m_participants.size(); ++i) {
797 const auto& pubkey = m_participants.at(i);
800 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
807 if (IsRangedDerivation()) {
818 for (
const auto& prov : m_participants) {
819 prov->GetPrivKey(pos, arg,
out);
825 return std::ranges::all_of(m_participants, [&](
const auto& prov) {
return prov->HavePrivateKeys(arg); });
833 std::optional<CPubKey> GetRootPubKey()
const override
837 std::optional<CExtPubKey> GetRootExtPubKey()
const override
842 std::unique_ptr<PubkeyProvider> Clone()
const override
844 std::vector<std::unique_ptr<PubkeyProvider>> providers;
845 providers.reserve(m_participants.size());
846 for (
const std::unique_ptr<PubkeyProvider>& p : m_participants) {
847 providers.emplace_back(p->Clone());
849 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers),
m_path, m_derive);
851 bool IsBIP32()
const override
854 return std::all_of(m_participants.begin(), m_participants.end(), [](
const auto& pubkey) { return pubkey->IsBIP32(); });
856 size_t GetKeyCount()
const override
858 return 1 + m_participants.size();
860 bool CanSelfExpand()
const override
864 for (
const auto& key : m_participants) {
865 if (!key->CanSelfExpand())
return false;
876 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
878 const std::string m_name;
880 std::vector<std::string> m_warnings;
886 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
889 virtual std::string ToStringExtra()
const {
return ""; }
901 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const = 0;
904 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
905 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))) {}
906 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)) {}
908 enum class StringType
920 for (
const auto& arg : m_subdescriptor_args) {
921 if (!arg->IsSolvable())
return false;
929 if (m_pubkey_args.empty() && m_subdescriptor_args.empty())
return false;
931 for (
const auto& sub: m_subdescriptor_args) {
932 if (!sub->HavePrivateKeys(arg))
return false;
935 for (
const auto& pubkey : m_pubkey_args) {
936 if (!pubkey->HavePrivateKeys(arg))
return false;
945 for (
const auto& pubkey : m_pubkey_args) {
946 if (pubkey->IsRange())
return true;
948 for (
const auto& arg : m_subdescriptor_args) {
949 if (arg->IsRange())
return true;
958 bool is_private{type == StringType::PRIVATE};
961 bool any_success{!is_private};
962 for (
const auto& scriptarg : m_subdescriptor_args) {
963 if (pos++)
ret +=
",";
965 bool subscript_res{scriptarg->ToStringHelper(arg, tmp, type, cache)};
966 if (!is_private && !subscript_res)
return false;
967 any_success = any_success || subscript_res;
976 std::string extra = ToStringExtra();
977 size_t pos = extra.size() > 0 ? 1 : 0;
978 std::string
ret = m_name +
"(" + extra;
979 bool is_private{type == StringType::PRIVATE};
982 bool any_success{!is_private};
984 for (
const auto& pubkey : m_pubkey_args) {
985 if (pos++)
ret +=
",";
988 case StringType::NORMALIZED:
989 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
991 case StringType::PRIVATE:
992 any_success = pubkey->ToPrivateString(*arg, tmp) || any_success;
994 case StringType::PUBLIC:
995 tmp = pubkey->ToString(PubkeyProvider::StringType::PUBLIC);
997 case StringType::COMPAT:
998 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
1000 case StringType::CANONICAL:
1001 tmp = pubkey->ToString(PubkeyProvider::StringType::CANONICAL);
1006 std::string subscript;
1007 bool subscript_res{ToStringSubScriptHelper(arg, subscript, type, cache)};
1008 if (!is_private && !subscript_res)
return false;
1009 any_success = any_success || subscript_res;
1010 if (pos && subscript.size())
ret +=
',';
1011 out = std::move(
ret) + std::move(subscript) +
")";
1015 std::string
ToString(
bool compat_format)
const final
1018 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
1019 return AddChecksum(
ret);
1025 ToStringHelper(
nullptr,
ret, StringType::CANONICAL);
1026 return AddChecksum(
ret);
1031 bool has_priv_key{ToStringHelper(&arg,
out, StringType::PRIVATE)};
1033 return has_priv_key;
1038 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
1047 std::vector<CPubKey> pubkeys;
1048 pubkeys.reserve(m_pubkey_args.size());
1051 for (
const auto& p : m_pubkey_args) {
1052 std::optional<CPubKey> pubkey = p->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
1053 if (!pubkey)
return false;
1054 pubkeys.push_back(pubkey.value());
1056 std::vector<CScript> subscripts;
1057 for (
const auto& subarg : m_subdescriptor_args) {
1058 std::vector<CScript> outscripts;
1059 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
1060 assert(outscripts.size() == 1);
1061 subscripts.emplace_back(std::move(outscripts[0]));
1063 out.Merge(std::move(subprovider));
1065 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
1071 return ExpandHelper(pos,
provider,
nullptr, output_scripts,
out, write_cache);
1082 for (
const auto& p : m_pubkey_args) {
1085 for (
const auto& arg : m_subdescriptor_args) {
1090 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
1092 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
1099 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
1106 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
1108 for (
const auto& p : m_pubkey_args) {
1109 std::optional<CPubKey> pub = p->GetRootPubKey();
1110 if (pub) pubkeys.insert(*pub);
1111 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
1112 if (ext_pub) ext_pubs.insert(*ext_pub);
1114 for (
const auto& arg : m_subdescriptor_args) {
1115 arg->GetPubKeys(pubkeys, ext_pubs);
1119 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
1121 bool HasScripts()
const override {
return true; }
1124 std::vector<std::string>
Warnings()
const override {
1125 std::vector<std::string> all = m_warnings;
1126 for (
const auto& sub : m_subdescriptor_args) {
1127 auto sub_w = sub->Warnings();
1128 all.insert(all.end(), sub_w.begin(), sub_w.end());
1135 uint32_t max_key_expr{0};
1136 std::vector<const DescriptorImpl*> todo = {
this};
1137 while (!todo.empty()) {
1138 const DescriptorImpl* desc = todo.back();
1140 for (
const auto& p : desc->m_pubkey_args) {
1141 max_key_expr = std::max(max_key_expr, p->m_expr_index);
1143 for (
const auto&
s : desc->m_subdescriptor_args) {
1144 todo.push_back(
s.get());
1147 return max_key_expr;
1150 size_t GetKeyCount() const final
1153 std::vector<const DescriptorImpl*> todo = {
this};
1154 while (!todo.empty()) {
1155 const DescriptorImpl* desc = todo.back();
1157 for (
const auto& p : desc->m_pubkey_args) {
1158 count += p->GetKeyCount();
1160 for (
const auto&
s : desc->m_subdescriptor_args) {
1161 todo.push_back(
s.get());
1168 bool CanSelfExpand()
const override
1170 for (
const auto& key : m_pubkey_args) {
1171 if (!key->CanSelfExpand())
return false;
1173 for (
const auto& sub : m_subdescriptor_args) {
1174 if (!sub->CanSelfExpand())
return false;
1181class AddressDescriptor final :
public DescriptorImpl
1185 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
1188 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1189 bool IsSolvable() const final {
return false; }
1195 bool IsSingleType() const final {
return true; }
1196 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1199 std::unique_ptr<DescriptorImpl> Clone()
const override
1201 return std::make_unique<AddressDescriptor>(m_destination);
1206class RawDescriptor final :
public DescriptorImpl
1210 std::string ToStringExtra()
const override {
return HexStr(m_script); }
1211 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>,
FlatSigningProvider&)
const override {
return Vector(m_script); }
1214 bool IsSolvable() const final {
return false; }
1222 bool IsSingleType() const final {
return true; }
1223 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1225 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1227 std::unique_ptr<DescriptorImpl> Clone()
const override
1229 return std::make_unique<RawDescriptor>(m_script);
1234class PKDescriptor final :
public DescriptorImpl
1239 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1249 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
1250 bool IsSingleType() const final {
return true; }
1252 std::optional<int64_t> ScriptSize()
const override {
1253 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1256 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1257 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1258 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1261 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1265 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1267 std::unique_ptr<DescriptorImpl> Clone()
const override
1269 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1274class PKHDescriptor final :
public DescriptorImpl
1277 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1283 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
1285 bool IsSingleType() const final {
return true; }
1287 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1289 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1290 const auto sig_size = use_max_sig ? 72 : 71;
1291 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1294 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1298 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1300 std::unique_ptr<DescriptorImpl> Clone()
const override
1302 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1307class WPKHDescriptor final :
public DescriptorImpl
1310 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1316 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
1318 bool IsSingleType() const final {
return true; }
1320 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1322 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1323 const auto sig_size = use_max_sig ? 72 : 71;
1327 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1328 return MaxSatSize(use_max_sig);
1331 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1333 std::unique_ptr<DescriptorImpl> Clone()
const override
1335 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1340class ComboDescriptor final :
public DescriptorImpl
1343 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&
out)
const override
1345 std::vector<CScript>
ret;
1349 if (
keys[0].IsCompressed()) {
1352 ret.emplace_back(p2wpkh);
1358 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
1359 bool IsSingleType() const final {
return false; }
1360 std::unique_ptr<DescriptorImpl> Clone()
const override
1362 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1367class MultisigDescriptor final :
public DescriptorImpl
1369 const int m_threshold;
1370 const bool m_sorted;
1372 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1373 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1375 std::vector<CPubKey> sorted_keys(
keys);
1376 std::sort(sorted_keys.begin(), sorted_keys.end());
1382 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) {}
1383 bool IsSingleType() const final {
return true; }
1385 std::optional<int64_t> ScriptSize()
const override {
1386 const auto n_keys = m_pubkey_args.size();
1387 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1388 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1392 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1393 const auto sig_size = use_max_sig ? 72 : 71;
1394 return (1 + (1 +
sig_size) * m_threshold);
1397 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1401 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1403 std::unique_ptr<DescriptorImpl> Clone()
const override
1405 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1406 providers.reserve(m_pubkey_args.size());
1407 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), std::back_inserter(providers), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1408 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1413class MultiADescriptor final :
public DescriptorImpl
1415 const int m_threshold;
1416 const bool m_sorted;
1418 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1419 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1421 std::vector<XOnlyPubKey> xkeys;
1422 xkeys.reserve(
keys.size());
1423 for (
const auto& key :
keys) xkeys.emplace_back(key);
1424 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1426 for (
size_t i = 1; i <
keys.size(); ++i) {
1433 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) {}
1434 bool IsSingleType() const final {
return true; }
1436 std::optional<int64_t> ScriptSize()
const override {
1437 const auto n_keys = m_pubkey_args.size();
1441 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1442 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1445 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1447 std::unique_ptr<DescriptorImpl> Clone()
const override
1449 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1450 providers.reserve(m_pubkey_args.size());
1451 for (
const auto& arg : m_pubkey_args) {
1452 providers.push_back(arg->Clone());
1454 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1459class SHDescriptor final :
public DescriptorImpl
1462 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1465 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1472 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1476 assert(m_subdescriptor_args.size() == 1);
1480 bool IsSingleType() const final {
return true; }
1482 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1484 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1485 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1486 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1490 if (
IsSegwit())
return subscript_weight + *sat_size;
1497 std::optional<int64_t> MaxSatisfactionElems()
const override {
1498 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1502 std::unique_ptr<DescriptorImpl> Clone()
const override
1504 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1509class WSHDescriptor final :
public DescriptorImpl
1512 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1515 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1519 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1521 bool IsSingleType() const final {
return true; }
1523 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1525 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1526 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1527 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1534 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1535 return MaxSatSize(use_max_sig);
1538 std::optional<int64_t> MaxSatisfactionElems()
const override {
1539 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1543 std::unique_ptr<DescriptorImpl> Clone()
const override
1545 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1550class TRDescriptor final :
public DescriptorImpl
1552 std::vector<int> m_depths;
1554 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1557 assert(m_depths.size() == scripts.size());
1558 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1564 if (!xpk.IsFullyValid())
return {};
1567 out.tr_trees[output] = builder;
1572 if (m_depths.empty()) {
1578 return type != StringType::PRIVATE;
1580 std::vector<bool> path;
1581 bool is_private{type == StringType::PRIVATE};
1584 bool any_success{!is_private};
1586 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1587 if (pos)
ret +=
',';
1588 while ((
int)path.size() <= m_depths[pos]) {
1589 if (path.size())
ret +=
'{';
1590 path.push_back(
false);
1593 bool subscript_res{m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)};
1594 if (!is_private && !subscript_res)
return false;
1595 any_success = any_success || subscript_res;
1597 while (!path.empty() && path.back()) {
1598 if (path.size() > 1)
ret +=
'}';
1601 if (!path.empty()) path.back() =
true;
1606 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1607 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1609 assert(m_subdescriptor_args.size() == m_depths.size());
1612 bool IsSingleType() const final {
return true; }
1614 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1616 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1621 std::optional<int64_t> MaxSatisfactionElems()
const override {
1626 std::unique_ptr<DescriptorImpl> Clone()
const override
1628 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1629 subdescs.reserve(m_subdescriptor_args.size());
1630 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), std::back_inserter(subdescs), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1631 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1645 const std::vector<CPubKey>& m_keys;
1652 uint160 GetHash160(uint32_t key)
const {
1656 return m_keys[key].GetID();
1662 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1665 return {m_keys[key].begin(), m_keys[key].end()};
1668 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1671 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1672 auto id = GetHash160(key);
1673 return {
id.begin(),
id.end()};
1684 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1686 const DescriptorImpl::StringType m_type;
1691 const std::vector<std::unique_ptr<PubkeyProvider>>& pubkeys
LIFETIMEBOUND,
1692 DescriptorImpl::StringType type,
1694 : m_arg(arg), m_pubkeys(pubkeys), m_type(type), m_cache(cache) {}
1696 std::optional<std::string>
ToString(uint32_t key,
bool& has_priv_key)
const
1699 has_priv_key =
false;
1701 case DescriptorImpl::StringType::PUBLIC:
1702 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::PUBLIC);
1704 case DescriptorImpl::StringType::PRIVATE:
1705 has_priv_key = m_pubkeys[key]->ToPrivateString(*m_arg,
ret);
1707 case DescriptorImpl::StringType::NORMALIZED:
1708 if (!m_pubkeys[key]->ToNormalizedString(*m_arg,
ret, m_cache))
return {};
1710 case DescriptorImpl::StringType::COMPAT:
1715 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::PUBLIC);
1717 case DescriptorImpl::StringType::CANONICAL:
1718 ret = m_pubkeys[key]->ToString(PubkeyProvider::StringType::CANONICAL);
1725class MiniscriptDescriptor final :
public DescriptorImpl
1731 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
1734 const auto script_ctx{
m_node.GetMsCtx()};
1735 for (
const auto& key :
keys) {
1739 provider.pubkeys.emplace(key.GetID(), key);
1752 const uint32_t raw = node.K();
1753 const uint32_t value_part = raw & ~CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG;
1754 if (value_part > CTxIn::SEQUENCE_LOCKTIME_MASK) {
1755 const bool is_time_based = (raw & CTxIn::SEQUENCE_LOCKTIME_TYPE_FLAG) != 0;
1756 if (is_time_based) {
1757 m_warnings.push_back(strprintf(
"time-based relative locktime: older(%u) > (65535 * 512) seconds is unsafe", raw));
1759 m_warnings.push_back(strprintf(
"height-based relative locktime: older(%u) > 65535 blocks is unsafe", raw));
1766 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1769 bool has_priv_key{
false};
1770 auto res =
m_node.ToString(StringMaker(arg, m_pubkey_args, type, cache), has_priv_key);
1771 if (res)
out = *res;
1772 if (type == StringType::PRIVATE) {
1774 return has_priv_key;
1776 return res.has_value();
1780 bool IsSolvable()
const override {
return true; }
1781 bool IsSingleType() const final {
return true; }
1783 std::optional<int64_t> ScriptSize()
const override {
return m_node.ScriptSize(); }
1785 std::optional<int64_t> MaxSatSize(
bool)
const override
1788 return m_node.GetWitnessSize();
1791 std::optional<int64_t> MaxSatisfactionElems()
const override
1793 return m_node.GetStackSize();
1796 std::unique_ptr<DescriptorImpl> Clone()
const override
1798 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1799 providers.reserve(m_pubkey_args.size());
1800 for (
const auto& arg : m_pubkey_args) {
1801 providers.push_back(arg->Clone());
1803 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node.Clone());
1808class RawTRDescriptor final :
public DescriptorImpl
1811 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1815 if (!xpk.IsFullyValid())
return {};
1820 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1822 bool IsSingleType() const final {
return true; }
1824 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1826 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1831 std::optional<int64_t> MaxSatisfactionElems()
const override {
1836 std::unique_ptr<DescriptorImpl> Clone()
const override
1838 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1843class UnusedDescriptor final :
public DescriptorImpl
1846 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&
keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override {
return {}; }
1848 UnusedDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"unused") {}
1849 bool IsSingleType() const final {
return true; }
1850 bool HasScripts()
const override {
return false; }
1852 std::unique_ptr<DescriptorImpl> Clone()
const override
1854 return std::make_unique<UnusedDescriptor>(m_pubkey_args.at(0)->Clone());
1863enum class ParseScriptContext {
1883[[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)
1885 auto parse_elem = [&](std::span<const char> elem) -> std::optional<uint32_t> {
1888 error = parsed.error();
1889 return std::nullopt;
1891 if (parsed->is_hardened) {
1892 has_hardened =
true;
1893 apostrophe = elem.back() ==
'\'';
1895 return parsed->ChildNumber();
1899 struct MultipathSubstitutes {
1900 size_t placeholder_index;
1901 std::vector<uint32_t>
values;
1903 std::optional<MultipathSubstitutes> substitutes;
1904 has_hardened =
false;
1906 for (
size_t i = 1; i <
split.size(); ++i) {
1907 const std::span<const char>& elem =
split[i];
1910 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1911 if (!allow_multipath) {
1912 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1916 error =
"Multiple multipath key path specifiers found";
1921 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1922 if (nums.size() < 2) {
1923 error =
"Multipath key path specifiers must have at least two items";
1927 substitutes.emplace();
1928 std::unordered_set<uint32_t> seen_substitutes;
1929 for (
const auto& num : nums) {
1930 const auto& op_num = parse_elem(num);
1931 if (!op_num)
return false;
1932 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1934 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1937 substitutes->values.emplace_back(*op_num);
1940 path.emplace_back();
1941 substitutes->placeholder_index = path.size() - 1;
1943 const auto& op_num = parse_elem(elem);
1944 if (!op_num)
return false;
1945 path.emplace_back(*op_num);
1950 out.emplace_back(std::move(path));
1953 for (uint32_t substitute : substitutes->values) {
1954 KeyPath branch_path = path;
1955 branch_path[substitutes->placeholder_index] = substitute;
1956 out.emplace_back(std::move(branch_path));
1962[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1965 return ParseKeyPath(
split,
out, apostrophe, error, allow_multipath, dummy);
1968static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1970 DeriveType type = DeriveType::NON_RANGED;
1971 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1973 type = DeriveType::UNHARDENED_RANGED;
1974 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1975 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1977 type = DeriveType::HARDENED_RANGED;
1983std::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)
1985 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1986 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1988 std::string str(
split[0].begin(),
split[0].end());
1989 if (str.size() == 0) {
1990 error =
"No key provided";
1994 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1997 if (
split.size() == 1) {
2001 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
2002 error =
"Hybrid public keys are not allowed";
2005 if (pubkey.IsFullyValid()) {
2006 if (permit_uncompressed || pubkey.IsCompressed()) {
2007 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
2011 error =
"Uncompressed keys are not allowed";
2014 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
2015 unsigned char fullkey[33] = {0x02};
2016 std::copy(
data.begin(),
data.end(), fullkey + 1);
2017 pubkey.Set(std::begin(fullkey), std::end(fullkey));
2018 if (pubkey.IsFullyValid()) {
2019 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
2024 error =
strprintf(
"Pubkey '%s' is invalid", str);
2031 out.keys.emplace(pubkey.
GetID(), key);
2032 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
2036 error =
"Uncompressed keys are not allowed";
2044 error =
strprintf(
"key '%s' is not valid", str);
2047 std::vector<KeyPath> paths;
2048 DeriveType type = ParseDeriveType(
split, apostrophe);
2049 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
2051 extpubkey = extkey.
Neuter();
2054 for (
auto& path : paths) {
2055 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
2063std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2065 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
2070 std::span<const char> span = sp;
2071 if (
Const(
"musig(", span,
false)) {
2072 if (ctx != ParseScriptContext::P2TR) {
2073 error =
"musig() is only allowed in tr() and rawtr()";
2080 if (
split.size() > 2) {
2081 error =
"Too many ')' in musig() expression";
2084 std::span<const char> expr(
split.at(0).begin(),
split.at(0).end());
2085 if (!
Func(
"musig", expr)) {
2086 error =
"Invalid musig() expression";
2091 bool any_ranged =
false;
2092 bool all_bip32 =
true;
2093 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2094 bool any_key_parsed =
false;
2095 size_t max_multipath_len = 0;
2096 while (expr.size()) {
2097 if (any_key_parsed && !
Const(
",", expr)) {
2098 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
2101 auto arg =
Expr(expr);
2102 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG,
out, error);
2104 error =
strprintf(
"musig(): %s", error);
2107 any_key_parsed =
true;
2109 any_ranged = any_ranged ||
pk.at(0)->IsRange();
2110 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
2112 max_multipath_len = std::max(max_multipath_len,
pk.size());
2114 providers.emplace_back(std::move(
pk));
2116 if (!any_key_parsed) {
2117 error =
"musig(): Must contain key expressions";
2122 DeriveType deriv_type = DeriveType::NON_RANGED;
2123 std::vector<KeyPath> derivation_multipaths;
2126 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
2130 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
2135 deriv_type = ParseDeriveType(deriv_split, dummy);
2136 if (deriv_type == DeriveType::HARDENED_RANGED) {
2137 error =
"musig(): Cannot have hardened child derivation";
2140 bool has_hardened =
false;
2141 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
2142 error =
"musig(): " + error;
2146 error =
"musig(): cannot have hardened derivation steps";
2150 derivation_multipaths.emplace_back();
2155 const auto& clone_providers = [&providers](
size_t length) ->
bool {
2156 for (
auto& multipath_providers : providers) {
2157 if (multipath_providers.size() == 1) {
2158 for (
size_t i = 1; i < length; ++i) {
2159 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
2161 }
else if (multipath_providers.size() != length) {
2170 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
2171 KeyPath& path = derivation_multipaths.at(path_idx);
2172 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2173 pubs.reserve(providers.size());
2174 for (
auto& vec : providers) {
2175 pubs.emplace_back(std::move(vec.at(vec_idx)));
2177 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
2180 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
2181 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
2183 }
else if (max_multipath_len > 1) {
2184 if (!clone_providers(max_multipath_len)) {
2185 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
2188 for (
size_t i = 0; i < max_multipath_len; ++i) {
2190 emplace_final_provider(i, 0);
2192 }
else if (derivation_multipaths.size() > 1) {
2194 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
2195 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
2198 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
2200 emplace_final_provider(i, i);
2204 emplace_final_provider(0, 0);
2210 auto origin_split =
Split(sp,
']');
2211 if (origin_split.size() > 2) {
2212 error =
"Multiple ']' characters found for a single pubkey";
2216 bool apostrophe =
false;
2217 if (origin_split.size() == 1) {
2218 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
2220 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
2221 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
2222 origin_split[0].empty() ?
']' : origin_split[0][0]);
2225 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
2226 if (slash_split[0].size() != 8) {
2227 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
2230 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
2231 if (!
IsHex(fpr_hex)) {
2232 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
2235 auto fpr_bytes =
ParseHex(fpr_hex);
2237 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
2238 assert(fpr_bytes.size() == 4);
2240 std::vector<KeyPath> path;
2241 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
2242 info.
path = path.at(0);
2243 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
2244 if (providers.empty())
return {};
2245 ret.reserve(providers.size());
2246 for (
auto& prov : providers) {
2247 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(prov->m_expr_index, info, std::move(prov), apostrophe));
2259 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2262 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2265 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2267 return key_provider;
2273 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2275 if (
provider.GetKeyOriginByXOnly(xkey, info)) {
2276 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2278 return key_provider;
2286 using Key = uint32_t;
2292 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2294 mutable std::string m_key_parsing_error;
2298 uint32_t& m_expr_index;
2302 : m_out(
out), m_in(in), m_script_ctx(ctx), m_expr_index(key_exp_index) {}
2304 bool KeyCompare(
const Key& a,
const Key& b)
const {
2308 const PubkeyProvider& key_a{*m_keys.at(a).at(0)};
2309 const PubkeyProvider& key_b{*m_keys.at(b).at(0)};
2312 const std::optional<CPubKey> pub_b{key_b.GetPubKey(0,
provider, out_b)};
2313 if (pub_a && pub_b)
return *pub_a < *pub_b;
2316 if (pub_a.has_value() != pub_b.has_value())
return !pub_a.has_value();
2317 return key_a.ToString(PubkeyProvider::StringType::PUBLIC) < key_b.ToString(PubkeyProvider::StringType::PUBLIC);
2321 switch (m_script_ctx) {
2328 std::optional<Key>
FromString(std::span<const char>& in)
const
2331 Key key = m_keys.
size();
2332 auto pk = ParsePubkey(m_expr_index, in,
ParseContext(), *m_out, m_key_parsing_error);
2333 if (
pk.empty())
return {};
2334 m_keys.emplace_back(std::move(
pk));
2338 std::optional<std::string>
ToString(
const Key& key,
bool&)
const
2340 return m_keys.at(key).at(0)->ToString(PubkeyProvider::StringType::PUBLIC);
2343 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2346 Key key = m_keys.size();
2349 std::copy(begin, end, pubkey.
begin());
2350 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2351 m_keys.emplace_back();
2352 m_keys.back().push_back(std::move(pubkey_provider));
2357 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2358 m_keys.emplace_back();
2359 m_keys.back().push_back(std::move(pubkey_provider));
2366 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2368 assert(end - begin == 20);
2371 std::copy(begin, end, hash.
begin());
2375 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2376 Key key = m_keys.
size();
2377 m_keys.emplace_back();
2378 m_keys.back().push_back(std::move(pubkey_provider));
2386 return m_script_ctx;
2392std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2395 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2396 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2397 auto expr =
Expr(sp);
2398 if (
Func(
"pk", expr)) {
2399 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2400 if (pubkeys.empty()) {
2404 for (
auto& pubkey : pubkeys) {
2405 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2409 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2410 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2411 if (pubkeys.empty()) {
2415 for (
auto& pubkey : pubkeys) {
2416 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2420 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2421 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2422 if (pubkeys.empty()) {
2423 error =
strprintf(
"combo(): %s", error);
2426 for (
auto& pubkey : pubkeys) {
2427 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2430 }
else if (
Func(
"combo", expr)) {
2431 error =
"Can only have combo() at top level";
2434 const bool multi =
Func(
"multi", expr);
2435 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2436 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2437 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2438 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2439 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2440 auto threshold =
Expr(expr);
2442 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2443 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2444 thres = *maybe_thres;
2446 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2449 size_t script_size = 0;
2450 size_t max_providers_len = 0;
2451 while (expr.size()) {
2452 if (!
Const(
",", expr)) {
2453 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2456 auto arg =
Expr(expr);
2457 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2462 script_size += pks.at(0)->GetSize() + 1;
2463 max_providers_len = std::max(max_providers_len, pks.size());
2464 providers.emplace_back(std::move(pks));
2472 }
else if (thres < 1) {
2473 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2475 }
else if (thres > providers.size()) {
2476 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2479 if (ctx == ParseScriptContext::TOP) {
2480 if (providers.size() > 3) {
2481 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2485 if (ctx == ParseScriptContext::P2SH) {
2495 for (
auto& vec : providers) {
2496 if (vec.size() == 1) {
2497 for (
size_t i = 1; i < max_providers_len; ++i) {
2498 vec.emplace_back(vec.at(0)->Clone());
2500 }
else if (vec.size() != max_providers_len) {
2501 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2507 for (
size_t i = 0; i < max_providers_len; ++i) {
2509 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2510 pubs.reserve(providers.size());
2511 for (
auto& pub : providers) {
2512 pubs.emplace_back(std::move(pub.at(i)));
2514 if (multi || sortedmulti) {
2515 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2517 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2521 }
else if (multi || sortedmulti) {
2522 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2524 }
else if (multi_a || sortedmulti_a) {
2525 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2528 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2529 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
2530 if (pubkeys.empty()) {
2534 for (
auto& pubkey : pubkeys) {
2535 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2538 }
else if (
Func(
"wpkh", expr)) {
2539 error =
"Can only have wpkh() at top level or inside sh()";
2542 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2543 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
2544 if (descs.empty() || expr.size())
return {};
2545 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2546 ret.reserve(descs.size());
2547 for (
auto& desc : descs) {
2548 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2551 }
else if (
Func(
"sh", expr)) {
2552 error =
"Can only have sh() at top level";
2555 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2556 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
2557 if (descs.empty() || expr.size())
return {};
2558 for (
auto& desc : descs) {
2559 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2562 }
else if (
Func(
"wsh", expr)) {
2563 error =
"Can only have wsh() at top level or inside sh()";
2566 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2569 error =
"Address is not valid";
2572 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2574 }
else if (
Func(
"addr", expr)) {
2575 error =
"Can only have addr() at top level";
2578 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2579 auto arg =
Expr(expr);
2580 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2581 if (internal_keys.empty()) {
2585 size_t max_providers_len = internal_keys.size();
2586 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2587 std::vector<int> depths;
2589 if (!
Const(
",", expr)) {
2590 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2596 std::vector<bool> branches;
2601 while (
Const(
"{", expr)) {
2602 branches.push_back(
false);
2609 auto sarg =
Expr(expr);
2610 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
2611 if (subscripts.back().empty())
return {};
2612 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2613 depths.push_back(branches.size());
2615 while (branches.size() && branches.back()) {
2616 if (!
Const(
"}", expr)) {
2617 error =
strprintf(
"tr(): expected '}' after script expression");
2620 branches.pop_back();
2623 if (branches.size() && !branches.back()) {
2624 if (!
Const(
",", expr)) {
2625 error =
strprintf(
"tr(): expected ',' after script expression");
2628 branches.back() =
true;
2630 }
while (branches.size());
2633 error =
strprintf(
"tr(): expected ')' after script expression");
2641 for (
auto& vec : subscripts) {
2642 if (vec.size() == 1) {
2643 for (
size_t i = 1; i < max_providers_len; ++i) {
2644 vec.emplace_back(vec.at(0)->Clone());
2646 }
else if (vec.size() != max_providers_len) {
2647 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2652 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2653 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2657 while (internal_keys.size() < max_providers_len) {
2658 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2662 for (
size_t i = 0; i < max_providers_len; ++i) {
2664 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2665 this_subs.reserve(subscripts.size());
2666 for (
auto& subs : subscripts) {
2667 this_subs.emplace_back(std::move(subs.at(i)));
2669 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2674 }
else if (
Func(
"tr", expr)) {
2675 error =
"Can only have tr at top level";
2678 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2679 auto arg =
Expr(expr);
2681 error =
strprintf(
"rawtr(): only one key expected.");
2684 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2685 if (output_keys.empty()) {
2686 error =
strprintf(
"rawtr(): %s", error);
2689 for (
auto& pubkey : output_keys) {
2690 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2693 }
else if (
Func(
"rawtr", expr)) {
2694 error =
"Can only have rawtr at top level";
2697 if (ctx == ParseScriptContext::TOP &&
Func(
"unused", expr)) {
2699 auto arg =
Expr(expr);
2701 error =
strprintf(
"unused(): only one key expected");
2704 auto keys = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2705 if (
keys.empty())
return {};
2706 for (
auto& pubkey :
keys) {
2707 if (pubkey->IsRange()) {
2708 error =
"unused(): key cannot be ranged";
2711 ret.emplace_back(std::make_unique<UnusedDescriptor>(std::move(pubkey)));
2714 }
else if (
Func(
"unused", expr)) {
2715 error =
"Can only have unused at top level";
2718 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2719 std::string str(expr.begin(), expr.end());
2721 error =
"Raw script is not hex";
2725 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2727 }
else if (
Func(
"raw", expr)) {
2728 error =
"Can only have raw() at top level";
2734 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2736 if (parser.m_key_parsing_error !=
"") {
2737 error = std::move(parser.m_key_parsing_error);
2741 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2742 error =
"Miniscript expressions can only be used in wsh or tr.";
2745 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2747 const auto* insane_node = &
node.value();
2748 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2749 error = *insane_node->ToString(parser);
2750 if (!insane_node->IsValid()) {
2751 error +=
" is invalid";
2752 }
else if (!
node->IsSane()) {
2753 error +=
" is not sane";
2754 if (!insane_node->IsNonMalleable()) {
2755 error +=
": malleable witnesses exist";
2756 }
else if (insane_node == &
node.value() && !insane_node->NeedsSignature()) {
2757 error +=
": witnesses without signature exist";
2758 }
else if (!insane_node->CheckTimeLocksMix()) {
2759 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2760 }
else if (!insane_node->CheckDuplicateKey()) {
2761 error +=
": contains duplicate public keys";
2762 }
else if (!insane_node->ValidSatisfactions()) {
2763 error +=
": needs witnesses that may exceed resource limits";
2766 error +=
" is not satisfiable";
2775 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2776 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2777 return a.size() < b.size();
2780 for (
auto& vec : parser.m_keys) {
2781 if (vec.size() == 1) {
2782 for (
size_t i = 1; i < num_multipath; ++i) {
2783 vec.emplace_back(vec.at(0)->Clone());
2785 }
else if (vec.size() != num_multipath) {
2786 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2792 for (
size_t i = 0; i < num_multipath; ++i) {
2794 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2795 pubs.reserve(parser.m_keys.size());
2796 for (
auto& pub : parser.m_keys) {
2797 pubs.emplace_back(std::move(pub.at(i)));
2799 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2804 if (ctx == ParseScriptContext::P2SH) {
2805 error =
"A function is needed within P2SH";
2807 }
else if (ctx == ParseScriptContext::P2WSH) {
2808 error =
"A function is needed within P2WSH";
2811 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2818 if (!match)
return {};
2819 std::vector<std::unique_ptr<PubkeyProvider>>
keys;
2820 keys.reserve(match->second.size());
2821 for (
const auto keyspan : match->second) {
2822 if (keyspan.size() != 32)
return {};
2824 if (!key)
return {};
2825 keys.push_back(std::move(key));
2827 return std::make_unique<MultiADescriptor>(match->first, std::move(
keys));
2835 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx,
provider),
true);
2838 if (ctx == ParseScriptContext::P2TR) {
2843 std::vector<std::vector<unsigned char>>
data;
2846 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2848 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2849 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2852 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2856 if (
provider.GetPubKey(keyid, pubkey)) {
2857 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2858 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2866 if (
provider.GetPubKey(keyid, pubkey)) {
2867 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH,
provider)) {
2868 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2872 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2874 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2875 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2877 if (
auto pubkey_provider = InferPubkey(pubkey, ctx,
provider)) {
2878 providers.push_back(std::move(pubkey_provider));
2884 if (ok)
return std::make_unique<MultisigDescriptor>((
int)
data[0][0], std::move(providers));
2890 if (
provider.GetCScript(scriptid, subscript)) {
2891 auto sub = InferScript(subscript, ParseScriptContext::P2SH,
provider);
2892 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2898 if (
provider.GetCScript(scriptid, subscript)) {
2899 auto sub = InferScript(subscript, ParseScriptContext::P2WSH,
provider);
2900 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2909 if (
provider.GetTaprootSpendData(pubkey, tap)) {
2915 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2916 std::vector<int> depths;
2917 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2918 std::unique_ptr<DescriptorImpl> subdesc;
2926 subscripts.push_back(std::move(subdesc));
2927 depths.push_back(depth);
2932 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2938 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR,
provider);
2940 return std::make_unique<RawTRDescriptor>(std::move(key));
2945 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2947 uint32_t key_exp_index = 0;
2948 KeyParser parser(
nullptr, &
provider, script_ctx, key_exp_index);
2951 std::vector<std::unique_ptr<PubkeyProvider>>
keys;
2952 keys.reserve(parser.m_keys.size());
2953 for (
auto& key : parser.m_keys) {
2954 keys.emplace_back(std::move(key.at(0)));
2956 return std::make_unique<MiniscriptDescriptor>(std::move(
keys), std::move(*
node));
2962 if (ctx != ParseScriptContext::TOP)
return nullptr;
2967 return std::make_unique<AddressDescriptor>(std::move(dest));
2971 return std::make_unique<RawDescriptor>(
script);
2978bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2980 auto check_split =
Split(sp,
'#');
2981 if (check_split.size() > 2) {
2982 error =
"Multiple '#' symbols";
2985 if (check_split.size() == 1 && require_checksum){
2986 error =
"Missing checksum";
2989 if (check_split.size() == 2) {
2990 if (check_split[1].size() != 8) {
2991 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2995 auto checksum = DescriptorChecksum(check_split[0]);
2996 if (checksum.empty()) {
2997 error =
"Invalid characters in payload";
3000 if (check_split.size() == 2) {
3001 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
3002 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
3006 if (out_checksum) *out_checksum = std::move(checksum);
3007 sp = check_split[0];
3013 std::span<const char> sp{descriptor};
3015 uint32_t key_exp_index = 0;
3017 if (sp.empty() && !
ret.empty()) {
3018 std::vector<std::unique_ptr<Descriptor>> descs;
3019 descs.reserve(
ret.size());
3020 for (
auto& r :
ret) {
3021 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
3032 std::span<const char> sp{descriptor};
3044 std::string desc_str = desc.
ToString(
true);
3058 xpubs[der_index] = xpub;
3078 const auto& der_it = key_exp_it->second.find(der_index);
3079 if (der_it == key_exp_it->second.end())
return false;
3080 xpub = der_it->second;
3098 if (xpub != parent_xpub_pair.second) {
3099 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
3107 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
3110 if (xpub != derived_xpub_pair.second) {
3111 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
3115 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3116 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
3122 if (xpub != lh_xpub_pair.second) {
3123 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)
util::Expected< KeyPathElement, std::string > ParseKeyPathElement(std::span< const char > elem)
Parse a single key path element like "0", "0'", or "0h".
bool HasHardenedDerivation(std::span< const uint32_t > keypath)
Whether a parsed HD keypath contains at least one hardened derivation step.
static constexpr uint32_t BIP32_HARDENED_FLAG
BIP32 hardened derivation flag (2^31)
#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.
KeyFingerprint fingerprint() const
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.
bool GetKeyByXOnly(const XOnlyPubKey &pubkey, CKey &key) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
virtual bool GetKey(const CKeyID &address, CKey &key) 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()
A node in a miniscript expression.
The util::Expected class provides a standard way for low-level functions to return either error value...
The util::Unexpected class represents an unexpected value stored in util::Expected.
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
constexpr 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.
constexpr uint8_t TAPROOT_LEAF_TAPSCRIPT
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.
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
std::optional< Node< typename Ctx::Key > > FromScript(const CScript &script, const Ctx &ctx)
void ForEachNode(const Node< Key > &root, Fn &&fn)
Unordered traversal of a miniscript node tree.
std::optional< Node< typename Ctx::Key > > FromString(const std::string &str, const Ctx &ctx)
@ OLDER
[n] OP_CHECKSEQUENCEVERIFY
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::vector< T > Split(std::span< const char > sp LIFETIMEBOUND, std::string_view separators, bool include_sep=false)
Split a string on any char found in separators, returning a vector.
std::string ToString(const T &t)
Locale-independent version of std::to_string.
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.
std::optional< OutputType > OutputTypeFromDestination(const CTxDestination &dest)
Get the OutputType for a CTxDestination.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
bool CheckChecksum(std::span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
std::vector< std::unique_ptr< Descriptor > > Parse(std::string_view descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
uint256 CompatDescriptorHash(const Descriptor &desc)
Hash of the COMPAT string representation of the descriptor that is not supposed to change over time.
util::Expected< void, std::string > CheckDescriptorRangeBounds(int64_t low, int64_t high)
Validate the numeric bounds of a descriptor key-expression range [low, high] (high inclusive).
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
constexpr unsigned int MAX_SCRIPT_ELEMENT_SIZE
constexpr int MAX_PUBKEYS_PER_MULTISIG
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
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::vector< std::string > Warnings() const =0
Semantic/safety warnings (includes subdescriptors).
virtual std::string ToCanonicalString() const =0
Convert the descriptor to the canonical string.
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 HasScripts() const =0
Whether this descriptor produces any scripts with the Expand functions.
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 uint32_t GetMaxKeyExpr() const =0
Get the maximum key expression index.
virtual bool ToPrivateString(const SigningProvider &provider, std::string &out) const =0
Convert the descriptor to a private string.
virtual bool HavePrivateKeys(const SigningProvider &provider) const =0
Whether the given provider has all private keys required by this descriptor.
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, std::pair< CPubKey, KeyOriginInfo > > origins
std::map< CKeyID, CPubKey > pubkeys
std::map< CKeyID, CKey > keys
KeyFingerprint fingerprint
First 32 bits of the Hash160 of the public key at the root of the path.
std::vector< uint32_t > path
XOnlyPubKey internal_key
The BIP341 internal key.
std::vector< uint16_t > keys
FuzzedDataProvider provider
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.