Bitcoin Core 32.99.0
P2P Digital Currency
key.h
Go to the documentation of this file.
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>
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
29
34typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
35
37inline constexpr size_t ECDH_SECRET_SIZE = CSHA256::OUTPUT_SIZE;
38
39// Used to represent ECDH shared secret (ECDH_SECRET_SIZE bytes)
40using ECDHSecret = std::array<std::byte, ECDH_SECRET_SIZE>;
41
42class KeyPair;
43
45class CKey
46{
47public:
51 static constexpr unsigned int SIZE{279};
52 static constexpr unsigned int COMPRESSED_SIZE{214};
57 static_assert(
59 "COMPRESSED_SIZE is larger than SIZE");
60
61private:
63 using KeyType = std::array<unsigned char, 32>;
64
66 bool fCompressed{false};
67
70
72 bool static Check(const unsigned char* vch);
73
75 {
76 if (!keydata) keydata = make_secure_unique<KeyType>();
77 }
78
80 {
81 keydata.reset();
82 }
83
84public:
85 CKey() noexcept = default;
86 CKey(CKey&&) noexcept = default;
87 CKey& operator=(CKey&&) noexcept = default;
88
89 CKey& operator=(const CKey& other)
90 {
91 if (this != &other) {
92 if (other.keydata) {
94 *keydata = *other.keydata;
95 } else {
97 }
98 fCompressed = other.fCompressed;
99 }
100 return *this;
101 }
102
103 CKey(const CKey& other) { *this = other; }
104
105 friend bool operator==(const CKey& a, const CKey& b)
106 {
107 return a.fCompressed == b.fCompressed &&
108 a.size() == b.size() &&
109 memcmp(a.data(), b.data(), a.size()) == 0;
110 }
111
113 template <typename T>
114 void Set(const T pbegin, const T pend, bool fCompressedIn)
115 {
116 if (size_t(pend - pbegin) != std::tuple_size_v<KeyType>) {
117 ClearKeyData();
118 } else if (Check(UCharCast(&pbegin[0]))) {
119 MakeKeyData();
120 memcpy(keydata->data(), (unsigned char*)&pbegin[0], keydata->size());
121 fCompressed = fCompressedIn;
122 } else {
123 ClearKeyData();
124 }
125 }
126
128 unsigned int size() const { return keydata ? keydata->size() : 0; }
129 const std::byte* data() const { return keydata ? reinterpret_cast<const std::byte*>(keydata->data()) : nullptr; }
130 const std::byte* begin() const { return data(); }
131 const std::byte* end() const { return data() + size(); }
132
134 bool IsValid() const { return !!keydata; }
135
137 bool IsCompressed() const { return fCompressed; }
138
140 void MakeNewKey(bool fCompressed);
141
146 CPrivKey GetPrivKey() const;
147
152 CPubKey GetPubKey() const;
153
158 bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool grind = true, uint32_t test_case = 0) const;
159
167 bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
168
184 bool SignSchnorr(const uint256& hash, std::span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const;
185
187 [[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
188
193 bool VerifyPubKey(const CPubKey& vchPubKey) const;
194
196 bool Load(const CPrivKey& privkey, const CPubKey& vchPubKey, bool fSkipCheck);
197
206 EllSwiftPubKey EllSwiftCreate(std::span<const std::byte> entropy) const;
207
216 const EllSwiftPubKey& our_ellswift,
217 bool initiating) const;
233 KeyPair ComputeKeyPair(const uint256* merkle_root) const;
234};
235
236CKey GenerateRandomKey(bool compressed = true) noexcept;
237
238struct CExtKey {
239 unsigned char nDepth;
241 unsigned int nChild;
244
245 friend bool operator==(const CExtKey& a, const CExtKey& b)
246 {
247 return a.nDepth == b.nDepth &&
248 a.fingerprint == b.fingerprint &&
249 a.nChild == b.nChild &&
250 a.chaincode == b.chaincode &&
251 a.key == b.key;
252 }
253
254 CExtKey() = default;
255 CExtKey(const CExtPubKey& xpub, const CKey& key_in) : nDepth(xpub.nDepth), fingerprint(xpub.fingerprint), nChild(xpub.nChild), chaincode(xpub.chaincode), key(key_in) {}
256
258 {
259 return key.GetPubKey().GetID().fingerprint();
260 }
261
263 template <typename Stream>
264 void Serialize(Stream& s) const
265 {
266 assert(key.size() == 32);
267 s << nDepth << fingerprint << Using<BigEndianFormatter<4>>(nChild) << chaincode << uint8_t{0} << std::span{key.data(), key.size()};
268 }
269 template <typename Stream>
271 {
272 uint8_t key_prefix;
273 std::vector<unsigned char, secure_allocator<unsigned char>> ser_key(32);
274 s >> nDepth >> fingerprint >> Using<BigEndianFormatter<4>>(nChild) >> chaincode >> key_prefix >> std::span{ser_key};
275 key.Set(ser_key.begin(), ser_key.end(), true);
276 if ((nDepth == 0 && (nChild != 0 || fingerprint != KeyFingerprint{})) || key_prefix != 0) key = CKey();
277 }
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
287std::optional<std::pair<CExtKey, KeyOriginInfo>> DeriveExtKey(const CExtKey& ext_key, const std::vector<uint32_t>& path);
288
301{
302public:
303 KeyPair() noexcept = default;
304 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) {
311 *m_keypair = *other.m_keypair;
312 } else {
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
326 {
327 return IsValid() ? reinterpret_cast<const secp256k1_keypair*>(m_keypair->data()) : nullptr;
328 }
329
331 bool IsValid() const { return !!m_keypair; }
332
333private:
334 KeyPair(const CKey& key, const uint256* merkle_root);
335
336 using KeyType = std::array<unsigned char, 96>;
338
340 {
341 if (!m_keypair) m_keypair = make_secure_unique<KeyType>();
342 }
343
345 {
346 m_keypair.reset();
347 }
348};
349
352
355
364{
365public:
366 ECC_Context();
367 ~ECC_Context();
368};
369
370#endif // BITCOIN_KEY_H
#define LIFETIMEBOUND
Definition: attributes.h:16
An encapsulated private key.
Definition: key.h:46
CKey() noexcept=default
KeyPair ComputeKeyPair(const uint256 *merkle_root) const
Compute a KeyPair.
Definition: key.cpp:349
void MakeKeyData()
Definition: key.h:74
static constexpr unsigned int COMPRESSED_SIZE
Definition: key.h:52
bool SignSchnorr(const uint256 &hash, std::span< unsigned char > sig, const uint256 *merkle_root, const uint256 &aux) const
Create a BIP-340 Schnorr signature, for the xonly-pubkey corresponding to *this, optionally tweaked b...
Definition: key.cpp:274
friend bool operator==(const CKey &a, const CKey &b)
Definition: key.h:105
void ClearKeyData()
Definition: key.h:79
unsigned int size() const
Simple read-only vector-like interface.
Definition: key.h:128
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:134
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig, bool grind=true, uint32_t test_case=0) const
Create a DER-serialized signature.
Definition: key.cpp:210
const std::byte * begin() const
Definition: key.h:130
ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey &their_ellswift, const EllSwiftPubKey &our_ellswift, bool initiating) const
Compute a BIP324-style ECDH shared secret.
Definition: key.cpp:329
static constexpr unsigned int SIZE
secp256k1:
Definition: key.h:51
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
Definition: key.cpp:171
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:137
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:163
bool fCompressed
Whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:66
EllSwiftPubKey EllSwiftCreate(std::span< const std::byte > entropy) const
Create an ellswift-encoded public key for this key, with specified entropy.
Definition: key.cpp:313
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:184
const std::byte * end() const
Definition: key.h:131
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:114
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
Definition: key.cpp:238
bool Load(const CPrivKey &privkey, const CPubKey &vchPubKey, bool fSkipCheck)
Load private key and check that public key matches.
Definition: key.cpp:280
static bool Check(const unsigned char *vch)
Check whether the 32-byte array pointed to by vch is valid keydata.
Definition: key.cpp:159
std::array< unsigned char, 32 > KeyType
see www.keylength.com script supports up to 75 for single byte push
Definition: key.h:63
bool Derive(CKey &keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const
Derive BIP32 child key.
Definition: key.cpp:294
secure_unique_ptr< KeyType > keydata
The actual byte data. nullptr for invalid keys.
Definition: key.h:69
CKey(const CKey &other)
Definition: key.h:103
bool SignCompact(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Create a compact signature (65 bytes), which allows reconstructing the used public key.
Definition: key.cpp:251
const std::byte * data() const
Definition: key.h:129
KeyFingerprint fingerprint() const
Definition: pubkey.h:33
An encapsulated public key.
Definition: pubkey.h:43
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:169
static constexpr size_t OUTPUT_SIZE
Definition: sha256.h:21
A BIP32 chain code.
Definition: hash.h:23
RAII class initializing and deinitializing global state for elliptic curve support.
Definition: key.h:364
ECC_Context()
Definition: key.cpp:476
~ECC_Context()
Definition: key.cpp:481
KeyPair.
Definition: key.h:301
KeyPair() noexcept=default
bool SignSchnorr(const uint256 &hash, std::span< unsigned char > sig, const uint256 &aux) const
Definition: key.cpp:421
void MakeKeyPairData()
Definition: key.h:339
std::array< unsigned char, 96 > KeyType
Definition: key.h:336
bool IsValid() const
Check whether this keypair is valid.
Definition: key.h:331
const secp256k1_keypair * GetSecpKeypair() const LIFETIMEBOUND
Pointer to this KeyPair's internal secp256k1_keypair data or nullptr if invalid.
Definition: key.h:325
secure_unique_ptr< KeyType > m_keypair
Definition: key.h:337
KeyPair(const KeyPair &other)
Definition: key.h:319
void ClearKeyPairData()
Definition: key.h:344
256-bit opaque blob.
Definition: uint256.h:196
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
CPrivKey is a serialized private key, with all parameters included (SIZE bytes)
Definition: key.h:34
secp256k1_context * GetSecp256k1SignContext()
Access the secp256k1 context used for signing and MuSig2 nonce generation.
Definition: key.cpp:443
constexpr size_t ECDH_SECRET_SIZE
Size of ECDH shared secrets.
Definition: key.h:37
std::optional< std::pair< CExtKey, KeyOriginInfo > > DeriveExtKey(const CExtKey &ext_key, const std::vector< uint32_t > &path)
Get extended key and origin info for a given path.
Definition: key.cpp:369
std::array< std::byte, ECDH_SECRET_SIZE > ECDHSecret
Definition: key.h:40
bool ECC_InitSanityCheck()
Check that required EC support is available at runtime.
Definition: key.cpp:437
CKey GenerateRandomKey(bool compressed=true) noexcept
Definition: key.cpp:354
SocketId Stream
Definition: util.h:30
std::array< unsigned char, 4 > KeyFingerprint
Definition: pubkey.h:25
std::unique_ptr< T, SecureUniqueDeleter< T > > secure_unique_ptr
Definition: secure.h:63
unsigned char * UCharCast(char *c)
Definition: span.h:95
Definition: key.h:238
CExtKey()=default
CExtKey(const CExtPubKey &xpub, const CKey &key_in)
Definition: key.h:255
KeyFingerprint id_key_fingerprint() const
Definition: key.h:257
void Serialize(Stream &s) const
BIP32 serialization without the version bytes (BIP32_EXTKEY_SIZE bytes)
Definition: key.h:264
KeyFingerprint fingerprint
Definition: key.h:240
CKey key
Definition: key.h:243
unsigned char nDepth
Definition: key.h:239
ChainCode chaincode
Definition: key.h:242
friend bool operator==(const CExtKey &a, const CExtKey &b)
Definition: key.h:245
unsigned int nChild
Definition: key.h:241
void Unserialize(Stream &s)
Definition: key.h:270
An ElligatorSwift-encoded public key.
Definition: pubkey.h:318
Opaque data structure that holds a keypair consisting of a secret and a public key.
assert(!tx.IsCoinBase())