]>
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. |
223b6f1b WL |
5 | #ifndef BITCOIN_KEY_H |
6 | #define BITCOIN_KEY_H | |
8bd66202 | 7 | |
fcedd45c VN |
8 | #include <vector> |
9 | ||
0a83c0fc | 10 | #include "allocators.h" |
fd61d6f5 | 11 | #include "serialize.h" |
fcedd45c | 12 | #include "uint256.h" |
0fb9073e | 13 | #include "hash.h" |
fcedd45c | 14 | |
8bd66202 GA |
15 | // secp256k1: |
16 | // const unsigned int PRIVATE_KEY_SIZE = 279; | |
17 | // const unsigned int PUBLIC_KEY_SIZE = 65; | |
18 | // const unsigned int SIGNATURE_SIZE = 72; | |
19 | // | |
20 | // see www.keylength.com | |
21 | // script supports up to 75 for single byte push | |
22 | ||
10254401 PW |
23 | /** A reference to a CKey: the Hash160 of its serialized public key */ |
24 | class CKeyID : public uint160 | |
25 | { | |
26 | public: | |
27 | CKeyID() : uint160(0) { } | |
28 | CKeyID(const uint160 &in) : uint160(in) { } | |
29 | }; | |
30 | ||
31 | /** A reference to a CScript: the Hash160 of its serialization (see script.h) */ | |
32 | class CScriptID : public uint160 | |
33 | { | |
34 | public: | |
35 | CScriptID() : uint160(0) { } | |
36 | CScriptID(const uint160 &in) : uint160(in) { } | |
37 | }; | |
38 | ||
39 | /** An encapsulated public key. */ | |
fd61d6f5 PW |
40 | class CPubKey { |
41 | private: | |
dfa23b94 PW |
42 | // Just store the serialized data. |
43 | // Its length can very cheaply be computed from the first byte. | |
5d891489 PW |
44 | unsigned char vch[65]; |
45 | ||
dfa23b94 | 46 | // Compute the length of a pubkey with a given first byte. |
5d891489 PW |
47 | unsigned int static GetLen(unsigned char chHeader) { |
48 | if (chHeader == 2 || chHeader == 3) | |
49 | return 33; | |
50 | if (chHeader == 4 || chHeader == 6 || chHeader == 7) | |
51 | return 65; | |
52 | return 0; | |
53 | } | |
54 | ||
dfa23b94 PW |
55 | // Set this key data to be invalid |
56 | void Invalidate() { | |
57 | vch[0] = 0xFF; | |
5d891489 PW |
58 | } |
59 | ||
fd61d6f5 | 60 | public: |
dfa23b94 PW |
61 | // Construct an invalid public key. |
62 | CPubKey() { | |
63 | Invalidate(); | |
5d891489 PW |
64 | } |
65 | ||
dfa23b94 PW |
66 | // Initialize a public key using begin/end iterators to byte data. |
67 | template<typename T> | |
68 | void Set(const T pbegin, const T pend) { | |
69 | int len = pend == pbegin ? 0 : GetLen(pbegin[0]); | |
70 | if (len && len == (pend-pbegin)) | |
71 | memcpy(vch, (unsigned char*)&pbegin[0], len); | |
72 | else | |
73 | Invalidate(); | |
5d891489 PW |
74 | } |
75 | ||
dfa23b94 PW |
76 | // Construct a public key using begin/end iterators to byte data. |
77 | template<typename T> | |
78 | CPubKey(const T pbegin, const T pend) { | |
79 | Set(pbegin, pend); | |
5d891489 | 80 | } |
fd61d6f5 | 81 | |
dfa23b94 PW |
82 | // Construct a public key from a byte vector. |
83 | CPubKey(const std::vector<unsigned char> &vch) { | |
84 | Set(vch.begin(), vch.end()); | |
5d891489 PW |
85 | } |
86 | ||
896185d7 | 87 | // Simple read-only vector-like interface to the pubkey data. |
dfa23b94 PW |
88 | unsigned int size() const { return GetLen(vch[0]); } |
89 | const unsigned char *begin() const { return vch; } | |
90 | const unsigned char *end() const { return vch+size(); } | |
91 | const unsigned char &operator[](unsigned int pos) const { return vch[pos]; } | |
92 | ||
93 | // Comparator implementation. | |
94 | friend bool operator==(const CPubKey &a, const CPubKey &b) { | |
95 | return a.vch[0] == b.vch[0] && | |
96 | memcmp(a.vch, b.vch, a.size()) == 0; | |
97 | } | |
98 | friend bool operator!=(const CPubKey &a, const CPubKey &b) { | |
99 | return !(a == b); | |
100 | } | |
5d891489 PW |
101 | friend bool operator<(const CPubKey &a, const CPubKey &b) { |
102 | return a.vch[0] < b.vch[0] || | |
dfa23b94 | 103 | (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0); |
5d891489 PW |
104 | } |
105 | ||
dfa23b94 | 106 | // Implement serialization, as if this was a byte vector. |
5d891489 PW |
107 | unsigned int GetSerializeSize(int nType, int nVersion) const { |
108 | return size() + 1; | |
109 | } | |
5d891489 PW |
110 | template<typename Stream> void Serialize(Stream &s, int nType, int nVersion) const { |
111 | unsigned int len = size(); | |
896185d7 | 112 | ::WriteCompactSize(s, len); |
5d891489 PW |
113 | s.write((char*)vch, len); |
114 | } | |
5d891489 | 115 | template<typename Stream> void Unserialize(Stream &s, int nType, int nVersion) { |
896185d7 | 116 | unsigned int len = ::ReadCompactSize(s); |
5d891489 PW |
117 | if (len <= 65) { |
118 | s.read((char*)vch, len); | |
119 | } else { | |
dfa23b94 | 120 | // invalid pubkey, skip available data |
5d891489 PW |
121 | char dummy; |
122 | while (len--) | |
123 | s.read(&dummy, 1); | |
dfa23b94 | 124 | Invalidate(); |
5d891489 PW |
125 | } |
126 | } | |
fd61d6f5 | 127 | |
dfa23b94 | 128 | // Get the KeyID of this public key (hash of its serialization) |
10254401 | 129 | CKeyID GetID() const { |
5d891489 | 130 | return CKeyID(Hash160(vch, vch+size())); |
fd61d6f5 PW |
131 | } |
132 | ||
dfa23b94 | 133 | // Get the 256-bit hash of this public key. |
fd61d6f5 | 134 | uint256 GetHash() const { |
5d891489 | 135 | return Hash(vch, vch+size()); |
fd61d6f5 PW |
136 | } |
137 | ||
dfa23b94 | 138 | // just check syntactic correctness. |
fd61d6f5 | 139 | bool IsValid() const { |
5d891489 | 140 | return size() > 0; |
fd61d6f5 PW |
141 | } |
142 | ||
dfa23b94 PW |
143 | // fully validate whether this is a valid public key (more expensive than IsValid()) |
144 | bool IsFullyValid() const; | |
145 | ||
146 | // Check whether this is a compressed public key. | |
10254401 | 147 | bool IsCompressed() const { |
5d891489 | 148 | return size() == 33; |
10254401 PW |
149 | } |
150 | ||
dfa23b94 PW |
151 | // Verify a DER signature (~72 bytes). |
152 | // If this public key is not fully valid, the return value will be false. | |
153 | bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const; | |
154 | ||
155 | // Verify a compact signature (~65 bytes). | |
156 | // See CKey::SignCompact. | |
157 | bool VerifyCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) const; | |
158 | ||
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(); | |
fd61d6f5 PW |
164 | }; |
165 | ||
8bd66202 | 166 | |
7fddf121 | 167 | // secure_allocator is defined in allocators.h |
d825e6a3 | 168 | // CPrivKey is a serialized private key, with all parameters included (279 bytes) |
223b6f1b | 169 | typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey; |
8bd66202 | 170 | |
dfa23b94 PW |
171 | /** An encapsulated private key. */ |
172 | class CKey { | |
173 | private: | |
174 | // Whether this private key is valid. We check for correctness when modifying the key | |
175 | // data, so fValid should always correspond to the actual state. | |
176 | bool fValid; | |
11529c6e | 177 | |
dfa23b94 PW |
178 | // Whether the public key corresponding to this private key is (to be) compressed. |
179 | bool fCompressed; | |
180 | ||
181 | // The actual byte data | |
182 | unsigned char vch[32]; | |
183 | ||
184 | // Check whether the 32-byte array pointed to be vch is valid keydata. | |
185 | bool static Check(const unsigned char *vch); | |
8bd66202 | 186 | public: |
11529c6e | 187 | |
dfa23b94 PW |
188 | // Construct an invalid private key. |
189 | CKey() : fValid(false) { | |
190 | LockObject(vch); | |
191 | } | |
8bd66202 | 192 | |
dfa23b94 PW |
193 | // Copy constructor. This is necessary because of memlocking. |
194 | CKey(const CKey &secret) : fValid(secret.fValid), fCompressed(secret.fCompressed) { | |
195 | LockObject(vch); | |
196 | memcpy(vch, secret.vch, sizeof(vch)); | |
197 | } | |
11529c6e | 198 | |
dfa23b94 PW |
199 | // Destructor (again necessary because of memlocking). |
200 | ~CKey() { | |
201 | UnlockObject(vch); | |
202 | } | |
8bd66202 | 203 | |
dfa23b94 PW |
204 | // Initialize using begin and end iterators to byte data. |
205 | template<typename T> | |
206 | void Set(const T pbegin, const T pend, bool fCompressedIn) { | |
207 | if (pend - pbegin != 32) { | |
208 | fValid = false; | |
209 | return; | |
210 | } | |
211 | if (Check(&pbegin[0])) { | |
212 | memcpy(vch, (unsigned char*)&pbegin[0], 32); | |
213 | fValid = true; | |
214 | fCompressed = fCompressedIn; | |
215 | } else { | |
216 | fValid = false; | |
217 | } | |
218 | } | |
219 | ||
220 | // Simple read-only vector-like interface. | |
221 | unsigned int size() const { return (fValid ? 32 : 0); } | |
222 | const unsigned char *begin() const { return vch; } | |
223 | const unsigned char *end() const { return vch + size(); } | |
224 | ||
225 | // Check whether this private key is valid. | |
226 | bool IsValid() const { return fValid; } | |
8bd66202 | 227 | |
dfa23b94 PW |
228 | // Check whether the public key corresponding to this private key is (to be) compressed. |
229 | bool IsCompressed() const { return fCompressed; } | |
acd65016 | 230 | |
dfa23b94 PW |
231 | // Initialize from a CPrivKey (serialized OpenSSL private key data). |
232 | bool SetPrivKey(const CPrivKey &vchPrivKey, bool fCompressed); | |
233 | ||
234 | // Generate a new private key using a cryptographic PRNG. | |
096e06db | 235 | void MakeNewKey(bool fCompressed); |
dfa23b94 PW |
236 | |
237 | // Convert the private key to a CPrivKey (serialized OpenSSL private key data). | |
238 | // This is expensive. | |
096e06db | 239 | CPrivKey GetPrivKey() const; |
dfa23b94 PW |
240 | |
241 | // Compute the public key from a private key. | |
242 | // This is expensive. | |
fd61d6f5 | 243 | CPubKey GetPubKey() const; |
acd65016 | 244 | |
dfa23b94 PW |
245 | // Create a DER-serialized signature. |
246 | bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const; | |
8bd66202 | 247 | |
dfa23b94 | 248 | // Create a compact signature (65 bytes), which allows reconstructing the used public key. |
d825e6a3 PW |
249 | // The format is one header byte, followed by two times 32 bytes for the serialized r and s values. |
250 | // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, | |
dfa23b94 PW |
251 | // 0x1D = second key with even y, 0x1E = second key with odd y, |
252 | // add 0x04 for compressed keys. | |
253 | bool SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const; | |
8bd66202 | 254 | }; |
223b6f1b WL |
255 | |
256 | #endif |