key.h 阅读与备注

      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);
    }
};

 


  

 

  

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值