]>
Commit | Line | Data |
---|---|---|
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 */ |
26 | class CKeyID : public uint160 | |
27 | { | |
28 | public: | |
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) */ | |
34 | class CScriptID : public uint160 | |
35 | { | |
36 | public: | |
37 | CScriptID() : uint160(0) { } | |
38 | CScriptID(const uint160 &in) : uint160(in) { } | |
39 | }; | |
40 | ||
41 | /** An encapsulated public key. */ | |
fd61d6f5 PW |
42 | class CPubKey { |
43 | private: | |
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 | 62 | public: |
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 | 172 | typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; |
8bd66202 | 173 | |
dfa23b94 PW |
174 | /** An encapsulated private key. */ |
175 | class CKey { | |
176 | private: | |
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 | 189 | public: |
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 | ||
273 | struct 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 | ||
290 | struct 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 |