c1890904cc4c284bc03f51dd11d386fa156a55ae
[novacoin.git] / src / key.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 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 #ifndef BITCOIN_KEY_H
6 #define BITCOIN_KEY_H
7
8 #include <stdexcept>
9 #include <vector>
10
11 #include "allocators.h"
12 #include "serialize.h"
13 #include "uint256.h"
14 #include "hash.h"
15 #include "bignum.h"
16
17 #include <openssl/ec.h> // for EC_KEY definition
18
19 // secp160k1
20 // const unsigned int PRIVATE_KEY_SIZE = 192;
21 // const unsigned int PUBLIC_KEY_SIZE  = 41;
22 // const unsigned int SIGNATURE_SIZE   = 48;
23 //
24 // secp192k1
25 // const unsigned int PRIVATE_KEY_SIZE = 222;
26 // const unsigned int PUBLIC_KEY_SIZE  = 49;
27 // const unsigned int SIGNATURE_SIZE   = 57;
28 //
29 // secp224k1
30 // const unsigned int PRIVATE_KEY_SIZE = 250;
31 // const unsigned int PUBLIC_KEY_SIZE  = 57;
32 // const unsigned int SIGNATURE_SIZE   = 66;
33 //
34 // secp256k1:
35 // const unsigned int PRIVATE_KEY_SIZE = 279;
36 // const unsigned int PUBLIC_KEY_SIZE  = 65;
37 // const unsigned int SIGNATURE_SIZE   = 72;
38 //
39 // see www.keylength.com
40 // script supports up to 75 for single byte push
41
42 class key_error : public std::runtime_error
43 {
44 public:
45     explicit key_error(const std::string& str) : std::runtime_error(str) {}
46 };
47
48 /** A reference to a CKey: the Hash160 of its serialized public key */
49 class CKeyID : public uint160
50 {
51 public:
52     CKeyID() : uint160(0) { }
53     CKeyID(const uint160 &in) : uint160(in) { }
54 };
55
56 /** A reference to a CScript: the Hash160 of its serialization (see script.h) */
57 class CScriptID : public uint160
58 {
59 public:
60     CScriptID() : uint160(0) { }
61     CScriptID(const uint160 &in) : uint160(in) { }
62 };
63
64 /** An encapsulated public key. */
65 class CPubKey {
66 private:
67     std::vector<unsigned char> vchPubKey;
68     friend class CKey;
69
70 public:
71     CPubKey() { }
72     CPubKey(const std::vector<unsigned char> &vchPubKeyIn) : vchPubKey(vchPubKeyIn) { }
73     friend bool operator==(const CPubKey &a, const CPubKey &b) { return a.vchPubKey == b.vchPubKey; }
74     friend bool operator!=(const CPubKey &a, const CPubKey &b) { return a.vchPubKey != b.vchPubKey; }
75     friend bool operator<(const CPubKey &a, const CPubKey &b) { return a.vchPubKey < b.vchPubKey; }
76
77     IMPLEMENT_SERIALIZE(
78         READWRITE(vchPubKey);
79     )
80
81     CKeyID GetID() const {
82         return CKeyID(Hash160(vchPubKey));
83     }
84
85     uint256 GetHash() const {
86         return Hash(vchPubKey.begin(), vchPubKey.end());
87     }
88
89     bool IsValid() const {
90         return vchPubKey.size() == 33 || vchPubKey.size() == 65;
91     }
92
93     bool IsCompressed() const {
94         return vchPubKey.size() == 33;
95     }
96
97     std::vector<unsigned char> Raw() const {
98         return vchPubKey;
99     }
100 };
101
102
103 // secure_allocator is defined in allocators.h
104 // CPrivKey is a serialized private key, with all parameters included (279 bytes)
105 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
106 // CSecret is a serialization of just the secret parameter (32 bytes)
107 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
108
109 /** An encapsulated OpenSSL Elliptic Curve key (public and/or private) */
110 class CKey
111 {
112 protected:
113     EC_KEY* pkey;
114     bool fSet;
115     bool fCompressedPubKey;
116
117     void SetCompressedPubKey();
118
119 public:
120
121     void Reset();
122
123     CKey();
124     CKey(const CKey& b);
125
126     CKey& operator=(const CKey& b);
127
128     ~CKey();
129
130     bool IsNull() const;
131     bool IsCompressed() const;
132
133     void MakeNewKey(bool fCompressed);
134     bool SetPrivKey(const CPrivKey& vchPrivKey);
135     bool SetSecret(const CSecret& vchSecret, bool fCompressed = false);
136     CSecret GetSecret(bool &fCompressed) const;
137     CPrivKey GetPrivKey() const;
138     bool SetPubKey(const CPubKey& vchPubKey);
139     CPubKey GetPubKey() const;
140
141     bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);
142
143     // create a compact signature (65 bytes), which allows reconstructing the used public key
144     // The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
145     // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
146     //                  0x1D = second key with even y, 0x1E = second key with odd y
147     bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig);
148
149     // reconstruct public key from a compact signature
150     // This is only slightly more CPU intensive than just verifying it.
151     // If this function succeeds, the recovered public key is guaranteed to be valid
152     // (the signature is a valid signature of the given data for that key)
153     bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig);
154
155     bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig);
156
157     // Verify a compact signature
158     bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig);
159
160     bool IsValid();
161
162     // Check whether an element of a signature (r or s) is valid.
163     static bool CheckSignatureElement(const unsigned char *vch, int len, bool half);
164
165     // Reserialize to DER
166     static bool ReserealizeSignature(std::vector<unsigned char>& vchSig);
167 };
168
169 class CPoint
170 {
171 private:
172     EC_POINT *point;
173     EC_GROUP* group;
174     BN_CTX* ctx;
175
176 public:
177     CPoint();
178     bool operator!=(const CPoint &a);
179     ~CPoint();
180
181     // Initialize from octets stream
182     bool setBytes(const std::vector<unsigned char> &vchBytes);
183
184     // Serialize to octets stream
185     bool getBytes(std::vector<unsigned char> &vchBytes);
186
187     // ECC multiplication by specified multiplier
188     bool ECMUL(const CBigNum &bnMultiplier);
189
190     // Calculate G*m + q
191     bool ECMULGEN(const CBigNum &bnMultiplier, const CPoint &qPoint);
192
193     bool IsInfinity() { return EC_POINT_is_at_infinity(group, point); }
194 };
195
196 class CMalleablePubKey
197 {
198 private:
199     unsigned char nVersion;
200     CPubKey pubKeyL;
201     CPubKey pubKeyH;
202     friend class CMalleableKey;
203
204     static const unsigned char CURRENT_VERSION = 1;
205
206 public:
207     CMalleablePubKey() { nVersion = CMalleablePubKey::CURRENT_VERSION; }
208     CMalleablePubKey(const std::string& strMalleablePubKey) { SetString(strMalleablePubKey); }
209     CMalleablePubKey(const CPubKey &pubKeyInL, const CPubKey &pubKeyInH) : pubKeyL(pubKeyInL), pubKeyH(pubKeyInH) { nVersion = CMalleablePubKey::CURRENT_VERSION; }
210     CMalleablePubKey(const std::vector<unsigned char> &pubKeyInL, const std::vector<unsigned char> &pubKeyInH) : pubKeyL(pubKeyInL), pubKeyH(pubKeyInH) { nVersion = CMalleablePubKey::CURRENT_VERSION; }
211
212     IMPLEMENT_SERIALIZE(
213         READWRITE(this->nVersion);
214         nVersion = this->nVersion;
215         READWRITE(pubKeyL);
216         READWRITE(pubKeyH);
217     )
218
219     bool IsValid() const {
220         return pubKeyL.IsValid() && pubKeyH.IsValid();
221     }
222
223     bool operator==(const CMalleablePubKey &b);
224     bool operator!=(const CMalleablePubKey &b) { return !(*this == b); }
225
226     std::string ToString();
227     bool SetString(const std::string& strMalleablePubKey);
228     uint256 GetID() const;
229
230     CPubKey& GetL() { return pubKeyL; }
231     CPubKey& GetH() { return pubKeyH; }
232     void GetVariant(CPubKey &R, CPubKey &vchPubKeyVariant);
233 };
234
235 class CMalleableKey
236 {
237 private:
238     unsigned char nVersion;
239     CSecret vchSecretL;
240     CSecret vchSecretH;
241
242     friend class CMalleableKeyView;
243
244     static const unsigned char CURRENT_VERSION = 1;
245
246 public:
247     CMalleableKey();
248     CMalleableKey(const CMalleableKey &b);
249     CMalleableKey(const CSecret &L, const CSecret &H);
250     CMalleableKey& operator=(const CMalleableKey &b);
251     ~CMalleableKey();
252
253     IMPLEMENT_SERIALIZE(
254         READWRITE(this->nVersion);
255         nVersion = this->nVersion;
256         READWRITE(vchSecretL);
257         READWRITE(vchSecretH);
258     )
259
260     std::string ToString();
261     bool SetString(const std::string& strMalleablePubKey);
262
263     void Reset();
264     void MakeNewKeys();
265     bool IsNull() const;
266     bool SetSecrets(const CSecret &pvchSecretL, const CSecret &pvchSecretH);
267     void GetSecrets(CSecret &pvchSecretL, CSecret &pvchSecretH) const;
268
269     CMalleablePubKey GetMalleablePubKey() const;
270
271     bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant);
272     bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant);
273 };
274
275 class CMalleableKeyView
276 {
277 private:
278     CSecret vchSecretL;
279     std::vector<unsigned char> vchPubKeyH;
280
281     // disabled constructor
282     CMalleableKeyView() { };
283
284     static const unsigned char CURRENT_VERSION = 1;
285
286 public:
287     CMalleableKeyView(const CMalleableKey &b);
288     CMalleableKeyView(const CSecret &L, const CPubKey &pvchPubKeyH);
289
290     CMalleableKeyView(const CMalleableKeyView &b);
291     CMalleableKeyView& operator=(const CMalleableKey &b);
292     ~CMalleableKeyView();
293
294     CMalleablePubKey GetMalleablePubKey() const;
295
296     bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant);
297 };
298
299 #endif