主页 > 怎么退出imtoken钱包 > 比特币源码研究(5)——私钥、公钥和地址

比特币源码研究(5)——私钥、公钥和地址

怎么退出imtoken钱包 2023-06-19 07:14:35

比特币中的私钥、公钥和地址类似于我们现实生活中的银行卡。私钥是密码,地址是卡号,公钥没有适当的类比。在转账过程中,我们有密码,知道对方的地址,转账就可以成功。谁有私钥,谁就可以花钱;谁拥有发送地址对应的私钥,谁就可以收到钱。

在比特币中,私钥、公钥和地址之间的关系如下:

私钥:随机生成的 256 位二进制数字。密钥由椭圆曲线乘法生成:公钥通过单向加密哈希算法得到

如下图

图片

私钥

比特币的私钥是一个1~2^256范围内的数字,非常非常大,保证了比特币的私钥不会被破解。那么数字 2^256 有多大呢?十进制大约是 10^77比特币私钥公钥地址,可见宇宙估计只有 10^80 个原子。超级计算机“神威太湖之光”的峰值性能为每秒12.50亿次,相当于10^17。如果用这台世界上第一台超级计算机与比特币私钥碰撞,需要10^60秒,也就是3*10^52年。我们可以得出结论,通过碰撞破解比特币的私钥是不可能的。

比特币代码中生成私钥的方法是MakeNewKey,在key.cpp文件中。循环通过GetStrongRandBytes通过伪随机数生成器生成私钥,然后检查是否满足要求,如果满足则跳出循环。

// 在key.cpp
void CKey::MakeNewKey(bool fCompressedIn) {
    do {
        GetStrongRandBytes(keydata.data(), keydata.size());
    } while (!Check(keydata.data()));
    fValid = true;
    fCompressed = fCompressedIn;
}
 
//在random.cpp
void GetStrongRandBytes(unsigned char* out, int num)
{
    assert(num <= 32);
    CSHA512 hasher;
    unsigned char buf[64];
 
    // First source: OpenSSL's RNG
    RandAddSeedPerfmon();
    GetRandBytes(buf, 32);
    hasher.Write(buf, 32);
 
    // Second source: OS RNG 操作系统熵值
    GetOSRand(buf);
    hasher.Write(buf, 32);
 
    // Third source: HW RNG, if available.
    if (GetHWRand(buf)) {
        hasher.Write(buf, 32);
    }
 
    // Combine with and update state
    {
        std::unique_lock lock(cs_rng_state);
        hasher.Write(rng_state, sizeof(rng_state));
        hasher.Write((const unsigned char*)&rng_counter, sizeof(rng_counter));
        ++rng_counter;
        hasher.Finalize(buf);
        memcpy(rng_state, buf + 32, 32);
    }
 
    // Produce output
    memcpy(out, buf, num);
    memory_cleanse(buf, 64);
}

公钥

公钥由私钥通过椭圆曲线相乘生成。私钥是从公钥逆向推导出来的,这是一个不可逆的过程。这个太复杂了比特币私钥公钥地址,等君易懂了再详细讲。

地址

地址是通过公钥的单向加密哈希算法,也是不可逆的。

以公钥K为输入,计算其SHA256哈希值,并用结果计算RIPEMD160哈希值,得到一个长度为160位(20字节)的数字:

A = RIPEMD160(SHA256(K))

在生成的 32 字节长散列(两个散列)中,我们只取前 4 个字节。这 4 个字节用作错误检查码或校验和。数据后加校验码。

结果由前缀、数据和校验和三部分组成,最后是Base58编码。