aboutsummaryrefslogtreecommitdiff
path: root/key.h
diff options
context:
space:
mode:
authorsirius-m <sirius-m@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2009-08-30 03:46:39 +0000
committersirius-m <sirius-m@1a98c847-1fd6-4fd8-948a-caf3550aa51b>2009-08-30 03:46:39 +0000
commit4405b78d6059e536c36974088a8ed4d9f0f29898 (patch)
tree1e8dec58f70505a3dd554918ce9b07384d047415 /key.h
downloadbitcoin-4405b78d6059e536c36974088a8ed4d9f0f29898.tar.xz
First commit
Diffstat (limited to 'key.h')
-rw-r--r--key.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/key.h b/key.h
new file mode 100644
index 0000000000..8b0b54e4b3
--- /dev/null
+++ b/key.h
@@ -0,0 +1,156 @@
+// Copyright (c) 2009 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 is serialize.h
+typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
+
+
+
+class CKey
+{
+protected:
+ EC_KEY* pkey;
+
+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");
+ }
+
+ CKey(const CKey& b)
+ {
+ pkey = EC_KEY_dup(b.pkey);
+ if (pkey == NULL)
+ throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
+ }
+
+ CKey& operator=(const CKey& b)
+ {
+ if (!EC_KEY_copy(pkey, b.pkey))
+ throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
+ return (*this);
+ }
+
+ ~CKey()
+ {
+ EC_KEY_free(pkey);
+ }
+
+ void MakeNewKey()
+ {
+ if (!EC_KEY_generate_key(pkey))
+ throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
+ }
+
+ bool SetPrivKey(const CPrivKey& vchPrivKey)
+ {
+ const unsigned char* pbegin = &vchPrivKey[0];
+ if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
+ return false;
+ 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;
+ 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);
+ }
+};