Branch data Line data Source code
1 : : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : : // Copyright (c) 2009-2022 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 <pubkey.h>
11 : : #include <serialize.h>
12 : : #include <support/allocators/secure.h>
13 : : #include <uint256.h>
14 : :
15 : : #include <stdexcept>
16 : : #include <vector>
17 : :
18 : :
19 : : /**
20 : : * CPrivKey is a serialized private key, with all parameters included
21 : : * (SIZE bytes)
22 : : */
23 : : typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
24 : :
25 : : /** Size of ECDH shared secrets. */
26 : : constexpr static size_t ECDH_SECRET_SIZE = CSHA256::OUTPUT_SIZE;
27 : :
28 : : // Used to represent ECDH shared secret (ECDH_SECRET_SIZE bytes)
29 : : using ECDHSecret = std::array<std::byte, ECDH_SECRET_SIZE>;
30 : :
31 : : /** An encapsulated private key. */
32 : : class CKey
33 : : {
34 : : public:
35 : : /**
36 : : * secp256k1:
37 : : */
38 : : static const unsigned int SIZE = 279;
39 : : static const unsigned int COMPRESSED_SIZE = 214;
40 : : /**
41 : : * see www.keylength.com
42 : : * script supports up to 75 for single byte push
43 : : */
44 : : static_assert(
45 : : SIZE >= COMPRESSED_SIZE,
46 : : "COMPRESSED_SIZE is larger than SIZE");
47 : :
48 : : private:
49 : : /** Internal data container for private key material. */
50 : : using KeyType = std::array<unsigned char, 32>;
51 : :
52 : : //! Whether the public key corresponding to this private key is (to be) compressed.
53 : 4190780 : bool fCompressed{false};
54 : :
55 : : //! The actual byte data. nullptr for invalid keys.
56 : : secure_unique_ptr<KeyType> keydata;
57 : :
58 : : //! Check whether the 32-byte array pointed to by vch is valid keydata.
59 : : bool static Check(const unsigned char* vch);
60 : :
61 : 4315205 : void MakeKeyData()
62 : : {
63 [ + + ]: 4315205 : if (!keydata) keydata = make_secure_unique<KeyType>();
64 : 4315205 : }
65 : :
66 : 514 : void ClearKeyData()
67 : : {
68 : 514 : keydata.reset();
69 : 514 : }
70 : :
71 : : public:
72 : 4124846 : CKey() noexcept = default;
73 : 0 : CKey(CKey&&) noexcept = default;
74 : 2726 : CKey& operator=(CKey&&) noexcept = default;
75 : :
76 : 3362948 : CKey& operator=(const CKey& other)
77 : : {
78 [ + - ]: 3362948 : if (other.keydata) {
79 : 3362948 : MakeKeyData();
80 : 3362948 : *keydata = *other.keydata;
81 : 3362948 : } else {
82 : 0 : ClearKeyData();
83 : : }
84 : 3362948 : fCompressed = other.fCompressed;
85 : 3362948 : return *this;
86 : : }
87 : :
88 [ + - + - ]: 4256714 : CKey(const CKey& other) { *this = other; }
89 : :
90 : 4024 : friend bool operator==(const CKey& a, const CKey& b)
91 : : {
92 [ + + ]: 7156 : return a.fCompressed == b.fCompressed &&
93 [ - + ]: 3132 : a.size() == b.size() &&
94 : 3132 : memcmp(a.data(), b.data(), a.size()) == 0;
95 : : }
96 : :
97 : : //! Initialize using begin and end iterators to byte data.
98 : : template <typename T>
99 : 951879 : void Set(const T pbegin, const T pend, bool fCompressedIn)
100 : : {
101 [ + + - + : 951879 : if (size_t(pend - pbegin) != std::tuple_size_v<KeyType>) {
# # ]
102 : 3 : ClearKeyData();
103 [ + + + - : 951879 : } else if (Check(UCharCast(&pbegin[0]))) {
# # ]
104 : 951365 : MakeKeyData();
105 : 951365 : memcpy(keydata->data(), (unsigned char*)&pbegin[0], keydata->size());
106 : 951365 : fCompressed = fCompressedIn;
107 : 951365 : } else {
108 : 511 : ClearKeyData();
109 : : }
110 : 951879 : }
111 : :
112 : : //! Simple read-only vector-like interface.
113 [ + + ]: 494558 : unsigned int size() const { return keydata ? keydata->size() : 0; }
114 [ + - ]: 5193998 : const std::byte* data() const { return keydata ? reinterpret_cast<const std::byte*>(keydata->data()) : nullptr; }
115 : 5171429 : const std::byte* begin() const { return data(); }
116 : 16305 : const std::byte* end() const { return data() + size(); }
117 : :
118 : : //! Check whether this private key is valid.
119 : 1560102 : bool IsValid() const { return !!keydata; }
120 : :
121 : : //! Check whether the public key corresponding to this private key is (to be) compressed.
122 : 832004 : bool IsCompressed() const { return fCompressed; }
123 : :
124 : : //! Generate a new private key using a cryptographic PRNG.
125 : : void MakeNewKey(bool fCompressed);
126 : :
127 : : //! Negate private key
128 : : bool Negate();
129 : :
130 : : /**
131 : : * Convert the private key to a CPrivKey (serialized OpenSSL private key data).
132 : : * This is expensive.
133 : : */
134 : : CPrivKey GetPrivKey() const;
135 : :
136 : : /**
137 : : * Compute the public key from a private key.
138 : : * This is expensive.
139 : : */
140 : : CPubKey GetPubKey() const;
141 : :
142 : : /**
143 : : * Create a DER-serialized signature.
144 : : * The test_case parameter tweaks the deterministic nonce.
145 : : */
146 : : bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool grind = true, uint32_t test_case = 0) const;
147 : :
148 : : /**
149 : : * Create a compact signature (65 bytes), which allows reconstructing the used public key.
150 : : * The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
151 : : * The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
152 : : * 0x1D = second key with even y, 0x1E = second key with odd y,
153 : : * add 0x04 for compressed keys.
154 : : */
155 : : bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
156 : :
157 : : /**
158 : : * Create a BIP-340 Schnorr signature, for the xonly-pubkey corresponding to *this,
159 : : * optionally tweaked by *merkle_root. Additional nonce entropy is provided through
160 : : * aux.
161 : : *
162 : : * merkle_root is used to optionally perform tweaking of the private key, as specified
163 : : * in BIP341:
164 : : * - If merkle_root == nullptr: no tweaking is done, sign with key directly (this is
165 : : * used for signatures in BIP342 script).
166 : : * - If merkle_root->IsNull(): sign with key + H_TapTweak(pubkey) (this is used for
167 : : * key path spending when no scripts are present).
168 : : * - Otherwise: sign with key + H_TapTweak(pubkey || *merkle_root)
169 : : * (this is used for key path spending, with specific
170 : : * Merkle root of the script tree).
171 : : */
172 : : bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const;
173 : :
174 : : //! Derive BIP32 child key.
175 : : [[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
176 : :
177 : : /**
178 : : * Verify thoroughly whether a private key and a public key match.
179 : : * This is done using a different mechanism than just regenerating it.
180 : : */
181 : : bool VerifyPubKey(const CPubKey& vchPubKey) const;
182 : :
183 : : //! Load private key and check that public key matches.
184 : : bool Load(const CPrivKey& privkey, const CPubKey& vchPubKey, bool fSkipCheck);
185 : :
186 : : /** Create an ellswift-encoded public key for this key, with specified entropy.
187 : : *
188 : : * entropy must be a 32-byte span with additional entropy to use in the encoding. Every
189 : : * public key has ~2^256 different encodings, and this function will deterministically pick
190 : : * one of them, based on entropy. Note that even without truly random entropy, the
191 : : * resulting encoding will be indistinguishable from uniform to any adversary who does not
192 : : * know the private key (because the private key itself is always used as entropy as well).
193 : : */
194 : : EllSwiftPubKey EllSwiftCreate(Span<const std::byte> entropy) const;
195 : :
196 : : /** Compute a BIP324-style ECDH shared secret.
197 : : *
198 : : * - their_ellswift: EllSwiftPubKey that was received from the other side.
199 : : * - our_ellswift: EllSwiftPubKey that was sent to the other side (must have been generated
200 : : * from *this using EllSwiftCreate()).
201 : : * - initiating: whether we are the initiating party (true) or responding party (false).
202 : : */
203 : : ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift,
204 : : const EllSwiftPubKey& our_ellswift,
205 : : bool initiating) const;
206 : : };
207 : :
208 : : CKey GenerateRandomKey(bool compressed = true) noexcept;
209 : :
210 : : struct CExtKey {
211 : : unsigned char nDepth;
212 : : unsigned char vchFingerprint[4];
213 : : unsigned int nChild;
214 : : ChainCode chaincode;
215 : : CKey key;
216 : :
217 : 5 : friend bool operator==(const CExtKey& a, const CExtKey& b)
218 : : {
219 [ + - ]: 10 : return a.nDepth == b.nDepth &&
220 [ + - ]: 5 : memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
221 [ + - ]: 5 : a.nChild == b.nChild &&
222 [ - + ]: 5 : a.chaincode == b.chaincode &&
223 : 5 : a.key == b.key;
224 : : }
225 : :
226 : 1139724 : CExtKey() = default;
227 : 0 : CExtKey(const CExtPubKey& xpub, const CKey& key_in) : nDepth(xpub.nDepth), nChild(xpub.nChild), chaincode(xpub.chaincode), key(key_in)
228 : : {
229 [ # # ]: 0 : std::copy(xpub.vchFingerprint, xpub.vchFingerprint + sizeof(xpub.vchFingerprint), vchFingerprint);
230 : 0 : }
231 : :
232 : : void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
233 : : void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
234 : : [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
235 : : CExtPubKey Neuter() const;
236 : : void SetSeed(Span<const std::byte> seed);
237 : : };
238 : :
239 : : /** Check that required EC support is available at runtime. */
240 : : bool ECC_InitSanityCheck();
241 : :
242 : : /**
243 : : * RAII class initializing and deinitializing global state for elliptic curve support.
244 : : * Only one instance may be initialized at a time.
245 : : *
246 : : * In the future global ECC state could be removed, and this class could contain
247 : : * state and be passed as an argument to ECC key functions.
248 : : */
249 : : class ECC_Context
250 : : {
251 : : public:
252 : : ECC_Context();
253 : : ~ECC_Context();
254 : : };
255 : :
256 : : #endif // BITCOIN_KEY_H
|