1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
7 #include <openssl/ec.h>
8 #include <openssl/ecdsa.h>
9 #include <openssl/obj_mac.h>
12 // const unsigned int PRIVATE_KEY_SIZE = 192;
13 // const unsigned int PUBLIC_KEY_SIZE = 41;
14 // const unsigned int SIGNATURE_SIZE = 48;
17 // const unsigned int PRIVATE_KEY_SIZE = 222;
18 // const unsigned int PUBLIC_KEY_SIZE = 49;
19 // const unsigned int SIGNATURE_SIZE = 57;
22 // const unsigned int PRIVATE_KEY_SIZE = 250;
23 // const unsigned int PUBLIC_KEY_SIZE = 57;
24 // const unsigned int SIGNATURE_SIZE = 66;
27 // const unsigned int PRIVATE_KEY_SIZE = 279;
28 // const unsigned int PUBLIC_KEY_SIZE = 65;
29 // const unsigned int SIGNATURE_SIZE = 72;
31 // see www.keylength.com
32 // script supports up to 75 for single byte push
36 class key_error : public std::runtime_error
39 explicit key_error(const std::string& str) : std::runtime_error(str) {}
43 // secure_allocator is defined in serialize.h
44 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
57 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
59 throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
65 pkey = EC_KEY_dup(b.pkey);
67 throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
71 CKey& operator=(const CKey& b)
73 if (!EC_KEY_copy(pkey, b.pkey))
74 throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
91 if (!EC_KEY_generate_key(pkey))
92 throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
96 bool SetPrivKey(const CPrivKey& vchPrivKey)
98 const unsigned char* pbegin = &vchPrivKey[0];
99 if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
105 CPrivKey GetPrivKey() const
107 unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
109 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
110 CPrivKey vchPrivKey(nSize, 0);
111 unsigned char* pbegin = &vchPrivKey[0];
112 if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
113 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
117 bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
119 const unsigned char* pbegin = &vchPubKey[0];
120 if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
126 std::vector<unsigned char> GetPubKey() const
128 unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
130 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
131 std::vector<unsigned char> vchPubKey(nSize, 0);
132 unsigned char* pbegin = &vchPubKey[0];
133 if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
134 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
138 bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
141 unsigned char pchSig[10000];
142 unsigned int nSize = 0;
143 if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
145 vchSig.resize(nSize);
146 memcpy(&vchSig[0], pchSig, nSize);
150 bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
152 // -1 = error, 0 = bad sig, 1 = good
153 if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
158 static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, std::vector<unsigned char>& vchSig)
161 if (!key.SetPrivKey(vchPrivKey))
163 return key.Sign(hash, vchSig);
166 static bool Verify(const std::vector<unsigned char>& vchPubKey, uint256 hash, const std::vector<unsigned char>& vchSig)
169 if (!key.SetPubKey(vchPubKey))
171 return key.Verify(hash, vchSig);