Bitcoin Core  26.1.0
P2P Digital Currency
key.h
Go to the documentation of this file.
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>
13 #include <uint256.h>
14 
15 #include <stdexcept>
16 #include <vector>
17 
18 
23 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
24 
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 
32 class CKey
33 {
34 public:
38  static const unsigned int SIZE = 279;
39  static const unsigned int COMPRESSED_SIZE = 214;
44  static_assert(
46  "COMPRESSED_SIZE is larger than SIZE");
47 
48 private:
50  using KeyType = std::array<unsigned char, 32>;
51 
53  bool fCompressed{false};
54 
57 
59  bool static Check(const unsigned char* vch);
60 
61  void MakeKeyData()
62  {
63  if (!keydata) keydata = make_secure_unique<KeyType>();
64  }
65 
66  void ClearKeyData()
67  {
68  keydata.reset();
69  }
70 
71 public:
72  CKey() noexcept = default;
73  CKey(CKey&&) noexcept = default;
74  CKey& operator=(CKey&&) noexcept = default;
75 
76  CKey& operator=(const CKey& other)
77  {
78  if (other.keydata) {
79  MakeKeyData();
80  *keydata = *other.keydata;
81  } else {
82  ClearKeyData();
83  }
84  fCompressed = other.fCompressed;
85  return *this;
86  }
87 
88  CKey(const CKey& other) { *this = other; }
89 
90  friend bool operator==(const CKey& a, const CKey& b)
91  {
92  return a.fCompressed == b.fCompressed &&
93  a.size() == b.size() &&
94  memcmp(a.data(), b.data(), a.size()) == 0;
95  }
96 
98  template <typename T>
99  void Set(const T pbegin, const T pend, bool fCompressedIn)
100  {
101  if (size_t(pend - pbegin) != std::tuple_size_v<KeyType>) {
102  ClearKeyData();
103  } else if (Check(&pbegin[0])) {
104  MakeKeyData();
105  memcpy(keydata->data(), (unsigned char*)&pbegin[0], keydata->size());
106  fCompressed = fCompressedIn;
107  } else {
108  ClearKeyData();
109  }
110  }
111 
113  unsigned int size() const { return keydata ? keydata->size() : 0; }
114  const std::byte* data() const { return keydata ? reinterpret_cast<const std::byte*>(keydata->data()) : nullptr; }
115  const unsigned char* begin() const { return keydata ? keydata->data() : nullptr; }
116  const unsigned char* end() const { return begin() + size(); }
117 
119  bool IsValid() const { return !!keydata; }
120 
122  bool IsCompressed() const { return fCompressed; }
123 
125  void MakeNewKey(bool fCompressed);
126 
128  bool Negate();
129 
134  CPrivKey GetPrivKey() const;
135 
140  CPubKey GetPubKey() const;
141 
146  bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, bool grind = true, uint32_t test_case = 0) const;
147 
155  bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
156 
172  bool SignSchnorr(const uint256& hash, Span<unsigned char> sig, const uint256* merkle_root, const uint256& aux) const;
173 
175  [[nodiscard]] bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
176 
181  bool VerifyPubKey(const CPubKey& vchPubKey) const;
182 
184  bool Load(const CPrivKey& privkey, const CPubKey& vchPubKey, bool fSkipCheck);
185 
195 
203  ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift,
204  const EllSwiftPubKey& our_ellswift,
205  bool initiating) const;
206 };
207 
208 struct CExtKey {
209  unsigned char nDepth;
210  unsigned char vchFingerprint[4];
211  unsigned int nChild;
214 
215  friend bool operator==(const CExtKey& a, const CExtKey& b)
216  {
217  return a.nDepth == b.nDepth &&
218  memcmp(a.vchFingerprint, b.vchFingerprint, sizeof(vchFingerprint)) == 0 &&
219  a.nChild == b.nChild &&
220  a.chaincode == b.chaincode &&
221  a.key == b.key;
222  }
223 
224  void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
225  void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
226  [[nodiscard]] bool Derive(CExtKey& out, unsigned int nChild) const;
227  CExtPubKey Neuter() const;
228  void SetSeed(Span<const std::byte> seed);
229 };
230 
232 void ECC_Start();
233 
235 void ECC_Stop();
236 
238 bool ECC_InitSanityCheck();
239 
240 #endif // BITCOIN_KEY_H
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
Definition: key.cpp:175
std::array< unsigned char, 32 > KeyType
see www.keylength.com script supports up to 75 for single byte push
Definition: key.h:50
CKey key
Definition: key.h:213
bool Negate()
Negate private key.
Definition: key.cpp:169
EllSwiftPubKey EllSwiftCreate(Span< const std::byte > entropy) const
Create an ellswift-encoded public key for this key, with specified entropy.
Definition: key.cpp:336
bool Derive(CExtKey &out, unsigned int nChild) const
Definition: key.cpp:372
void ECC_Stop()
Deinitialize the elliptic curve support.
Definition: key.cpp:446
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
Definition: key.cpp:242
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:188
Definition: key.h:208
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
Definition: key.cpp:403
secure_unique_ptr< KeyType > keydata
The actual byte data. nullptr for invalid keys.
Definition: key.h:56
CKey(const CKey &other)
Definition: key.h:88
unsigned char vchFingerprint[4]
Definition: key.h:210
static const unsigned int SIZE
secp256k1:
Definition: key.h:38
bool SignSchnorr(const uint256 &hash, 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:278
const unsigned char * begin() const
Definition: key.h:115
ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey &their_ellswift, const EllSwiftPubKey &our_ellswift, bool initiating) const
Compute a BIP324-style ECDH shared secret.
Definition: key.cpp:352
void ClearKeyData()
Definition: key.h:66
std::unique_ptr< T, SecureUniqueDeleter< T > > secure_unique_ptr
Definition: secure.h:68
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:255
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
CPrivKey is a serialized private key, with all parameters included (SIZE bytes)
Definition: key.h:23
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:214
static const unsigned int COMPRESSED_SIZE
Definition: key.h:39
const std::byte * data() const
Definition: key.h:114
unsigned char nDepth
Definition: key.h:209
friend bool operator==(const CExtKey &a, const CExtKey &b)
Definition: key.h:215
An encapsulated public key.
Definition: pubkey.h:33
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:161
unsigned int nChild
Definition: key.h:211
An ElligatorSwift-encoded public key.
Definition: pubkey.h:303
unsigned int size() const
Simple read-only vector-like interface.
Definition: key.h:113
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:122
ChainCode chaincode
Definition: key.h:212
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:99
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
Definition: key.cpp:413
256-bit opaque blob.
Definition: uint256.h:106
std::array< std::byte, ECDH_SECRET_SIZE > ECDHSecret
Definition: key.h:29
void SetSeed(Span< const std::byte > seed)
Definition: key.cpp:381
CExtPubKey Neuter() const
Definition: key.cpp:393
static constexpr size_t ECDH_SECRET_SIZE
Size of ECDH shared secrets.
Definition: key.h:26
bool Derive(CKey &keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const
Derive BIP32 child key.
Definition: key.cpp:317
const unsigned char * end() const
Definition: key.h:116
const unsigned int BIP32_EXTKEY_SIZE
Definition: pubkey.h:19
bool fCompressed
Whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:53
static const size_t OUTPUT_SIZE
Definition: sha256.h:21
bool ECC_InitSanityCheck()
Check that required EC support is available at runtime.
Definition: key.cpp:422
static bool Check(const unsigned char *vch)
Check whether the 32-byte array pointed to by vch is valid keydata.
Definition: key.cpp:157
An encapsulated private key.
Definition: key.h:32
A Span is an object that can refer to a contiguous sequence of objects.
Definition: solver.h:20
void MakeKeyData()
Definition: key.h:61
CKey() noexcept=default
bool Load(const CPrivKey &privkey, const CPubKey &vchPubKey, bool fSkipCheck)
Load private key and check that public key matches.
Definition: key.cpp:303
friend bool operator==(const CKey &a, const CKey &b)
Definition: key.h:90
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:119
void ECC_Start()
Initialize the elliptic curve support.
Definition: key.cpp:429