【区块链学习笔记】1:比特币中的密码学原理

跟着肖臻老师公开课学习一下区块链技术。

加密货币

加密货币(crypto-currency)是不加密的,区块链上的所有交易都是公开的,包括转账地址和转账金额。比特币中和密码学有关的技术主要就是哈希签名两种技术。

密码学中的哈希函数

密码学中的哈希函数叫cryptographic hash function,有如下两个性质。

性质1:collision resistance(collision free)

这里的collision哈希碰撞,即两个不同的输入用哈希函数算出的哈希值相等:
x ≠ y , H ( x ) = H ( y ) x \neq y ,H(x)=H(y) x̸=y,H(x)=H(y)
哈希碰撞是不可避免的,因为输入空间总是远大于输出空间(不然用哈希干嘛)。按鸽笼原理来看,当实际输入超过输出空间大小时就必然发生哈希碰撞了。

collision resistance的意思就是没有什么高效的方法去人为的制造哈希碰撞,即知道一个y,没有特定的找到x的方法使得H(x)=H(y)。如果一定要找的话只能用brute-force的方式,即遍历输入空间不断计算哈希值,直到找到恰好碰撞的那个x。

collision resistance可以用来对一个信息求digest,用来检测对这个信息的篡改。因为如果这个信息的内容被改掉了,那么哈希值就会改变,没有专门的修改信息内容而不改变其哈希值的手段。比如使用云存储时,在上传文件之前计算一个哈希值放在本地,以后下载下来再计算一下哈希值和本地之前记录的哈希值比较一下,如果一样就说明下载下来的内容还是之前的内容,没有被篡改。

没有哪个哈希函数能在数学上证明是collision resistance的,这个性质只是靠实践中的经验,也就是那些符合这个性质的哈希函数只是长期下来没有找到人为制造哈希碰撞的方法,这时候也就认为它们是collision resistance的。
有些函数以前认为是collision resistance的,后来人们找到了人为制造哈希碰撞的方法,比如MD5,所以它已经不安全了。

性质2:hiding

hiding是指哈希函数的计算过程是单向的,是不可逆的。即可以 x → H ( x ) x \to H(x) xH(x),但无法 x ← H ( x ) x \gets H(x) xH(x)。这表示哈希值 H ( x ) H(x) H(x)没有泄露有关输入 x x x的任何信息。

因为总可以蛮力求解,所以hiding成立的前提是输入空间足够大,使得蛮力求解在当下计算力条件下不可行。而且输入的分布要比较均匀,各种取值的可能性都差不多,不然只需要在分布的峰值部分做蛮力求解就很可能能找到输入值了。

实现digital commitment

用前面两个性质可以实现digital commitment,这也叫digital equivalent of a sealed envelop

这里肖老师为了解释sealed envelop,举了一个现实生活的例子。如一个人说自己能预测股票涨停,那么如何证明呢?如果让他提前公布自己的“预测”——明天股票的涨停,然后明天再去看股市,那么他公布的信息本身就会影响到股票涨停。如果在股票涨停之后再公布,那么大家会怀疑他有没有篡改自己的“预测”。

而这里sealed envelop也就是解决这个问题的办法,让这个人先把预测结果写在纸上,放进信封里封好,然后交给第三方的公证机构保管。第二天股市收盘后,再让公证机构检查信封完好、打开信封、查看纸上的预测结果和实际涨停是不是一致即可。


而使用digital commitment在这个问题上的做法是把预测结果计算出一个哈希值,然后把哈希值公布出去,因为有hiding的性质,所以大家没法通过哈希值知道预测结果。第二天收盘后公布预测结果,因为有collision resistance的性质,所以预测结果是没有篡改过的,否则和公布的哈希值就对不上了。


在这个问题里,例如预测的是“涨的股票的名字”,那么因为股票一共就那么多支,输入空间并不是足够大,这样就不满足hiding的性质(大家可以遍历所有的股票取哈希去知道预测的是哪支股票涨)。这时候的解决办法可以是在输入后面加上一个随机数nonce,强行增大输入空间
H ( x ∣ ∣ n o n c e ) H(x||nonce) H(xnonce)

比特币中的哈希函数

比特币中使用的哈希函数需要满足前面密码学中哈希函数的两个性质,但还有一些额外的内容。

性质3:puzzle friendly

