Branch data Line data Source code
1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : : // Copyright (c) 2009-present The Bitcoin Core developers
3 : : // Copyright (c) 2017 The Zcash developers
4 : : // Distributed under the MIT software license, see the accompanying
5 : : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 : :
7 : : #ifndef BITCOIN_KEY_H
8 : : #define BITCOIN_KEY_H
9 : :
10 : : #include <attributes.h>
11 : : #include <pubkey.h>
12 : : #include <script/keyorigin.h>
13 : : #include <serialize.h>
14 : : #include <support/allocators/secure.h>
15 : : #include <support/cleanse.h>
16 : : #include <uint256.h>
17 : :
18 : : #include <array>
19 : : #include <cassert>
20 : : #include <optional>
21 : : #include <span>
22 : : #include <stdexcept>
23 : : #include <utility>
24 : : #include <vector>
25 : :
26 : : struct secp256k1_context_struct;
27 : : typedef struct secp256k1_context_struct secp256k1_context;
28 : : struct secp256k1_keypair;
29 : :
30 : : /**
31 : : * CPrivKey is a serialized private key, with all parameters included
32 : : * (SIZE bytes)
33 : : */
34 : : typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
35 : :
36 : : /** Size of ECDH shared secrets. */
37 : : inline constexpr size_t ECDH_SECRET_SIZE = CSHA256::OUTPUT_SIZE;
38 : :
39 : : // Used to represent ECDH shared secret (ECDH_SECRET_SIZE bytes)
40 : : using ECDHSecret = std::array<std::byte, ECDH_SECRET_SIZE>;
41 : :
42 : : class KeyPair;
43 : :
44 : : /** An encapsulated private key. */
45 [ + - ][ - + : 28156 : class CKey
- + + - -
+ - + + -
- + ][ + -
+ - + - #
# # # # #
# # # # #
# # # ][ +
- + - + -
+ - + - +
- + - + -
+ - + - ]
[ + - + -
# # ]
46 : : {
47 : : public:
48 : : /**
49 : : * secp256k1:
50 : : */
51 : : static constexpr unsigned int SIZE{279};
52 : : static constexpr unsigned int COMPRESSED_SIZE{214};
53 : : /**
54 : : * see www.keylength.com
55 : : * script supports up to 75 for single byte push
56 : : */
57 : : static_assert(
58 : : SIZE >= COMPRESSED_SIZE,
59 : : "COMPRESSED_SIZE is larger than SIZE");
60 : :
61 : : private:
62 : : /** Internal data container for private key material. */
63 : : using KeyType = std::array<unsigned char, 32>;
64 : :
65 : : //! Whether the public key corresponding to this private key is (to be) compressed.
66 : : bool fCompressed{false};
67 : :
68 : : //! The actual byte data. nullptr for invalid keys.
69 : : secure_unique_ptr<KeyType> keydata;
70 : :
71 : : //! Check whether the 32-byte array pointed to by vch is valid keydata.
72 : : bool static Check(const unsigned char* vch);
73 : :
74 : 40374 : void MakeKeyData()
75 : : {
76 [ + + ]: 40374 : if (!keydata) keydata = make_secure_unique<KeyType>();
77 : 40374 : }
78 : :
79 : 2 : void ClearKeyData()
80 : : {
81 : 2 : keydata.reset();
82 : 2 : }
83 : :
84 : : public:
85 [ + - ][ + - : 4768 : CKey() noexcept = default;
+ - + - +
- + - - +
+ - + - ]
[ + + + - ]
[ + - + -
+ - + - ]
86 : 930 : CKey(CKey&&) noexcept = default;
87 : 612 : CKey& operator=(CKey&&) noexcept = default;
88 : :
89 : 31237 : CKey& operator=(const CKey& other)
90 : : {
91 [ + - ]: 31237 : if (this != &other) {
92 [ + - ]: 31237 : if (other.keydata) {
93 : 31237 : MakeKeyData();
94 : 31237 : *keydata = *other.keydata;
95 : : } else {
96 : 0 : ClearKeyData();
97 : : }
98 : 31237 : fCompressed = other.fCompressed;
99 : : }
100 : 31237 : return *this;
101 : : }
102 : :
103 [ + - ]: 10433 : CKey(const CKey& other) { *this = other; }
104 : :
105 : 273 : friend bool operator==(const CKey& a, const CKey& b)
106 : : {
107 : 546 : return a.fCompressed == b.fCompressed &&
108 [ + - + - ]: 546 : a.size() == b.size() &&
109 [ - + ]: 273 : memcmp(a.data(), b.data(), a.size()) == 0;
110 : : }
111 : :
112 : : //! Initialize using begin and end iterators to byte data.
113 : : template <typename T>
114 [ - + ]: 8847 : void Set(const T pbegin, const T pend, bool fCompressedIn)
115 : : {
116 [ - + ]: 8847 : if (size_t(pend - pbegin) != std::tuple_size_v<KeyType>) {
117 : 0 : ClearKeyData();
118 [ + + ]: 8847 : } else if (Check(UCharCast(&pbegin[0]))) {
119 : 8845 : MakeKeyData();
120 : 8845 : memcpy(keydata->data(), (unsigned char*)&pbegin[0], keydata->size());
121 : 8845 : fCompressed = fCompressedIn;
122 : : } else {
123 : 2 : ClearKeyData();
124 : : }
125 : 8847 : }
126 : :
127 : : //! Simple read-only vector-like interface.
128 [ - + - + : 6370 : unsigned int size() const { return keydata ? keydata->size() : 0; }
+ - ]
[ - + - + ]
[ + + ]
129 [ + - + - ]: 39006 : const std::byte* data() const { return keydata ? reinterpret_cast<const std::byte*>(keydata->data()) : nullptr; }
[ + - ]
130 [ + - # # ]: 91015 : const std::byte* begin() const { return data(); }
[ + - + - ]
[ + - + -
+ - + - ]
[ + - - +
+ - ][ + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - ]
131 [ + - + - ]: 408 : const std::byte* end() const { return data() + size(); }
[ + - + -
+ - + - ]
132 : :
133 : : //! Check whether this private key is valid.
134 [ + + + + : 12105 : bool IsValid() const { return !!keydata; }
+ + + + #
# # # ]
[ + + + + ]
[ + - + -
+ - + - +
- + - ]
[ - + # # ]
[ - - - -
- + ]
135 : :
136 : : //! Check whether the public key corresponding to this private key is (to be) compressed.
137 [ + + # # : 12800 : bool IsCompressed() const { return fCompressed; }
# # # # #
# ][ + + +
- + - + -
+ - ]
138 : :
139 : : //! Generate a new private key using a cryptographic PRNG.
140 : : void MakeNewKey(bool fCompressed);
141 : :
142 : : /**
143 : : * Convert the private key to a CPrivKey (serialized OpenSSL private key data).
144 : : * This is expensive.
145 : : */
146 : : CPrivKey GetPrivKey() const;
147 : :
148 : : /**
149 : : * Compute the public key from a private key.
150 : : * This is expensive.
151 : : */
152 : : CPubKey GetPubKey() const;
153 : :
154 : : /**
155 : : * Create a DER-serialized signature.
156 : : * The test_case parameter tweaks the deterministic nonce.
157 : : */
158 : : bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool grind = true, uint32_t test_case = 0) const;
159 : :
160 : : /**
161 : : * Create a compact signature (65 bytes), which allows reconstructing the used public key.
162 : : * The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
163 : : * The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
164 : : * 0x1D = second key with even y, 0x1E = second key with odd y,
165 : : * add 0x04 for compressed keys.
166 : : */
167 : : bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
168 : :
169 : : /**
170 : : * Create a BIP-340 Schnorr signature, for the xonly-pubkey corresponding to *this,
171 : : * optionally tweaked by *merkle_root. Additional nonce entropy is provided through
172 : : * aux.
173 : : *
174 : : * merkle_root is used to optionally perform tweaking of the private key, as specified
175 : : * in BIP341:
176 : : * - If merkle_root == nullptr: no tweaking is done, sign with key directly (this is
177 : : * used for signatures in BIP342 script).
178 : : * - If merkle_root->IsNull(): sign with key + H_TapTweak(pubkey) (this is used for
179 : : * key path spending when no scripts are present).
180 : : * - Otherwise: sign with key + H_TapTweak(pubkey || *merkle_root)
181 : : * (this is used for key path spending, with specific
182 : : * Merkle root of the script tree).
183 : : */
184 : : bool SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const;
185 : :
186 : : //! Derive BIP32 child key.
187 : : [[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
188 : :
189 : : /**
190 : : * Verify thoroughly whether a private key and a public key match.
191 : : * This is done using a different mechanism than just regenerating it.
192 : : */
193 : : bool VerifyPubKey(const CPubKey& vchPubKey) const;
194 : :
195 : : //! Load private key and check that public key matches.
196 : : bool Load(const CPrivKey& privkey, const CPubKey& vchPubKey, bool fSkipCheck);
197 : :
198 : : /** Create an ellswift-encoded public key for this key, with specified entropy.
199 : : *
200 : : * entropy must be a 32-byte span with additional entropy to use in the encoding. Every
201 : : * public key has ~2^256 different encodings, and this function will deterministically pick
202 : : * one of them, based on entropy. Note that even without truly random entropy, the
203 : : * resulting encoding will be indistinguishable from uniform to any adversary who does not
204 : : * know the private key (because the private key itself is always used as entropy as well).
205 : : */
206 : : EllSwiftPubKey EllSwiftCreate(std::span<const std::byte> entropy) const;
207 : :
208 : : /** Compute a BIP324-style ECDH shared secret.
209 : : *
210 : : * - their_ellswift: EllSwiftPubKey that was received from the other side.
211 : : * - our_ellswift: EllSwiftPubKey that was sent to the other side (must have been generated
212 : : * from *this using EllSwiftCreate()).
213 : : * - initiating: whether we are the initiating party (true) or responding party (false).
214 : : */
215 : : ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift,
216 : : const EllSwiftPubKey& our_ellswift,
217 : : bool initiating) const;
218 : : /** Compute a KeyPair
219 : : *
220 : : * Wraps a `secp256k1_keypair` type.
221 : : *
222 : : * `merkle_root` is used to optionally perform tweaking of
223 : : * the internal key, as specified in BIP341:
224 : : *
225 : : * - If merkle_root == nullptr: no tweaking is done, use the internal key directly (this is
226 : : * used for signatures in BIP342 script).
227 : : * - If merkle_root->IsNull(): tweak the internal key with H_TapTweak(pubkey) (this is used for
228 : : * key path spending when no scripts are present).
229 : : * - Otherwise: tweak the internal key with H_TapTweak(pubkey || *merkle_root)
230 : : * (this is used for key path spending with the
231 : : * Merkle root of the script tree).
232 : : */
233 : : KeyPair ComputeKeyPair(const uint256* merkle_root) const;
234 : : };
235 : :
236 : : CKey GenerateRandomKey(bool compressed = true) noexcept;
237 : :
238 : 257 : struct CExtKey {
239 : : unsigned char nDepth;
240 : : KeyFingerprint fingerprint;
241 : : unsigned int nChild;
242 : : ChainCode chaincode;
243 : : CKey key;
244 : :
245 : 36 : friend bool operator==(const CExtKey& a, const CExtKey& b)
246 : : {
247 [ + - ]: 36 : return a.nDepth == b.nDepth &&
248 [ + - ]: 36 : a.fingerprint == b.fingerprint &&
249 [ + - ]: 36 : a.nChild == b.nChild &&
250 [ + - + - ]: 72 : a.chaincode == b.chaincode &&
251 [ - + ]: 36 : a.key == b.key;
252 : : }
253 : :
254 [ + - ][ + - : 4742 : CExtKey() = default;
+ - + - +
- + - - +
+ - + - ]
[ + + + - ]
[ + - - +
+ - + - +
- ]
255 [ # # ]: 0 : CExtKey(const CExtPubKey& xpub, const CKey& key_in) : nDepth(xpub.nDepth), fingerprint(xpub.fingerprint), nChild(xpub.nChild), chaincode(xpub.chaincode), key(key_in) {}
256 : :
257 : 7369 : KeyFingerprint id_key_fingerprint() const
258 : : {
259 : 7369 : return key.GetPubKey().GetID().fingerprint();
260 : : }
261 : :
262 : : //! BIP32 serialization without the version bytes (BIP32_EXTKEY_SIZE bytes)
263 : : template <typename Stream>
264 : 403 : void Serialize(Stream& s) const
265 : : {
266 [ + - ]: 403 : assert(key.size() == 32);
267 [ + - - + ]: 806 : s << nDepth << fingerprint << Using<BigEndianFormatter<4>>(nChild) << chaincode << uint8_t{0} << std::span{key.data(), key.size()};
268 : 403 : }
269 : : template <typename Stream>
270 : 337 : void Unserialize(Stream& s)
271 : : {
272 : : uint8_t key_prefix;
273 : 337 : std::vector<unsigned char, secure_allocator<unsigned char>> ser_key(32);
274 [ + + + + : 337 : s >> nDepth >> fingerprint >> Using<BigEndianFormatter<4>>(nChild) >> chaincode >> key_prefix >> std::span{ser_key};
+ + + + +
+ - + +
+ ]
275 [ + - ]: 263 : key.Set(ser_key.begin(), ser_key.end(), true);
276 [ + + + + : 263 : if ((nDepth == 0 && (nChild != 0 || fingerprint != KeyFingerprint{})) || key_prefix != 0) key = CKey();
+ + + + ]
277 : 337 : }
278 : : [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
279 : : CExtPubKey Neuter() const;
280 : : void SetSeed(std::span<const std::byte> seed);
281 : : };
282 : :
283 : : //! Get extended key and origin info for a given path
284 : : //! @param[in] ext_key The extended private key to derive from
285 : : //! @param[in] path The BIP 32 path
286 : : //! @return the resulting extended private key and origin info
287 : : std::optional<std::pair<CExtKey, KeyOriginInfo>> DeriveExtKey(const CExtKey& ext_key, const std::vector<uint32_t>& path);
288 : :
289 : : /** KeyPair
290 : : *
291 : : * Wraps a `secp256k1_keypair` type, an opaque data structure for holding a secret and public key.
292 : : * This is intended for BIP340 keys and allows us to easily determine if the secret key needs to
293 : : * be negated by checking the parity of the public key. This class primarily intended for passing
294 : : * secret keys to libsecp256k1 functions expecting a `secp256k1_keypair`. For all other cases,
295 : : * CKey should be preferred.
296 : : *
297 : : * A KeyPair can be created from a CKey with an optional merkle_root tweak (per BIP342). See
298 : : * CKey::ComputeKeyPair for more details.
299 : : */
300 : 443 : class KeyPair
301 : : {
302 : : public:
303 : : KeyPair() noexcept = default;
304 : 11 : KeyPair(KeyPair&&) noexcept = default;
305 : : KeyPair& operator=(KeyPair&&) noexcept = default;
306 : : KeyPair& operator=(const KeyPair& other)
307 : : {
308 : : if (this != &other) {
309 : : if (other.m_keypair) {
310 : : MakeKeyPairData();
311 : : *m_keypair = *other.m_keypair;
312 : : } else {
313 : : ClearKeyPairData();
314 : : }
315 : : }
316 : : return *this;
317 : : }
318 : :
319 : : KeyPair(const KeyPair& other) { *this = other; }
320 : :
321 : : friend KeyPair CKey::ComputeKeyPair(const uint256* merkle_root) const;
322 : : [[nodiscard]] bool SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256& aux) const;
323 : :
324 : : //! Pointer to this KeyPair's internal `secp256k1_keypair` data or nullptr if invalid.
325 : 9 : const secp256k1_keypair* GetSecpKeypair() const LIFETIMEBOUND
326 : : {
327 : 9 : return IsValid() ? reinterpret_cast<const secp256k1_keypair*>(m_keypair->data()) : nullptr;
328 : : }
329 : :
330 : : //! Check whether this keypair is valid.
331 [ - + + - ]: 432 : bool IsValid() const { return !!m_keypair; }
[ + - ]
332 : :
333 : : private:
334 : : KeyPair(const CKey& key, const uint256* merkle_root);
335 : :
336 : : using KeyType = std::array<unsigned char, 96>;
337 : : secure_unique_ptr<KeyType> m_keypair;
338 : :
339 : 432 : void MakeKeyPairData()
340 : : {
341 [ + - ]: 432 : if (!m_keypair) m_keypair = make_secure_unique<KeyType>();
342 : 432 : }
343 : :
344 : 0 : void ClearKeyPairData()
345 : : {
346 : 0 : m_keypair.reset();
347 : 0 : }
348 : : };
349 : :
350 : : /** Check that required EC support is available at runtime. */
351 : : bool ECC_InitSanityCheck();
352 : :
353 : : /** Access the secp256k1 context used for signing and MuSig2 nonce generation. */
354 : : secp256k1_context* GetSecp256k1SignContext();
355 : :
356 : : /**
357 : : * RAII class initializing and deinitializing global state for elliptic curve support.
358 : : * Only one instance may be initialized at a time.
359 : : *
360 : : * In the future global ECC state could be removed, and this class could contain
361 : : * state and be passed as an argument to ECC key functions.
362 : : */
363 : : class ECC_Context
364 : : {
365 : : public:
366 : : ECC_Context();
367 : : ~ECC_Context();
368 : : };
369 : :
370 : : #endif // BITCOIN_KEY_H
|