key.h 是bitcoin0.1.5 中调用openssl生成管理公钥,签名与验签的文件。下载地址【https://github.com/bitcoin/bitcoin/archive/v0.1.5.tar.gz】。openssl 中关于ECDSA的使用,可以查阅https://wenku.baidu.com/view/cd1de8cdba0d4a7303763a29.html
// 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
//#### wxx备注:定义key_error
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; //#### wxx备注: EC_KEY
public:
CKey()
{
//#### wxx备注:调用OpenSSL的EC_KEY_new_by_curve_name初始化key
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)
{
//#### wxx备注:调用OpenSSL的EC_KEY_dup 。待补充
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)
{
//#### wxx备注: 调用OpenSSL的EC_KEY_copy 复制key
if (!EC_KEY_copy(pkey, b.pkey))
throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
return (*this);
}
~CKey()
{
//#### wxx备注: 调用OpenSSL的EC_KEY_free 释放Key
EC_KEY_free(pkey);
}
//#### wxx备注: 创建公钥与私钥
void MakeNewKey()
{
if (!EC_KEY_generate_key(pkey)) //#### wxx备注: 生成公钥与私钥并填充到Key中
throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
}
//#### wxx备注: 设置私钥(私钥就是一个字符串)
bool SetPrivKey(const CPrivKey& vchPrivKey)
{
const unsigned char* pbegin = &vchPrivKey[0];
//#### wxx备注: 调用OpenSSL的d2i_ECPrivateKey给EC_Key设置私钥
if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))
return false;
return true;
}
//#### wxx备注: 获取私钥
CPrivKey GetPrivKey() const
{
//#### wxx备注: 调用OpenSsl的i2d_ECPrivateKey获取私钥的大小,第二个参数为私钥地址,传null不返回私钥信息
unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
if (!nSize)
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
//#### wxx备注: 初始一个nSize大小的私钥
CPrivKey vchPrivKey(nSize, 0);
unsigned char* pbegin = &vchPrivKey[0];
//#### wxx备注: 调用OpenSsl的i2d_ECPrivateKey获取私钥
if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
return vchPrivKey;
}
//#### wxx备注: 设置公钥信息,公钥已是一个字符串
bool SetPubKey(const vector<unsigned char>& vchPubKey)
{
const unsigned char* pbegin = &vchPubKey[0];
//#### wxx备注: 调用OpenSSL的o2i_ECPublicKey,给Key设置公钥
if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))
return false;
return true;
}
//#### wxx备注: 获取公钥信息
vector<unsigned char> GetPubKey() const
{
//#### wxx备注: 调用OpenSsl的i20_ECPublicKey获取公钥长度
unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
if (!nSize)
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
//#### wxx备注: 初始化一个公钥
vector<unsigned char> vchPubKey(nSize, 0);
unsigned char* pbegin = &vchPubKey[0];
//#### wxx备注: 调用OpenSSL的i2o_ECPublicKey获取公钥
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
return vchPubKey;
}
//#### wxx备注: 对HASH 进行签名
bool Sign(uint256 hash, vector<unsigned char>& vchSig)
{
vchSig.clear();
unsigned char pchSig[10000];
unsigned int nSize = 0;
//#### wxx备注: 调用OpenSSL的ECDSA_sign对数据起签名。
if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
return false;
vchSig.resize(nSize);
memcpy(&vchSig[0], pchSig, nSize);
return true;
}
//#### wxx备注: 签名验证
bool Verify(uint256 hash, const vector<unsigned char>& vchSig)
{
//#### wxx备注: 调用OpenSsl的ECDSA_verify验证签名
// -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;
}
//#### wxx备注: 根据私钥进行签名
static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig)
{
CKey key;
if (!key.SetPrivKey(vchPrivKey)) //#### wxx备注: 设置私钥
return false;
return key.Sign(hash, vchSig); //#### wxx备注: 进行签名
}
//#### wxx备注: 使用公钥验证签名
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);
}
};