MCPcopy Create free account
hub / github.com/ElementsProject/elements / ParsePubkeyInner

Function ParsePubkeyInner

src/script/descriptor.cpp:932–998  ·  view source on GitHub ↗

Parse a public key that excludes origin information. */

Source from the content-addressed store, hash-verified

930
931/** Parse a public key that excludes origin information. */
932std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
933{
934 using namespace spanparsing;
935
936 bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
937 auto split = Split(sp, '/');
938 std::string str(split[0].begin(), split[0].end());
939 if (str.size() == 0) {
940 error = "No key provided";
941 return nullptr;
942 }
943 if (split.size() == 1) {
944 if (IsHex(str)) {
945 std::vector<unsigned char> data = ParseHex(str);
946 CPubKey pubkey(data);
947 if (pubkey.IsFullyValid()) {
948 if (permit_uncompressed || pubkey.IsCompressed()) {
949 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, false);
950 } else {
951 error = "Uncompressed keys are not allowed";
952 return nullptr;
953 }
954 } else if (data.size() == 32 && ctx == ParseScriptContext::P2TR) {
955 unsigned char fullkey[33] = {0x02};
956 std::copy(data.begin(), data.end(), fullkey + 1);
957 pubkey.Set(std::begin(fullkey), std::end(fullkey));
958 if (pubkey.IsFullyValid()) {
959 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, true);
960 }
961 }
962 error = strprintf("Pubkey '%s' is invalid", str);
963 return nullptr;
964 }
965 CKey key = DecodeSecret(str);
966 if (key.IsValid()) {
967 if (permit_uncompressed || key.IsCompressed()) {
968 CPubKey pubkey = key.GetPubKey();
969 out.keys.emplace(pubkey.GetID(), key);
970 return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey, ctx == ParseScriptContext::P2TR);
971 } else {
972 error = "Uncompressed keys are not allowed";
973 return nullptr;
974 }
975 }
976 }
977 CExtKey extkey = DecodeExtKey(str);
978 CExtPubKey extpubkey = DecodeExtPubKey(str);
979 if (!extkey.key.IsValid() && !extpubkey.pubkey.IsValid()) {
980 error = strprintf("key '%s' is not valid", str);
981 return nullptr;
982 }
983 KeyPath path;
984 DeriveType type = DeriveType::NO;
985 if (split.back() == Span{"*"}.first(1)) {
986 split.pop_back();
987 type = DeriveType::UNHARDENED;
988 } else if (split.back() == Span{"*'"}.first(2) || split.back() == Span{"*h"}.first(2)) {
989 split.pop_back();

Callers 1

ParsePubkeyFunction · 0.85

Calls 15

IsHexFunction · 0.85
ParseHexFunction · 0.85
beginFunction · 0.85
endFunction · 0.85
DecodeSecretFunction · 0.85
DecodeExtKeyFunction · 0.85
DecodeExtPubKeyFunction · 0.85
IsFullyValidMethod · 0.80
NeuterMethod · 0.80
ParseKeyPathFunction · 0.70
SplitFunction · 0.50
beginMethod · 0.45

Tested by

no test coverage detected