]> Git Repo - VerusCoin.git/blob - src/key.h
Merge pull request #4758 from theuni/osx-dmg-codesign-rebase
[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 private:
44     // Just store the serialized data.
45     // Its length can very cheaply be computed from the first byte.
46     unsigned char vch[65];
47
48     // Compute the length of a pubkey with a given first byte.
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
57     // Set this key data to be invalid
58     void Invalidate() {
59         vch[0] = 0xFF;
60     }
61
62 public:
63     // Construct an invalid public key.
64     CPubKey() {
65         Invalidate();
66     }
67
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();
76     }
77
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);
82     }
83
84     // Construct a public key from a byte vector.
85     CPubKey(const std::vector<unsigned char> &vch) {
86         Set(vch.begin(), vch.end());
87     }
88
89     // Simple read-only vector-like interface to the pubkey data.
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     }
103     friend bool operator<(const CPubKey &a, const CPubKey &b) {
104         return a.vch[0] < b.vch[0] ||
105                (a.vch[0] == b.vch[0] && memcmp(a.vch, b.vch, a.size()) < 0);
106     }
107
108     // Implement serialization, as if this was a byte vector.
109     unsigned int GetSerializeSize(int nType, int nVersion) const {
110         return size() + 1;
111     }
112     template<typename Stream> void Serialize(Stream &s, int nType, int nVersion) const {
113         unsigned int len = size();
114         ::WriteCompactSize(s, len);
115         s.write((char*)vch, len);
116     }
117     template<typename Stream> void Unserialize(Stream &s, int nType, int nVersion) {
118         unsigned int len = ::ReadCompactSize(s);
119         if (len <= 65) {
120             s.read((char*)vch, len);
121         } else {
122             // invalid pubkey, skip available data
123             char dummy;
124             while (len--)
125                 s.read(&dummy, 1);
126             Invalidate();
127         }
128     }
129
130     // Get the KeyID of this public key (hash of its serialization)
131     CKeyID GetID() const {
132         return CKeyID(Hash160(vch, vch+size()));
133     }
134
135     // Get the 256-bit hash of this public key.
136     uint256 GetHash() const {
137         return Hash(vch, vch+size());
138     }
139
140     // Check syntactic correctness.
141     //
142     // Note that this is consensus critical as CheckSig() calls it!
143     bool IsValid() const {
144         return size() > 0;
145     }
146
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.
151     bool IsCompressed() const {
152         return size() == 33;
153     }
154
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
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();
164
165     // Derive BIP32 child pubkey.
166     bool Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const;
167 };
168
169
170 // secure_allocator is defined in allocators.h
171 // CPrivKey is a serialized private key, with all parameters included (279 bytes)
172 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
173
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;
180
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);
189 public:
190
191     // Construct an invalid private key.
192     CKey() : fValid(false), fCompressed(false) {
193         LockObject(vch);
194     }
195
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     }
201
202     // Destructor (again necessary because of memlocking).
203     ~CKey() {
204         UnlockObject(vch);
205     }
206
207     friend bool operator==(const CKey &a, const CKey &b) {
208         return a.fCompressed == b.fCompressed && a.size() == b.size() &&
209                memcmp(&a.vch[0], &b.vch[0], a.size()) == 0;
210     }
211
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; }
235
236     // Check whether the public key corresponding to this private key is (to be) compressed.
237     bool IsCompressed() const { return fCompressed; }
238
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.
243     void MakeNewKey(bool fCompressed);
244
245     // Convert the private key to a CPrivKey (serialized OpenSSL private key data).
246     // This is expensive.
247     CPrivKey GetPrivKey() const;
248
249     // Compute the public key from a private key.
250     // This is expensive.
251     CPubKey GetPubKey() const;
252
253     // Create a DER-serialized signature.
254     bool Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const;
255
256     // Create a compact signature (65 bytes), which allows reconstructing the used public key.
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,
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;
262
263     // Derive BIP32 child key.
264     bool Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const;
265
266     // Load private key and check that public key matches.
267     bool Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck);
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);
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);
307 };
308
309 /** Check that required EC support is available at runtime */
310 bool ECC_InitSanityCheck(void);
311
312 #endif // BITCOIN_KEY_H
This page took 0.039166 seconds and 4 git commands to generate.