除了前面两个性质,比特币中的哈希函数还要满足puzzle friendly这个性质。这个性质是说哈希值的计算结果是不可预测的,也就是光是去看这个输入没法知道计算出来的哈希值可能是什么样的(具有什么特征)。

即例如,想要计算出的哈希值落在某个范围内,那没有特定的办法去构造输入。又如,想要计算出的哈希值前面有k个连续的0,也没有特定的办法去构造输入。甚至无法知道什么样的输入更有可能得到具有特定特征的哈希值,要想得到这种输入就只能一个一个去试,没有捷径。

比特币挖矿的过程就是去找一个随机数nonce,这个nonce和区块的块头里的其它信息合并在一起作为输入,取哈希值,所得哈希值要小于等于某个指定的阈值:
H ( b l o c k   h e a d e r ) ≤ t a r g e t H(block \ header) \leq target H(block header)target
注意,nonce不是区块块头以外的东西,它是其中的一个域,但是可以人为设置。挖矿的过程就是不停的去试nonce,使得整个块头部分取哈希小于等于target。
【区块链学习笔记】1:比特币中的密码学原理_第1张图片
有了puzzle friendly这个性质,使得比特币挖矿的过程没有捷径可言,只能不停的去试大量的nonce才能找到符合要求的解,所以才能用来用作工作量证明(proof of work)。

这个puzzle friendly和最前面的collision resistance有一定的联系,但不是完全一样。那个是无法去人为制造哈希碰撞,而这个是无法去人为构造符合特定特征的哈希值。

difficult to solve,but essay to verify

虽然找到一个符合要求的nonce很难,但一旦找到之后,将它发布出去以后,其他人要验证这个nonce是不是符合要求是很容易的,只要算一次哈希值再和target比较一下就可以了。

SHA-256

这是比特币中使用的哈希函数,SHA是Secure Hash Algorithm的缩写。

两种加密体系

对称加密体系

最早的加密体系是对称的加密体系symmetric encryption algorithm)。如两方进行通信,商量好一个密钥encryption key),发送方使用密钥加密,接收方使用密钥解密。因为加密解密用的是用一个密钥,所以这是对称的加密体系。这种方式假设了存在某种安全的渠道,能够把密钥分发给通讯双方,这是对称加密体系的一个弱点。

非对称加密体系

非对称的加密体系asymmetric encryption algorithm)不再像对称加密那样使用一个密钥,而是使用一对密钥,即公钥和私钥,加密用的是公钥,解密用的是私钥

例如A要发信息给B,那么使用B的公钥对信息进行加密,B收到信息后用B自己的私钥进行解密就能得到原来的信息。也就是说加密和解密用的都是接收方的公钥和私钥。

这样做的好处是公钥是不用保密的,可以告诉所有人,有的人主页上就有PGP public key。只有私钥是要保密的,但是私钥只需要保存在本地就可以了,不用传递给任何人,这样就避免了传输密钥过程不安全的问题。要回复对方再用对方的公钥加密,始终都不需要知道其他人的私钥,这就解决了对称加密体系中密钥分发不安全(不方便)的问题。

比特币中的签名

加密货币是不加密的,前面学的非对称加密的公钥和私钥在比特币系统中就是用来做签名的。

比特币系统中的账户管理

日常生活中想要开个账户,那就是带上证件去银行办理,这种就是中心化的账户管理方式。在比特币系统中是去中心化的,也就是没有银行之类的机构。每个用户自己决定开户,不需要任何人批准,开户的过程就是在本地创立一对公钥和私钥的过程
( p u b l i c   k e y ,   p r i v a t e   k e y ) (public \ key, \ private \ key) (public key, private key)
公钥就相当于用户的银行账户,转账只需要知道公钥就可以了。私钥相当于账户密码,知道了私钥就可以将账户上的钱转走。

对交易签名

比如A要向B转账,即A在区块链上发起一个交易,所有交易是公开的,但大家怎么判断这个交易确实是A发起的,而不是别人冒名顶替的,这就需要A用户用自己的私钥对交易进行签名。其他用户拿到签名和交易信息后,可以用A的公钥去验证签名的正确性。

签名用的是私钥,验证签名用的是公钥。都是同一个用户的公钥和私钥。

公钥私钥对重复问题

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

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

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

a good source of randness

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

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


比特币系统中的签名,一般是先对message取一个哈希,然后再对哈希值签名。

你可能感兴趣的:(区块链)