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 license.txt or http://www.opensource.org/licenses/mit-license.php.
11 #include <openssl/ec.h>
12 #include <openssl/ecdsa.h>
13 #include <openssl/obj_mac.h>
15 #include "serialize.h"
20 // const unsigned int PRIVATE_KEY_SIZE = 192;
21 // const unsigned int PUBLIC_KEY_SIZE = 41;
22 // const unsigned int SIGNATURE_SIZE = 48;
25 // const unsigned int PRIVATE_KEY_SIZE = 222;
26 // const unsigned int PUBLIC_KEY_SIZE = 49;
27 // const unsigned int SIGNATURE_SIZE = 57;
30 // const unsigned int PRIVATE_KEY_SIZE = 250;
31 // const unsigned int PUBLIC_KEY_SIZE = 57;
32 // const unsigned int SIGNATURE_SIZE = 66;
35 // const unsigned int PRIVATE_KEY_SIZE = 279;
36 // const unsigned int PUBLIC_KEY_SIZE = 65;
37 // const unsigned int SIGNATURE_SIZE = 72;
39 // see www.keylength.com
40 // script supports up to 75 for single byte push
42 int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
46 EC_POINT *pub_key = NULL;
50 const EC_GROUP *group = EC_KEY_get0_group(eckey);
52 if ((ctx = BN_CTX_new()) == NULL)
55 pub_key = EC_POINT_new(group);
60 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
63 EC_KEY_set_private_key(eckey,priv_key);
64 EC_KEY_set_public_key(eckey,pub_key);
71 EC_POINT_free(pub_key);
79 class key_error : public std::runtime_error
82 explicit key_error(const std::string& str) : std::runtime_error(str) {}
86 // secure_allocator is defined in serialize.h
87 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
88 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
99 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
101 throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
107 pkey = EC_KEY_dup(b.pkey);
109 throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
113 CKey& operator=(const CKey& b)
115 if (!EC_KEY_copy(pkey, b.pkey))
116 throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
133 if (!EC_KEY_generate_key(pkey))
134 throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
138 bool SetPrivKey(const CPrivKey& vchPrivKey)
140 const unsigned char* pbegin = &vchPrivKey[0];
141 if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
147 bool SetSecret(const CSecret& vchSecret)
150 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
152 throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
153 if (vchSecret.size() != 32)
154 throw key_error("CKey::SetSecret() : secret must be 32 bytes");
155 BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
157 throw key_error("CKey::SetSecret() : BN_bin2bn failed");
158 if (!EC_KEY_regenerate_key(pkey,bn))
161 throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
168 CSecret GetSecret() const
172 const BIGNUM *bn = EC_KEY_get0_private_key(pkey);
173 int nBytes = BN_num_bytes(bn);
175 throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed");
176 int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
178 throw key_error("CKey::GetSecret(): BN_bn2bin failed");
182 CPrivKey GetPrivKey() const
184 int nSize = i2d_ECPrivateKey(pkey, NULL);
186 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
187 CPrivKey vchPrivKey(nSize, 0);
188 unsigned char* pbegin = &vchPrivKey[0];
189 if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
190 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
194 bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
196 const unsigned char* pbegin = &vchPubKey[0];
197 if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
203 std::vector<unsigned char> GetPubKey() const
205 int nSize = i2o_ECPublicKey(pkey, NULL);
207 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
208 std::vector<unsigned char> vchPubKey(nSize, 0);
209 unsigned char* pbegin = &vchPubKey[0];
210 if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
211 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
215 bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
217 unsigned int nSize = ECDSA_size(pkey);
218 vchSig.resize(nSize); // Make sure it is big enough
219 if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], &nSize, pkey))
224 vchSig.resize(nSize); // Shrink to fit actual size
228 bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
230 // -1 = error, 0 = bad sig, 1 = good
231 if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
236 CBitcoinAddress GetAddress() const
238 return CBitcoinAddress(GetPubKey());
246 CSecret secret = GetSecret();
248 key2.SetSecret(secret);
249 return GetPubKey() == key2.GetPubKey();