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()) {
649 extpub.
pubkey = m_aggregate_pubkey.value();
651 m_aggregate_provider = std::make_unique<BIP32PubkeyProvider>(m_expr_index, extpub, m_path, m_derive,
false);
653 m_aggregate_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, m_aggregate_pubkey.value(),
false);
658 std::vector<CPubKey> pubkeys;
659 for (
const auto& prov : m_participants) {
660 std::optional<CPubKey> pub = prov->GetPubKey(pos, arg,
out, read_cache, write_cache);
661 if (!pub)
return std::nullopt;
662 pubkeys.emplace_back(*pub);
664 std::sort(pubkeys.begin(), pubkeys.end());
667 if (m_aggregate_provider) {
671 std::optional<CPubKey> pub = m_aggregate_provider->GetPubKey(pos, dummy,
out, read_cache, write_cache);
672 if (!pub)
return std::nullopt;
674 out.aggregate_pubkeys.emplace(m_aggregate_pubkey.value(), pubkeys);
676 if (!
Assume(m_ranged_participants) || !
Assume(m_path.empty()))
return std::nullopt;
679 if (!aggregate_pubkey)
return std::nullopt;
680 pubout = *aggregate_pubkey;
682 std::unique_ptr<ConstPubkeyProvider> this_agg_provider = std::make_unique<ConstPubkeyProvider>(m_expr_index, aggregate_pubkey.value(),
false);
683 this_agg_provider->GetPubKey(0, dummy,
out, read_cache, write_cache);
684 out.aggregate_pubkeys.emplace(pubout, pubkeys);
690 bool IsRange()
const override {
return IsRangedDerivation() || m_ranged_participants; }
692 size_t GetSize()
const override {
return 32; }
694 std::string
ToString(StringType type=StringType::PUBLIC)
const override
696 std::string
out =
"musig(";
697 for (
size_t i = 0; i < m_participants.size(); ++i) {
698 const auto& pubkey = m_participants.at(i);
700 out += pubkey->ToString(type);
704 if (IsRangedDerivation()) {
711 bool any_privkeys =
false;
713 for (
size_t i = 0; i < m_participants.size(); ++i) {
714 const auto& pubkey = m_participants.at(i);
717 if (pubkey->ToPrivateString(arg, tmp)) {
721 out += pubkey->ToString();
726 if (IsRangedDerivation()) {
729 if (!any_privkeys)
out.clear();
735 for (
size_t i = 0; i < m_participants.size(); ++i) {
736 const auto& pubkey = m_participants.at(i);
739 if (!pubkey->ToNormalizedString(arg, tmp, cache)) {
746 if (IsRangedDerivation()) {
757 for (
const auto& prov : m_participants) {
758 prov->GetPrivKey(pos, arg,
out);
767 std::optional<CPubKey> GetRootPubKey()
const override
771 std::optional<CExtPubKey> GetRootExtPubKey()
const override
776 std::unique_ptr<PubkeyProvider> Clone()
const override
778 std::vector<std::unique_ptr<PubkeyProvider>> providers;
779 providers.reserve(m_participants.size());
780 for (
const std::unique_ptr<PubkeyProvider>& p : m_participants) {
781 providers.emplace_back(p->Clone());
783 return std::make_unique<MuSigPubkeyProvider>(m_expr_index, std::move(providers), m_path, m_derive);
785 bool IsBIP32()
const override
788 return std::all_of(m_participants.begin(), m_participants.end(), [](
const auto& pubkey) { return pubkey->IsBIP32(); });
797 const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
799 const std::string m_name;
805 const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
808 virtual std::string ToStringExtra()
const {
return ""; }
820 virtual std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& pubkeys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const = 0;
823 DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys,
const std::string&
name) : m_pubkey_args(
std::move(pubkeys)), m_name(
name), m_subdescriptor_args() {}
824 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))) {}
825 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)) {}
827 enum class StringType
838 for (
const auto& arg : m_subdescriptor_args) {
839 if (!arg->IsSolvable())
return false;
847 for (
const auto& pubkey : m_pubkey_args) {
848 if (pubkey->IsRange())
return true;
850 for (
const auto& arg : m_subdescriptor_args) {
851 if (arg->IsRange())
return true;
860 for (
const auto& scriptarg : m_subdescriptor_args) {
861 if (pos++)
ret +=
",";
863 if (!scriptarg->ToStringHelper(arg, tmp, type, cache))
return false;
872 std::string extra = ToStringExtra();
873 size_t pos = extra.size() > 0 ? 1 : 0;
874 std::string
ret = m_name +
"(" + extra;
875 for (
const auto& pubkey : m_pubkey_args) {
876 if (pos++)
ret +=
",";
879 case StringType::NORMALIZED:
880 if (!pubkey->ToNormalizedString(*arg, tmp, cache))
return false;
882 case StringType::PRIVATE:
883 if (!pubkey->ToPrivateString(*arg, tmp))
return false;
885 case StringType::PUBLIC:
886 tmp = pubkey->ToString();
888 case StringType::COMPAT:
889 tmp = pubkey->ToString(PubkeyProvider::StringType::COMPAT);
894 std::string subscript;
895 if (!ToStringSubScriptHelper(arg, subscript, type, cache))
return false;
896 if (pos && subscript.size())
ret +=
',';
897 out = std::move(
ret) + std::move(subscript) +
")";
901 std::string
ToString(
bool compat_format)
const final
904 ToStringHelper(
nullptr,
ret, compat_format ? StringType::COMPAT : StringType::PUBLIC);
905 return AddChecksum(
ret);
910 bool ret = ToStringHelper(&arg,
out, StringType::PRIVATE);
917 bool ret = ToStringHelper(&arg,
out, StringType::NORMALIZED, cache);
926 std::vector<CPubKey> pubkeys;
927 pubkeys.reserve(m_pubkey_args.size());
930 for (
const auto& p : m_pubkey_args) {
931 std::optional<CPubKey> pubkey = p->
GetPubKey(pos, arg, subprovider, read_cache, write_cache);
932 if (!pubkey)
return false;
933 pubkeys.push_back(pubkey.value());
935 std::vector<CScript> subscripts;
936 for (
const auto& subarg : m_subdescriptor_args) {
937 std::vector<CScript> outscripts;
938 if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache))
return false;
939 assert(outscripts.size() == 1);
940 subscripts.emplace_back(std::move(outscripts[0]));
942 out.Merge(std::move(subprovider));
944 output_scripts = MakeScripts(pubkeys, std::span{subscripts},
out);
950 return ExpandHelper(pos, provider,
nullptr, output_scripts,
out, write_cache);
961 for (
const auto& p : m_pubkey_args) {
962 p->GetPrivKey(pos, provider,
out);
964 for (
const auto& arg : m_subdescriptor_args) {
965 arg->ExpandPrivate(pos, provider,
out);
969 std::optional<OutputType>
GetOutputType()
const override {
return std::nullopt; }
971 std::optional<int64_t>
ScriptSize()
const override {
return {}; }
978 virtual std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const {
return {}; }
985 void GetPubKeys(std::set<CPubKey>& pubkeys, std::set<CExtPubKey>& ext_pubs)
const override
987 for (
const auto& p : m_pubkey_args) {
988 std::optional<CPubKey> pub = p->GetRootPubKey();
989 if (pub) pubkeys.insert(*pub);
990 std::optional<CExtPubKey> ext_pub = p->GetRootExtPubKey();
991 if (ext_pub) ext_pubs.insert(*ext_pub);
993 for (
const auto& arg : m_subdescriptor_args) {
994 arg->GetPubKeys(pubkeys, ext_pubs);
998 virtual std::unique_ptr<DescriptorImpl> Clone()
const = 0;
1002class AddressDescriptor final :
public DescriptorImpl
1006 std::string ToStringExtra()
const override {
return EncodeDestination(m_destination); }
1009 AddressDescriptor(
CTxDestination destination) : DescriptorImpl({},
"addr"), m_destination(std::move(destination)) {}
1010 bool IsSolvable() const final {
return false; }
1016 bool IsSingleType() const final {
return true; }
1017 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1020 std::unique_ptr<DescriptorImpl> Clone()
const override
1022 return std::make_unique<AddressDescriptor>(m_destination);
1027class RawDescriptor final :
public DescriptorImpl
1031 std::string ToStringExtra()
const override {
return HexStr(m_script); }
1032 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript>,
FlatSigningProvider&)
const override {
return Vector(m_script); }
1035 bool IsSolvable() const final {
return false; }
1043 bool IsSingleType() const final {
return true; }
1044 bool ToPrivateString(
const SigningProvider& arg, std::string&
out)
const final {
return false; }
1046 std::optional<int64_t> ScriptSize()
const override {
return m_script.size(); }
1048 std::unique_ptr<DescriptorImpl> Clone()
const override
1050 return std::make_unique<RawDescriptor>(m_script);
1055class PKDescriptor final :
public DescriptorImpl
1060 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1070 PKDescriptor(std::unique_ptr<PubkeyProvider> prov,
bool xonly =
false) : DescriptorImpl(
Vector(
std::move(prov)),
"pk"), m_xonly(xonly) {}
1071 bool IsSingleType() const final {
return true; }
1073 std::optional<int64_t> ScriptSize()
const override {
1074 return 1 + (m_xonly ? 32 : m_pubkey_args[0]->GetSize()) + 1;
1077 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1078 const auto ecdsa_sig_size = use_max_sig ? 72 : 71;
1079 return 1 + (m_xonly ? 65 : ecdsa_sig_size);
1082 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1086 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1; }
1088 std::unique_ptr<DescriptorImpl> Clone()
const override
1090 return std::make_unique<PKDescriptor>(m_pubkey_args.at(0)->Clone(), m_xonly);
1095class PKHDescriptor final :
public DescriptorImpl
1098 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1100 CKeyID id = keys[0].GetID();
1104 PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"pkh") {}
1106 bool IsSingleType() const final {
return true; }
1108 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 1 + 20 + 1 + 1; }
1110 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1111 const auto sig_size = use_max_sig ? 72 : 71;
1112 return 1 +
sig_size + 1 + m_pubkey_args[0]->GetSize();
1115 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1119 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1121 std::unique_ptr<DescriptorImpl> Clone()
const override
1123 return std::make_unique<PKHDescriptor>(m_pubkey_args.at(0)->Clone());
1128class WPKHDescriptor final :
public DescriptorImpl
1131 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override
1133 CKeyID id = keys[0].GetID();
1137 WPKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"wpkh") {}
1139 bool IsSingleType() const final {
return true; }
1141 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20; }
1143 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1144 const auto sig_size = use_max_sig ? 72 : 71;
1148 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1149 return MaxSatSize(use_max_sig);
1152 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 2; }
1154 std::unique_ptr<DescriptorImpl> Clone()
const override
1156 return std::make_unique<WPKHDescriptor>(m_pubkey_args.at(0)->Clone());
1161class ComboDescriptor final :
public DescriptorImpl
1164 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&
out)
const override
1166 std::vector<CScript>
ret;
1167 CKeyID id = keys[0].GetID();
1170 if (keys[0].IsCompressed()) {
1173 ret.emplace_back(p2wpkh);
1179 ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(
Vector(
std::move(prov)),
"combo") {}
1180 bool IsSingleType() const final {
return false; }
1181 std::unique_ptr<DescriptorImpl> Clone()
const override
1183 return std::make_unique<ComboDescriptor>(m_pubkey_args.at(0)->Clone());
1188class MultisigDescriptor final :
public DescriptorImpl
1190 const int m_threshold;
1191 const bool m_sorted;
1193 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1194 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1196 std::vector<CPubKey> sorted_keys(keys);
1197 std::sort(sorted_keys.begin(), sorted_keys.end());
1203 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) {}
1204 bool IsSingleType() const final {
return true; }
1206 std::optional<int64_t> ScriptSize()
const override {
1207 const auto n_keys = m_pubkey_args.size();
1208 auto op = [](int64_t acc,
const std::unique_ptr<PubkeyProvider>&
pk) {
return acc + 1 +
pk->GetSize();};
1209 const auto pubkeys_size{std::accumulate(m_pubkey_args.begin(), m_pubkey_args.end(), int64_t{0}, op)};
1213 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1214 const auto sig_size = use_max_sig ? 72 : 71;
1215 return (1 + (1 +
sig_size) * m_threshold);
1218 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1222 std::optional<int64_t> MaxSatisfactionElems()
const override {
return 1 + m_threshold; }
1224 std::unique_ptr<DescriptorImpl> Clone()
const override
1226 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1227 providers.reserve(m_pubkey_args.size());
1228 std::transform(m_pubkey_args.begin(), m_pubkey_args.end(), providers.begin(), [](
const std::unique_ptr<PubkeyProvider>& p) { return p->Clone(); });
1229 return std::make_unique<MultisigDescriptor>(m_threshold, std::move(providers), m_sorted);
1234class MultiADescriptor final :
public DescriptorImpl
1236 const int m_threshold;
1237 const bool m_sorted;
1239 std::string ToStringExtra()
const override {
return strprintf(
"%i", m_threshold); }
1240 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript>,
FlatSigningProvider&)
const override {
1242 std::vector<XOnlyPubKey> xkeys;
1243 xkeys.reserve(keys.size());
1244 for (
const auto& key : keys) xkeys.emplace_back(key);
1245 if (m_sorted) std::sort(xkeys.begin(), xkeys.end());
1247 for (
size_t i = 1; i < keys.size(); ++i) {
1254 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) {}
1255 bool IsSingleType() const final {
return true; }
1257 std::optional<int64_t> ScriptSize()
const override {
1258 const auto n_keys = m_pubkey_args.size();
1262 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1263 return (1 + 65) * m_threshold + (m_pubkey_args.size() - m_threshold);
1266 std::optional<int64_t> MaxSatisfactionElems()
const override {
return m_pubkey_args.size(); }
1268 std::unique_ptr<DescriptorImpl> Clone()
const override
1270 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1271 providers.reserve(m_pubkey_args.size());
1272 for (
const auto& arg : m_pubkey_args) {
1273 providers.push_back(arg->Clone());
1275 return std::make_unique<MultiADescriptor>(m_threshold, std::move(providers), m_sorted);
1280class SHDescriptor final :
public DescriptorImpl
1283 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1286 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1293 SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"sh") {}
1297 assert(m_subdescriptor_args.size() == 1);
1301 bool IsSingleType() const final {
return true; }
1303 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 20 + 1; }
1305 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1306 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1307 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1311 if (
IsSegwit())
return subscript_weight + *sat_size;
1318 std::optional<int64_t> MaxSatisfactionElems()
const override {
1319 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1323 std::unique_ptr<DescriptorImpl> Clone()
const override
1325 return std::make_unique<SHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1330class WSHDescriptor final :
public DescriptorImpl
1333 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>&, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1336 if (
ret.size())
out.scripts.emplace(
CScriptID(scripts[0]), scripts[0]);
1340 WSHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc),
"wsh") {}
1342 bool IsSingleType() const final {
return true; }
1344 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1346 std::optional<int64_t> MaxSatSize(
bool use_max_sig)
const override {
1347 if (
const auto sat_size = m_subdescriptor_args[0]->MaxSatSize(use_max_sig)) {
1348 if (
const auto subscript_size = m_subdescriptor_args[0]->ScriptSize()) {
1355 std::optional<int64_t> MaxSatisfactionWeight(
bool use_max_sig)
const override {
1356 return MaxSatSize(use_max_sig);
1359 std::optional<int64_t> MaxSatisfactionElems()
const override {
1360 if (
const auto sub_elems = m_subdescriptor_args[0]->MaxSatisfactionElems())
return 1 + *sub_elems;
1364 std::unique_ptr<DescriptorImpl> Clone()
const override
1366 return std::make_unique<WSHDescriptor>(m_subdescriptor_args.at(0)->Clone());
1371class TRDescriptor final :
public DescriptorImpl
1373 std::vector<int> m_depths;
1375 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1378 assert(m_depths.size() == scripts.size());
1379 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1383 assert(keys.size() == 1);
1385 if (!xpk.IsFullyValid())
return {};
1388 out.tr_trees[output] = builder;
1393 if (m_depths.empty())
return true;
1394 std::vector<bool> path;
1395 for (
size_t pos = 0; pos < m_depths.size(); ++pos) {
1396 if (pos)
ret +=
',';
1397 while ((
int)path.size() <= m_depths[pos]) {
1398 if (path.size())
ret +=
'{';
1399 path.push_back(
false);
1402 if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache))
return false;
1404 while (!path.empty() && path.back()) {
1405 if (path.size() > 1)
ret +=
'}';
1408 if (!path.empty()) path.back() =
true;
1413 TRDescriptor(std::unique_ptr<PubkeyProvider> internal_key, std::vector<std::unique_ptr<DescriptorImpl>> descs, std::vector<int> depths) :
1414 DescriptorImpl(
Vector(
std::move(internal_key)),
std::move(descs),
"tr"), m_depths(
std::move(depths))
1416 assert(m_subdescriptor_args.size() == m_depths.size());
1419 bool IsSingleType() const final {
return true; }
1421 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1423 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1428 std::optional<int64_t> MaxSatisfactionElems()
const override {
1433 std::unique_ptr<DescriptorImpl> Clone()
const override
1435 std::vector<std::unique_ptr<DescriptorImpl>> subdescs;
1436 subdescs.reserve(m_subdescriptor_args.size());
1437 std::transform(m_subdescriptor_args.begin(), m_subdescriptor_args.end(), subdescs.begin(), [](
const std::unique_ptr<DescriptorImpl>& d) { return d->Clone(); });
1438 return std::make_unique<TRDescriptor>(m_pubkey_args.at(0)->Clone(), std::move(subdescs), m_depths);
1452 const std::vector<CPubKey>& m_keys;
1459 uint160 GetHash160(uint32_t key)
const {
1463 return m_keys[key].GetID();
1469 std::vector<unsigned char> ToPKBytes(uint32_t key)
const {
1472 return {m_keys[key].begin(), m_keys[key].end()};
1475 return {xonly_pubkey.
begin(), xonly_pubkey.end()};
1478 std::vector<unsigned char> ToPKHBytes(uint32_t key)
const {
1479 auto id = GetHash160(key);
1480 return {
id.begin(),
id.end()};
1491 const std::vector<std::unique_ptr<PubkeyProvider>>& m_pubkeys;
1497 : m_arg(arg), m_pubkeys(pubkeys), m_private(priv) {}
1499 std::optional<std::string>
ToString(uint32_t key)
const
1503 if (!m_pubkeys[key]->ToPrivateString(*m_arg,
ret))
return {};
1505 ret = m_pubkeys[key]->ToString();
1511class MiniscriptDescriptor final :
public DescriptorImpl
1517 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
1520 const auto script_ctx{
m_node->GetMsCtx()};
1521 for (
const auto& key : keys) {
1525 provider.
pubkeys.emplace(key.GetID(), key);
1528 return Vector(
m_node->ToScript(ScriptMaker(keys, script_ctx)));
1535 bool ToStringHelper(
const SigningProvider* arg, std::string&
out,
const StringType type,
1538 if (
const auto res =
m_node->ToString(StringMaker(arg, m_pubkey_args, type == StringType::PRIVATE))) {
1545 bool IsSolvable()
const override {
return true; }
1546 bool IsSingleType() const final {
return true; }
1548 std::optional<int64_t> ScriptSize()
const override {
return m_node->ScriptSize(); }
1550 std::optional<int64_t> MaxSatSize(
bool)
const override {
1552 return m_node->GetWitnessSize();
1555 std::optional<int64_t> MaxSatisfactionElems()
const override {
1556 return m_node->GetStackSize();
1559 std::unique_ptr<DescriptorImpl> Clone()
const override
1561 std::vector<std::unique_ptr<PubkeyProvider>> providers;
1562 providers.reserve(m_pubkey_args.size());
1563 for (
const auto& arg : m_pubkey_args) {
1564 providers.push_back(arg->Clone());
1566 return std::make_unique<MiniscriptDescriptor>(std::move(providers),
m_node->Clone());
1571class RawTRDescriptor final :
public DescriptorImpl
1574 std::vector<CScript> MakeScripts(
const std::vector<CPubKey>& keys, std::span<const CScript> scripts,
FlatSigningProvider&
out)
const override
1576 assert(keys.size() == 1);
1578 if (!xpk.IsFullyValid())
return {};
1583 RawTRDescriptor(std::unique_ptr<PubkeyProvider> output_key) : DescriptorImpl(
Vector(
std::move(output_key)),
"rawtr") {}
1585 bool IsSingleType() const final {
return true; }
1587 std::optional<int64_t> ScriptSize()
const override {
return 1 + 1 + 32; }
1589 std::optional<int64_t> MaxSatisfactionWeight(
bool)
const override {
1594 std::optional<int64_t> MaxSatisfactionElems()
const override {
1599 std::unique_ptr<DescriptorImpl> Clone()
const override
1601 return std::make_unique<RawTRDescriptor>(m_pubkey_args.at(0)->Clone());
1609enum class ParseScriptContext {
1618std::optional<uint32_t> ParseKeyPathNum(std::span<const char> elem,
bool& apostrophe, std::string& error,
bool& has_hardened)
1620 bool hardened =
false;
1621 if (elem.size() > 0) {
1622 const char last = elem[elem.size() - 1];
1623 if (last ==
'\'' || last ==
'h') {
1624 elem = elem.first(elem.size() - 1);
1626 apostrophe = last ==
'\'';
1629 const auto p{ToIntegral<uint32_t>(std::string_view{elem.begin(), elem.end()})};
1631 error =
strprintf(
"Key path value '%s' is not a valid uint32", std::string_view{elem.begin(), elem.end()});
1632 return std::nullopt;
1633 }
else if (*p > 0x7FFFFFFFUL) {
1634 error =
strprintf(
"Key path value %u is out of range", *p);
1635 return std::nullopt;
1637 has_hardened = has_hardened || hardened;
1639 return std::make_optional<uint32_t>(*p | (((uint32_t)hardened) << 31));
1652[[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)
1655 struct MultipathSubstitutes {
1656 size_t placeholder_index;
1657 std::vector<uint32_t>
values;
1659 std::optional<MultipathSubstitutes> substitutes;
1660 has_hardened =
false;
1662 for (
size_t i = 1; i <
split.size(); ++i) {
1663 const std::span<const char>& elem =
split[i];
1666 if (!elem.empty() && elem.front() ==
'<' && elem.back() ==
'>') {
1667 if (!allow_multipath) {
1668 error =
strprintf(
"Key path value '%s' specifies multipath in a section where multipath is not allowed", std::string(elem.begin(), elem.end()));
1672 error =
"Multiple multipath key path specifiers found";
1677 std::vector<std::span<const char>> nums =
Split(std::span(elem.begin()+1, elem.end()-1),
";");
1678 if (nums.size() < 2) {
1679 error =
"Multipath key path specifiers must have at least two items";
1683 substitutes.emplace();
1684 std::unordered_set<uint32_t> seen_substitutes;
1685 for (
const auto& num : nums) {
1686 const auto& op_num = ParseKeyPathNum(num, apostrophe, error, has_hardened);
1687 if (!op_num)
return false;
1688 auto [
_, inserted] = seen_substitutes.insert(*op_num);
1690 error =
strprintf(
"Duplicated key path value %u in multipath specifier", *op_num);
1693 substitutes->values.emplace_back(*op_num);
1696 path.emplace_back();
1697 substitutes->placeholder_index = path.size() - 1;
1699 const auto& op_num = ParseKeyPathNum(elem, apostrophe, error, has_hardened);
1700 if (!op_num)
return false;
1701 path.emplace_back(*op_num);
1706 out.emplace_back(std::move(path));
1709 for (uint32_t substitute : substitutes->values) {
1710 KeyPath branch_path = path;
1711 branch_path[substitutes->placeholder_index] = substitute;
1712 out.emplace_back(std::move(branch_path));
1718[[nodiscard]]
bool ParseKeyPath(
const std::vector<std::span<const char>>&
split, std::vector<KeyPath>&
out,
bool& apostrophe, std::string& error,
bool allow_multipath)
1721 return ParseKeyPath(
split,
out, apostrophe, error, allow_multipath, dummy);
1724static DeriveType ParseDeriveType(std::vector<std::span<const char>>&
split,
bool& apostrophe)
1726 DeriveType type = DeriveType::NO;
1727 if (std::ranges::equal(
split.back(), std::span{
"*"}.first(1))) {
1729 type = DeriveType::UNHARDENED;
1730 }
else if (std::ranges::equal(
split.back(), std::span{
"*'"}.first(2)) || std::ranges::equal(
split.back(), std::span{
"*h"}.first(2))) {
1731 apostrophe = std::ranges::equal(
split.back(), std::span{
"*'"}.first(2));
1733 type = DeriveType::HARDENED;
1739std::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)
1741 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1742 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
1744 std::string str(
split[0].begin(),
split[0].end());
1745 if (str.size() == 0) {
1746 error =
"No key provided";
1750 error =
strprintf(
"Key '%s' is invalid due to whitespace", str);
1753 if (
split.size() == 1) {
1757 if (pubkey.IsValid() && !pubkey.IsValidNonHybrid()) {
1758 error =
"Hybrid public keys are not allowed";
1761 if (pubkey.IsFullyValid()) {
1762 if (permit_uncompressed || pubkey.IsCompressed()) {
1763 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
false));
1766 error =
"Uncompressed keys are not allowed";
1769 }
else if (
data.size() == 32 && ctx == ParseScriptContext::P2TR) {
1770 unsigned char fullkey[33] = {0x02};
1771 std::copy(
data.begin(),
data.end(), fullkey + 1);
1772 pubkey.Set(std::begin(fullkey), std::end(fullkey));
1773 if (pubkey.IsFullyValid()) {
1774 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey,
true));
1778 error =
strprintf(
"Pubkey '%s' is invalid", str);
1785 out.keys.emplace(pubkey.
GetID(), key);
1786 ret.emplace_back(std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR));
1789 error =
"Uncompressed keys are not allowed";
1797 error =
strprintf(
"key '%s' is not valid", str);
1800 std::vector<KeyPath> paths;
1801 DeriveType type = ParseDeriveType(
split, apostrophe);
1802 if (!ParseKeyPath(
split, paths, apostrophe, error,
true))
return {};
1804 extpubkey = extkey.
Neuter();
1807 for (
auto& path : paths) {
1808 ret.emplace_back(std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe));
1815std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index,
const std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
1817 std::vector<std::unique_ptr<PubkeyProvider>>
ret;
1822 std::span<const char> span = sp;
1823 if (
Const(
"musig(", span,
false)) {
1824 if (ctx != ParseScriptContext::P2TR) {
1825 error =
"musig() is only allowed in tr() and rawtr()";
1832 if (
split.size() > 2) {
1833 error =
"Too many ')' in musig() expression";
1836 std::span<const char> expr(
split.at(0).begin(),
split.at(0).end());
1837 if (!
Func(
"musig", expr)) {
1838 error =
"Invalid musig() expression";
1843 bool any_ranged =
false;
1844 bool all_bip32 =
true;
1845 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
1846 bool any_key_parsed =
true;
1847 size_t max_multipath_len = 0;
1848 while (expr.size()) {
1849 if (!any_key_parsed && !
Const(
",", expr)) {
1850 error =
strprintf(
"musig(): expected ',', got '%c'", expr[0]);
1853 any_key_parsed =
false;
1854 auto arg =
Expr(expr);
1855 auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG,
out, error);
1857 error =
strprintf(
"musig(): %s", error);
1861 any_ranged = any_ranged ||
pk.at(0)->IsRange();
1862 all_bip32 = all_bip32 &&
pk.at(0)->IsBIP32();
1864 max_multipath_len = std::max(max_multipath_len,
pk.size());
1866 providers.emplace_back(std::move(
pk));
1869 if (any_key_parsed) {
1870 error =
"musig(): Must contain key expressions";
1875 DeriveType deriv_type = DeriveType::NO;
1876 std::vector<KeyPath> derivation_multipaths;
1879 error =
"musig(): derivation requires all participants to be xpubs or xprvs";
1883 error =
"musig(): Cannot have ranged participant keys if musig() also has derivation";
1888 deriv_type = ParseDeriveType(deriv_split, dummy);
1889 if (deriv_type == DeriveType::HARDENED) {
1890 error =
"musig(): Cannot have hardened child derivation";
1893 bool has_hardened =
false;
1894 if (!ParseKeyPath(deriv_split, derivation_multipaths, dummy, error,
true, has_hardened)) {
1895 error =
"musig(): " + error;
1899 error =
"musig(): cannot have hardened derivation steps";
1903 derivation_multipaths.emplace_back();
1908 const auto& clone_providers = [&providers](
size_t length) ->
bool {
1909 for (
auto& multipath_providers : providers) {
1910 if (multipath_providers.size() == 1) {
1911 for (
size_t i = 1; i < length; ++i) {
1912 multipath_providers.emplace_back(multipath_providers.at(0)->Clone());
1914 }
else if (multipath_providers.size() != length) {
1923 const auto& emplace_final_provider = [&
ret, &key_exp_index, &deriv_type, &derivation_multipaths, &providers](
size_t vec_idx,
size_t path_idx) ->
void {
1924 KeyPath& path = derivation_multipaths.at(path_idx);
1925 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
1926 pubs.reserve(providers.size());
1927 for (
auto& vec : providers) {
1928 pubs.emplace_back(std::move(vec.at(vec_idx)));
1930 ret.emplace_back(std::make_unique<MuSigPubkeyProvider>(key_exp_index, std::move(pubs), path, deriv_type));
1933 if (max_multipath_len > 1 && derivation_multipaths.size() > 1) {
1934 error =
"musig(): Cannot have multipath participant keys if musig() is also multipath";
1936 }
else if (max_multipath_len > 1) {
1937 if (!clone_providers(max_multipath_len)) {
1938 error =
strprintf(
"musig(): Multipath derivation paths have mismatched lengths");
1941 for (
size_t i = 0; i < max_multipath_len; ++i) {
1943 emplace_final_provider(i, 0);
1945 }
else if (derivation_multipaths.size() > 1) {
1947 if (!
Assume(clone_providers(derivation_multipaths.size()))) {
1948 error =
"musig(): Multipath derivation path with multipath participants is disallowed";
1951 for (
size_t i = 0; i < derivation_multipaths.size(); ++i) {
1953 emplace_final_provider(i, i);
1957 emplace_final_provider(0, 0);
1962 auto origin_split =
Split(sp,
']');
1963 if (origin_split.size() > 2) {
1964 error =
"Multiple ']' characters found for a single pubkey";
1968 bool apostrophe =
false;
1969 if (origin_split.size() == 1) {
1970 return ParsePubkeyInner(key_exp_index, origin_split[0], ctx,
out, apostrophe, error);
1972 if (origin_split[0].empty() || origin_split[0][0] !=
'[') {
1973 error =
strprintf(
"Key origin start '[ character expected but not found, got '%c' instead",
1974 origin_split[0].empty() ?
']' : origin_split[0][0]);
1977 auto slash_split =
Split(origin_split[0].subspan(1),
'/');
1978 if (slash_split[0].size() != 8) {
1979 error =
strprintf(
"Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
1982 std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
1983 if (!
IsHex(fpr_hex)) {
1984 error =
strprintf(
"Fingerprint '%s' is not hex", fpr_hex);
1987 auto fpr_bytes =
ParseHex(fpr_hex);
1989 static_assert(
sizeof(info.
fingerprint) == 4,
"Fingerprint must be 4 bytes");
1990 assert(fpr_bytes.size() == 4);
1991 std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.
fingerprint);
1992 std::vector<KeyPath> path;
1993 if (!ParseKeyPath(slash_split, path, apostrophe, error,
false))
return {};
1994 info.
path = path.at(0);
1995 auto providers = ParsePubkeyInner(key_exp_index, origin_split[1], ctx,
out, apostrophe, error);
1996 if (providers.empty())
return {};
1997 ret.reserve(providers.size());
1998 for (
auto& prov : providers) {
1999 ret.emplace_back(std::make_unique<OriginPubkeyProvider>(key_exp_index, info, std::move(prov), apostrophe));
2004std::unique_ptr<PubkeyProvider> InferPubkey(
const CPubKey& pubkey, ParseScriptContext ctx,
const SigningProvider& provider)
2011 if (ctx != ParseScriptContext::TOP && ctx != ParseScriptContext::P2SH && !pubkey.
IsCompressed()) {
2014 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
false);
2017 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2019 return key_provider;
2022std::unique_ptr<PubkeyProvider> InferXOnlyPubkey(
const XOnlyPubKey& xkey, ParseScriptContext ctx,
const SigningProvider& provider)
2025 std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey,
true);
2028 return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider),
false);
2030 return key_provider;
2038 using Key = uint32_t;
2044 mutable std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> m_keys;
2046 mutable std::string m_key_parsing_error;
2054 : m_out(
out), m_in(in), m_script_ctx(ctx), m_offset(offset) {}
2056 bool KeyCompare(
const Key& a,
const Key& b)
const {
2057 return *m_keys.at(a).at(0) < *m_keys.at(b).at(0);
2061 switch (m_script_ctx) {
2068 template<
typename I> std::optional<Key>
FromString(I begin, I end)
const
2071 Key key = m_keys.
size();
2072 uint32_t exp_index = m_offset + key;
2073 auto pk = ParsePubkey(exp_index, {&*begin, &*end},
ParseContext(), *m_out, m_key_parsing_error);
2074 if (
pk.empty())
return {};
2075 m_keys.emplace_back(std::move(
pk));
2079 std::optional<std::string>
ToString(
const Key& key)
const
2081 return m_keys.at(key).at(0)->ToString();
2084 template<
typename I> std::optional<Key> FromPKBytes(I begin, I end)
const
2087 Key key = m_keys.size();
2090 std::copy(begin, end, pubkey.
begin());
2091 if (
auto pubkey_provider = InferXOnlyPubkey(pubkey,
ParseContext(), *m_in)) {
2092 m_keys.emplace_back();
2093 m_keys.back().push_back(std::move(pubkey_provider));
2098 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2099 m_keys.emplace_back();
2100 m_keys.back().push_back(std::move(pubkey_provider));
2107 template<
typename I> std::optional<Key> FromPKHBytes(I begin, I end)
const
2109 assert(end - begin == 20);
2112 std::copy(begin, end, hash.
begin());
2116 if (
auto pubkey_provider = InferPubkey(pubkey,
ParseContext(), *m_in)) {
2117 Key key = m_keys.
size();
2118 m_keys.emplace_back();
2119 m_keys.back().push_back(std::move(pubkey_provider));
2127 return m_script_ctx;
2133std::vector<std::unique_ptr<DescriptorImpl>>
ParseScript(uint32_t& key_exp_index, std::span<const char>& sp, ParseScriptContext ctx,
FlatSigningProvider&
out, std::string& error)
2136 Assume(ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR);
2137 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2138 auto expr =
Expr(sp);
2139 if (
Func(
"pk", expr)) {
2140 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2141 if (pubkeys.empty()) {
2146 for (
auto& pubkey : pubkeys) {
2147 ret.emplace_back(std::make_unique<PKDescriptor>(std::move(pubkey), ctx == ParseScriptContext::P2TR));
2151 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) &&
Func(
"pkh", expr)) {
2152 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2153 if (pubkeys.empty()) {
2158 for (
auto& pubkey : pubkeys) {
2159 ret.emplace_back(std::make_unique<PKHDescriptor>(std::move(pubkey)));
2163 if (ctx == ParseScriptContext::TOP &&
Func(
"combo", expr)) {
2164 auto pubkeys = ParsePubkey(key_exp_index, expr, ctx,
out, error);
2165 if (pubkeys.empty()) {
2166 error =
strprintf(
"combo(): %s", error);
2170 for (
auto& pubkey : pubkeys) {
2171 ret.emplace_back(std::make_unique<ComboDescriptor>(std::move(pubkey)));
2174 }
else if (
Func(
"combo", expr)) {
2175 error =
"Can only have combo() at top level";
2178 const bool multi =
Func(
"multi", expr);
2179 const bool sortedmulti = !multi &&
Func(
"sortedmulti", expr);
2180 const bool multi_a = !(multi || sortedmulti) &&
Func(
"multi_a", expr);
2181 const bool sortedmulti_a = !(multi || sortedmulti || multi_a) &&
Func(
"sortedmulti_a", expr);
2182 if (((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH) && (multi || sortedmulti)) ||
2183 (ctx == ParseScriptContext::P2TR && (multi_a || sortedmulti_a))) {
2184 auto threshold =
Expr(expr);
2186 std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers;
2187 if (
const auto maybe_thres{ToIntegral<uint32_t>(std::string_view{threshold.begin(), threshold.end()})}) {
2188 thres = *maybe_thres;
2190 error =
strprintf(
"Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
2193 size_t script_size = 0;
2194 size_t max_providers_len = 0;
2195 while (expr.size()) {
2196 if (!
Const(
",", expr)) {
2197 error =
strprintf(
"Multi: expected ',', got '%c'", expr[0]);
2200 auto arg =
Expr(expr);
2201 auto pks = ParsePubkey(key_exp_index, arg, ctx,
out, error);
2206 script_size += pks.at(0)->GetSize() + 1;
2207 max_providers_len = std::max(max_providers_len, pks.size());
2208 providers.emplace_back(std::move(pks));
2217 }
else if (thres < 1) {
2218 error =
strprintf(
"Multisig threshold cannot be %d, must be at least 1", thres);
2220 }
else if (thres > providers.size()) {
2221 error =
strprintf(
"Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
2224 if (ctx == ParseScriptContext::TOP) {
2225 if (providers.size() > 3) {
2226 error =
strprintf(
"Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
2230 if (ctx == ParseScriptContext::P2SH) {
2240 for (
auto& vec : providers) {
2241 if (vec.size() == 1) {
2242 for (
size_t i = 1; i < max_providers_len; ++i) {
2243 vec.emplace_back(vec.at(0)->Clone());
2245 }
else if (vec.size() != max_providers_len) {
2246 error =
strprintf(
"multi(): Multipath derivation paths have mismatched lengths");
2252 for (
size_t i = 0; i < max_providers_len; ++i) {
2254 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2255 pubs.reserve(providers.size());
2256 for (
auto& pub : providers) {
2257 pubs.emplace_back(std::move(pub.at(i)));
2259 if (multi || sortedmulti) {
2260 ret.emplace_back(std::make_unique<MultisigDescriptor>(thres, std::move(pubs), sortedmulti));
2262 ret.emplace_back(std::make_unique<MultiADescriptor>(thres, std::move(pubs), sortedmulti_a));
2266 }
else if (multi || sortedmulti) {
2267 error =
"Can only have multi/sortedmulti at top level, in sh(), or in wsh()";
2269 }
else if (multi_a || sortedmulti_a) {
2270 error =
"Can only have multi_a/sortedmulti_a inside tr()";
2273 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wpkh", expr)) {
2274 auto pubkeys = ParsePubkey(key_exp_index, expr, ParseScriptContext::P2WPKH,
out, error);
2275 if (pubkeys.empty()) {
2280 for (
auto& pubkey : pubkeys) {
2281 ret.emplace_back(std::make_unique<WPKHDescriptor>(std::move(pubkey)));
2284 }
else if (
Func(
"wpkh", expr)) {
2285 error =
"Can only have wpkh() at top level or inside sh()";
2288 if (ctx == ParseScriptContext::TOP &&
Func(
"sh", expr)) {
2289 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2SH,
out, error);
2290 if (descs.empty() || expr.size())
return {};
2291 std::vector<std::unique_ptr<DescriptorImpl>>
ret;
2292 ret.reserve(descs.size());
2293 for (
auto& desc : descs) {
2294 ret.push_back(std::make_unique<SHDescriptor>(std::move(desc)));
2297 }
else if (
Func(
"sh", expr)) {
2298 error =
"Can only have sh() at top level";
2301 if ((ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH) &&
Func(
"wsh", expr)) {
2302 auto descs =
ParseScript(key_exp_index, expr, ParseScriptContext::P2WSH,
out, error);
2303 if (descs.empty() || expr.size())
return {};
2304 for (
auto& desc : descs) {
2305 ret.emplace_back(std::make_unique<WSHDescriptor>(std::move(desc)));
2308 }
else if (
Func(
"wsh", expr)) {
2309 error =
"Can only have wsh() at top level or inside sh()";
2312 if (ctx == ParseScriptContext::TOP &&
Func(
"addr", expr)) {
2315 error =
"Address is not valid";
2318 ret.emplace_back(std::make_unique<AddressDescriptor>(std::move(dest)));
2320 }
else if (
Func(
"addr", expr)) {
2321 error =
"Can only have addr() at top level";
2324 if (ctx == ParseScriptContext::TOP &&
Func(
"tr", expr)) {
2325 auto arg =
Expr(expr);
2326 auto internal_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2327 if (internal_keys.empty()) {
2331 size_t max_providers_len = internal_keys.size();
2333 std::vector<std::vector<std::unique_ptr<DescriptorImpl>>> subscripts;
2334 std::vector<int> depths;
2336 if (!
Const(
",", expr)) {
2337 error =
strprintf(
"tr: expected ',', got '%c'", expr[0]);
2343 std::vector<bool> branches;
2348 while (
Const(
"{", expr)) {
2349 branches.push_back(
false);
2356 auto sarg =
Expr(expr);
2357 subscripts.emplace_back(
ParseScript(key_exp_index, sarg, ParseScriptContext::P2TR,
out, error));
2358 if (subscripts.back().empty())
return {};
2359 max_providers_len = std::max(max_providers_len, subscripts.back().size());
2360 depths.push_back(branches.size());
2362 while (branches.size() && branches.back()) {
2363 if (!
Const(
"}", expr)) {
2364 error =
strprintf(
"tr(): expected '}' after script expression");
2367 branches.pop_back();
2370 if (branches.size() && !branches.back()) {
2371 if (!
Const(
",", expr)) {
2372 error =
strprintf(
"tr(): expected ',' after script expression");
2375 branches.back() =
true;
2377 }
while (branches.size());
2380 error =
strprintf(
"tr(): expected ')' after script expression");
2388 for (
auto& vec : subscripts) {
2389 if (vec.size() == 1) {
2390 for (
size_t i = 1; i < max_providers_len; ++i) {
2391 vec.emplace_back(vec.at(0)->Clone());
2393 }
else if (vec.size() != max_providers_len) {
2394 error =
strprintf(
"tr(): Multipath subscripts have mismatched lengths");
2399 if (internal_keys.size() > 1 && internal_keys.size() != max_providers_len) {
2400 error =
strprintf(
"tr(): Multipath internal key mismatches multipath subscripts lengths");
2404 while (internal_keys.size() < max_providers_len) {
2405 internal_keys.emplace_back(internal_keys.at(0)->Clone());
2409 for (
size_t i = 0; i < max_providers_len; ++i) {
2411 std::vector<std::unique_ptr<DescriptorImpl>> this_subs;
2412 this_subs.reserve(subscripts.size());
2413 for (
auto& subs : subscripts) {
2414 this_subs.emplace_back(std::move(subs.at(i)));
2416 ret.emplace_back(std::make_unique<TRDescriptor>(std::move(internal_keys.at(i)), std::move(this_subs), depths));
2421 }
else if (
Func(
"tr", expr)) {
2422 error =
"Can only have tr at top level";
2425 if (ctx == ParseScriptContext::TOP &&
Func(
"rawtr", expr)) {
2426 auto arg =
Expr(expr);
2428 error =
strprintf(
"rawtr(): only one key expected.");
2431 auto output_keys = ParsePubkey(key_exp_index, arg, ParseScriptContext::P2TR,
out, error);
2432 if (output_keys.empty()) {
2433 error =
strprintf(
"rawtr(): %s", error);
2437 for (
auto& pubkey : output_keys) {
2438 ret.emplace_back(std::make_unique<RawTRDescriptor>(std::move(pubkey)));
2441 }
else if (
Func(
"rawtr", expr)) {
2442 error =
"Can only have rawtr at top level";
2445 if (ctx == ParseScriptContext::TOP &&
Func(
"raw", expr)) {
2446 std::string str(expr.begin(), expr.end());
2448 error =
"Raw script is not hex";
2452 ret.emplace_back(std::make_unique<RawDescriptor>(
CScript(bytes.begin(), bytes.end())));
2454 }
else if (
Func(
"raw", expr)) {
2455 error =
"Can only have raw() at top level";
2461 KeyParser parser(&
out,
nullptr, script_ctx, key_exp_index);
2463 if (parser.m_key_parsing_error !=
"") {
2464 error = std::move(parser.m_key_parsing_error);
2468 if (ctx != ParseScriptContext::P2WSH && ctx != ParseScriptContext::P2TR) {
2469 error =
"Miniscript expressions can only be used in wsh or tr.";
2472 if (!
node->IsSane() ||
node->IsNotSatisfiable()) {
2474 auto insane_node =
node.get();
2475 if (
const auto sub =
node->FindInsaneSub()) insane_node = sub;
2476 if (
const auto str = insane_node->ToString(parser)) error = *str;
2477 if (!insane_node->IsValid()) {
2478 error +=
" is invalid";
2479 }
else if (!
node->IsSane()) {
2480 error +=
" is not sane";
2481 if (!insane_node->IsNonMalleable()) {
2482 error +=
": malleable witnesses exist";
2483 }
else if (insane_node ==
node.get() && !insane_node->NeedsSignature()) {
2484 error +=
": witnesses without signature exist";
2485 }
else if (!insane_node->CheckTimeLocksMix()) {
2486 error +=
": contains mixes of timelocks expressed in blocks and seconds";
2487 }
else if (!insane_node->CheckDuplicateKey()) {
2488 error +=
": contains duplicate public keys";
2489 }
else if (!insane_node->ValidSatisfactions()) {
2490 error +=
": needs witnesses that may exceed resource limits";
2493 error +=
" is not satisfiable";
2500 key_exp_index += parser.m_keys.size();
2503 size_t num_multipath = std::max_element(parser.m_keys.begin(), parser.m_keys.end(),
2504 [](
const std::vector<std::unique_ptr<PubkeyProvider>>& a,
const std::vector<std::unique_ptr<PubkeyProvider>>& b) {
2505 return a.size() < b.size();
2508 for (
auto& vec : parser.m_keys) {
2509 if (vec.size() == 1) {
2510 for (
size_t i = 1; i < num_multipath; ++i) {
2511 vec.emplace_back(vec.at(0)->Clone());
2513 }
else if (vec.size() != num_multipath) {
2514 error =
strprintf(
"Miniscript: Multipath derivation paths have mismatched lengths");
2520 for (
size_t i = 0; i < num_multipath; ++i) {
2522 std::vector<std::unique_ptr<PubkeyProvider>> pubs;
2523 pubs.reserve(parser.m_keys.size());
2524 for (
auto& pub : parser.m_keys) {
2525 pubs.emplace_back(std::move(pub.at(i)));
2527 ret.emplace_back(std::make_unique<MiniscriptDescriptor>(std::move(pubs),
node->Clone()));
2532 if (ctx == ParseScriptContext::P2SH) {
2533 error =
"A function is needed within P2SH";
2535 }
else if (ctx == ParseScriptContext::P2WSH) {
2536 error =
"A function is needed within P2WSH";
2539 error =
strprintf(
"'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
2546 if (!match)
return {};
2547 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2548 keys.reserve(match->second.size());
2549 for (
const auto keyspan : match->second) {
2550 if (keyspan.size() != 32)
return {};
2551 auto key = InferXOnlyPubkey(
XOnlyPubKey{keyspan}, ctx, provider);
2552 if (!key)
return {};
2553 keys.push_back(std::move(key));
2555 return std::make_unique<MultiADescriptor>(match->first, std::move(keys));
2563 return std::make_unique<PKDescriptor>(InferXOnlyPubkey(key, ctx, provider),
true);
2566 if (ctx == ParseScriptContext::P2TR) {
2567 auto ret = InferMultiA(
script, ctx, provider);
2571 std::vector<std::vector<unsigned char>>
data;
2574 if (txntype ==
TxoutType::PUBKEY && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2576 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2577 return std::make_unique<PKDescriptor>(std::move(pubkey_provider));
2580 if (txntype ==
TxoutType::PUBKEYHASH && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2584 if (provider.
GetPubKey(keyid, pubkey)) {
2585 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2586 return std::make_unique<PKHDescriptor>(std::move(pubkey_provider));
2594 if (provider.
GetPubKey(keyid, pubkey)) {
2595 if (
auto pubkey_provider = InferPubkey(pubkey, ParseScriptContext::P2WPKH, provider)) {
2596 return std::make_unique<WPKHDescriptor>(std::move(pubkey_provider));
2600 if (txntype ==
TxoutType::MULTISIG && (ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH || ctx == ParseScriptContext::P2WSH)) {
2602 std::vector<std::unique_ptr<PubkeyProvider>> providers;
2603 for (
size_t i = 1; i + 1 <
data.size(); ++i) {
2605 if (
auto pubkey_provider = InferPubkey(pubkey, ctx, provider)) {
2606 providers.push_back(std::move(pubkey_provider));
2612 if (ok)
return std::make_unique<MultisigDescriptor>((
int)
data[0][0], std::move(providers));
2618 if (provider.
GetCScript(scriptid, subscript)) {
2619 auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
2620 if (sub)
return std::make_unique<SHDescriptor>(std::move(sub));
2626 if (provider.
GetCScript(scriptid, subscript)) {
2627 auto sub = InferScript(subscript, ParseScriptContext::P2WSH, provider);
2628 if (sub)
return std::make_unique<WSHDescriptor>(std::move(sub));
2643 std::vector<std::unique_ptr<DescriptorImpl>> subscripts;
2644 std::vector<int> depths;
2645 for (
const auto& [depth,
script, leaf_ver] : *tree) {
2646 std::unique_ptr<DescriptorImpl> subdesc;
2648 subdesc = InferScript(
CScript(
script.begin(),
script.end()), ParseScriptContext::P2TR, provider);
2654 subscripts.push_back(std::move(subdesc));
2655 depths.push_back(depth);
2659 auto key = InferXOnlyPubkey(tap.
internal_key, ParseScriptContext::P2TR, provider);
2660 return std::make_unique<TRDescriptor>(std::move(key), std::move(subscripts), std::move(depths));
2666 auto key = InferXOnlyPubkey(pubkey, ParseScriptContext::P2TR, provider);
2668 return std::make_unique<RawTRDescriptor>(std::move(key));
2673 if (ctx == ParseScriptContext::P2WSH || ctx == ParseScriptContext::P2TR) {
2675 KeyParser parser(
nullptr, &provider, script_ctx);
2678 std::vector<std::unique_ptr<PubkeyProvider>> keys;
2679 keys.reserve(parser.m_keys.size());
2680 for (
auto& key : parser.m_keys) {
2681 keys.emplace_back(std::move(key.at(0)));
2683 return std::make_unique<MiniscriptDescriptor>(std::move(keys), std::move(
node));
2689 if (ctx != ParseScriptContext::TOP)
return nullptr;
2694 return std::make_unique<AddressDescriptor>(std::move(dest));
2698 return std::make_unique<RawDescriptor>(
script);
2705bool CheckChecksum(std::span<const char>& sp,
bool require_checksum, std::string& error, std::string* out_checksum =
nullptr)
2707 auto check_split =
Split(sp,
'#');
2708 if (check_split.size() > 2) {
2709 error =
"Multiple '#' symbols";
2712 if (check_split.size() == 1 && require_checksum){
2713 error =
"Missing checksum";
2716 if (check_split.size() == 2) {
2717 if (check_split[1].size() != 8) {
2718 error =
strprintf(
"Expected 8 character checksum, not %u characters", check_split[1].size());
2722 auto checksum = DescriptorChecksum(check_split[0]);
2723 if (checksum.empty()) {
2724 error =
"Invalid characters in payload";
2727 if (check_split.size() == 2) {
2728 if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
2729 error =
strprintf(
"Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
2733 if (out_checksum) *out_checksum = std::move(checksum);
2734 sp = check_split[0];
2740 std::span<const char> sp{descriptor};
2742 uint32_t key_exp_index = 0;
2744 if (sp.size() == 0 && !
ret.empty()) {
2745 std::vector<std::unique_ptr<Descriptor>> descs;
2746 descs.reserve(
ret.size());
2747 for (
auto& r :
ret) {
2748 descs.emplace_back(std::unique_ptr<Descriptor>(std::move(r)));
2759 std::span<const char> sp{descriptor};
2766 return InferScript(
script, ParseScriptContext::TOP, provider);
2771 std::string desc_str = desc.
ToString(
true);
2785 xpubs[der_index] = xpub;
2805 const auto& der_it = key_exp_it->second.find(der_index);
2806 if (der_it == key_exp_it->second.end())
return false;
2807 xpub = der_it->second;
2825 if (xpub != parent_xpub_pair.second) {
2826 throw std::runtime_error(std::string(__func__) +
": New cached parent xpub does not match already cached parent xpub");
2834 for (
const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
2837 if (xpub != derived_xpub_pair.second) {
2838 throw std::runtime_error(std::string(__func__) +
": New cached derived xpub does not match already cached derived xpub");
2842 CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2843 diff.
CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
2849 if (xpub != lh_xpub_pair.second) {
2850 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)
std::optional< CPubKey > MuSig2AggregatePubkeys(const std::vector< CPubKey > &pubkeys)
Compute the full aggregate pubkey from the given participant pubkeys in their current order.
constexpr uint256 MUSIG_CHAINCODE
NodeRef< typename Ctx::Key > FromString(const std::string &str, const Ctx &ctx)
constexpr bool IsTapscript(MiniscriptContext ms_ctx)
Whether the context Tapscript, ensuring the only other possibility is P2WSH.
NodeRef< typename Ctx::Key > FromScript(const CScript &script, const Ctx &ctx)
std::unique_ptr< const Node< Key > > NodeRef
std::span< const char > Expr(std::span< const char > &sp)
Extract the expression that sp begins with.
bool Func(const std::string &str, std::span< const char > &sp)
Parse a function call.
bool Const(const std::string &str, std::span< const char > &sp, bool skip)
Parse a constant.
static std::vector< std::string > split(const std::string &str, const std::string &delims=" \t")
std::string ToString(const T &t)
Locale-independent version of std::to_string.
std::vector< T > Split(const std::span< const char > &sp, std::string_view separators, bool include_sep=false)
Split a string on any char found in separators, returning a vector.
static OutputType GetOutputType(TxoutType type, bool is_from_p2sh)
static bool IsSegwit(const Descriptor &desc)
Whether the descriptor represents, directly or not, a witness program.
bool operator<(const CNetAddr &a, const CNetAddr &b)
std::optional< OutputType > OutputTypeFromDestination(const CTxDestination &dest)
Get the OutputType for a CTxDestination.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
uint256 DescriptorID(const Descriptor &desc)
Unique identifier that may not change over time, unless explicitly marked as not backwards compatible...
bool CheckChecksum(std::span< const char > &sp, bool require_checksum, std::string &error, std::string *out_checksum=nullptr)
Check a descriptor checksum, and update desc to be the checksum-less part.
std::vector< std::unique_ptr< Descriptor > > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
std::string GetDescriptorChecksum(const std::string &descriptor)
Get the checksum for a descriptor.
std::unordered_map< uint32_t, CExtPubKey > ExtPubKeyMap
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE
static constexpr unsigned int MAX_PUBKEYS_PER_MULTI_A
The limit of keys in OP_CHECKSIGADD-based scripts.
CScript BuildScript(Ts &&... inputs)
Build a script by concatenating other scripts, or any argument accepted by CScript::operator<<.
static const int MAX_PUBKEYS_PER_MULTISIG
std::vector< unsigned char > ToByteVector(const T &in)
static const int64_t values[]
A selection of numbers that do not trigger int64_t overflow when added/subtracted.
constexpr unsigned int GetSizeOfCompactSize(uint64_t nSize)
Compact Size size < 253 – 1 byte size <= USHRT_MAX – 3 bytes (253 + 2 bytes) size <= UINT_MAX – 5 byt...
static bool GetPubKey(const SigningProvider &provider, const SignatureData &sigdata, const CKeyID &address, CPubKey &pubkey)
std::optional< std::vector< std::tuple< int, std::vector< unsigned char >, int > > > InferTaprootTree(const TaprootSpendData &spenddata, const XOnlyPubKey &output)
Given a TaprootSpendData and the output key, reconstruct its script tree.
const SigningProvider & DUMMY_SIGNING_PROVIDER
void PolyMod(const std::vector< typename F::Elem > &mod, std::vector< typename F::Elem > &val, const F &field)
Compute the remainder of a polynomial division of val by mod, putting the result in mod.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
CScript GetScriptForMultisig(int nRequired, const std::vector< CPubKey > &keys)
Generate a multisig script.
std::optional< std::pair< int, std::vector< std::span< const unsigned char > > > > MatchMultiA(const CScript &script)
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
CExtPubKey Neuter() const
bool Derive(CExtKey &out, unsigned int nChild) const
bool Derive(CExtPubKey &out, unsigned int nChild) const
unsigned char vchFingerprint[4]
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.