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