1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2011 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.
8 #include <openssl/ec.h>
9 #include <openssl/ecdsa.h>
10 #include <openssl/obj_mac.h>
13 // const unsigned int PRIVATE_KEY_SIZE = 192;
14 // const unsigned int PUBLIC_KEY_SIZE = 41;
15 // const unsigned int SIGNATURE_SIZE = 48;
18 // const unsigned int PRIVATE_KEY_SIZE = 222;
19 // const unsigned int PUBLIC_KEY_SIZE = 49;
20 // const unsigned int SIGNATURE_SIZE = 57;
23 // const unsigned int PRIVATE_KEY_SIZE = 250;
24 // const unsigned int PUBLIC_KEY_SIZE = 57;
25 // const unsigned int SIGNATURE_SIZE = 66;
28 // const unsigned int PRIVATE_KEY_SIZE = 279;
29 // const unsigned int PUBLIC_KEY_SIZE = 65;
30 // const unsigned int SIGNATURE_SIZE = 72;
32 // see www.keylength.com
33 // script supports up to 75 for single byte push
35 int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
39 EC_POINT *pub_key = NULL;
43 const EC_GROUP *group = EC_KEY_get0_group(eckey);
45 if ((ctx = BN_CTX_new()) == NULL)
48 pub_key = EC_POINT_new(group);
53 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
56 EC_KEY_set_private_key(eckey,priv_key);
57 EC_KEY_set_public_key(eckey,pub_key);
64 EC_POINT_free(pub_key);
72 class key_error : public std::runtime_error
75 explicit key_error(const std::string& str) : std::runtime_error(str) {}
79 // secure_allocator is defined in serialize.h
80 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
81 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
92 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
94 throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
100 pkey = EC_KEY_dup(b.pkey);
102 throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
106 CKey& operator=(const CKey& b)
108 if (!EC_KEY_copy(pkey, b.pkey))
109 throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
126 if (!EC_KEY_generate_key(pkey))
127 throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
131 bool SetPrivKey(const CPrivKey& vchPrivKey)
133 const unsigned char* pbegin = &vchPrivKey[0];
134 if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
140 bool SetSecret(const CSecret& vchSecret)
143 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
145 throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
146 if (vchSecret.size() != 32)
147 throw key_error("CKey::SetSecret() : secret must be 32 bytes");
148 BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
150 throw key_error("CKey::SetSecret() : BN_bin2bn failed");
151 if (!EC_KEY_regenerate_key(pkey,bn))
152 throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
158 CSecret GetSecret() const
162 const BIGNUM *bn = EC_KEY_get0_private_key(pkey);
163 int nBytes = BN_num_bytes(bn);
165 throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed");
166 int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
168 throw key_error("CKey::GetSecret(): BN_bn2bin failed");
172 CPrivKey GetPrivKey() const
174 unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
176 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
177 CPrivKey vchPrivKey(nSize, 0);
178 unsigned char* pbegin = &vchPrivKey[0];
179 if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
180 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
184 bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
186 const unsigned char* pbegin = &vchPubKey[0];
187 if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
193 std::vector<unsigned char> GetPubKey() const
195 unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
197 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
198 std::vector<unsigned char> vchPubKey(nSize, 0);
199 unsigned char* pbegin = &vchPubKey[0];
200 if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
201 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
205 bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
208 unsigned char pchSig[10000];
209 unsigned int nSize = 0;
210 if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
212 vchSig.resize(nSize);
213 memcpy(&vchSig[0], pchSig, nSize);
217 bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
219 // -1 = error, 0 = bad sig, 1 = good
220 if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
225 CBitcoinAddress GetAddress() const
227 return CBitcoinAddress(GetPubKey());