Parse a public key including origin information (if enabled). */ NOLINTNEXTLINE(misc-no-recursion)
| 2016 | /** Parse a public key including origin information (if enabled). */ |
| 2017 | // NOLINTNEXTLINE(misc-no-recursion) |
| 2018 | std::vector<std::unique_ptr<PubkeyProvider>> ParsePubkey(uint32_t& key_exp_index, const std::span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error) |
| 2019 | { |
| 2020 | std::vector<std::unique_ptr<PubkeyProvider>> ret; |
| 2021 | |
| 2022 | using namespace script; |
| 2023 | |
| 2024 | // musig cannot be nested inside of an origin |
| 2025 | std::span<const char> span = sp; |
| 2026 | if (Const("musig(", span, /*skip=*/false)) { |
| 2027 | if (ctx != ParseScriptContext::P2TR) { |
| 2028 | error = "musig() is only allowed in tr() and rawtr()"; |
| 2029 | return {}; |
| 2030 | } |
| 2031 | |
| 2032 | // Split the span on the end parentheses. The end parentheses must |
| 2033 | // be included in the resulting span so that Expr is happy. |
| 2034 | auto split = Split(sp, ')', /*include_sep=*/true); |
| 2035 | if (split.size() > 2) { |
| 2036 | error = "Too many ')' in musig() expression"; |
| 2037 | return {}; |
| 2038 | } |
| 2039 | std::span<const char> expr(split.at(0).begin(), split.at(0).end()); |
| 2040 | if (!Func("musig", expr)) { |
| 2041 | error = "Invalid musig() expression"; |
| 2042 | return {}; |
| 2043 | } |
| 2044 | |
| 2045 | // Parse the participant pubkeys |
| 2046 | bool any_ranged = false; |
| 2047 | bool all_bip32 = true; |
| 2048 | std::vector<std::vector<std::unique_ptr<PubkeyProvider>>> providers; |
| 2049 | bool any_key_parsed = false; |
| 2050 | size_t max_multipath_len = 0; |
| 2051 | while (expr.size()) { |
| 2052 | if (any_key_parsed && !Const(",", expr)) { |
| 2053 | error = strprintf("musig(): expected ',', got '%c'", expr[0]); |
| 2054 | return {}; |
| 2055 | } |
| 2056 | auto arg = Expr(expr); |
| 2057 | auto pk = ParsePubkey(key_exp_index, arg, ParseScriptContext::MUSIG, out, error); |
| 2058 | if (pk.empty()) { |
| 2059 | error = strprintf("musig(): %s", error); |
| 2060 | return {}; |
| 2061 | } |
| 2062 | any_key_parsed = true; |
| 2063 | |
| 2064 | any_ranged = any_ranged || pk.at(0)->IsRange(); |
| 2065 | all_bip32 = all_bip32 && pk.at(0)->IsBIP32(); |
| 2066 | |
| 2067 | max_multipath_len = std::max(max_multipath_len, pk.size()); |
| 2068 | |
| 2069 | providers.emplace_back(std::move(pk)); |
| 2070 | } |
| 2071 | if (!any_key_parsed) { |
| 2072 | error = "musig(): Must contain key expressions"; |
| 2073 | return {}; |
| 2074 | } |
| 2075 |
no test coverage detected