【BTC】密码学原理

主要是根据北京大学肖臻老师讲的《区块链技术与应用》公开课所撰写的笔记

哈希(Hash)

简介

密码学中用的哈希函数被称为密码散列函数(Cryptographic hash function),又被称为加密散列函数,是散列函数的一种。它被认为是一种单向函数,也就是说极其难以由散列函数输出的结果,回推输入的数据是什么。这种散列函数的输入数据,通常被称为消息(Message),而它的输出结果,经常被称为消息摘要(Message digest)或摘要(Digest)。在信息安全中,有许多重要的应用,都使用了密码散列函数来实现,例如数字签名消息认证码。密码学中要求的两个重要的性质:抗碰撞性(Collision resistance)隐蔽性(Hiding),以及比特币(BTC)要求的第三个特性:Puzzle friendly

抗碰撞性(Collision resistance)

"哈希碰撞"是指输入不相等的值XY,使得XY的求出哈希值相等
即:X≠Y ,H(X)=H(Y) , H()表示哈希函数
到目前为止,没有哪个哈希函数能够在数学上证明是抗碰撞性(Collision resistance)的,也就是说从理论上是无法证明的,只能通过实践中的经验。
有些哈希函数经过长期的实践检验,我们认为它是抗碰撞性(Collision resistance)的,可是后来被世人找到了人为制造哈希碰撞的方法,比如像比较著名的哈希函数:MD5。

用途

比如有一个消息(M),取它的哈希值:M → H(M),求得哈希值结果假如是:Digest,用Digest来检测对M的篡改;
举例:有人修改了消息M,就会使得哈希值H(M)也会改变;
如果结合抗碰撞性(Collision resistance)来说:无法找到另外一个消息(X),使得H(X) = H(M)
总结得出:没有什么办法能够篡改内容而又不被检测出来

  • 自己有个文件,把它上传到服务器上,想使用到这个文件的时候把它从服务器上下载下来。那怎么检测到你所下载下来的文件是否已经被其他人篡改过了呢?

    可以在上传文件(M)的时候,给这个(M)求一个哈希值M → H(M),自己本地保存这个哈希值H(M),然后从服务器上再把这个之前所上传的文件下载下来后,再给下载下来的文件(X)求一个哈希值H(X),即X → H(X)。最后跟上传本地保存的哈希值H(M)比较下,如果H(X) = H(M),说明服务器上的这个文件(M)没有被其他人篡改过;反之,说明服务器上的文件(M)被别人篡改过。

隐蔽性(Hiding)

隐蔽性(Hiding)指的是哈希函数的计算是单向的,不可逆的。X → H(X),输入X,可以获取哈希值H(X),即 X → H(X),但是无法通过H(X)反推出输入值X。除非用穷举的方式,因此隐蔽性(Hiding)成立的前提是:输入的空间要足够的大,且取值概率是比较均匀的,则难以破解

用途

可以跟上面的抗碰撞性(Collision resistance)结合使用,可以实现数字承诺(Digital commitment),也可以称为密封的数字信封(Digital equivalent of a sealed envelope)


现实生活中密封的信封(Sealed envelope)是干嘛用的呢?可以理解为:预测可能影响结果

比如说有一个人他能够预测股市的走向,可以预测第二天哪些股票会涨停。那怎么证明这个人预测的是不是准确呢?
一种办法是:这个人提前一天在电视台上公布预测结果;第二天收盘之后看一下这个股票是不是真的涨停,这就知道他预测的准不准了。但这样做会有一个问题?如果预测结果提前公布了,可能会影响股市的走向。比如股市界的泰斗/大V预测走向,可能引领一堆人去买。本来这支股票不会涨停,他这么一公开预测,大家拼命的去买。结果它变成了涨停。当然了不同方向的情况也有可能发生,就这支股票本来确实是需要涨停的,但有人想踢场子,你不是预测它涨停吗?我就不让它涨停,拼命的砸盘。这都有可能发生,这说明预测结果不能提前公开。但是预测结果不提前公开,你等第二天收盘之后再公开,那你怎么知道这个预测结果有没有被篡改过?你最后公开的结果是不是你提前一天做出来的?
另外一种办法(Sealed envelope)是:你把你所预测的结果写在一张纸上,放到一个信封里给密封好,然后把这个信封要交给第三方的公正机构保管。等第二天收盘之后再把它打开,验证一下这个结果准不准确。现实中Sealed envelope就是这样使用的。


那在电子世界中Digital sealed envelope是如何使用的呢?(也以预测股市举例)

把预测结果作为输入X算出一个哈希值H(x)来,即:X→H(X),然后把这个哈希值H(x)在电子世界中公布出去。因为有这个隐蔽性(Hiding)的性质,所以从这个哈希值H(x)中无法反推出预测结果是什么
然后第二天收盘之后,再把预测结果X公布出去。因为有抗碰撞性(Collision resistance) 的性质,所以预测结果H(X)是不可能被篡改的;如果要是被改了的话,就跟当初公布出来的哈希值H(x)是对不上的


在实际操作中,有些细节要注意,隐蔽性(Hiding)的性质的前提是:输入的空间要足够的大,且取值概率是比较均匀的,则难以破解

如果输入的空间不满足这个前提,比如上面的预测股市的例子中。因为世界上的股票总共没多少,导致输入的空间不是足够大,于是我们可以把这个输入值(X)后面拼接一个随机数(Nonce),然后再一起来取哈希值H(X||Noce),即:X||Noce → H(X||Noce),这样就可以保证输入空间是足够随机,足够大的,分布也是足够均匀的。

