-// Copyright (c) 2009 Satoshi Nakamoto\r
-// Distributed under the MIT/X11 software license, see the accompanying\r
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.\r
-\r
-\r
-// secp160k1\r
-// const unsigned int PRIVATE_KEY_SIZE = 192;\r
-// const unsigned int PUBLIC_KEY_SIZE = 41;\r
-// const unsigned int SIGNATURE_SIZE = 48;\r
-//\r
-// secp192k1\r
-// const unsigned int PRIVATE_KEY_SIZE = 222;\r
-// const unsigned int PUBLIC_KEY_SIZE = 49;\r
-// const unsigned int SIGNATURE_SIZE = 57;\r
-//\r
-// secp224k1\r
-// const unsigned int PRIVATE_KEY_SIZE = 250;\r
-// const unsigned int PUBLIC_KEY_SIZE = 57;\r
-// const unsigned int SIGNATURE_SIZE = 66;\r
-//\r
-// secp256k1:\r
-// const unsigned int PRIVATE_KEY_SIZE = 279;\r
-// const unsigned int PUBLIC_KEY_SIZE = 65;\r
-// const unsigned int SIGNATURE_SIZE = 72;\r
-//\r
-// see www.keylength.com\r
-// script supports up to 75 for single byte push\r
-\r
-\r
-\r
-class key_error : public std::runtime_error\r
-{\r
-public:\r
- explicit key_error(const std::string& str) : std::runtime_error(str) {}\r
-};\r
-\r
-\r
-// secure_allocator is defined is serialize.h\r
-typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;\r
-\r
-\r
-\r
-class CKey\r
-{\r
-protected:\r
- EC_KEY* pkey;\r
-\r
-public:\r
- CKey()\r
- {\r
- pkey = EC_KEY_new_by_curve_name(NID_secp256k1);\r
- if (pkey == NULL)\r
- throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");\r
- }\r
-\r
- CKey(const CKey& b)\r
- {\r
- pkey = EC_KEY_dup(b.pkey);\r
- if (pkey == NULL)\r
- throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");\r
- }\r
-\r
- CKey& operator=(const CKey& b)\r
- {\r
- if (!EC_KEY_copy(pkey, b.pkey))\r
- throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");\r
- return (*this);\r
- }\r
-\r
- ~CKey()\r
- {\r
- EC_KEY_free(pkey);\r
- }\r
-\r
- void MakeNewKey()\r
- {\r
- if (!EC_KEY_generate_key(pkey))\r
- throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");\r
- }\r
-\r
- bool SetPrivKey(const CPrivKey& vchPrivKey)\r
- {\r
- const unsigned char* pbegin = &vchPrivKey[0];\r
- if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))\r
- return false;\r
- return true;\r
- }\r
-\r
- CPrivKey GetPrivKey() const\r
- {\r
- unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);\r
- if (!nSize)\r
- throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");\r
- CPrivKey vchPrivKey(nSize, 0);\r
- unsigned char* pbegin = &vchPrivKey[0];\r
- if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)\r
- throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");\r
- return vchPrivKey;\r
- }\r
-\r
- bool SetPubKey(const vector<unsigned char>& vchPubKey)\r
- {\r
- const unsigned char* pbegin = &vchPubKey[0];\r
- if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))\r
- return false;\r
- return true;\r
- }\r
-\r
- vector<unsigned char> GetPubKey() const\r
- {\r
- unsigned int nSize = i2o_ECPublicKey(pkey, NULL);\r
- if (!nSize)\r
- throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");\r
- vector<unsigned char> vchPubKey(nSize, 0);\r
- unsigned char* pbegin = &vchPubKey[0];\r
- if (i2o_ECPublicKey(pkey, &pbegin) != nSize)\r
- throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");\r
- return vchPubKey;\r
- }\r
-\r
- bool Sign(uint256 hash, vector<unsigned char>& vchSig)\r
- {\r
- vchSig.clear();\r
- unsigned char pchSig[10000];\r
- unsigned int nSize = 0;\r
- if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))\r
- return false;\r
- vchSig.resize(nSize);\r
- memcpy(&vchSig[0], pchSig, nSize);\r
- return true;\r
- }\r
-\r
- bool Verify(uint256 hash, const vector<unsigned char>& vchSig)\r
- {\r
- // -1 = error, 0 = bad sig, 1 = good\r
- if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)\r
- return false;\r
- return true;\r
- }\r
-\r
- static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig)\r
- {\r
- CKey key;\r
- if (!key.SetPrivKey(vchPrivKey))\r
- return false;\r
- return key.Sign(hash, vchSig);\r
- }\r
-\r
- static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig)\r
- {\r
- CKey key;\r
- if (!key.SetPubKey(vchPubKey))\r
- return false;\r
- return key.Verify(hash, vchSig);\r
- }\r
-};\r
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+
+// secp160k1
+// const unsigned int PRIVATE_KEY_SIZE = 192;
+// const unsigned int PUBLIC_KEY_SIZE = 41;
+// const unsigned int SIGNATURE_SIZE = 48;
+//
+// secp192k1
+// const unsigned int PRIVATE_KEY_SIZE = 222;
+// const unsigned int PUBLIC_KEY_SIZE = 49;
+// const unsigned int SIGNATURE_SIZE = 57;
+//
+// secp224k1
+// const unsigned int PRIVATE_KEY_SIZE = 250;
+// const unsigned int PUBLIC_KEY_SIZE = 57;
+// const unsigned int SIGNATURE_SIZE = 66;
+//
+// secp256k1:
+// const unsigned int PRIVATE_KEY_SIZE = 279;
+// const unsigned int PUBLIC_KEY_SIZE = 65;
+// const unsigned int SIGNATURE_SIZE = 72;
+//
+// see www.keylength.com
+// script supports up to 75 for single byte push
+
+
+
+class key_error : public std::runtime_error
+{
+public:
+ explicit key_error(const std::string& str) : std::runtime_error(str) {}
+};
+
+
+// secure_allocator is defined in serialize.h
+typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
+
+
+
+class CKey
+{
+protected:
+ EC_KEY* pkey;
+ bool fSet;
+
+public:
+ CKey()
+ {
+ pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
+ if (pkey == NULL)
+ throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
+ fSet = false;
+ }
+
+ CKey(const CKey& b)
+ {
+ pkey = EC_KEY_dup(b.pkey);
+ if (pkey == NULL)
+ throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
+ fSet = b.fSet;
+ }
+
+ CKey& operator=(const CKey& b)
+ {
+ if (!EC_KEY_copy(pkey, b.pkey))
+ throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
+ fSet = b.fSet;
+ return (*this);
+ }
+
+ ~CKey()
+ {
+ EC_KEY_free(pkey);
+ }
+
+ bool IsNull() const
+ {
+ return !fSet;
+ }
+
+ void MakeNewKey()
+ {
+ if (!EC_KEY_generate_key(pkey))
+ throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
+ fSet = true;
+ }
+
+ bool SetPrivKey(const CPrivKey& vchPrivKey)
+ {
+ const unsigned char* pbegin = &vchPrivKey[0];
+ if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
+ return false;
+ fSet = true;
+ return true;
+ }
+
+ CPrivKey GetPrivKey() const
+ {
+ unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
+ if (!nSize)
+ throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
+ CPrivKey vchPrivKey(nSize, 0);
+ unsigned char* pbegin = &vchPrivKey[0];
+ if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
+ throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
+ return vchPrivKey;
+ }
+
+ bool SetPubKey(const vector<unsigned char>& vchPubKey)
+ {
+ const unsigned char* pbegin = &vchPubKey[0];
+ if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
+ return false;
+ fSet = true;
+ return true;
+ }
+
+ vector<unsigned char> GetPubKey() const
+ {
+ unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
+ if (!nSize)
+ throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
+ vector<unsigned char> vchPubKey(nSize, 0);
+ unsigned char* pbegin = &vchPubKey[0];
+ if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
+ throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
+ return vchPubKey;
+ }
+
+ bool Sign(uint256 hash, vector<unsigned char>& vchSig)
+ {
+ vchSig.clear();
+ unsigned char pchSig[10000];
+ unsigned int nSize = 0;
+ if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
+ return false;
+ vchSig.resize(nSize);
+ memcpy(&vchSig[0], pchSig, nSize);
+ return true;
+ }
+
+ bool Verify(uint256 hash, const vector<unsigned char>& vchSig)
+ {
+ // -1 = error, 0 = bad sig, 1 = good
+ if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)
+ return false;
+ return true;
+ }
+
+ static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig)
+ {
+ CKey key;
+ if (!key.SetPrivKey(vchPrivKey))
+ return false;
+ return key.Sign(hash, vchSig);
+ }
+
+ static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig)
+ {
+ CKey key;
+ if (!key.SetPubKey(vchPubKey))
+ return false;
+ return key.Verify(hash, vchSig);
+ }
+};