/tmp/bitcoin/src/script/signingprovider.h
Line | Count | Source |
1 | | // Copyright (c) 2009-2010 Satoshi Nakamoto |
2 | | // Copyright (c) 2009-present The Bitcoin Core developers |
3 | | // Distributed under the MIT software license, see the accompanying |
4 | | // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
5 | | |
6 | | #ifndef BITCOIN_SCRIPT_SIGNINGPROVIDER_H |
7 | | #define BITCOIN_SCRIPT_SIGNINGPROVIDER_H |
8 | | |
9 | | #include <addresstype.h> |
10 | | #include <attributes.h> |
11 | | #include <key.h> |
12 | | #include <pubkey.h> |
13 | | #include <script/keyorigin.h> |
14 | | #include <script/script.h> |
15 | | #include <sync.h> |
16 | | #include <uint256.h> |
17 | | |
18 | | #include <compare> |
19 | | #include <cstdint> |
20 | | #include <functional> |
21 | | #include <map> |
22 | | #include <memory> |
23 | | #include <optional> |
24 | | #include <set> |
25 | | #include <span> |
26 | | #include <tuple> |
27 | | #include <utility> |
28 | | #include <variant> |
29 | | #include <vector> |
30 | | |
31 | | class MuSig2SecNonce; |
32 | | |
33 | | struct ShortestVectorFirstComparator |
34 | | { |
35 | | bool operator()(const std::vector<unsigned char>& a, const std::vector<unsigned char>& b) const |
36 | 9.76k | { |
37 | 9.76k | if (a.size() < b.size()) return true; |
38 | 6.85k | if (a.size() > b.size()) return false; |
39 | 5.32k | return a < b; |
40 | 6.85k | } |
41 | | }; |
42 | | |
43 | | struct TaprootSpendData |
44 | | { |
45 | | /** The BIP341 internal key. */ |
46 | | XOnlyPubKey internal_key; |
47 | | /** The Merkle root of the script tree (0 if no scripts). */ |
48 | | uint256 merkle_root; |
49 | | /** Map from (script, leaf_version) to (sets of) control blocks. |
50 | | * More than one control block for a given script is only possible if it |
51 | | * appears in multiple branches of the tree. We keep them all so that |
52 | | * inference can reconstruct the full tree. Within each set, the control |
53 | | * blocks are sorted by size, so that the signing logic can easily |
54 | | * prefer the cheapest one. */ |
55 | | std::map<std::pair<std::vector<unsigned char>, int>, std::set<std::vector<unsigned char>, ShortestVectorFirstComparator>> scripts; |
56 | | /** Merge other TaprootSpendData (for the same scriptPubKey) into this. */ |
57 | | void Merge(TaprootSpendData other); |
58 | | }; |
59 | | |
60 | | /** Utility class to construct Taproot outputs from internal key and script tree. */ |
61 | | class TaprootBuilder |
62 | | { |
63 | | private: |
64 | | /** Information about a tracked leaf in the Merkle tree. */ |
65 | | struct LeafInfo |
66 | | { |
67 | | std::vector<unsigned char> script; //!< The script. |
68 | | int leaf_version; //!< The leaf version for that script. |
69 | | std::vector<uint256> merkle_branch; //!< The hashing partners above this leaf. |
70 | | }; |
71 | | |
72 | | /** Information associated with a node in the Merkle tree. */ |
73 | | struct NodeInfo |
74 | | { |
75 | | /** Merkle hash of this node. */ |
76 | | uint256 hash; |
77 | | /** Tracked leaves underneath this node (either from the node itself, or its children). |
78 | | * The merkle_branch field of each is the partners to get to *this* node. */ |
79 | | std::vector<LeafInfo> leaves; |
80 | | }; |
81 | | /** Whether the builder is in a valid state so far. */ |
82 | | bool m_valid = true; |
83 | | |
84 | | /** The current state of the builder. |
85 | | * |
86 | | * For each level in the tree, one NodeInfo object may be present. m_branch[0] |
87 | | * is information about the root; further values are for deeper subtrees being |
88 | | * explored. |
89 | | * |
90 | | * For every right branch taken to reach the position we're currently |
91 | | * working in, there will be a (non-nullopt) entry in m_branch corresponding |
92 | | * to the left branch at that level. |
93 | | * |
94 | | * For example, imagine this tree: - N0 - |
95 | | * / \ |
96 | | * N1 N2 |
97 | | * / \ / \ |
98 | | * A B C N3 |
99 | | * / \ |
100 | | * D E |
101 | | * |
102 | | * Initially, m_branch is empty. After processing leaf A, it would become |
103 | | * {nullopt, nullopt, A}. When processing leaf B, an entry at level 2 already |
104 | | * exists, and it would thus be combined with it to produce a level 1 one, |
105 | | * resulting in {nullopt, N1}. Adding C and D takes us to {nullopt, N1, C} |
106 | | * and {nullopt, N1, C, D} respectively. When E is processed, it is combined |
107 | | * with D, and then C, and then N1, to produce the root, resulting in {N0}. |
108 | | * |
109 | | * This structure allows processing with just O(log n) overhead if the leaves |
110 | | * are computed on the fly. |
111 | | * |
112 | | * As an invariant, there can never be nullopt entries at the end. There can |
113 | | * also not be more than 128 entries (as that would mean more than 128 levels |
114 | | * in the tree). The depth of newly added entries will always be at least |
115 | | * equal to the current size of m_branch (otherwise it does not correspond |
116 | | * to a depth-first traversal of a tree). m_branch is only empty if no entries |
117 | | * have ever be processed. m_branch having length 1 corresponds to being done. |
118 | | */ |
119 | | std::vector<std::optional<NodeInfo>> m_branch; |
120 | | |
121 | | XOnlyPubKey m_internal_key; //!< The internal key, set when finalizing. |
122 | | XOnlyPubKey m_output_key; //!< The output key, computed when finalizing. |
123 | | bool m_parity; //!< The tweak parity, computed when finalizing. |
124 | | |
125 | | /** Combine information about a parent Merkle tree node from its child nodes. */ |
126 | | static NodeInfo Combine(NodeInfo&& a, NodeInfo&& b); |
127 | | /** Insert information about a node at a certain depth, and propagate information up. */ |
128 | | void Insert(NodeInfo&& node, int depth); |
129 | | |
130 | | public: |
131 | | /** Add a new script at a certain depth in the tree. Add() operations must be called |
132 | | * in depth-first traversal order of binary tree. If track is true, it will be included in |
133 | | * the GetSpendData() output. */ |
134 | | TaprootBuilder& Add(int depth, std::span<const unsigned char> script, int leaf_version, bool track = true); |
135 | | /** Like Add(), but for a Merkle node with a given hash to the tree. */ |
136 | | TaprootBuilder& AddOmitted(int depth, const uint256& hash); |
137 | | /** Finalize the construction. Can only be called when IsComplete() is true. |
138 | | internal_key.IsFullyValid() must be true. */ |
139 | | TaprootBuilder& Finalize(const XOnlyPubKey& internal_key); |
140 | | |
141 | | /** Return true if so far all input was valid. */ |
142 | 38.4k | bool IsValid() const { return m_valid; } |
143 | | /** Return whether there were either no leaves, or the leaves form a Huffman tree. */ |
144 | 259k | bool IsComplete() const { return m_valid && (m_branch.size() == 0 || (m_branch.size() == 1 && m_branch[0].has_value())); } |
145 | | /** Compute scriptPubKey (after Finalize()). */ |
146 | | WitnessV1Taproot GetOutput(); |
147 | | /** Check if a list of depths is legal (will lead to IsComplete()). */ |
148 | | static bool ValidDepths(const std::vector<int>& depths); |
149 | | /** Compute spending data (after Finalize()). */ |
150 | | TaprootSpendData GetSpendData() const; |
151 | | /** Returns a vector of tuples representing the depth, leaf version, and script */ |
152 | | std::vector<std::tuple<uint8_t, uint8_t, std::vector<unsigned char>>> GetTreeTuples() const; |
153 | | /** Returns true if there are any tapscripts */ |
154 | 244 | bool HasScripts() const { return !m_branch.empty(); } |
155 | | |
156 | 0 | bool operator==(const TaprootBuilder& other) const { return GetTreeTuples() == other.GetTreeTuples(); } |
157 | | }; |
158 | | |
159 | | /** Given a TaprootSpendData and the output key, reconstruct its script tree. |
160 | | * |
161 | | * If the output doesn't match the spenddata, or if the data in spenddata is incomplete, |
162 | | * std::nullopt is returned. Otherwise, a vector of (depth, script, leaf_ver) tuples is |
163 | | * returned, corresponding to a depth-first traversal of the script tree. |
164 | | */ |
165 | | std::optional<std::vector<std::tuple<int, std::vector<unsigned char>, int>>> InferTaprootTree(const TaprootSpendData& spenddata, const XOnlyPubKey& output); |
166 | | |
167 | | /** An interface to be implemented by keystores that support signing. */ |
168 | | class SigningProvider |
169 | | { |
170 | | public: |
171 | 2.12M | virtual ~SigningProvider() = default; |
172 | 632 | virtual bool GetCScript(const CScriptID &scriptid, CScript& script) const { return false; } |
173 | 0 | virtual bool HaveCScript(const CScriptID &scriptid) const { return false; } |
174 | 1.87k | virtual bool GetPubKey(const CKeyID &address, CPubKey& pubkey) const { return false; } |
175 | 23.2k | virtual bool GetKey(const CKeyID &address, CKey& key) const { return false; } |
176 | 0 | virtual bool HaveKey(const CKeyID &address) const { return false; } |
177 | 56.0k | virtual bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const { return false; } |
178 | 13.5k | virtual bool GetTaprootSpendData(const XOnlyPubKey& output_key, TaprootSpendData& spenddata) const { return false; } |
179 | 296 | virtual bool GetTaprootBuilder(const XOnlyPubKey& output_key, TaprootBuilder& builder) const { return false; } |
180 | 0 | virtual std::vector<CPubKey> GetMuSig2ParticipantPubkeys(const CPubKey& pubkey) const { return {}; } |
181 | 296 | virtual std::map<CPubKey, std::vector<CPubKey>> GetAllMuSig2ParticipantPubkeys() const {return {}; } |
182 | 0 | virtual void SetMuSig2SecNonce(const uint256& id, MuSig2SecNonce&& nonce) const {} |
183 | 0 | virtual std::optional<std::reference_wrapper<MuSig2SecNonce>> GetMuSig2SecNonce(const uint256& session_id) const { return std::nullopt; } |
184 | 0 | virtual void DeleteMuSig2Session(const uint256& session_id) const {} |
185 | | |
186 | | bool GetKeyByXOnly(const XOnlyPubKey& pubkey, CKey& key) const |
187 | 157k | { |
188 | 314k | for (const auto& id : pubkey.GetKeyIDs()) { |
189 | 314k | if (GetKey(id, key)) return true; |
190 | 314k | } |
191 | 156k | return false; |
192 | 157k | } |
193 | | |
194 | | bool GetPubKeyByXOnly(const XOnlyPubKey& pubkey, CPubKey& out) const |
195 | 45 | { |
196 | 66 | for (const auto& id : pubkey.GetKeyIDs()) { |
197 | 66 | if (GetPubKey(id, out)) return true; |
198 | 66 | } |
199 | 0 | return false; |
200 | 45 | } |
201 | | |
202 | | bool GetKeyOriginByXOnly(const XOnlyPubKey& pubkey, KeyOriginInfo& info) const |
203 | 238k | { |
204 | 314k | for (const auto& id : pubkey.GetKeyIDs()) { |
205 | 314k | if (GetKeyOrigin(id, info)) return true; |
206 | 314k | } |
207 | 71.0k | return false; |
208 | 238k | } |
209 | | }; |
210 | | |
211 | | extern const SigningProvider& DUMMY_SIGNING_PROVIDER; |
212 | | |
213 | | class HidingSigningProvider : public SigningProvider |
214 | | { |
215 | | private: |
216 | | const bool m_hide_secret; |
217 | | const bool m_hide_origin; |
218 | | const SigningProvider* m_provider; |
219 | | |
220 | | public: |
221 | 24.3k | HidingSigningProvider(const SigningProvider* provider, bool hide_secret, bool hide_origin) : m_hide_secret(hide_secret), m_hide_origin(hide_origin), m_provider(provider) {} |
222 | | bool GetCScript(const CScriptID& scriptid, CScript& script) const override; |
223 | | bool GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const override; |
224 | | bool GetKey(const CKeyID& keyid, CKey& key) const override; |
225 | | bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override; |
226 | | bool GetTaprootSpendData(const XOnlyPubKey& output_key, TaprootSpendData& spenddata) const override; |
227 | | bool GetTaprootBuilder(const XOnlyPubKey& output_key, TaprootBuilder& builder) const override; |
228 | | std::vector<CPubKey> GetMuSig2ParticipantPubkeys(const CPubKey& pubkey) const override; |
229 | | std::map<CPubKey, std::vector<CPubKey>> GetAllMuSig2ParticipantPubkeys() const override; |
230 | | void SetMuSig2SecNonce(const uint256& id, MuSig2SecNonce&& nonce) const override; |
231 | | std::optional<std::reference_wrapper<MuSig2SecNonce>> GetMuSig2SecNonce(const uint256& session_id) const override; |
232 | | void DeleteMuSig2Session(const uint256& session_id) const override; |
233 | | }; |
234 | | |
235 | | struct FlatSigningProvider final : public SigningProvider |
236 | | { |
237 | | std::map<CScriptID, CScript> scripts; |
238 | | std::map<CKeyID, CPubKey> pubkeys; |
239 | | std::map<CKeyID, std::pair<CPubKey, KeyOriginInfo>> origins; |
240 | | std::map<CKeyID, CKey> keys; |
241 | | std::map<XOnlyPubKey, TaprootBuilder> tr_trees; /** Map from output key to Taproot tree (which can then make the TaprootSpendData */ |
242 | | std::map<CPubKey, std::vector<CPubKey>> aggregate_pubkeys; /** MuSig2 aggregate pubkeys */ |
243 | | std::map<uint256, MuSig2SecNonce>* musig2_secnonces{nullptr}; |
244 | | |
245 | | bool GetCScript(const CScriptID& scriptid, CScript& script) const override; |
246 | | bool GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const override; |
247 | | bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override; |
248 | | bool HaveKey(const CKeyID &keyid) const override; |
249 | | bool GetKey(const CKeyID& keyid, CKey& key) const override; |
250 | | bool GetTaprootSpendData(const XOnlyPubKey& output_key, TaprootSpendData& spenddata) const override; |
251 | | bool GetTaprootBuilder(const XOnlyPubKey& output_key, TaprootBuilder& builder) const override; |
252 | | std::vector<CPubKey> GetMuSig2ParticipantPubkeys(const CPubKey& pubkey) const override; |
253 | | std::map<CPubKey, std::vector<CPubKey>> GetAllMuSig2ParticipantPubkeys() const override; |
254 | | void SetMuSig2SecNonce(const uint256& id, MuSig2SecNonce&& nonce) const override; |
255 | | std::optional<std::reference_wrapper<MuSig2SecNonce>> GetMuSig2SecNonce(const uint256& session_id) const override; |
256 | | void DeleteMuSig2Session(const uint256& session_id) const override; |
257 | | |
258 | | FlatSigningProvider& Merge(FlatSigningProvider&& b) LIFETIMEBOUND; |
259 | | }; |
260 | | |
261 | | /** Fillable signing provider that keeps keys in an address->secret map */ |
262 | | class FillableSigningProvider : public SigningProvider |
263 | | { |
264 | | protected: |
265 | | using KeyMap = std::map<CKeyID, CKey>; |
266 | | using ScriptMap = std::map<CScriptID, CScript>; |
267 | | |
268 | | /** |
269 | | * Map of key id to unencrypted private keys known by the signing provider. |
270 | | * Map may be empty if the provider has another source of keys, like an |
271 | | * encrypted store. |
272 | | */ |
273 | | KeyMap mapKeys GUARDED_BY(cs_KeyStore); |
274 | | |
275 | | /** |
276 | | * Map of script id to scripts known by the signing provider. |
277 | | * |
278 | | * This map originally just held P2SH redeemScripts, and was used by wallet |
279 | | * code to look up script ids referenced in "OP_HASH160 <script id> |
280 | | * OP_EQUAL" P2SH outputs. Later in 605e8473a7d it was extended to hold |
281 | | * P2WSH witnessScripts as well, and used to look up nested scripts |
282 | | * referenced in "OP_0 <script hash>" P2WSH outputs. Later in commits |
283 | | * f4691ab3a9d and 248f3a76a82, it was extended once again to hold segwit |
284 | | * "OP_0 <key or script hash>" scriptPubKeys, in order to give the wallet a |
285 | | * way to distinguish between segwit outputs that it generated addresses for |
286 | | * and wanted to receive payments from, and segwit outputs that it never |
287 | | * generated addresses for, but it could spend just because of having keys. |
288 | | * (Before segwit activation it was also important to not treat segwit |
289 | | * outputs to arbitrary wallet keys as payments, because these could be |
290 | | * spent by anyone without even needing to sign with the keys.) |
291 | | * |
292 | | * Some of the scripts stored in mapScripts are memory-only and |
293 | | * intentionally not saved to disk. Specifically, scripts added by |
294 | | * ImplicitlyLearnRelatedKeyScripts(pubkey) calls are not written to disk so |
295 | | * future wallet code can have flexibility to be more selective about what |
296 | | * transaction outputs it recognizes as payments, instead of having to treat |
297 | | * all outputs spending to keys it knows as payments. By contrast, |
298 | | * mapScripts entries added by AddCScript(script), |
299 | | * LearnRelatedScripts(pubkey, type), and LearnAllRelatedScripts(pubkey) |
300 | | * calls are saved because they are all intentionally used to receive |
301 | | * payments. |
302 | | * |
303 | | * The FillableSigningProvider::mapScripts script map should not be confused |
304 | | * with LegacyScriptPubKeyMan::setWatchOnly script set. The two collections |
305 | | * can hold the same scripts, but they serve different purposes. The |
306 | | * setWatchOnly script set is intended to expand the set of outputs the |
307 | | * wallet considers payments. Every output with a script it contains is |
308 | | * considered to belong to the wallet, regardless of whether the script is |
309 | | * solvable or signable. By contrast, the scripts in mapScripts are only |
310 | | * used for solving, and to restrict which outputs are considered payments |
311 | | * by the wallet. An output with a script in mapScripts, unlike |
312 | | * setWatchOnly, is not automatically considered to belong to the wallet if |
313 | | * it can't be solved and signed for. |
314 | | */ |
315 | | ScriptMap mapScripts GUARDED_BY(cs_KeyStore); |
316 | | |
317 | | void ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore); |
318 | | |
319 | | public: |
320 | | mutable RecursiveMutex cs_KeyStore; |
321 | | |
322 | | virtual bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey); |
323 | 173 | virtual bool AddKey(const CKey &key) { return AddKeyPubKey(key, key.GetPubKey()); } |
324 | | virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const override; |
325 | | virtual bool HaveKey(const CKeyID &address) const override; |
326 | | virtual std::set<CKeyID> GetKeys() const; |
327 | | virtual bool GetKey(const CKeyID &address, CKey &keyOut) const override; |
328 | | virtual bool AddCScript(const CScript& redeemScript); |
329 | | virtual bool HaveCScript(const CScriptID &hash) const override; |
330 | | virtual std::set<CScriptID> GetCScripts() const; |
331 | | virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const override; |
332 | | }; |
333 | | |
334 | | /** Return the CKeyID of the key involved in a script (if there is a unique one). */ |
335 | | CKeyID GetKeyForDestination(const SigningProvider& store, const CTxDestination& dest); |
336 | | |
337 | | /** A signing provider to be used to interface with multiple signing providers at once. */ |
338 | | class MultiSigningProvider: public SigningProvider { |
339 | | std::vector<std::unique_ptr<SigningProvider>> m_providers; |
340 | | |
341 | | public: |
342 | | void AddProvider(std::unique_ptr<SigningProvider> provider); |
343 | | |
344 | | bool GetCScript(const CScriptID& scriptid, CScript& script) const override; |
345 | | bool GetPubKey(const CKeyID& keyid, CPubKey& pubkey) const override; |
346 | | bool GetKeyOrigin(const CKeyID& keyid, KeyOriginInfo& info) const override; |
347 | | bool GetKey(const CKeyID& keyid, CKey& key) const override; |
348 | | bool GetTaprootSpendData(const XOnlyPubKey& output_key, TaprootSpendData& spenddata) const override; |
349 | | bool GetTaprootBuilder(const XOnlyPubKey& output_key, TaprootBuilder& builder) const override; |
350 | | }; |
351 | | |
352 | | #endif // BITCOIN_SCRIPT_SIGNINGPROVIDER_H |