diff options
author | Jeff Garzik <jeff@garzik.org> | 2011-05-09 14:00:14 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2011-05-09 14:00:14 -0400 |
commit | b17be7e14b4a62b7935c75fe7e7645e736fd68d2 (patch) | |
tree | be44c7310683df72aeb5781ec74a85451206cfbc /src/key.h | |
parent | c0430f42b868dbf996a416d3a9d81d1c8c07e47c (diff) | |
parent | 84c3fb07b0b8199c7f85c5de280e7100bad0786f (diff) |
Manual merge of jaromil's source tree reorg commit.
Conflicts:
src/sha256.cpp
Diffstat (limited to 'src/key.h')
-rw-r--r-- | src/key.h | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/key.h b/src/key.h new file mode 100644 index 0000000000..06f88cc907 --- /dev/null +++ b/src/key.h @@ -0,0 +1,168 @@ +// 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); + } +}; |