BTC 密码学原理
比特币被称为加密货币(Crypto-currency),但区块链上内容都是公开的,包括区块的地址,转账的金额。
比特币主要用到了密码学中的两个功能:哈希 和 签名。
# 一、哈希
密码学中用到的哈希函数被称为 Cryptographic hash function,它有几个重要的性质:
- collision resistance:抗碰撞性,这里指哈希碰撞。
- hiding:计算过程是单向的,不可逆的。
- puzzle friendly:哈希值的计算事先是不可预测的。
比特币中用的哈希函数叫作 SHA-256,以上三个性质它都是满足的,下面来对这三个性质进行详细说明。
# 1.1 抗碰撞性
例如 ,两个不同的输入,输出却是相等的,这就称哈希碰撞。一般来说哈希碰撞是不可避免的,因为输入空间总大于输出空间。
这里的抗碰撞性是说没有什么高效的方法去人为的制造哈希碰撞,即给出 ,很难找出 ,使得 ,除非蛮力破解。
该性质的作用是对一个 message 求 digest。比如有一个 message 取 , 的哈希值是 ,如果有人想篡改 的值,则该性质可以保证在篡改后无法让 保持不变。
哈希碰撞无法人为制造,无法验证,是根据实践经验得来的。一些我们曾经认为具有抗碰撞性的哈希函数,已经可以找到构造哈希碰撞的方法,比如 MD5。
# 1.2 计算过程不可逆
例如 ,但 ,即哈希值并没有泄露输入的信息。
该性质前提是输入空间足够大,分布比较均匀,使得蛮力求解不可行。如果不是足够大,一般在 后面拼接一个随机数,如 。
该性质的作用是和 collision resistance(抗碰撞性)结合在一起,用来实现 digital commitment(又称为 digital equivalent of a sealed envelope)。
例如把预测结果作为输入 ,算出一个哈希值,将哈希值公布,hiding 让人们无法根据哈希值求解 ,最后再将 公布,因为有 collision resistance 的性质,预测结果是不可篡改的。
# 1.3 结果不可预测
例如哈希值是 ,事先无法知道哪个值更容易算出这个结果,需要一个一个带入计算。
比特币挖矿的过程中实际就是找一个 nonce,nonce 跟区块的块头里的其他信息合一起作为输入,得出的哈希值要小于等于某个指定的目标域值,即 。
block header 指块头,块头里有很多域,其中一个域是我们可以设置的随机数 nonce,挖矿的过程是不停的试随机数,使得 落在指定的范围之内。
puzzle friendly 是指挖矿过程中没有捷径,为了使输出值落在指定范围,只能一个一个去试,所以这个过程还可以作为 工作量证明(proof of work)。
挖矿很难,验证很容易(difficult to solve ,but easy to verify),只需要根据发布出去的 nonce 计算一次哈希值即可验证。
# 二、签名
# 2.1 BTC 系统中的账户管理
BTC 是去中心化的,只需要在本地创立一个公私钥匙对(public key, private key),这就是一个账户,其中公私钥的概念来自于非对称的加密技术(asymmetric encryption algorithm)。
# 2.2 加密体系
最早的加密体系是对称的(symmetric encryption algorithm),比如两个人之间要进行信息交流,但通讯的网络是有可能被窃听的,这时可以让双方约定一个密钥(encryption key),A 将信息加密后发给 B,B 收到后用密钥解密,因为加密和解密用的是同一个密钥,所以叫对称加密。
对称加密方法的前提是假设有某种安全的渠道能够把密钥分发给通讯的双方,但在网络上是很容易被窃听的,因此 密钥的分发不方便就是对称加密方法的一个缺点。
为解决对称加密方法的缺点,非对称加密指出可以使用一对密钥而不是一个,加密用公钥,解密用私钥,加密和解密用的都是接收方的公钥和私钥。公钥是不用保密的,私钥要保密但是私钥只要保存在本地就行,不用传给对方。
公钥相当于银行账号,别人转账只要知道公钥就行,私钥相当于账户密码,知道私钥可以把账户上钱转走。这就解决了对称加密方法中密钥分发不方便的问题。
# 2.3 交易签名
假如 A 想向 B 转 10 个比特币,A 把交易放在区块链上,别人怎么知道这笔交易是 A 发起的呢?
这就需要 A 要用自己的私钥给交易签名,其他人收到这笔交易后,要用 A 的公钥去验证签名。签名用私钥,验证用公钥,用的仍然是同一个人的。
创建账户产生相同公私钥的可能性微乎其微,所以大量创建账户来窃取其他人账户是不可行的。该结论基于我们假设产生公私钥时有一个好的随机源(a good source of randomness),产生公私钥是随机的,如果随机源不好,就有可能产生相同的公私钥。
比特币中用的签名算法,不仅是生成公私钥的时候要有好的随机源,之后每一次签名时也要有好的随机源。只要有一次签名用的随机源不好的话,就有可能泄露私钥。