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
34 int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
38 EC_POINT *pub_key = NULL;
42 const EC_GROUP *group = EC_KEY_get0_group(eckey);
44 if ((ctx = BN_CTX_new()) == NULL)
47 pub_key = EC_POINT_new(group);
52 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
55 EC_KEY_set_private_key(eckey,priv_key);
56 EC_KEY_set_public_key(eckey,pub_key);
63 EC_POINT_free(pub_key);
71 class key_error : public std::runtime_error
74 explicit key_error(const std::string& str) : std::runtime_error(str) {}
78 // secure_allocator is defined in serialize.h
79 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
80 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CSecret;
91 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
93 throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
99 pkey = EC_KEY_dup(b.pkey);
101 throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
105 CKey& operator=(const CKey& b)
107 if (!EC_KEY_copy(pkey, b.pkey))
108 throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
125 if (!EC_KEY_generate_key(pkey))
126 throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
130 bool SetPrivKey(const CPrivKey& vchPrivKey)
132 const unsigned char* pbegin = &vchPrivKey[0];
133 if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
139 bool SetSecret(const CSecret& vchSecret)
142 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
144 throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed");
145 if (vchSecret.size() != 32)
146 throw key_error("CKey::SetSecret() : secret must be 32 bytes");
147 BIGNUM *bn = BN_bin2bn(&vchSecret[0],32,BN_new());
149 throw key_error("CKey::SetSecret() : BN_bin2bn failed");
150 if (!EC_KEY_regenerate_key(pkey,bn))
151 throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed");
157 CSecret GetSecret() const
161 const BIGNUM *bn = EC_KEY_get0_private_key(pkey);
162 int nBytes = BN_num_bytes(bn);
164 throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed");
165 int n=BN_bn2bin(bn,&vchRet[32 - nBytes]);
167 throw key_error("CKey::GetSecret(): BN_bn2bin failed");
171 CPrivKey GetPrivKey() const
173 unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
175 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
176 CPrivKey vchPrivKey(nSize, 0);
177 unsigned char* pbegin = &vchPrivKey[0];
178 if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
179 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
183 bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
185 const unsigned char* pbegin = &vchPubKey[0];
186 if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
192 std::vector<unsigned char> GetPubKey() const
194 unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
196 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
197 std::vector<unsigned char> vchPubKey(nSize, 0);
198 unsigned char* pbegin = &vchPubKey[0];
199 if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
200 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
204 bool Sign(uint256 hash, std::vector<unsigned char>& vchSig)
207 unsigned char pchSig[10000];
208 unsigned int nSize = 0;
209 if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
211 vchSig.resize(nSize);
212 memcpy(&vchSig[0], pchSig, nSize);
216 bool Verify(uint256 hash, const std::vector<unsigned char>& vchSig)
218 // -1 = error, 0 = bad sig, 1 = good
219 if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
224 static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, std::vector<unsigned char>& vchSig)
227 if (!key.SetPrivKey(vchPrivKey))
229 return key.Sign(hash, vchSig);
232 static bool Verify(const std::vector<unsigned char>& vchPubKey, uint256 hash, const std::vector<unsigned char>& vchSig)
235 if (!key.SetPubKey(vchPubKey))
237 return key.Verify(hash, vchSig);