Automatically reserialize non-canonical proof-of-stake block signatures.
[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 #endif