]> Git Repo - VerusCoin.git/blame - src/key.h
Generalize version bytes
[VerusCoin.git] / src / key.h
CommitLineData
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 */
24class CKeyID : public uint160
25{
26public:
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) */
32class CScriptID : public uint160
33{
34public:
35 CScriptID() : uint160(0) { }
36 CScriptID(const uint160 &in) : uint160(in) { }
37};
38
39/** An encapsulated public key. */
fd61d6f5
PW
40class CPubKey {
41private:
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 60public:
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 169typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
8bd66202 170
dfa23b94
PW
171/** An encapsulated private key. */
172class CKey {
173private:
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 186public:
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
This page took 0.148189 seconds and 4 git commands to generate.