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 CScript& in);
63 CScriptID(const uint160 &in) : uint160(in) { }
66 /** An encapsulated OpenSSL Elliptic Curve key (public) */
72 * Just store the serialized data.
73 * Its length can very cheaply be computed from the first byte.
75 unsigned char vbytes[65];
77 //! Compute the length of a pubkey with a given first byte.
78 unsigned int static GetLen(unsigned char chHeader)
80 if (chHeader == 2 || chHeader == 3)
82 if (chHeader == 4 || chHeader == 6 || chHeader == 7)
87 // Set this key data to be invalid
94 // Construct an invalid public key.
100 // Initialize a public key using begin/end iterators to byte data.
101 template <typename T>
102 void Set(const T pbegin, const T pend)
104 int len = pend == pbegin ? 0 : GetLen(pbegin[0]);
105 if (len && len == (pend - pbegin))
106 memcpy(vbytes, (unsigned char*)&pbegin[0], len);
111 void Set(const std::vector<unsigned char>& vch)
113 Set(vch.begin(), vch.end());
116 template <typename T>
117 CPubKey(const T pbegin, const T pend)
122 CPubKey(const std::vector<unsigned char>& vch)
124 Set(vch.begin(), vch.end());
127 // Read-only vector-like interface to the data.
128 unsigned int size() const { return GetLen(vbytes[0]); }
129 const unsigned char* begin() const { return vbytes; }
130 const unsigned char* end() const { return vbytes + size(); }
131 const unsigned char& operator[](unsigned int pos) const { return vbytes[pos]; }
133 friend bool operator==(const CPubKey& a, const CPubKey& b) { return a.vbytes[0] == b.vbytes[0] && memcmp(a.vbytes, b.vbytes, a.size()) == 0; }
134 friend bool operator!=(const CPubKey& a, const CPubKey& b) { return !(a == b); }
135 friend bool operator<(const CPubKey& a, const CPubKey& b) { return a.vbytes[0] < b.vbytes[0] || (a.vbytes[0] == b.vbytes[0] && memcmp(a.vbytes, b.vbytes, a.size()) < 0); }
137 //! Implement serialization, as if this was a byte vector.
138 unsigned int GetSerializeSize(int nType, int nVersion) const
142 template <typename Stream>
143 void Serialize(Stream& s, int nType, int nVersion) const
145 unsigned int len = size();
146 ::WriteCompactSize(s, len);
147 s.write((char*)vbytes, len);
149 template <typename Stream>
150 void Unserialize(Stream& s, int nType, int nVersion)
152 unsigned int len = ::ReadCompactSize(s);
154 s.read((char*)vbytes, len);
156 // invalid pubkey, skip available data
166 return CKeyID(Hash160(vbytes, vbytes + size()));
169 uint256 GetHash() const
171 return Hash(vbytes, vbytes + size());
175 * Check syntactic correctness.
177 * Note that this is consensus critical as CheckSig() calls it!
184 //! fully validate whether this is a valid public key (more expensive than IsValid())
185 bool IsFullyValid() const
187 const unsigned char* pbegin = &vbytes[0];
188 EC_KEY *pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
189 if (o2i_ECPublicKey(&pkey, &pbegin, size()))
197 //! Check whether this is a compressed public key.
198 bool IsCompressed() const
203 bool Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
204 bool VerifyCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig);
206 bool SetCompactSignature(const uint256 &hash, const std::vector<unsigned char>& vchSig);
208 // Reserialize to DER
209 static bool ReserealizeSignature(std::vector<unsigned char>& vchSig);
212 void EncryptData(const std::vector<unsigned char>& data, std::vector<unsigned char>& encrypted);
215 // secure_allocator is defined in allocators.h
216 // CPrivKey is a serialized private key, with all parameters included (279 bytes)
217 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
218 // CSecret is a serialization of just the secret parameter (32 bytes)
219 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
221 /** An encapsulated OpenSSL Elliptic Curve key (private) */
234 CKey(const CSecret& b, bool fCompressed=true);
236 CKey& operator=(const CKey& b);
241 bool IsCompressed() const;
243 void SetCompressedPubKey(bool fCompressed=true);
244 void MakeNewKey(bool fCompressed=true);
245 bool SetPrivKey(const CPrivKey& vchPrivKey);
246 bool SetSecret(const CSecret& vchSecret, bool fCompressed = true);
247 CSecret GetSecret(bool &fCompressed) const;
248 CSecret GetSecret() const;
249 CPrivKey GetPrivKey() const;
250 CPubKey GetPubKey() const;
251 bool WritePEM(BIO *streamObj, const SecureString &strPassKey) const;
253 bool Sign(uint256 hash, std::vector<unsigned char>& vchSig);
255 // create a compact signature (65 bytes), which allows reconstructing the used public key
256 // The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
257 // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
258 // 0x1D = second key with even y, 0x1E = second key with odd y
259 bool SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig);
263 // Check whether an element of a signature (r or s) is valid.
264 static bool CheckSignatureElement(const unsigned char *vch, int len, bool half);
267 void DecryptData(const std::vector<unsigned char>& encrypted, std::vector<unsigned char>& data);
279 bool operator!=(const CPoint &a);
282 // Initialize from octets stream
283 bool setBytes(const std::vector<unsigned char> &vchBytes);
285 // Initialize from pubkey
286 bool setPubKey(const CPubKey &vchPubKey);
288 // Serialize to octets stream
289 bool getBytes(std::vector<unsigned char> &vchBytes);
291 // ECC multiplication by specified multiplier
292 bool ECMUL(const CBigNum &bnMultiplier);
295 bool ECMULGEN(const CBigNum &bnMultiplier, const CPoint &qPoint);
297 bool IsInfinity() { return EC_POINT_is_at_infinity(group, point) != 0; }
300 class CMalleablePubKey
305 friend class CMalleableKey;
307 static const unsigned char CURRENT_VERSION = 1;
310 CMalleablePubKey() { }
311 CMalleablePubKey(const CMalleablePubKey& mpk)
313 pubKeyL = mpk.pubKeyL;
314 pubKeyH = mpk.pubKeyH;
316 CMalleablePubKey(const std::vector<unsigned char> &vchPubKeyPair) { setvch(vchPubKeyPair); }
317 CMalleablePubKey(const std::string& strMalleablePubKey) { SetString(strMalleablePubKey); }
318 CMalleablePubKey(const CPubKey &pubKeyInL, const CPubKey &pubKeyInH) : pubKeyL(pubKeyInL), pubKeyH(pubKeyInH) { }
325 bool IsValid() const {
326 return pubKeyL.IsValid() && pubKeyH.IsValid();
329 bool operator==(const CMalleablePubKey &b);
330 bool operator!=(const CMalleablePubKey &b) { return !(*this == b); }
331 CMalleablePubKey& operator=(const CMalleablePubKey& mpk) {
332 pubKeyL = mpk.pubKeyL;
333 pubKeyH = mpk.pubKeyH;
337 std::string ToString() const;
338 bool SetString(const std::string& strMalleablePubKey);
340 CKeyID GetID() const {
341 return pubKeyL.GetID();
344 bool setvch(const std::vector<unsigned char> &vchPubKeyPair);
345 std::vector<unsigned char> Raw() const;
347 CPubKey& GetL() { return pubKeyL; }
348 CPubKey& GetH() { return pubKeyH; }
349 void GetVariant(CPubKey &R, CPubKey &vchPubKeyVariant);
358 friend class CMalleableKeyView;
362 CMalleableKey(const CMalleableKey &b);
363 CMalleableKey(const CSecret &L, const CSecret &H);
367 READWRITE(vchSecretL);
368 READWRITE(vchSecretH);
371 std::string ToString() const;
372 bool SetString(const std::string& strMalleablePubKey);
373 std::vector<unsigned char> Raw() const;
374 CMalleableKey& operator=(const CMalleableKey& mk) {
375 vchSecretL = mk.vchSecretL;
376 vchSecretH = mk.vchSecretH;
383 bool IsValid() const { return !IsNull() && GetMalleablePubKey().IsValid(); }
384 bool SetSecrets(const CSecret &pvchSecretL, const CSecret &pvchSecretH);
386 CSecret GetSecretL() const { return vchSecretL; }
387 CSecret GetSecretH() const { return vchSecretH; }
389 CKeyID GetID() const {
390 return GetMalleablePubKey().GetID();
392 CMalleablePubKey GetMalleablePubKey() const;
393 bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const;
394 bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant) const;
397 class CMalleableKeyView
404 CMalleableKeyView() { }
405 CMalleableKeyView(const CMalleableKey &b);
406 CMalleableKeyView(const std::string &strMalleableKey);
408 CMalleableKeyView(const CMalleableKeyView &b);
409 CMalleableKeyView& operator=(const CMalleableKey &b);
410 ~CMalleableKeyView();
413 READWRITE(vchSecretL);
414 READWRITE(vchPubKeyH);
417 bool IsValid() const;
418 std::string ToString() const;
419 bool SetString(const std::string& strMalleablePubKey);
420 std::vector<unsigned char> Raw() const;
421 CMalleableKeyView& operator=(const CMalleableKeyView& mkv) {
422 vchSecretL = mkv.vchSecretL;
423 vchPubKeyH = mkv.vchPubKeyH;
427 CKeyID GetID() const {
428 return GetMalleablePubKey().GetID();
430 CMalleablePubKey GetMalleablePubKey() const;
431 CMalleableKey GetMalleableKey(const CSecret &vchSecretH) const { return CMalleableKey(vchSecretL, vchSecretH); }
432 bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const;
434 bool operator <(const CMalleableKeyView& kv) const { return vchPubKeyH.GetID() < kv.vchPubKeyH.GetID(); }