Puzzle friendly

除了密码学要求的两个性质(Collision resistanceHiding)以外,比特币中还要求哈希函数的另一个性质,叫做Puzzle friendly。它是指:哈希的计算是事先不可预测的

知道输入值X,很难知道X的输出哈希值H(X)是什么。
如果想知道算出来的哈希值H(X)是否落在某个范围之内?目前是没有好的方法,只能通过遍历每个输入值X去试,看哪个X算出来的哈希值恰好落在要求的那个范围内。


其实挖矿实际上就是尝试寻找一个Nonce随机数,这个Nonce跟区块头里的信息组合在一起,作为输入值X,求出哈希值H(X),使得H(X)要小于等于某个指定的目标阈值(Target),即 H(Block header) ≤ Target


比特币是区块链,区块链就是一个一个区块组成的链表,每一个区块都有一个块头(Block header),Block header中有很多的域,其中有一个域是我们可以设置的随机数Nonce
挖矿的过程就是不停的去尝试找出各种不同的Nonce,使得整个Block header取哈希值H(Block header)之后落在指定的范围之内。


因此Puzzle friendly的性质是说:挖矿的过程是没有捷径的,只有不停的去尝试计算大量的随机数Nonce,才能找打符合要求的解
所以这个挖矿的过程才可以用来作为工作量证明(Proof of work), 简称 POW

假如挖到矿了,找到了符合要求的随机数Nonce,说明一定是因为做了大量寻找随机数Nonce的工作,因为没有别的捷径可走。


比特币中用的哈希函数是:SHA-256,这个SHA是Secure Hash Algorithm

签名

讲签名之前我们要了解下比特币系统中的账户管理

在日常生活中我们想要开个银行账户怎么办呢?必须要带上证件去银行办理开户手续,这就是中心化系统中的账户管理方式 。
那比特币是去中心化的,它没有银行之类的这类机构,那我们怎么开账户呢?每个用户自己来决定开户,不需要任何人批准
开户的过程很简单,就是创立一个公钥和私钥的对(Public key, Private key)。在本地创立一个公私钥对,就是一个账户,这个就在比特币中代表了一个账户,公私钥这个概念是来自非对称加密这个体系,叫做Asymmetric encryption algorithm)。最早的加密体系是对称的,叫做Symmetric encryption algorithm

比如说两个人之间要进行通信,我要把某个信息发给你。但是这个通信的网络是有可能被窃听的,那怎么办呢?咱们两个事先商量一个密钥,一个叫做Encyption key,我把这个信息加密之后发送给你,你收到之后再用这个密钥解密,因为这个加密和解密用的是同一个密钥,所以这个叫做对称的加密体系。它有个弱点:密钥的分发不是很方便


解决这个问题非对称加密体系就提出来我们不是用一个密钥,而是用一对密钥,即一个公钥和一个私钥一起使用。加密用的是公钥,解密用的是私钥。比如说我要把一个信息传给你,我用你的公钥给这个信息加密,你收到之后再用你的私钥解密,得到原来的信息。加密和解密用的是同一个人的公钥和私钥,都是这个接收方的公钥和私钥。


这有什么好处呢?公钥是不用保密的,加密用的公钥是不用保密的,你可以告诉所有的人。私钥是要保密的,解密是要用私钥解密的,但是私钥只要保存在本地就行了,不用传给对方。这就解决了对称加密体系中密钥分发的不方便的问题。


在比特币系统中,要创建一个账户,就是在本地产生一对公私钥。公钥就相当于银行账号,别人要给你转账,只要知道你的公钥就行了,私钥相当于你的账户密码。比特币系统中,我们要这个公钥和私钥干什么呢?实际上用来做签名的。

比如说我要转10个比特币给你,然后我这个交易发布到区块链上,那别人怎么知道这个交易确定是我发起的呢?会不会是有人冒名顶替,偷偷把我帐上的钱转走呢?这就需要我在发布这个交易的时候要用我自己的私钥对这个交易进行签名,那其他人收到这个交易之后呢?在用我的公钥去验证这个签名的正确性。签名用的是私钥,验证签名用的是这个人的公钥。


既然每一个人都是独立的产生账户,那万一两个人生成的公私钥对相同怎么办呢?比如说有人想偷取比特币,一种方法是不停的产生公私钥对,然后对比一下我产生的公钥,跟区块链上某个已有的公钥是不是相同,如果是一样的话,就可以用私钥把这个帐上钱给偷走?这种攻击方法从理论上说好像是可以的,但是实际当中是不可行的。

比如说是256位的哈希值的话,产生相同的公私钥的可能性是微乎其微的。
比如你有一台超级计算机每天产生大量的公私钥对,出现来两个人的公私钥对相同的情况概率也是可以忽略不计的,这个概率比地球爆炸的概率还要小。
到目前为止还没有发现那个人用这种方法,能够攻击成功的先例。


产生公私钥的时候有一个好的随机源,这叫做A good source of randomness,最终可以保证生成公私钥的过程是随机的。
如果选取的随机源不好的话,那么前面的分析就不存在了,就会出现两个人的公私钥对生成的是一样的。


比特币中用的签名算法不仅是:生成公私钥的时候要有好的随机源,之后每一次签名的时候也要有好的随机源。

总结

这两个功能是可以结合起来使用的,比特币系统中一般是先对一个消息M求一个哈希值H(M),即M → H(M),然后在对这个哈希值H(M)做签名。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值