]> Git Repo - VerusCoin.git/blame - src/key.h
Merge pull request #3683
[VerusCoin.git] / src / key.h
CommitLineData
8bd66202 1// Copyright (c) 2009-2010 Satoshi Nakamoto
dfa23b94 2// Copyright (c) 2009-2013 The Bitcoin developers
8bd66202 3// Distributed under the MIT/X11 software license, see the accompanying
3a25a2b9 4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
51ed9ec9 5
223b6f1b
WL
6#ifndef BITCOIN_KEY_H
7#define BITCOIN_KEY_H
8bd66202 8
0a83c0fc 9#include "allocators.h"
51ed9ec9 10#include "hash.h"
fd61d6f5 11#include "serialize.h"
fcedd45c 12#include "uint256.h"
51ed9ec9
BD
13
14#include <stdexcept>
15#include <vector>
fcedd45c 16
8bd66202
GA
17// secp256k1:
18// const unsigned int PRIVATE_KEY_SIZE = 279;
19// const unsigned int PUBLIC_KEY_SIZE = 65;
20// const unsigned int SIGNATURE_SIZE = 72;
21//
22// see www.keylength.com
23// script supports up to 75 for single byte push
24
10254401
PW
25/** A reference to a CKey: the Hash160 of its serialized public key */
26class CKeyID : public uint160
27{
28public:
29 CKeyID() : uint160(0) { }
30 CKeyID(const uint160 &in) : uint160(in) { }
31};
32
33/** A reference to a CScript: the Hash160 of its serialization (see script.h) */
34class CScriptID : public uint160
35{
36public:
37 CScriptID() : uint160(0) { }
38 CScriptID(const uint160 &in) : uint160(in) { }
39};
40
41/** An encapsulated public key. */
fd61d6f5
PW
42class CPubKey {
43private:
dfa23b94
PW
44 // Just store the serialized data.
45 // Its length can very cheaply be computed from the first byte.
5d891489
PW
46 unsigned char vch[65];
47
dfa23b94 48 // Compute the length of a pubkey with a given first byte.
5d891489
PW
49 unsigned int static GetLen(unsigned char chHeader) {
50 if (chHeader == 2 || chHeader == 3)
51 return 33;
52 if (chHeader == 4 || chHeader == 6 || chHeader == 7)
53 return 65;
54 return 0;
55 }
56
dfa23b94
PW
57 // Set this key data to be invalid
58 void Invalidate() {
59 vch[0] = 0xFF;
5d891489
PW
60 }
61
fd61d6f5 62public:
dfa23b94
PW
63 // Construct an invalid public key.
64 CPubKey() {
65 Invalidate();
5d891489
PW
66 }
67
dfa23b94
PW
68 // Initialize a public key using begin/end iterators to byte data.
69 template<typename T>
70 void Set(const T pbegin, const T pend) {
71 int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
72 if (len && len == (pend-pbegin))
73 memcpy(vch, (unsigned char*)&pbegin[0], len);
74 else
75 Invalidate();
5d891489
PW
76 }
77
dfa23b94
PW
78 // Construct a public key using begin/end iterators to byte data.
79 template<typename T>
80 CPubKey(const T pbegin, const T pend) {
81 Set(pbegin, pend);
5d891489 82 }
fd61d6f5 83
dfa23b94
PW
84 // Construct a public key from a byte vector.
85 CPubKey(const std::vector<unsigned char> &vch) {
86 Set(vch.begin(), vch.end());
5d891489
PW
87 }
88
896185d7 89 // Simple read-only vector-like interface to the pubkey data.
dfa23b94
PW
90 unsigned int size() const { return GetLen(vch[0]); }
91 const unsigned char *begin() const { return vch; }
92 const unsigned char *end() const { return vch+size(); }
93 const unsigned char &operator[](unsigned int pos) const { return vch[pos]; }
94
95 // Comparator implementation.
96 friend bool operator==(const CPubKey &a, const CPubKey &b) {
97 return a.vch[0] == b.vch[0] &&
98 memcmp(a.vch, b.vch, a.size()) == 0;
99 }
100 friend bool operator!=(const CPubKey &a, const CPubKey &b) {
101 return !(a == b);
102 }
5d891489
PW
103 friend bool operator<(const CPubKey &a, const CPubKey &b) {
104 return a.vch[0] < b.vch[0] ||
dfa23b94 105 (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
5d891489
PW
106 }
107
dfa23b94 108 // Implement serialization, as if this was a byte vector.
5d891489
PW
109 unsigned int GetSerializeSize(int nType, int nVersion) const {
110 return size() + 1;
111 }
5d891489
PW
112 template<typename Stream> void Serialize(Stream &s, int nType, int nVersion) const {
113 unsigned int len = size();
896185d7 114 ::WriteCompactSize(s, len);
5d891489
PW
115 s.write((char*)vch, len);
116 }
5d891489 117 template<typename Stream> void Unserialize(Stream &s, int nType, int nVersion) {
896185d7 118 unsigned int len = ::ReadCompactSize(s);
5d891489
PW
119 if (len <= 65) {
120 s.read((char*)vch, len);
121 } else {
dfa23b94 122 // invalid pubkey, skip available data
5d891489
PW
123 char dummy;
124 while (len--)
125 s.read(&dummy, 1);
dfa23b94 126 Invalidate();
5d891489
PW
127 }
128 }
fd61d6f5 129
dfa23b94 130 // Get the KeyID of this public key (hash of its serialization)
10254401 131 CKeyID GetID() const {
5d891489 132 return CKeyID(Hash160(vch, vch+size()));
fd61d6f5
PW
133 }
134
dfa23b94 135 // Get the 256-bit hash of this public key.
fd61d6f5 136 uint256 GetHash() const {
5d891489 137 return Hash(vch, vch+size());
fd61d6f5
PW
138 }
139
5a986eda
PT
140 // Check syntactic correctness.
141 //
142 // Note that this is consensus critical as CheckSig() calls it!
fd61d6f5 143 bool IsValid() const {
5d891489 144 return size() > 0;
fd61d6f5
PW
145 }
146
dfa23b94
PW
147 // fully validate whether this is a valid public key (more expensive than IsValid())
148 bool IsFullyValid() const;
149
150 // Check whether this is a compressed public key.
10254401 151 bool IsCompressed() const {
5d891489 152 return size() == 33;
10254401
PW
153 }
154
dfa23b94
PW
155 // Verify a DER signature (~72 bytes).
156 // If this public key is not fully valid, the return value will be false.
157 bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const;
158
dfa23b94
PW
159 // Recover a public key from a compact signature.
160 bool RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig);
161
162 // Turn this public key into an uncompressed public key.
163 bool Decompress();
eb2c9990
PW
164
165 // Derive BIP32 child pubkey.
166 bool Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const;
fd61d6f5
PW
167};
168
8bd66202 169
7fddf121 170// secure_allocator is defined in allocators.h
d825e6a3 171// CPrivKey is a serialized private key, with all parameters included (279 bytes)
223b6f1b 172typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
8bd66202 173
dfa23b94
PW
174/** An encapsulated private key. */
175class CKey {
176private:
177 // Whether this private key is valid. We check for correctness when modifying the key
178 // data, so fValid should always correspond to the actual state.
179 bool fValid;
11529c6e 180
dfa23b94
PW
181 // Whether the public key corresponding to this private key is (to be) compressed.
182 bool fCompressed;
183
184 // The actual byte data
185 unsigned char vch[32];
186
187 // Check whether the 32-byte array pointed to be vch is valid keydata.
188 bool static Check(const unsigned char *vch);
8bd66202 189public:
11529c6e 190
dfa23b94
PW
191 // Construct an invalid private key.
192 CKey() : fValid(false) {
193 LockObject(vch);
194 }
8bd66202 195
dfa23b94
PW
196 // Copy constructor. This is necessary because of memlocking.
197 CKey(const CKey &secret) : fValid(secret.fValid), fCompressed(secret.fCompressed) {
198 LockObject(vch);
199 memcpy(vch, secret.vch, sizeof(vch));
200 }
11529c6e 201
dfa23b94
PW
202 // Destructor (again necessary because of memlocking).
203 ~CKey() {
204 UnlockObject(vch);
205 }
8bd66202 206
eb2c9990 207 friend bool operator==(const CKey &a, const CKey &b) {
a3996740
PK
208 return a.fCompressed == b.fCompressed && a.size() == b.size() &&
209 memcmp(&a.vch[0], &b.vch[0], a.size()) == 0;
eb2c9990
PW
210 }
211
dfa23b94
PW
212 // Initialize using begin and end iterators to byte data.
213 template<typename T>
214 void Set(const T pbegin, const T pend, bool fCompressedIn) {
215 if (pend - pbegin != 32) {
216 fValid = false;
217 return;
218 }
219 if (Check(&pbegin[0])) {
220 memcpy(vch, (unsigned char*)&pbegin[0], 32);
221 fValid = true;
222 fCompressed = fCompressedIn;
223 } else {
224 fValid = false;
225 }
226 }
227
228 // Simple read-only vector-like interface.
229 unsigned int size() const { return (fValid ? 32 : 0); }
230 const unsigned char *begin() const { return vch; }
231 const unsigned char *end() const { return vch + size(); }
232
233 // Check whether this private key is valid.
234 bool IsValid() const { return fValid; }
8bd66202 235
dfa23b94
PW
236 // Check whether the public key corresponding to this private key is (to be) compressed.
237 bool IsCompressed() const { return fCompressed; }
acd65016 238
dfa23b94
PW
239 // Initialize from a CPrivKey (serialized OpenSSL private key data).
240 bool SetPrivKey(const CPrivKey &vchPrivKey, bool fCompressed);
241
242 // Generate a new private key using a cryptographic PRNG.
096e06db 243 void MakeNewKey(bool fCompressed);
dfa23b94
PW
244
245 // Convert the private key to a CPrivKey (serialized OpenSSL private key data).
246 // This is expensive.
096e06db 247 CPrivKey GetPrivKey() const;
dfa23b94
PW
248
249 // Compute the public key from a private key.
250 // This is expensive.
fd61d6f5 251 CPubKey GetPubKey() const;
acd65016 252
dfa23b94
PW
253 // Create a DER-serialized signature.
254 bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const;
8bd66202 255
dfa23b94 256 // Create a compact signature (65 bytes), which allows reconstructing the used public key.
d825e6a3
PW
257 // The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
258 // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
dfa23b94
PW
259 // 0x1D = second key with even y, 0x1E = second key with odd y,
260 // add 0x04 for compressed keys.
261 bool SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const;
eb2c9990
PW
262
263 // Derive BIP32 child key.
264 bool Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const;
a3996740 265
6e51b3bd 266 // Load private key and check that public key matches.
a3996740 267 bool Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck);
6fd7ef2b
PW
268
269 // Check whether an element of a signature (r or s) is valid.
270 static bool CheckSignatureElement(const unsigned char *vch, int len, bool half);
eb2c9990
PW
271};
272
273struct CExtPubKey {
274 unsigned char nDepth;
275 unsigned char vchFingerprint[4];
276 unsigned int nChild;
277 unsigned char vchChainCode[32];
278 CPubKey pubkey;
279
280 friend bool operator==(const CExtPubKey &a, const CExtPubKey &b) {
281 return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
282 memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.pubkey == b.pubkey;
283 }
284
285 void Encode(unsigned char code[74]) const;
286 void Decode(const unsigned char code[74]);
287 bool Derive(CExtPubKey &out, unsigned int nChild) const;
288};
289
290struct CExtKey {
291 unsigned char nDepth;
292 unsigned char vchFingerprint[4];
293 unsigned int nChild;
294 unsigned char vchChainCode[32];
295 CKey key;
296
297 friend bool operator==(const CExtKey &a, const CExtKey &b) {
298 return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
299 memcmp(&a.vchChainCode[0], &b.vchChainCode[0], 32) == 0 && a.key == b.key;
300 }
301
302 void Encode(unsigned char code[74]) const;
303 void Decode(const unsigned char code[74]);
304 bool Derive(CExtKey &out, unsigned int nChild) const;
305 CExtPubKey Neuter() const;
306 void SetMaster(const unsigned char *seed, unsigned int nSeedLen);
8bd66202 307};
223b6f1b
WL
308
309#endif
This page took 0.155476 seconds and 4 git commands to generate.