Line data Source code
1 : // Copyright (c) 2018-2022 The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #include <script/descriptor.h>
6 :
7 : #include <key_io.h>
8 : #include <pubkey.h>
9 : #include <script/script.h>
10 : #include <script/standard.h>
11 :
12 : #include <span.h>
13 : #include <util/bip32.h>
14 : #include <util/spanparsing.h>
15 : #include <util/strencodings.h>
16 : #include <util/system.h>
17 : #include <util/vector.h>
18 :
19 : #include <memory>
20 : #include <optional>
21 : #include <string>
22 : #include <vector>
23 :
24 : namespace {
25 :
26 : ////////////////////////////////////////////////////////////////////////////
27 : // Checksum //
28 : ////////////////////////////////////////////////////////////////////////////
29 :
30 : // This section implements a checksum algorithm for descriptors with the
31 : // following properties:
32 : // * Mistakes in a descriptor string are measured in "symbol errors". The higher
33 : // the number of symbol errors, the harder it is to detect:
34 : // * An error substituting a character from 0123456789()[],'/*abcdefgh@:$%{} for
35 : // another in that set always counts as 1 symbol error.
36 : // * Note that hex encoded keys are covered by these characters. Xprvs and
37 : // xpubs use other characters too, but already have their own checksum
38 : // mechanism.
39 : // * Function names like "multi()" use other characters, but mistakes in
40 : // these would generally result in an unparsable descriptor.
41 : // * A case error always counts as 1 symbol error.
42 : // * Any other 1 character substitution error counts as 1 or 2 symbol errors.
43 : // * Any 1 symbol error is always detected.
44 : // * Any 2 or 3 symbol error in a descriptor of up to 49154 characters is always detected.
45 : // * Any 4 symbol error in a descriptor of up to 507 characters is always detected.
46 : // * Any 5 symbol error in a descriptor of up to 77 characters is always detected.
47 : // * Is optimized to minimize the chance a 5 symbol error in a descriptor up to 387 characters is undetected
48 : // * Random errors have a chance of 1 in 2**40 of being undetected.
49 : //
50 : // These properties are achieved by expanding every group of 3 (non checksum) characters into
51 : // 4 GF(32) symbols, over which a cyclic code is defined.
52 :
53 : /*
54 : * Interprets c as 8 groups of 5 bits which are the coefficients of a degree 8 polynomial over GF(32),
55 : * multiplies that polynomial by x, computes its remainder modulo a generator, and adds the constant term val.
56 : *
57 : * This generator is G(x) = x^8 + {30}x^7 + {23}x^6 + {15}x^5 + {14}x^4 + {10}x^3 + {6}x^2 + {12}x + {9}.
58 : * It is chosen to define an cyclic error detecting code which is selected by:
59 : * - Starting from all BCH codes over GF(32) of degree 8 and below, which by construction guarantee detecting
60 : * 3 errors in windows up to 19000 symbols.
61 : * - Taking all those generators, and for degree 7 ones, extend them to degree 8 by adding all degree-1 factors.
62 : * - Selecting just the set of generators that guarantee detecting 4 errors in a window of length 512.
63 : * - Selecting one of those with best worst-case behavior for 5 errors in windows of length up to 512.
64 : *
65 : * The generator and the constants to implement it can be verified using this Sage code:
66 : * B = GF(2) # Binary field
67 : * BP.<b> = B[] # Polynomials over the binary field
68 : * F_mod = b**5 + b**3 + 1
69 : * F.<f> = GF(32, modulus=F_mod, repr='int') # GF(32) definition
70 : * FP.<x> = F[] # Polynomials over GF(32)
71 : * E_mod = x**3 + x + F.fetch_int(8)
72 : * E.<e> = F.extension(E_mod) # Extension field definition
73 : * alpha = e**2743 # Choice of an element in extension field
74 : * for p in divisors(E.order() - 1): # Verify alpha has order 32767.
75 : * assert((alpha**p == 1) == (p % 32767 == 0))
76 : * G = lcm([(alpha**i).minpoly() for i in [1056,1057,1058]] + [x + 1])
77 : * print(G) # Print out the generator
78 : * for i in [1,2,4,8,16]: # Print out {1,2,4,8,16}*(G mod x^8), packed in hex integers.
79 : * v = 0
80 : * for coef in reversed((F.fetch_int(i)*(G % x**8)).coefficients(sparse=True)):
81 : * v = v*32 + coef.integer_representation()
82 : * print("0x%x" % v)
83 : */
84 61671137 : uint64_t PolyMod(uint64_t c, int val)
85 : {
86 61671137 : uint8_t c0 = c >> 35;
87 61671137 : c = ((c & 0x7ffffffff) << 5) ^ val;
88 61671137 : if (c0 & 1) c ^= 0xf5dee51989;
89 61671137 : if (c0 & 2) c ^= 0xa9fdca3312;
90 61671137 : if (c0 & 4) c ^= 0x1bab10e32d;
91 61671137 : if (c0 & 8) c ^= 0x3706b1677a;
92 61671137 : if (c0 & 16) c ^= 0x644d626ffd;
93 61671137 : return c;
94 : }
95 :
96 255031 : std::string DescriptorChecksum(const Span<const char>& span)
97 : {
98 : /** A character set designed such that:
99 : * - The most common 'unprotected' descriptor characters (hex, keypaths) are in the first group of 32.
100 : * - Case errors cause an offset that's a multiple of 32.
101 : * - As many alphabetic characters are in the same group (while following the above restrictions).
102 : *
103 : * If p(x) gives the position of a character c in this character set, every group of 3 characters
104 : * (a,b,c) is encoded as the 4 symbols (p(a) & 31, p(b) & 31, p(c) & 31, (p(a) / 32) + 3 * (p(b) / 32) + 9 * (p(c) / 32).
105 : * This means that changes that only affect the lower 5 bits of the position, or only the higher 2 bits, will just
106 : * affect a single symbol.
107 : *
108 : * As a result, within-group-of-32 errors count as 1 symbol, as do cross-group errors that don't affect
109 : * the position within the groups.
110 : */
111 256003 : static std::string INPUT_CHARSET =
112 972 : "0123456789()[],'/*abcdefgh@:$%{}"
113 : "IJKLMNOPQRSTUVWXYZ&+-.;<=>?!^_|~"
114 : "ijklmnopqrstuvwxyzABCDEFGH`#\"\\ ";
115 :
116 : /** The character set for the checksum itself (same as bech32). */
117 255031 : static std::string CHECKSUM_CHARSET = "qpzry9x8gf2tvdw0s3jn54khce6mua7l";
118 :
119 255031 : uint64_t c = 1;
120 255031 : int cls = 0;
121 255031 : int clscount = 0;
122 44887081 : for (auto ch : span) {
123 44632051 : auto pos = INPUT_CHARSET.find(ch);
124 44632051 : if (pos == std::string::npos) return "";
125 44632050 : c = PolyMod(c, pos & 31); // Emit a symbol for the position inside the group, for every character.
126 44632050 : cls = cls * 3 + (pos >> 5); // Accumulate the group numbers
127 44632050 : if (++clscount == 3) {
128 : // Emit an extra symbol representing the group numbers, for every 3 characters.
129 14795561 : c = PolyMod(c, cls);
130 14795561 : cls = 0;
131 14795561 : clscount = 0;
132 14795561 : }
133 : }
134 255030 : if (clscount > 0) c = PolyMod(c, cls);
135 2295270 : for (int j = 0; j < 8; ++j) c = PolyMod(c, 0); // Shift further to determine the checksum.
136 255030 : c ^= 1; // Prevent appending zeroes from not affecting the checksum.
137 :
138 255030 : std::string ret(8, ' ');
139 2295270 : for (int j = 0; j < 8; ++j) ret[j] = CHECKSUM_CHARSET[(c >> (5 * (7 - j))) & 31];
140 255030 : return ret;
141 510061 : }
142 :
143 248571 : std::string AddChecksum(const std::string& str) { return str + "#" + DescriptorChecksum(str); }
144 :
145 : ////////////////////////////////////////////////////////////////////////////
146 : // Internal representation //
147 : ////////////////////////////////////////////////////////////////////////////
148 :
149 : typedef std::vector<uint32_t> KeyPath;
150 :
151 : /** Interface for public key objects in descriptors. */
152 : struct PubkeyProvider
153 : {
154 : protected:
155 : //! Index of this key expression in the descriptor
156 : //! E.g. If this PubkeyProvider is key1 in multi(2, key1, key2, key3), then m_expr_index = 0
157 : uint32_t m_expr_index;
158 :
159 : public:
160 508879 : explicit PubkeyProvider(uint32_t exp_index) : m_expr_index(exp_index) {}
161 :
162 508879 : virtual ~PubkeyProvider() = default;
163 :
164 : /** Derive a public key.
165 : * read_cache is the cache to read keys from (if not nullptr)
166 : * write_cache is the cache to write keys to (if not nullptr)
167 : * Caches are not exclusive but this is not tested. Currently we use them exclusively
168 : */
169 : virtual bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const = 0;
170 :
171 : /** Whether this represent multiple public keys at different positions. */
172 : virtual bool IsRange() const = 0;
173 :
174 : /** Get the size of the generated public key(s) in bytes (33 or 65). */
175 : virtual size_t GetSize() const = 0;
176 :
177 : /** Get the descriptor string form. */
178 : virtual std::string ToString() const = 0;
179 :
180 : /** Get the descriptor string form including private data (if available in arg). */
181 : virtual bool ToPrivateString(const SigningProvider& arg, std::string& out) const = 0;
182 :
183 : /** Get the descriptor string form with the xpub at the last hardened derivation,
184 : * and always use h for hardened derivation.
185 : */
186 : virtual bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache = nullptr) const = 0;
187 :
188 : /** Derive a private key, if private data is available in arg. */
189 : virtual bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const = 0;
190 : };
191 :
192 : class OriginPubkeyProvider final : public PubkeyProvider
193 : {
194 : KeyOriginInfo m_origin;
195 : std::unique_ptr<PubkeyProvider> m_provider;
196 : bool m_apostrophe;
197 :
198 121917 : std::string OriginString(bool normalized=false) const
199 : {
200 121917 : return HexStr(m_origin.fingerprint) + FormatHDKeypath(m_origin.path, /*apostrophe=*/!normalized && m_apostrophe);
201 0 : }
202 :
203 : public:
204 504574 : 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) {}
205 196207 : bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
206 : {
207 196207 : if (!m_provider->GetPubKey(pos, arg, key, info, read_cache, write_cache)) return false;
208 196157 : std::copy(std::begin(m_origin.fingerprint), std::end(m_origin.fingerprint), info.fingerprint);
209 196157 : info.path.insert(info.path.begin(), m_origin.path.begin(), m_origin.path.end());
210 196157 : return true;
211 196207 : }
212 811 : bool IsRange() const override { return m_provider->IsRange(); }
213 70 : size_t GetSize() const override { return m_provider->GetSize(); }
214 121839 : std::string ToString() const override { return "[" + OriginString() + "]" + m_provider->ToString(); }
215 64 : bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
216 : {
217 64 : std::string sub;
218 64 : if (!m_provider->ToPrivateString(arg, sub)) return false;
219 30 : ret = "[" + OriginString() + "]" + std::move(sub);
220 30 : return true;
221 64 : }
222 48 : bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
223 : {
224 48 : std::string sub;
225 48 : if (!m_provider->ToNormalizedString(arg, sub, cache)) return false;
226 : // If m_provider is a BIP32PubkeyProvider, we may get a string formatted like a OriginPubkeyProvider
227 : // In that case, we need to strip out the leading square bracket and fingerprint from the substring,
228 : // and append that to our own origin string.
229 48 : if (sub[0] == '[') {
230 4 : sub = sub.substr(9);
231 4 : ret = "[" + OriginString(/*normalized=*/true) + std::move(sub);
232 4 : } else {
233 44 : ret = "[" + OriginString(/*normalized=*/true) + "]" + std::move(sub);
234 : }
235 48 : return true;
236 48 : }
237 134 : bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
238 : {
239 134 : return m_provider->GetPrivKey(pos, arg, key);
240 : }
241 : };
242 :
243 : /** An object representing a parsed constant public key in a descriptor. */
244 : class ConstPubkeyProvider final : public PubkeyProvider
245 : {
246 : CPubKey m_pubkey;
247 :
248 : public:
249 507562 : ConstPubkeyProvider(uint32_t exp_index, const CPubKey& pubkey) : PubkeyProvider(exp_index), m_pubkey(pubkey) {}
250 133071 : bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key, KeyOriginInfo& info, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
251 : {
252 133071 : key = m_pubkey;
253 133071 : info.path.clear();
254 133071 : CKeyID keyid = m_pubkey.GetID();
255 133071 : std::copy(keyid.begin(), keyid.begin() + sizeof(info.fingerprint), info.fingerprint);
256 133071 : return true;
257 : }
258 17241 : bool IsRange() const override { return false; }
259 187 : size_t GetSize() const override { return m_pubkey.size(); }
260 138743 : std::string ToString() const override { return HexStr(m_pubkey); }
261 106 : bool ToPrivateString(const SigningProvider& arg, std::string& ret) const override
262 : {
263 106 : CKey key;
264 106 : if (!arg.GetKey(m_pubkey.GetID(), key)) return false;
265 68 : ret = EncodeSecret(key);
266 68 : return true;
267 106 : }
268 85 : bool ToNormalizedString(const SigningProvider& arg, std::string& ret, const DescriptorCache* cache) const override
269 : {
270 85 : ret = ToString();
271 85 : return true;
272 : }
273 9922 : bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
274 : {
275 9922 : return arg.GetKey(m_pubkey.GetID(), key);
276 : }
277 : };
278 :
279 : enum class DeriveType {
280 : NO,
281 : UNHARDENED,
282 : HARDENED,
283 : };
284 :
285 : /** An object representing a parsed extended public key in a descriptor. */
286 : class BIP32PubkeyProvider final : public PubkeyProvider
287 : {
288 : // Root xpub, path, and final derivation step type being used, if any
289 : CExtPubKey m_root_extkey;
290 : KeyPath m_path;
291 : DeriveType m_derive;
292 : // Whether ' or h is used in harded derivation
293 : bool m_apostrophe;
294 :
295 31038 : bool GetExtKey(const SigningProvider& arg, CExtKey& ret) const
296 : {
297 31038 : CKey key;
298 31038 : if (!arg.GetKey(m_root_extkey.pubkey.GetID(), key)) return false;
299 30241 : ret.nDepth = m_root_extkey.nDepth;
300 30241 : std::copy(m_root_extkey.vchFingerprint, m_root_extkey.vchFingerprint + sizeof(ret.vchFingerprint), ret.vchFingerprint);
301 30241 : ret.nChild = m_root_extkey.nChild;
302 30241 : ret.chaincode = m_root_extkey.chaincode;
303 30241 : ret.key = key;
304 30241 : return true;
305 31038 : }
306 :
307 : // Derives the last xprv
308 30820 : bool GetDerivedExtKey(const SigningProvider& arg, CExtKey& xprv, CExtKey& last_hardened) const
309 : {
310 30820 : if (!GetExtKey(arg, xprv)) return false;
311 102990 : for (auto entry : m_path) {
312 72937 : if (!xprv.Derive(xprv, entry)) return false;
313 72937 : if (entry >> 31) {
314 54130 : last_hardened = xprv;
315 54130 : }
316 : }
317 30053 : return true;
318 30820 : }
319 :
320 40531 : bool IsHardened() const
321 : {
322 40531 : if (m_derive == DeriveType::HARDENED) return true;
323 57847 : for (auto entry : m_path) {
324 41537 : if (entry >> 31) return true;
325 : }
326 16310 : return false;
327 40531 : }
328 :
329 : public:
330 5622 : 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) {}
331 161258 : bool IsRange() const override { return m_derive != DeriveType::NO; }
332 252 : size_t GetSize() const override { return 33; }
333 379605 : bool GetPubKey(int pos, const SigningProvider& arg, CPubKey& key_out, KeyOriginInfo& final_info_out, const DescriptorCache* read_cache = nullptr, DescriptorCache* write_cache = nullptr) const override
334 : {
335 : // Info of parent of the to be derived pubkey
336 379605 : KeyOriginInfo parent_info;
337 379605 : CKeyID keyid = m_root_extkey.pubkey.GetID();
338 379605 : std::copy(keyid.begin(), keyid.begin() + sizeof(parent_info.fingerprint), parent_info.fingerprint);
339 379605 : parent_info.path = m_path;
340 :
341 : // Info of the derived key itself which is copied out upon successful completion
342 379605 : KeyOriginInfo final_info_out_tmp = parent_info;
343 379605 : if (m_derive == DeriveType::UNHARDENED) final_info_out_tmp.path.push_back((uint32_t)pos);
344 379605 : if (m_derive == DeriveType::HARDENED) final_info_out_tmp.path.push_back(((uint32_t)pos) | 0x80000000L);
345 :
346 : // Derive keys or fetch them from cache
347 379605 : CExtPubKey final_extkey = m_root_extkey;
348 379605 : CExtPubKey parent_extkey = m_root_extkey;
349 379605 : CExtPubKey last_hardened_extkey;
350 379605 : bool der = true;
351 379605 : if (read_cache) {
352 339074 : if (!read_cache->GetCachedDerivedExtPubKey(m_expr_index, pos, final_extkey)) {
353 338755 : if (m_derive == DeriveType::HARDENED) return false;
354 : // Try to get the derivation parent
355 336939 : if (!read_cache->GetCachedParentExtPubKey(m_expr_index, parent_extkey)) return false;
356 335603 : final_extkey = parent_extkey;
357 335603 : if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
358 335603 : }
359 376453 : } else if (IsHardened()) {
360 24221 : CExtKey xprv;
361 24221 : CExtKey lh_xprv;
362 24221 : if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
363 24199 : parent_extkey = xprv.Neuter();
364 24199 : if (m_derive == DeriveType::UNHARDENED) der = xprv.Derive(xprv, pos);
365 24199 : if (m_derive == DeriveType::HARDENED) der = xprv.Derive(xprv, pos | 0x80000000UL);
366 24199 : final_extkey = xprv.Neuter();
367 24199 : if (lh_xprv.key.IsValid()) {
368 18197 : last_hardened_extkey = lh_xprv.Neuter();
369 18197 : }
370 24221 : } else {
371 47452 : for (auto entry : m_path) {
372 31142 : if (!parent_extkey.Derive(parent_extkey, entry)) return false;
373 : }
374 16310 : final_extkey = parent_extkey;
375 16310 : if (m_derive == DeriveType::UNHARDENED) der = parent_extkey.Derive(final_extkey, pos);
376 16310 : assert(m_derive != DeriveType::HARDENED);
377 : }
378 376431 : if (!der) return false;
379 :
380 376431 : final_info_out = final_info_out_tmp;
381 376431 : key_out = final_extkey.pubkey;
382 :
383 376431 : if (write_cache) {
384 : // Only cache parent if there is any unhardened derivation
385 3382 : if (m_derive != DeriveType::HARDENED) {
386 1594 : write_cache->CacheParentExtPubKey(m_expr_index, parent_extkey);
387 : // Cache last hardened xpub if we have it
388 1594 : if (last_hardened_extkey.pubkey.IsValid()) {
389 1291 : write_cache->CacheLastHardenedExtPubKey(m_expr_index, last_hardened_extkey);
390 1291 : }
391 3382 : } else if (final_info_out.path.size() > 0) {
392 1788 : write_cache->CacheDerivedExtPubKey(m_expr_index, pos, final_extkey);
393 1788 : }
394 3382 : }
395 :
396 376431 : return true;
397 379605 : }
398 77762 : std::string ToString(bool normalized) const
399 : {
400 77762 : const bool use_apostrophe = !normalized && m_apostrophe;
401 77762 : std::string ret = EncodeExtPubKey(m_root_extkey) + FormatHDKeypath(m_path, /*apostrophe=*/use_apostrophe);
402 77762 : if (IsRange()) {
403 77672 : ret += "/*";
404 77672 : if (m_derive == DeriveType::HARDENED) ret += use_apostrophe ? '\'' : 'h';
405 77672 : }
406 77762 : return ret;
407 77762 : }
408 77688 : std::string ToString() const override
409 : {
410 77688 : return ToString(/*normalized=*/false);
411 : }
412 218 : bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
413 : {
414 218 : CExtKey key;
415 218 : if (!GetExtKey(arg, key)) return false;
416 188 : out = EncodeExtKey(key) + FormatHDKeypath(m_path, /*apostrophe=*/m_apostrophe);
417 188 : if (IsRange()) {
418 152 : out += "/*";
419 152 : if (m_derive == DeriveType::HARDENED) out += m_apostrophe ? '\'' : 'h';
420 152 : }
421 188 : return true;
422 218 : }
423 727 : bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override
424 : {
425 727 : if (m_derive == DeriveType::HARDENED) {
426 4 : out = ToString(/*normalized=*/true);
427 :
428 4 : return true;
429 : }
430 : // Step backwards to find the last hardened step in the path
431 723 : int i = (int)m_path.size() - 1;
432 1420 : for (; i >= 0; --i) {
433 1350 : if (m_path.at(i) >> 31) {
434 653 : break;
435 : }
436 697 : }
437 : // Either no derivation or all unhardened derivation
438 723 : if (i == -1) {
439 70 : out = ToString(/*normalized=*/true);
440 70 : return true;
441 : }
442 : // Get the path to the last hardened stup
443 653 : KeyOriginInfo origin;
444 653 : int k = 0;
445 2634 : for (; k <= i; ++k) {
446 : // Add to the path
447 1981 : origin.path.push_back(m_path.at(k));
448 1981 : }
449 : // Build the remaining path
450 653 : KeyPath end_path;
451 1306 : for (; k < (int)m_path.size(); ++k) {
452 653 : end_path.push_back(m_path.at(k));
453 653 : }
454 : // Get the fingerprint
455 653 : CKeyID id = m_root_extkey.pubkey.GetID();
456 653 : std::copy(id.begin(), id.begin() + 4, origin.fingerprint);
457 :
458 653 : CExtPubKey xpub;
459 653 : CExtKey lh_xprv;
460 : // If we have the cache, just get the parent xpub
461 653 : if (cache != nullptr) {
462 645 : cache->GetCachedLastHardenedExtPubKey(m_expr_index, xpub);
463 645 : }
464 653 : if (!xpub.pubkey.IsValid()) {
465 : // Cache miss, or nor cache, or need privkey
466 8 : CExtKey xprv;
467 8 : if (!GetDerivedExtKey(arg, xprv, lh_xprv)) return false;
468 8 : xpub = lh_xprv.Neuter();
469 8 : }
470 653 : assert(xpub.pubkey.IsValid());
471 :
472 : // Build the string
473 653 : std::string origin_str = HexStr(origin.fingerprint) + FormatHDKeypath(origin.path);
474 653 : out = "[" + origin_str + "]" + EncodeExtPubKey(xpub) + FormatHDKeypath(end_path);
475 653 : if (IsRange()) {
476 645 : out += "/*";
477 645 : assert(m_derive == DeriveType::UNHARDENED);
478 645 : }
479 653 : return true;
480 727 : }
481 6591 : bool GetPrivKey(int pos, const SigningProvider& arg, CKey& key) const override
482 : {
483 6591 : CExtKey extkey;
484 6591 : CExtKey dummy;
485 6591 : if (!GetDerivedExtKey(arg, extkey, dummy)) return false;
486 5846 : if (m_derive == DeriveType::UNHARDENED && !extkey.Derive(extkey, pos)) return false;
487 5846 : if (m_derive == DeriveType::HARDENED && !extkey.Derive(extkey, pos | 0x80000000UL)) return false;
488 5846 : key = extkey.key;
489 5846 : return true;
490 6591 : }
491 : };
492 :
493 : /** Base class for all Descriptor implementations. */
494 : class DescriptorImpl : public Descriptor
495 : {
496 : //! Public key arguments for this descriptor (size 1 for PK, PKH; any size for Multisig).
497 : const std::vector<std::unique_ptr<PubkeyProvider>> m_pubkey_args;
498 : //! The string name of the descriptor function.
499 : const std::string m_name;
500 :
501 : protected:
502 : //! The sub-descriptor arguments (empty for everything but SH and WSH).
503 : //! In doc/descriptors.m this is referred to as SCRIPT expressions sh(SCRIPT)
504 : //! and wsh(SCRIPT), and distinct from KEY expressions and ADDR expressions.
505 : //! Subdescriptors can only ever generate a single script.
506 : const std::vector<std::unique_ptr<DescriptorImpl>> m_subdescriptor_args;
507 :
508 : //! Return a serialization of anything except pubkey and script arguments, to be prepended to those.
509 251480 : virtual std::string ToStringExtra() const { return ""; }
510 :
511 : /** A helper function to construct the scripts for this descriptor.
512 : *
513 : * This function is invoked once by ExpandHelper.
514 : *
515 : * @param pubkeys The evaluations of the m_pubkey_args field.
516 : * @param scripts The evaluations of m_subdescriptor_args (one for each m_subdescriptor_args element).
517 : * @param out A FlatSigningProvider to put scripts or public keys in that are necessary to the solver.
518 : * The origin info of the provided pubkeys is automatically added.
519 : * @return A vector with scriptPubKeys for this descriptor.
520 : */
521 : virtual std::vector<CScript> MakeScripts(const std::vector<CPubKey>& pubkeys, Span<const CScript> scripts, FlatSigningProvider& out) const = 0;
522 :
523 : public:
524 292570 : DescriptorImpl(std::vector<std::unique_ptr<PubkeyProvider>> pubkeys, const std::string& name) : m_pubkey_args(std::move(pubkeys)), m_name(name), m_subdescriptor_args() {}
525 36722 : 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))) {}
526 :
527 : enum class StringType
528 : {
529 : PUBLIC,
530 : PRIVATE,
531 : NORMALIZED,
532 : };
533 :
534 456 : bool IsSolvable() const override
535 : {
536 582 : for (const auto& arg : m_subdescriptor_args) {
537 126 : if (!arg->IsSolvable()) return false;
538 : }
539 456 : return true;
540 456 : }
541 :
542 103961 : bool IsRange() const final
543 : {
544 121348 : for (const auto& pubkey : m_pubkey_args) {
545 99896 : if (pubkey->IsRange()) return true;
546 : }
547 21700 : for (const auto& arg : m_subdescriptor_args) {
548 1120 : if (arg->IsRange()) return true;
549 : }
550 20580 : return false;
551 103961 : }
552 :
553 285575 : virtual bool ToStringSubScriptHelper(const SigningProvider* arg, std::string& ret, const StringType type, const DescriptorCache* cache = nullptr) const
554 : {
555 285575 : size_t pos = 0;
556 322629 : for (const auto& scriptarg : m_subdescriptor_args) {
557 37072 : if (pos++) ret += ",";
558 37072 : std::string tmp;
559 37072 : if (!scriptarg->ToStringHelper(arg, tmp, type, cache)) return false;
560 37054 : ret += tmp;
561 37072 : }
562 285557 : return true;
563 285575 : }
564 :
565 285643 : bool ToStringHelper(const SigningProvider* arg, std::string& out, const StringType type, const DescriptorCache* cache = nullptr) const
566 : {
567 285643 : std::string extra = ToStringExtra();
568 285643 : size_t pos = extra.size() > 0 ? 1 : 0;
569 285643 : std::string ret = m_name + "(" + extra;
570 503057 : for (const auto& pubkey : m_pubkey_args) {
571 217482 : if (pos++) ret += ",";
572 217482 : std::string tmp;
573 217482 : switch (type) {
574 : case StringType::NORMALIZED:
575 812 : if (!pubkey->ToNormalizedString(*arg, tmp, cache)) return false;
576 812 : break;
577 : case StringType::PRIVATE:
578 324 : if (!pubkey->ToPrivateString(*arg, tmp)) return false;
579 256 : break;
580 : case StringType::PUBLIC:
581 216346 : tmp = pubkey->ToString();
582 216346 : break;
583 : }
584 217414 : ret += tmp;
585 217482 : }
586 285575 : std::string subscript;
587 285575 : if (!ToStringSubScriptHelper(arg, subscript, type, cache)) return false;
588 285557 : if (pos && subscript.size()) ret += ',';
589 285557 : out = std::move(ret) + std::move(subscript) + ")";
590 285557 : return true;
591 285643 : }
592 :
593 247515 : std::string ToString() const final
594 : {
595 247515 : std::string ret;
596 247515 : ToStringHelper(nullptr, ret, StringType::PUBLIC);
597 247515 : return AddChecksum(ret);
598 247515 : }
599 :
600 298 : bool ToPrivateString(const SigningProvider& arg, std::string& out) const override
601 : {
602 298 : bool ret = ToStringHelper(&arg, out, StringType::PRIVATE);
603 298 : out = AddChecksum(out);
604 298 : return ret;
605 : }
606 :
607 758 : bool ToNormalizedString(const SigningProvider& arg, std::string& out, const DescriptorCache* cache) const override final
608 : {
609 758 : bool ret = ToStringHelper(&arg, out, StringType::NORMALIZED, cache);
610 758 : out = AddChecksum(out);
611 758 : return ret;
612 : }
613 :
614 439491 : bool ExpandHelper(int pos, const SigningProvider& arg, const DescriptorCache* read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache) const
615 : {
616 439491 : std::vector<std::pair<CPubKey, KeyOriginInfo>> entries;
617 439491 : entries.reserve(m_pubkey_args.size());
618 :
619 : // Construct temporary data in `entries`, `subscripts`, and `subprovider` to avoid producing output in case of failure.
620 948993 : for (const auto& p : m_pubkey_args) {
621 512676 : entries.emplace_back();
622 512676 : if (!p->GetPubKey(pos, arg, entries.back().first, entries.back().second, read_cache, write_cache)) return false;
623 : }
624 436317 : std::vector<CScript> subscripts;
625 436317 : FlatSigningProvider subprovider;
626 466765 : for (const auto& subarg : m_subdescriptor_args) {
627 30700 : std::vector<CScript> outscripts;
628 30700 : if (!subarg->ExpandHelper(pos, arg, read_cache, outscripts, subprovider, write_cache)) return false;
629 30448 : assert(outscripts.size() == 1);
630 30448 : subscripts.emplace_back(std::move(outscripts[0]));
631 30700 : }
632 436065 : out.Merge(std::move(subprovider));
633 :
634 436065 : std::vector<CPubKey> pubkeys;
635 436065 : pubkeys.reserve(entries.size());
636 945567 : for (auto& entry : entries) {
637 509502 : pubkeys.push_back(entry.first);
638 509502 : out.origins.emplace(entry.first.GetID(), std::make_pair<CPubKey, KeyOriginInfo>(CPubKey(entry.first), std::move(entry.second)));
639 : }
640 :
641 436065 : output_scripts = MakeScripts(pubkeys, Span{subscripts}, out);
642 436065 : return true;
643 439491 : }
644 :
645 175939 : bool Expand(int pos, const SigningProvider& provider, std::vector<CScript>& output_scripts, FlatSigningProvider& out, DescriptorCache* write_cache = nullptr) const final
646 : {
647 175939 : return ExpandHelper(pos, provider, nullptr, output_scripts, out, write_cache);
648 : }
649 :
650 232852 : bool ExpandFromCache(int pos, const DescriptorCache& read_cache, std::vector<CScript>& output_scripts, FlatSigningProvider& out) const final
651 : {
652 232852 : return ExpandHelper(pos, DUMMY_SIGNING_PROVIDER, &read_cache, output_scripts, out, nullptr);
653 : }
654 :
655 16464 : void ExpandPrivate(int pos, const SigningProvider& provider, FlatSigningProvider& out) const final
656 : {
657 32977 : for (const auto& p : m_pubkey_args) {
658 16513 : CKey key;
659 16513 : if (!p->GetPrivKey(pos, provider, key)) continue;
660 15679 : out.keys.emplace(key.GetPubKey().GetID(), key);
661 16513 : }
662 16599 : for (const auto& arg : m_subdescriptor_args) {
663 135 : arg->ExpandPrivate(pos, provider, out);
664 : }
665 16464 : }
666 10 : std::optional<OutputType> GetOutputType() const override { return std::nullopt; }
667 : };
668 :
669 : /** A parsed addr(A) descriptor. */
670 : class AddressDescriptor final : public DescriptorImpl
671 : {
672 : const CTxDestination m_destination;
673 : protected:
674 32846 : std::string ToStringExtra() const override { return EncodeDestination(m_destination); }
675 1320 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForDestination(m_destination)); }
676 : public:
677 67970 : AddressDescriptor(CTxDestination destination) : DescriptorImpl({}, "addr"), m_destination(std::move(destination)) {}
678 0 : bool IsSolvable() const final { return false; }
679 :
680 23 : std::optional<OutputType> GetOutputType() const override
681 : {
682 23 : switch (m_destination.index()) {
683 : case 1 /* PKHash */:
684 23 : case 2 /* ScriptHash */: return OutputType::LEGACY;
685 0 : case 0 /* CNoDestination */:
686 0 : default: return std::nullopt;
687 : }
688 23 : }
689 0 : bool IsSingleType() const final { return true; }
690 4 : bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }
691 : };
692 :
693 : /** A parsed raw(H) descriptor. */
694 : class RawDescriptor final : public DescriptorImpl
695 : {
696 : const CScript m_script;
697 : protected:
698 441 : std::string ToStringExtra() const override { return HexStr(m_script); }
699 2874 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript>, FlatSigningProvider&) const override { return Vector(m_script); }
700 : public:
701 6366 : RawDescriptor(CScript script) : DescriptorImpl({}, "raw"), m_script(std::move(script)) {}
702 0 : bool IsSolvable() const final { return false; }
703 :
704 2 : std::optional<OutputType> GetOutputType() const override
705 : {
706 2 : CTxDestination dest;
707 2 : ExtractDestination(m_script, dest);
708 2 : switch (dest.index()) {
709 : case 1 /* PKHash */:
710 2 : case 2 /* ScriptHash */: return OutputType::LEGACY;
711 0 : case 0 /* CNoDestination */:
712 0 : default: return std::nullopt;
713 : }
714 2 : }
715 0 : bool IsSingleType() const final { return true; }
716 0 : bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; }
717 : };
718 :
719 : /** A parsed pk(P) descriptor. */
720 : class PKDescriptor final : public DescriptorImpl
721 : {
722 : protected:
723 665 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override { return Vector(GetScriptForRawPubKey(keys[0])); }
724 : public:
725 74058 : PKDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "pk") {}
726 8 : std::optional<OutputType> GetOutputType() const override { return OutputType::LEGACY; }
727 2 : bool IsSingleType() const final { return true; }
728 : };
729 :
730 : /** A parsed pkh(P) descriptor. */
731 : class PKHDescriptor final : public DescriptorImpl
732 : {
733 : protected:
734 333101 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider& out) const override
735 : {
736 333101 : CKeyID id = keys[0].GetID();
737 333101 : out.pubkeys.emplace(id, keys[0]);
738 333101 : return Vector(GetScriptForDestination(PKHash(id)));
739 0 : }
740 : public:
741 434486 : PKHDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "pkh") {}
742 8140 : std::optional<OutputType> GetOutputType() const override { return OutputType::LEGACY; }
743 38573 : bool IsSingleType() const final { return true; }
744 : };
745 :
746 : /** A parsed multi(...) or sortedmulti(...) descriptor */
747 : class MultisigDescriptor final : public DescriptorImpl
748 : {
749 : const int m_threshold;
750 : const bool m_sorted;
751 : protected:
752 876 : std::string ToStringExtra() const override { return strprintf("%i", m_threshold); }
753 30091 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript>, FlatSigningProvider&) const override {
754 30091 : if (m_sorted) {
755 1578 : std::vector<CPubKey> sorted_keys(keys);
756 1578 : std::sort(sorted_keys.begin(), sorted_keys.end());
757 1578 : return Vector(GetScriptForMultisig(m_threshold, sorted_keys));
758 1578 : }
759 28513 : return Vector(GetScriptForMultisig(m_threshold, keys));
760 30091 : }
761 : public:
762 950 : 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) {}
763 0 : bool IsSingleType() const final { return true; }
764 : };
765 :
766 : /** A parsed sh(...) descriptor. */
767 : class SHDescriptor final : public DescriptorImpl
768 : {
769 : protected:
770 30448 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>&, Span<const CScript> scripts, FlatSigningProvider& out) const override
771 : {
772 30448 : auto ret = Vector(GetScriptForDestination(ScriptHash(scripts[0])));
773 30448 : if (ret.size()) out.scripts.emplace(CScriptID(scripts[0]), scripts[0]);
774 30448 : return ret;
775 30448 : }
776 : public:
777 73444 : SHDescriptor(std::unique_ptr<DescriptorImpl> desc) : DescriptorImpl({}, std::move(desc), "sh") {}
778 :
779 136 : std::optional<OutputType> GetOutputType() const override
780 : {
781 136 : assert(m_subdescriptor_args.size() == 1);
782 136 : return OutputType::LEGACY;
783 : }
784 488 : bool IsSingleType() const final { return true; }
785 : };
786 :
787 : /** A parsed combo(P) descriptor. */
788 : class ComboDescriptor final : public DescriptorImpl
789 : {
790 : protected:
791 37566 : std::vector<CScript> MakeScripts(const std::vector<CPubKey>& keys, Span<const CScript> scripts, FlatSigningProvider& out) const override
792 : {
793 37566 : std::vector<CScript> ret;
794 37566 : CKeyID id = keys[0].GetID();
795 37566 : out.pubkeys.emplace(id, keys[0]);
796 37566 : ret.emplace_back(GetScriptForRawPubKey(keys[0])); // P2PK
797 37566 : if (keys[0].IsCompressed()) {
798 37542 : CScript p2pkh = GetScriptForDestination(PKHash(id));
799 37542 : out.scripts.emplace(CScriptID(p2pkh), p2pkh);
800 37542 : ret.emplace_back(p2pkh);
801 37542 : ret.emplace_back(GetScriptForDestination(ScriptHash(p2pkh))); // P2SH-P2PKH
802 37542 : }
803 37566 : return ret;
804 37566 : }
805 :
806 : public:
807 1310 : ComboDescriptor(std::unique_ptr<PubkeyProvider> prov) : DescriptorImpl(Vector(std::move(prov)), "combo") {}
808 282 : std::optional<OutputType> GetOutputType() const override { return OutputType::LEGACY; }
809 2 : bool IsSingleType() const final { return false; }
810 : };
811 :
812 : ////////////////////////////////////////////////////////////////////////////
813 : // Parser //
814 : ////////////////////////////////////////////////////////////////////////////
815 :
816 : enum class ParseScriptContext {
817 : TOP, //!< Top-level context (script goes directly in scriptPubKey)
818 : P2SH, //!< Inside sh() (script becomes P2SH redeemScript)
819 : };
820 :
821 : /**
822 : * Parse a key path, being passed a split list of elements (the first element is ignored).
823 : *
824 : * @param[in] split BIP32 path string, using either ' or h for hardened derivation
825 : * @param[out] out the key path
826 : * @param[out] apostrophe only updated if hardened derivation is found
827 : * @param[out] error parsing error message
828 : * @returns false if parsing failed
829 : **/
830 3049 : [[nodiscard]] bool ParseKeyPath(const std::vector<Span<const char>>& split, KeyPath& out, bool& apostrophe, std::string& error)
831 : {
832 14281 : for (size_t i = 1; i < split.size(); ++i) {
833 11236 : Span<const char> elem = split[i];
834 11236 : bool hardened = false;
835 11236 : if (elem.size() > 0) {
836 11236 : const char last = elem[elem.size() - 1];
837 11236 : if (last == '\'' || last == 'h') {
838 8352 : elem = elem.first(elem.size() - 1);
839 8352 : hardened = true;
840 8352 : apostrophe = last == '\'';
841 8352 : }
842 11236 : }
843 : uint32_t p;
844 11236 : if (!ParseUInt32(std::string(elem.begin(), elem.end()), &p)) {
845 2 : error = strprintf("Key path value '%s' is not a valid uint32", std::string(elem.begin(), elem.end()));
846 2 : return false;
847 11234 : } else if (p > 0x7FFFFFFFUL) {
848 2 : error = strprintf("Key path value %u is out of range", p);
849 2 : return false;
850 : }
851 11232 : out.push_back(p | (((uint32_t)hardened) << 31));
852 11232 : }
853 3045 : return true;
854 3049 : }
855 :
856 : /** Parse a public key that excludes origin information. */
857 3716 : std::unique_ptr<PubkeyProvider> ParsePubkeyInner(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, bool& apostrophe, std::string& error)
858 : {
859 : using namespace spanparsing;
860 :
861 3716 : bool permit_uncompressed = ctx == ParseScriptContext::TOP || ctx == ParseScriptContext::P2SH;
862 3716 : auto split = Split(sp, '/');
863 3716 : std::string str(split[0].begin(), split[0].end());
864 3716 : if (str.size() == 0) {
865 0 : error = "No key provided";
866 0 : return nullptr;
867 : }
868 3716 : if (split.size() == 1) {
869 921 : if (IsHex(str)) {
870 563 : std::vector<unsigned char> data = ParseHex(str);
871 563 : CPubKey pubkey(data);
872 563 : if (pubkey.IsFullyValid()) {
873 563 : if (permit_uncompressed || pubkey.IsCompressed()) {
874 563 : return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey);
875 : } else {
876 0 : error = "Uncompressed keys are not allowed";
877 0 : return nullptr;
878 : }
879 : }
880 0 : error = strprintf("Pubkey '%s' is invalid", str);
881 0 : return nullptr;
882 563 : }
883 358 : CKey key = DecodeSecret(str);
884 358 : if (key.IsValid()) {
885 333 : if (permit_uncompressed || key.IsCompressed()) {
886 333 : CPubKey pubkey = key.GetPubKey();
887 333 : out.keys.emplace(pubkey.GetID(), key);
888 333 : return std::make_unique<ConstPubkeyProvider>(key_exp_index, pubkey);
889 : } else {
890 0 : error = "Uncompressed keys are not allowed";
891 0 : return nullptr;
892 : }
893 : }
894 358 : }
895 2820 : CExtKey extkey = DecodeExtKey(str);
896 2820 : CExtPubKey extpubkey = DecodeExtPubKey(str);
897 2820 : if (!extkey.key.IsValid() && !extpubkey.pubkey.IsValid()) {
898 5 : error = strprintf("key '%s' is not valid", str);
899 5 : return nullptr;
900 : }
901 2815 : KeyPath path;
902 2815 : DeriveType type = DeriveType::NO;
903 2815 : if (split.back() == Span{"*"}.first(1)) {
904 2636 : split.pop_back();
905 2636 : type = DeriveType::UNHARDENED;
906 2815 : } else if (split.back() == Span{"*'"}.first(2) || split.back() == Span{"*h"}.first(2)) {
907 63 : apostrophe = split.back() == Span{"*'"}.first(2);
908 63 : split.pop_back();
909 63 : type = DeriveType::HARDENED;
910 63 : }
911 2815 : if (!ParseKeyPath(split, path, apostrophe, error)) return nullptr;
912 2811 : if (extkey.key.IsValid()) {
913 258 : extpubkey = extkey.Neuter();
914 258 : out.keys.emplace(extpubkey.pubkey.GetID(), extkey.key);
915 258 : }
916 2811 : return std::make_unique<BIP32PubkeyProvider>(key_exp_index, extpubkey, std::move(path), type, apostrophe);
917 3716 : }
918 :
919 : /** Parse a public key including origin information (if enabled). */
920 3722 : std::unique_ptr<PubkeyProvider> ParsePubkey(uint32_t key_exp_index, const Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
921 : {
922 : using namespace spanparsing;
923 :
924 3722 : auto origin_split = Split(sp, ']');
925 3722 : if (origin_split.size() > 2) {
926 2 : error = "Multiple ']' characters found for a single pubkey";
927 2 : return nullptr;
928 : }
929 3720 : bool apostrophe = false;
930 3720 : if (origin_split.size() == 1) return ParsePubkeyInner(key_exp_index, origin_split[0], ctx, out, apostrophe, error);
931 238 : if (origin_split[0].empty() || origin_split[0][0] != '[') {
932 2 : error = strprintf("Key origin start '[ character expected but not found, got '%c' instead",
933 2 : origin_split[0].empty() ? /** empty, implies split char */ ']' : origin_split[0][0]);
934 2 : return nullptr;
935 : }
936 236 : auto slash_split = Split(origin_split[0].subspan(1), '/');
937 236 : if (slash_split[0].size() != 8) {
938 2 : error = strprintf("Fingerprint is not 4 bytes (%u characters instead of 8 characters)", slash_split[0].size());
939 2 : return nullptr;
940 : }
941 234 : std::string fpr_hex = std::string(slash_split[0].begin(), slash_split[0].end());
942 234 : if (!IsHex(fpr_hex)) {
943 0 : error = strprintf("Fingerprint '%s' is not hex", fpr_hex);
944 0 : return nullptr;
945 : }
946 234 : auto fpr_bytes = ParseHex(fpr_hex);
947 234 : KeyOriginInfo info;
948 : static_assert(sizeof(info.fingerprint) == 4, "Fingerprint must be 4 bytes");
949 234 : assert(fpr_bytes.size() == 4);
950 234 : std::copy(fpr_bytes.begin(), fpr_bytes.end(), info.fingerprint);
951 234 : if (!ParseKeyPath(slash_split, info.path, apostrophe, error)) return nullptr;
952 234 : auto provider = ParsePubkeyInner(key_exp_index, origin_split[1], ctx, out, apostrophe, error);
953 234 : if (!provider) return nullptr;
954 234 : return std::make_unique<OriginPubkeyProvider>(key_exp_index, std::move(info), std::move(provider), apostrophe);
955 3722 : }
956 :
957 : /** Parse a script in a particular context. */
958 6640 : std::unique_ptr<DescriptorImpl> ParseScript(uint32_t& key_exp_index, Span<const char>& sp, ParseScriptContext ctx, FlatSigningProvider& out, std::string& error)
959 : {
960 : using namespace spanparsing;
961 :
962 6640 : auto expr = Expr(sp);
963 6640 : bool sorted_multi = false;
964 6640 : if (Func("pk", expr)) {
965 26 : auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
966 26 : if (!pubkey) {
967 0 : error = strprintf("pk(): %s", error);
968 0 : return nullptr;
969 : }
970 26 : ++key_exp_index;
971 26 : return std::make_unique<PKDescriptor>(std::move(pubkey));
972 26 : }
973 6614 : if (Func("pkh", expr)) {
974 2595 : auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
975 2595 : if (!pubkey) {
976 8 : error = strprintf("pkh(): %s", error);
977 8 : return nullptr;
978 : }
979 2587 : ++key_exp_index;
980 2587 : return std::make_unique<PKHDescriptor>(std::move(pubkey));
981 2595 : }
982 7917 : if (ctx == ParseScriptContext::TOP && Func("combo", expr)) {
983 657 : auto pubkey = ParsePubkey(key_exp_index, expr, ctx, out, error);
984 657 : if (!pubkey) {
985 2 : error = strprintf("combo(): %s", error);
986 2 : return nullptr;
987 : }
988 655 : ++key_exp_index;
989 655 : return std::make_unique<ComboDescriptor>(std::move(pubkey));
990 4019 : } else if (Func("combo", expr)) {
991 2 : error = "Can only have combo() at top level";
992 2 : return nullptr;
993 : }
994 3360 : if ((sorted_multi = Func("sortedmulti", expr)) || Func("multi", expr)) {
995 145 : auto threshold = Expr(expr);
996 : uint32_t thres;
997 145 : std::vector<std::unique_ptr<PubkeyProvider>> providers;
998 145 : if (!ParseUInt32(std::string(threshold.begin(), threshold.end()), &thres)) {
999 2 : error = strprintf("Multi threshold '%s' is not valid", std::string(threshold.begin(), threshold.end()));
1000 2 : return nullptr;
1001 : }
1002 143 : size_t script_size = 0;
1003 582 : while (expr.size()) {
1004 444 : if (!Const(",", expr)) {
1005 0 : error = strprintf("Multi: expected ',', got '%c'", expr[0]);
1006 0 : return nullptr;
1007 : }
1008 444 : auto arg = Expr(expr);
1009 444 : auto pk = ParsePubkey(key_exp_index, arg, ctx, out, error);
1010 444 : if (!pk) {
1011 5 : error = strprintf("Multi: %s", error);
1012 5 : return nullptr;
1013 : }
1014 439 : script_size += pk->GetSize() + 1;
1015 439 : providers.emplace_back(std::move(pk));
1016 439 : key_exp_index++;
1017 444 : }
1018 138 : if (providers.empty() || providers.size() > MAX_PUBKEYS_PER_MULTISIG) {
1019 0 : error = strprintf("Cannot have %u keys in multisig; must have between 1 and %d keys, inclusive", providers.size(), MAX_PUBKEYS_PER_MULTISIG);
1020 0 : return nullptr;
1021 138 : } else if (thres < 1) {
1022 1 : error = strprintf("Multisig threshold cannot be %d, must be at least 1", thres);
1023 1 : return nullptr;
1024 137 : } else if (thres > providers.size()) {
1025 1 : error = strprintf("Multisig threshold cannot be larger than the number of keys; threshold is %d but only %u keys specified", thres, providers.size());
1026 1 : return nullptr;
1027 : }
1028 136 : if (ctx == ParseScriptContext::TOP) {
1029 23 : if (providers.size() > 3) {
1030 1 : error = strprintf("Cannot have %u pubkeys in bare multisig; only at most 3 pubkeys", providers.size());
1031 1 : return nullptr;
1032 : }
1033 22 : }
1034 135 : if (ctx == ParseScriptContext::P2SH) {
1035 : // This limits the maximum number of compressed pubkeys to 15.
1036 113 : if (script_size + 3 > MAX_SCRIPT_ELEMENT_SIZE) {
1037 2 : error = strprintf("P2SH script is too large, %d bytes is larger than %d bytes", script_size + 3, MAX_SCRIPT_ELEMENT_SIZE);
1038 2 : return nullptr;
1039 : }
1040 111 : }
1041 133 : return std::make_unique<MultisigDescriptor>(thres, std::move(providers), sorted_multi);
1042 145 : }
1043 6426 : if (ctx == ParseScriptContext::TOP && Func("sh", expr)) {
1044 267 : auto desc = ParseScript(key_exp_index, expr, ParseScriptContext::P2SH, out, error);
1045 267 : if (!desc || expr.size()) return nullptr;
1046 257 : return std::make_unique<SHDescriptor>(std::move(desc));
1047 3215 : } else if (Func("sh", expr)) {
1048 2 : error = "Can only have sh() at top level";
1049 2 : return nullptr;
1050 : }
1051 5890 : if (ctx == ParseScriptContext::TOP && Func("addr", expr)) {
1052 58 : CTxDestination dest = DecodeDestination(std::string(expr.begin(), expr.end()));
1053 58 : if (!IsValidDestination(dest)) {
1054 7 : error = "Address is not valid";
1055 7 : return nullptr;
1056 : }
1057 51 : return std::make_unique<AddressDescriptor>(std::move(dest));
1058 2888 : } else if (Func("addr", expr)) {
1059 0 : error = "Can only have addr() at top level";
1060 0 : return nullptr;
1061 : }
1062 5774 : if (ctx == ParseScriptContext::TOP && Func("raw", expr)) {
1063 2863 : std::string str(expr.begin(), expr.end());
1064 2863 : if (!IsHex(str)) {
1065 1 : error = "Raw script is not hex";
1066 1 : return nullptr;
1067 : }
1068 2862 : auto bytes = ParseHex(str);
1069 2862 : return std::make_unique<RawDescriptor>(CScript(bytes.begin(), bytes.end()));
1070 2888 : } else if (Func("raw", expr)) {
1071 0 : error = "Can only have raw() at top level";
1072 0 : return nullptr;
1073 : }
1074 25 : if (ctx == ParseScriptContext::P2SH) {
1075 2 : error = "A function is needed within P2SH";
1076 2 : return nullptr;
1077 : }
1078 23 : error = strprintf("'%s' is not a valid descriptor function", std::string(expr.begin(), expr.end()));
1079 23 : return nullptr;
1080 6640 : }
1081 :
1082 252885 : std::unique_ptr<PubkeyProvider> InferPubkey(const CPubKey& pubkey, ParseScriptContext, const SigningProvider& provider)
1083 : {
1084 252885 : std::unique_ptr<PubkeyProvider> key_provider = std::make_unique<ConstPubkeyProvider>(0, pubkey);
1085 252885 : KeyOriginInfo info;
1086 252885 : if (provider.GetKeyOrigin(pubkey.GetID(), info)) {
1087 252053 : return std::make_unique<OriginPubkeyProvider>(0, std::move(info), std::move(key_provider), /*apostrophe=*/false);
1088 : }
1089 832 : return key_provider;
1090 252885 : }
1091 :
1092 322721 : std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
1093 : {
1094 322721 : std::vector<std::vector<unsigned char>> data;
1095 322721 : TxoutType txntype = Solver(script, data);
1096 :
1097 322721 : if (txntype == TxoutType::PUBKEY) {
1098 37003 : CPubKey pubkey(data[0]);
1099 37003 : if (pubkey.IsValid()) {
1100 37003 : return std::make_unique<PKDescriptor>(InferPubkey(pubkey, ctx, provider));
1101 : }
1102 0 : }
1103 285718 : if (txntype == TxoutType::PUBKEYHASH) {
1104 235398 : uint160 hash(data[0]);
1105 235398 : CKeyID keyid(hash);
1106 235398 : CPubKey pubkey;
1107 235398 : if (provider.GetPubKey(keyid, pubkey)) {
1108 214656 : return std::make_unique<PKHDescriptor>(InferPubkey(pubkey, ctx, provider));
1109 : }
1110 20742 : }
1111 71062 : if (txntype == TxoutType::MULTISIG) {
1112 342 : std::vector<std::unique_ptr<PubkeyProvider>> providers;
1113 1568 : for (size_t i = 1; i + 1 < data.size(); ++i) {
1114 1226 : CPubKey pubkey(data[i]);
1115 1226 : providers.push_back(InferPubkey(pubkey, ctx, provider));
1116 1226 : }
1117 342 : return std::make_unique<MultisigDescriptor>((int)data[0][0], std::move(providers));
1118 342 : }
1119 70720 : if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
1120 49657 : uint160 hash(data[0]);
1121 49657 : CScriptID scriptid(hash);
1122 49657 : CScript subscript;
1123 49657 : if (provider.GetCScript(scriptid, subscript)) {
1124 36465 : auto sub = InferScript(subscript, ParseScriptContext::P2SH, provider);
1125 36465 : if (sub) return std::make_unique<SHDescriptor>(std::move(sub));
1126 36465 : }
1127 49657 : }
1128 :
1129 34255 : CTxDestination dest;
1130 34255 : if (ExtractDestination(script, dest)) {
1131 33934 : if (GetScriptForDestination(dest) == script) {
1132 33934 : return std::make_unique<AddressDescriptor>(std::move(dest));
1133 : }
1134 0 : }
1135 :
1136 321 : return std::make_unique<RawDescriptor>(script);
1137 322721 : }
1138 :
1139 :
1140 : } // namespace
1141 :
1142 : /** Check a descriptor checksum, and update desc to be the checksum-less part. */
1143 6488 : bool CheckChecksum(Span<const char>& sp, bool require_checksum, std::string& error, std::string* out_checksum = nullptr)
1144 : {
1145 : using namespace spanparsing;
1146 :
1147 6488 : auto check_split = Split(sp, '#');
1148 6488 : if (check_split.size() > 2) {
1149 2 : error = "Multiple '#' symbols";
1150 2 : return false;
1151 : }
1152 6486 : if (check_split.size() == 1 && require_checksum){
1153 20 : error = "Missing checksum";
1154 20 : return false;
1155 : }
1156 6466 : if (check_split.size() == 2) {
1157 4930 : if (check_split[1].size() != 8) {
1158 6 : error = strprintf("Expected 8 character checksum, not %u characters", check_split[1].size());
1159 6 : return false;
1160 : }
1161 4924 : }
1162 6460 : auto checksum = DescriptorChecksum(check_split[0]);
1163 6460 : if (checksum.empty()) {
1164 1 : error = "Invalid characters in payload";
1165 1 : return false;
1166 : }
1167 6459 : if (check_split.size() == 2) {
1168 4923 : if (!std::equal(checksum.begin(), checksum.end(), check_split[1].begin())) {
1169 14 : error = strprintf("Provided checksum '%s' does not match computed checksum '%s'", std::string(check_split[1].begin(), check_split[1].end()), checksum);
1170 14 : return false;
1171 : }
1172 4909 : }
1173 6445 : if (out_checksum) *out_checksum = std::move(checksum);
1174 6445 : sp = check_split[0];
1175 6445 : return true;
1176 6488 : }
1177 :
1178 6414 : std::unique_ptr<Descriptor> Parse(const std::string& descriptor, FlatSigningProvider& out, std::string& error, bool require_checksum)
1179 : {
1180 6414 : Span<const char> sp{descriptor};
1181 6414 : if (!CheckChecksum(sp, require_checksum, error)) return nullptr;
1182 6373 : uint32_t key_exp_index = 0;
1183 6373 : auto ret = ParseScript(key_exp_index, sp, ParseScriptContext::TOP, out, error);
1184 6373 : if (sp.size() == 0 && ret) return std::unique_ptr<Descriptor>(std::move(ret));
1185 59 : return nullptr;
1186 6414 : }
1187 :
1188 74 : std::string GetDescriptorChecksum(const std::string& descriptor)
1189 : {
1190 74 : std::string ret;
1191 74 : std::string error;
1192 74 : Span<const char> sp{descriptor};
1193 74 : if (!CheckChecksum(sp, false, error, &ret)) return "";
1194 72 : return ret;
1195 74 : }
1196 :
1197 286256 : std::unique_ptr<Descriptor> InferDescriptor(const CScript& script, const SigningProvider& provider)
1198 : {
1199 286256 : return InferScript(script, ParseScriptContext::TOP, provider);
1200 : }
1201 :
1202 2985 : uint256 DescriptorID(const Descriptor& desc)
1203 : {
1204 2985 : std::string desc_str = desc.ToString();
1205 2985 : uint256 id;
1206 2985 : CSHA256().Write((unsigned char*)desc_str.data(), desc_str.size()).Finalize(id.begin());
1207 : return id;
1208 2985 : }
1209 :
1210 5550 : void DescriptorCache::CacheParentExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
1211 : {
1212 5550 : m_parent_xpubs[key_exp_pos] = xpub;
1213 5550 : }
1214 :
1215 5364 : void DescriptorCache::CacheDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, const CExtPubKey& xpub)
1216 : {
1217 5364 : auto& xpubs = m_derived_xpubs[key_exp_pos];
1218 5364 : xpubs[der_index] = xpub;
1219 5364 : }
1220 :
1221 4840 : void DescriptorCache::CacheLastHardenedExtPubKey(uint32_t key_exp_pos, const CExtPubKey& xpub)
1222 : {
1223 4840 : m_last_hardened_xpubs[key_exp_pos] = xpub;
1224 4840 : }
1225 :
1226 338409 : bool DescriptorCache::GetCachedParentExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
1227 : {
1228 338409 : const auto& it = m_parent_xpubs.find(key_exp_pos);
1229 338409 : if (it == m_parent_xpubs.end()) return false;
1230 335615 : xpub = it->second;
1231 335615 : return true;
1232 338409 : }
1233 :
1234 340862 : bool DescriptorCache::GetCachedDerivedExtPubKey(uint32_t key_exp_pos, uint32_t der_index, CExtPubKey& xpub) const
1235 : {
1236 340862 : const auto& key_exp_it = m_derived_xpubs.find(key_exp_pos);
1237 340862 : if (key_exp_it == m_derived_xpubs.end()) return false;
1238 3877 : const auto& der_it = key_exp_it->second.find(der_index);
1239 3877 : if (der_it == key_exp_it->second.end()) return false;
1240 319 : xpub = der_it->second;
1241 319 : return true;
1242 340862 : }
1243 :
1244 1912 : bool DescriptorCache::GetCachedLastHardenedExtPubKey(uint32_t key_exp_pos, CExtPubKey& xpub) const
1245 : {
1246 1912 : const auto& it = m_last_hardened_xpubs.find(key_exp_pos);
1247 1912 : if (it == m_last_hardened_xpubs.end()) return false;
1248 645 : xpub = it->second;
1249 645 : return true;
1250 1912 : }
1251 :
1252 154632 : DescriptorCache DescriptorCache::MergeAndDiff(const DescriptorCache& other)
1253 : {
1254 154632 : DescriptorCache diff;
1255 156102 : for (const auto& parent_xpub_pair : other.GetCachedParentExtPubKeys()) {
1256 1470 : CExtPubKey xpub;
1257 1470 : if (GetCachedParentExtPubKey(parent_xpub_pair.first, xpub)) {
1258 12 : if (xpub != parent_xpub_pair.second) {
1259 0 : throw std::runtime_error(std::string(__func__) + ": New cached parent xpub does not match already cached parent xpub");
1260 : }
1261 12 : continue;
1262 : }
1263 1458 : CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
1264 1458 : diff.CacheParentExtPubKey(parent_xpub_pair.first, parent_xpub_pair.second);
1265 : }
1266 156420 : for (const auto& derived_xpub_map_pair : other.GetCachedDerivedExtPubKeys()) {
1267 3576 : for (const auto& derived_xpub_pair : derived_xpub_map_pair.second) {
1268 1788 : CExtPubKey xpub;
1269 1788 : if (GetCachedDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, xpub)) {
1270 0 : if (xpub != derived_xpub_pair.second) {
1271 0 : throw std::runtime_error(std::string(__func__) + ": New cached derived xpub does not match already cached derived xpub");
1272 : }
1273 0 : continue;
1274 : }
1275 1788 : CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
1276 1788 : diff.CacheDerivedExtPubKey(derived_xpub_map_pair.first, derived_xpub_pair.first, derived_xpub_pair.second);
1277 : }
1278 : }
1279 155899 : for (const auto& lh_xpub_pair : other.GetCachedLastHardenedExtPubKeys()) {
1280 1267 : CExtPubKey xpub;
1281 1267 : if (GetCachedLastHardenedExtPubKey(lh_xpub_pair.first, xpub)) {
1282 0 : if (xpub != lh_xpub_pair.second) {
1283 0 : throw std::runtime_error(std::string(__func__) + ": New cached last hardened xpub does not match already cached last hardened xpub");
1284 : }
1285 0 : continue;
1286 : }
1287 1267 : CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
1288 1267 : diff.CacheLastHardenedExtPubKey(lh_xpub_pair.first, lh_xpub_pair.second);
1289 : }
1290 154632 : return diff;
1291 154632 : }
1292 :
1293 309418 : ExtPubKeyMap DescriptorCache::GetCachedParentExtPubKeys() const
1294 : {
1295 309418 : return m_parent_xpubs;
1296 : }
1297 :
1298 309418 : std::unordered_map<uint32_t, ExtPubKeyMap> DescriptorCache::GetCachedDerivedExtPubKeys() const
1299 : {
1300 309418 : return m_derived_xpubs;
1301 : }
1302 :
1303 309934 : ExtPubKeyMap DescriptorCache::GetCachedLastHardenedExtPubKeys() const
1304 : {
1305 309934 : return m_last_hardened_xpubs;
1306 : }
|