1 // Copyright (c) 2009 Satoshi Nakamoto
\r
2 // Distributed under the MIT/X11 software license, see the accompanying
\r
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
\r
7 // const unsigned int PRIVATE_KEY_SIZE = 192;
\r
8 // const unsigned int PUBLIC_KEY_SIZE = 41;
\r
9 // const unsigned int SIGNATURE_SIZE = 48;
\r
12 // const unsigned int PRIVATE_KEY_SIZE = 222;
\r
13 // const unsigned int PUBLIC_KEY_SIZE = 49;
\r
14 // const unsigned int SIGNATURE_SIZE = 57;
\r
17 // const unsigned int PRIVATE_KEY_SIZE = 250;
\r
18 // const unsigned int PUBLIC_KEY_SIZE = 57;
\r
19 // const unsigned int SIGNATURE_SIZE = 66;
\r
22 // const unsigned int PRIVATE_KEY_SIZE = 279;
\r
23 // const unsigned int PUBLIC_KEY_SIZE = 65;
\r
24 // const unsigned int SIGNATURE_SIZE = 72;
\r
26 // see www.keylength.com
\r
27 // script supports up to 75 for single byte push
\r
31 class key_error : public std::runtime_error
\r
34 explicit key_error(const std::string& str) : std::runtime_error(str) {}
\r
38 // secure_allocator is defined is serialize.h
\r
39 typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
\r
51 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
\r
53 throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
\r
58 pkey = EC_KEY_dup(b.pkey);
\r
60 throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
\r
63 CKey& operator=(const CKey& b)
\r
65 if (!EC_KEY_copy(pkey, b.pkey))
\r
66 throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
\r
77 if (!EC_KEY_generate_key(pkey))
\r
78 throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
\r
81 bool SetPrivKey(const CPrivKey& vchPrivKey)
\r
83 const unsigned char* pbegin = &vchPrivKey[0];
\r
84 if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
\r
89 CPrivKey GetPrivKey() const
\r
91 unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
\r
93 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
\r
94 CPrivKey vchPrivKey(nSize, 0);
\r
95 unsigned char* pbegin = &vchPrivKey[0];
\r
96 if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
\r
97 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
\r
101 bool SetPubKey(const vector<unsigned char>& vchPubKey)
\r
103 const unsigned char* pbegin = &vchPubKey[0];
\r
104 if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
\r
109 vector<unsigned char> GetPubKey() const
\r
111 unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
\r
113 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
\r
114 vector<unsigned char> vchPubKey(nSize, 0);
\r
115 unsigned char* pbegin = &vchPubKey[0];
\r
116 if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
\r
117 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
\r
121 bool Sign(uint256 hash, vector<unsigned char>& vchSig)
\r
124 unsigned char pchSig[10000];
\r
125 unsigned int nSize = 0;
\r
126 if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
\r
128 vchSig.resize(nSize);
\r
129 memcpy(&vchSig[0], pchSig, nSize);
\r
133 bool Verify(uint256 hash, const vector<unsigned char>& vchSig)
\r
135 // -1 = error, 0 = bad sig, 1 = good
\r
136 if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
\r
141 static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig)
\r
144 if (!key.SetPrivKey(vchPrivKey))
\r
146 return key.Sign(hash, vchSig);
\r
149 static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig)
\r
152 if (!key.SetPubKey(vchPubKey))
\r
154 return key.Verify(hash, vchSig);
\r