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.
11 #include "allocators.h"
12 #include "serialize.h"
18 #include <openssl/ec.h> // for EC_KEY definition
21 // const unsigned int PRIVATE_KEY_SIZE = 192;
22 // const unsigned int PUBLIC_KEY_SIZE = 41;
23 // const unsigned int SIGNATURE_SIZE = 48;
26 // const unsigned int PRIVATE_KEY_SIZE = 222;
27 // const unsigned int PUBLIC_KEY_SIZE = 49;
28 // const unsigned int SIGNATURE_SIZE = 57;
31 // const unsigned int PRIVATE_KEY_SIZE = 250;
32 // const unsigned int PUBLIC_KEY_SIZE = 57;
33 // const unsigned int SIGNATURE_SIZE = 66;
36 // const unsigned int PRIVATE_KEY_SIZE = 279;
37 // const unsigned int PUBLIC_KEY_SIZE = 65;
38 // const unsigned int SIGNATURE_SIZE = 72;
40 // see www.keylength.com
41 // script supports up to 75 for single byte push
43 class key_error : public std::runtime_error
46 explicit key_error(const std::string& str) : std::runtime_error(str) {}
49 /** A reference to a CKey: the Hash160 of its serialized public key */
50 class CKeyID : public uint160
53 CKeyID() : uint160(0) { }
54 CKeyID(const uint160 &in) : uint160(in) { }
57 /** A reference to a CScript: the Hash160 of its serialization (see script.h) */
58 class CScriptID : public uint160
61 CScriptID() : uint160(0) { }
62 CScriptID(const uint160 &in) : uint160(in) { }
65 /** An encapsulated public key. */
68 std::vector<unsigned char> vchPubKey;
73 CPubKey(const std::vector<unsigned char> &vchPubKeyIn) : vchPubKey(vchPubKeyIn) { }
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 friend bool operator<(const CPubKey &a, const CPubKey &b) { return a.vchPubKey < b.vchPubKey; }
82 CKeyID GetID() const {
83 return CKeyID(Hash160(vchPubKey));
86 uint256 GetHash() const {
87 return Hash(vchPubKey.begin(), vchPubKey.end());
90 bool IsValid() const {
91 return vchPubKey.size() == 33 || vchPubKey.size() == 65;
94 bool IsCompressed() const {
95 return vchPubKey.size() == 33;
98 std::vector<unsigned char> Raw() const {
103 void EncryptData(const std::vector<unsigned char>& data, std::vector<unsigned char>& encrypted);
107 // secure_allocator is defined in allocators.h
108 // CPrivKey is a serialized private key, with all parameters included (279 bytes)
109 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
110 // CSecret is a serialization of just the secret parameter (32 bytes)
111 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
113 /** An encapsulated OpenSSL Elliptic Curve key (public and/or private) */
119 bool fCompressedPubKey;
121 void SetCompressedPubKey();
130 CKey& operator=(const CKey& b);
135 bool IsCompressed() const;
137 void MakeNewKey(bool fCompressed);
138 bool SetPrivKey(const CPrivKey& vchPrivKey);
139 bool SetSecret(const CSecret& vchSecret, bool fCompressed = false);
140 CSecret GetSecret(bool &fCompressed) const;
141 CPrivKey GetPrivKey() const;
142 bool SetPubKey(const CPubKey& vchPubKey);
143 CPubKey GetPubKey() const;
145 bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);
147 // create a compact signature (65 bytes), which allows reconstructing the used public key
148 // The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
149 // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
150 // 0x1D = second key with even y, 0x1E = second key with odd y
151 bool SignCompact(uint256 hash, std::vector<unsigned char>& vchSig);
153 // reconstruct public key from a compact signature
154 // This is only slightly more CPU intensive than just verifying it.
155 // If this function succeeds, the recovered public key is guaranteed to be valid
156 // (the signature is a valid signature of the given data for that key)
157 bool SetCompactSignature(uint256 hash, const std::vector<unsigned char>& vchSig);
159 bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig);
161 // Verify a compact signature
162 bool VerifyCompact(uint256 hash, const std::vector<unsigned char>& vchSig);
166 // Check whether an element of a signature (r or s) is valid.
167 static bool CheckSignatureElement(const unsigned char *vch, int len, bool half);
169 // Reserialize to DER
170 static bool ReserealizeSignature(std::vector<unsigned char>& vchSig);
173 void EncryptData(const std::vector<unsigned char>& data, std::vector<unsigned char>& encrypted);
176 void DecryptData(const std::vector<unsigned char>& encrypted, std::vector<unsigned char>& data);
188 bool operator!=(const CPoint &a);
191 // Initialize from octets stream
192 bool setBytes(const std::vector<unsigned char> &vchBytes);
194 // Initialize from pubkey
195 bool setPubKey(const CPubKey &vchPubKey);
197 // Serialize to octets stream
198 bool getBytes(std::vector<unsigned char> &vchBytes);
200 // ECC multiplication by specified multiplier
201 bool ECMUL(const CBigNum &bnMultiplier);
204 bool ECMULGEN(const CBigNum &bnMultiplier, const CPoint &qPoint);
206 bool IsInfinity() { return EC_POINT_is_at_infinity(group, point); }
209 class CMalleablePubKey
212 unsigned char nVersion;
215 friend class CMalleableKey;
217 static const unsigned char CURRENT_VERSION = 1;
220 CMalleablePubKey() { nVersion = CMalleablePubKey::CURRENT_VERSION; }
221 CMalleablePubKey(const CMalleablePubKey& mpk)
223 nVersion = mpk.nVersion;
224 pubKeyL = mpk.pubKeyL;
225 pubKeyH = mpk.pubKeyH;
227 CMalleablePubKey(const std::string& strMalleablePubKey) { SetString(strMalleablePubKey); }
228 CMalleablePubKey(const CPubKey &pubKeyInL, const CPubKey &pubKeyInH) : pubKeyL(pubKeyInL), pubKeyH(pubKeyInH) { nVersion = CMalleablePubKey::CURRENT_VERSION; }
229 CMalleablePubKey(const std::vector<unsigned char> &pubKeyInL, const std::vector<unsigned char> &pubKeyInH) : pubKeyL(pubKeyInL), pubKeyH(pubKeyInH) { nVersion = CMalleablePubKey::CURRENT_VERSION; }
232 READWRITE(this->nVersion);
233 nVersion = this->nVersion;
238 bool IsValid() const {
239 return pubKeyL.IsValid() && pubKeyH.IsValid();
242 bool operator==(const CMalleablePubKey &b);
243 bool operator!=(const CMalleablePubKey &b) { return !(*this == b); }
244 CMalleablePubKey& operator=(const CMalleablePubKey& mpk) {
245 nVersion = mpk.nVersion;
246 pubKeyL = mpk.pubKeyL;
247 pubKeyH = mpk.pubKeyH;
251 std::string ToString() const;
252 bool SetString(const std::string& strMalleablePubKey);
254 CKeyID GetID() const {
255 return pubKeyL.GetID();
258 std::vector<unsigned char> Raw() const;
260 CPubKey& GetL() { return pubKeyL; }
261 CPubKey& GetH() { return pubKeyH; }
262 void GetVariant(CPubKey &R, CPubKey &vchPubKeyVariant);
268 unsigned char nVersion;
272 friend class CMalleableKeyView;
274 static const unsigned char CURRENT_VERSION = 1;
278 CMalleableKey(const CMalleableKey &b);
279 CMalleableKey(const CSecret &L, const CSecret &H);
283 READWRITE(this->nVersion);
284 nVersion = this->nVersion;
285 READWRITE(vchSecretL);
286 READWRITE(vchSecretH);
289 std::string ToString() const;
290 bool SetString(const std::string& strMalleablePubKey);
291 std::vector<unsigned char> Raw() const;
292 CMalleableKey& operator=(const CMalleableKey& mk) {
293 nVersion = mk.nVersion;
294 vchSecretL = mk.vchSecretL;
295 vchSecretH = mk.vchSecretH;
302 bool SetSecrets(const CSecret &pvchSecretL, const CSecret &pvchSecretH);
303 void GetSecrets(CSecret &pvchSecretL, CSecret &pvchSecretH) const;
305 CKeyID GetID() const {
306 return GetMalleablePubKey().GetID();
308 CMalleablePubKey GetMalleablePubKey() const;
309 bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const;
310 bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant) const;
313 class CMalleableKeyView
316 unsigned char nVersion;
320 static const unsigned char CURRENT_VERSION = 1;
323 CMalleableKeyView() { nVersion = 0; };
324 CMalleableKeyView(const CMalleableKey &b);
325 CMalleableKeyView(const CSecret &L, const CPubKey &pvchPubKeyH);
327 CMalleableKeyView(const CMalleableKeyView &b);
328 CMalleableKeyView& operator=(const CMalleableKey &b);
329 ~CMalleableKeyView();
333 READWRITE(this->nVersion);
334 nVersion = this->nVersion;
335 READWRITE(vchSecretL);
336 READWRITE(vchPubKeyH);
340 std::string ToString() const;
341 bool SetString(const std::string& strMalleablePubKey);
342 std::vector<unsigned char> Raw() const;
343 CMalleableKeyView& operator=(const CMalleableKeyView& mkv) {
344 nVersion = mkv.nVersion;
345 vchSecretL = mkv.vchSecretL;
346 vchPubKeyH = mkv.vchPubKeyH;
350 CKeyID GetID() const {
351 return GetMalleablePubKey().GetID();
353 CMalleablePubKey GetMalleablePubKey() const;
354 bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const;
356 bool operator <(const CMalleableKeyView& kv) const { return vchPubKeyH.GetID() < kv.vchPubKeyH.GetID(); }