比特币的密码学原理

前言:这一系列的文章是看肖臻老师《区块链技术与应用》公开课做的笔记


比特币用到了密码学的两个功能,一个是哈希,一个是签名

哈希

函数

对于集合A中的任意一个数x,在集合B中都有唯一确定的数y与之对应

要注意:
集合A中的元素a,都能找到有且仅有一个集合B中的数与之对应;即不存在f(a)=b1,又有f(a)=b2的情况。但是,存在f(a1)=b,同时又有f(a2)=b的情况,如偶函数y=x2

哈希函数

本质是一个函数,但是特殊在输入值是任意字符串,输出值是固定长度的字符串,比如比特币用的SHA256,是将输入的字符串计算成64位十六进制数(256位二进制数)

比特币用到的哈希函数的三个特性

  1. collision resistance(抗碰撞性)
    什么是碰撞?
    对于函数f(x) ,如果存在a!=b,使得f(a)==f(b),那么就称为碰撞
    什么是抗碰撞性?
    除了暴力枚举输入空间,很难找到会发生碰撞的两个输入值
    抗碰撞性的作用
    上传文件之前可以对文件计算一个hash值,下次下载下来,再计算一个hash值,如果两个hash值不同,则说明被文件篡改了。因为抗碰撞性使得修改后的文件的计算出来的hash值和原来的文件极大概率是不同的。

  2. hiding property(隐藏性)
    光给你一串hash值,除了暴力求解,你是很难知道加密前的内容是什么,这就叫隐藏性。但是hiding成立的前提是输入空间无限大,而且输入的分布比较均匀,各种取值的可能性是差不多的,所以暴力求解也是不可行的。
    隐藏性的作用
    假如有一个人说他预测股票很准,怎么验证他说的准不准呢?如果他公布预测结果,可能会有人故意和他反着来,操纵股市导致预测不准,所以预测结果不能提前公布。那么大家又是如何知道他预测准不准呢?这个时候可以先让这个预测的人将预测结果取个hash值公布出来,由于隐藏性,光是知道hash值很难知道加密前的内容,这样就不会影响股市。然后收盘之后,让这个预测的人把预测结果公布出来,由于抗碰撞性,预测的人是无法篡改预测结果的,要是改了的话就和当初公布的hash对不上,这样就起到了一个sealed envelope 的作用。但是这个例子有一个问题,就是股票的数量是非常有限的,不满足隐藏性成立的前提条件,所以实际操作会在预测结果后面加一串随机数,然后整个取hash

  3. puzzle friendly
    光是看输入,很难猜出来hash值是什么样的,所以你想让hash值落在某个范围之内,那只能暴力枚举了。比如想得出hash值前面k位数都是0,怎么得出呢?没有办法,不能事先知道,只能一个一个去试,所以叫puzzle friendly ,挖矿的过程就是计算H(block header)<=target。 block header是区块的信息,其中包括一个nonce(随机数),我们所要做的就是不断就试这个nonce,使得hash值落在一个target space中,所以这个挖矿的过程没有捷径,只能不断去试nonce,所以这个才可以作为工作量证明。

签名

日常生活中想要开一个银行账户,怎么开,带上证件去银行。
那比特币怎么开账户呢?很简单,只需要一对公钥和私钥,每个用户自己决定开不开户。在本地中创建一个公钥私钥对就完成了开户。
公钥和私钥来自非对称加密。

什么是对称加密?
双方在进行信息交换的时候用同一个密钥对内容进行加密/解密,那么这个密钥就一定要在网络中传输,但是网络是有可能被窃听的,所以对称加密并不安全。

什么是非对称加密?
双方都有一对公钥和私钥,我给你发信息时,我用你的公钥对内容进行加密,然后你用你的私钥对信息解密,同理你给我发信息时得用我的公钥对信息进行加密,然后我用我的私钥对你发来的信息解密。公钥不需要保密,但是私钥需要保密。解决了对称加密的密钥分发的安全问题。

在比特币系统中,非对称加密的真正用途其实是签名,而不是信息传输,何谓签名?比如我想发起一笔交易,别人怎么知道是我发起的而不是别人偷偷的替我发起的呢,这就需要我在发布交易的时候用我的私钥进行签名(先对交易信息进行hash),然后别人用我的公钥去验证这个签名的正确性,如果不正确,说明不是我本人发起的。

所以总的来说,非对称加密算法的作用是:公钥加密,私钥解密; 私钥签名,公钥验证。

公钥私钥对重复问题
既然公钥私钥对始终是在本地产生,那么产生重复怎么办?

如大量生成公钥私钥对,然后去对比产生的公钥是不是和区块链上已有的某个公钥相同。如果相同,那么就可以用对应的私钥把账户上的钱转走。

这种方式理论上可行,但是实际上没法做,因为产生重复的公钥私钥对的概率非常小,可以忽略不计。到目前为止还没有能用这种方法攻击成功的先例。

a good source of randness
生成公钥私钥的过程是随机的,但要求选取一个好的随机源,否则前面的分析就不成立了(就有不足够小的可能生成重复的公钥私钥对)。

比特币中使用的签名算法不仅在生成公钥私钥对时有好的随机源,在之后每次签名的时候也要有好的随机源。如果签名时使用的随机源不好,就有可能泄露私钥。