1、Hash
1) 概念
哈希函数:Hash(原始信息) =摘 要信息
原始信息可以是任意的信息,hash之后会得到一个简短的摘要信息。
哈希函数(Hash Function),也称为散列函数或杂凑函数。哈希函数是一个公开函数,可以将任意长度的消息M映射成为一个长度较短且长度固定的值H(M),称H(M)为哈希值、散列值(Hash Value)、杂凑值或者消息摘要(Message Digest)。它是一种单向密码体制,即一个从明文到密文的不可逆映射,只有加密过程,没有解密过程。
它的函数表达式为:h=H(m)
无论输入是什么数字格式、文件有多大,输出都是固定长度的比特串。以比特币使用的Sha256算法为例,无论输入是什么数据文件,输出就是256bit。
每个bit就是一位0或者1,256bit就是256个0或者1二进制数字串,用16进制数字表示的话,就是64位。
于是你通常看到的哈希值,就是这样的了:
00740f40257a13bf03b40f54a9fe398c79a664bb21cfa2870ab07888b21eeba8。
2) 特点:
易压缩:对于任意大小的输入x,函数H产生的Hash值其长度是固定的。
易计算:对于任意给定的消息,计算其Hash值比较容易。而且,同样的原始信息用同一个哈希函数总能得到相同的摘要信息
单向性:从摘要信息无法逆向推算出原始信息,对于给定的Hash值,要找到原始信息在计算上是不可行的,即从哈希输出无法倒推输入的原始数值。这是哈希函数安全性的基础。
抗碰撞性:碰撞性,即两个不同的原始信息,产生同样的hash值,理想的Hash函数是无碰撞的,但在实际算法的设计中很难做到这一点。
有两种抗碰撞性:一种是弱抗碰撞性,即对于给定的消息,要发现另一个消息,满足在计算上是不可行的;另一种是强抗碰撞性,即对于任意一对不同的消息,使得在计算上也是不可行的。高灵敏性:这是从比特位角度出发的,指的是1比特位的输入变化会造成1/2的比特位发生变化。消息M的任何改变都会导致哈希值H(M)发生改变。即如果输入有微小不同,哈希运算后的输出一定不同。
原始信息任何微小的变化都会哈希出面目全非的摘要信息
3) 常见的哈希算法
1、SHA-1算法
SHA-1的输入是最大长度小于264位的消息,输入消息以512位的分组为单位进行处理,输出是160位的消息摘要。SHA-1具有实现速度高、容易实现、应用范围广等优点-
2、SHA-2算法
SHA-2系列Hash算法,其输出长度可取SHA-2系列哈希算法的输出长度可取224位、256位、384位、512位,分别对应SHA-224、SHA-256、SHA-384、SHA-512。它还包含另外两个算法:SHA-512/224、SHA-512/256。比之前的Hash算法具有更强的安全强度和更灵活的输出长度,其中SHA-256是常用的算法。SHA-256算法的输入是最大长度小于2^64位的消息,输出是256位的消息摘要,输入消息以512位的分组为单位进行处理。算法描述如下。
-
3、RIPEMD160算法
RIPEMD(RACE Integrity Primitives Evaluation Message Digest),即RACE原始完整性校验消息摘要。RIPEMD使用MD4的设计原理,并针对MD4的算法缺陷进行改进,1996年首次发布RIPEMD-128版本,它在性能上与SHA-1相类似。RIPEMD-160是对RIPEMD-128的改进,并且是RIPEMD中最常见的版本。RIPEMD-160输出160位的Hash值,对160位Hash函数的暴力碰撞搜索攻击需要2^80次计算,其计算强度大大提高
2、对称加密算法
- 密钥:加解密钥相同
- 缺点:无法确保密钥被安全传递
- 常用算法:DES、3DES(TripleDES)、AES等
注:这个在区块链中并不会使用
3、非对称加密算法
- 密钥:公私钥加密对,公钥加密,私钥解密
- 公钥由私钥生成,私钥可以推导出公钥,但是从公钥无法推出私钥
- 优点:解决了密钥传输中的安全问题
- 常用算法:RSA、ECC(椭圆曲线加密算法)
- 使用场景: SSH安全验证等
- 缺点:解决了信息传送的问题,但是又引入了新问题,即无法验证发送方是正确的,就是说,可能被伪造成发送方
4、数字签名
数字签名:就是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。数字签名了的文件的完整性是很容易验证的
流程:
(1) 被发送文件用密码散列函数(MD5,SHA,SM3)产生的摘要
(2) 发送方用自己的私用密钥对摘要再加密,这就形成了数字签名。
(3) 将原文和加密的摘要同时传给对方。
(4) 对方用发送方的公共密钥对摘要验签,获取发送方生成的摘要,同时对收到的文件用SHA编码加密产生又一摘要。
(5) 将解密后的摘要和收到的文件在接收方重新加密产生的摘要相互对比。如两者一致,则说明传送过程中信息没有被破坏或篡改过。否则不然。
数字签名,可以保证收到的文件没有被篡改,也可以保证发送者的身份。因为私钥生产了数字签名,私钥是不公开的。
下图中流程,是把非对称加密和数字签名结合到一起了,解决了非对称加密算法中无法验证发送方的问题(发送方要签名)。
- 密钥:私钥签名,公钥验证签名
- 使用场景: 比特币交易验证等
5、merkle树
Merkle 树是一种哈希二叉树,用于快速递归和校验大规模数据完整性,是一种平衡树(如果是奇数个交易,则多余的那个自己复制自己)
- 每个区块都包括了产生于该区块的所有交易,并且以Merkle 树表示
- H(A)=SHA256(SHA256(交易A))
- H(AB)=SHA256(SHA256(H(A)+H(B)))
- 为了证明区块中存在某个特定的交易,只需要计算log2(N)个哈希,16笔交易可以由4个哈希+Merkle树根来证明了,65535交易,只需16个哈希
区块链中每个区块都会有一个 Merkle 树,它从叶子节点(树的底部)开始,一个叶子节点就是一个交易哈希。叶子节点的数量必须是双数,但是并非每个块都包含了双数的交易。如果一个块里面的交易数为单数,那么就将最后一个叶子节点(也就是 Merkle 树的最后一个交易,不是区块的最后一笔交易)复制一份凑成双数。
从下往上,两两成对,连接两个节点哈希,将组合哈希作为新的哈希。新的哈希就成为新的树节点。重复该过程,直到仅有一个节点,也就是树根。根哈希然后就会当做是整个块交易的唯一标示,将它保存到区块头,然后用于工作量证明。
SPV : 简单支付验证,一个节点只需要仅下载区块头(80字节)+Merkle路径就能证明一笔交易的存在,这个节点称之为轻节点。
如上图,假如我们想要确定H(K)这笔交易的准确性,证明方法:
1)服务器A,轻节点,只有区块头,没有区块体,但是能够与全2节点通信,获得Merkle树的hash;
2)服务器B,全节点,区块头和区块体都有;
3)确定Merkle路径(H(L),H(IJ),H(MNOP),H(ABCDEFGH))
4)向全节点B请求数据(H(L),H(IJ),H(MNOP),H(ABCDEFGH))
5)进行验证,多次hash运算,最后跟Merkle根做hash比较
使用场景:
- 一致性检验:也被称为“一致性证明”,你可以用它验证两份日志的版本是否一致
- 数据校验:也被称为“审计证明”,这是因为它可以让你知道某一条具体的记录是否存在于日志当中。
- 数据同步:Merkle tree在分布式数据存储中的数据同步中发挥着重要的 作用,这是因为它允许分布式系统中的每个节点可以迅速高效地识别已经更改的记录而无需将发送所有的数据来进行比对。一旦树中有特定的叶节点的变更被识别,我们只需要将与该特定叶节点相关的数据上传至网络即可
6、Bloom Filter
布隆过滤器(Bloom Filter),1970 年由 Burton Howard Bloom 在论文《Space/Time Trade-offs in Hash Coding with Allowable Errors》提出。布隆过滤器是一种基于 Hash 的高效查找结构,能够快速(常数时间内)回答“某个元素是否在一个集合内”的问题。
该结构因为其高效性,被大量应用到网络和安全领域,例如信息检索(BigTable 和 HBase)、垃圾邮件规则、注册管理等。
基于 Hash 的快速查找
在布隆过滤器之前,先来看基于 Hash 的快速查找算法。在前面的讲解中,我们提到,Hash 可以将任意内容映射到一个固定长度的字符串,而且不同内容映射到相同串的概率很低。因此,这就构成了一个很好的“内容 -> 索引”的生成关系。
试想,如果给定一个内容和存储数组,通过构造 Hash 函数,让映射后的 Hash 值总不超过数组的大小,则可以实现快速的基于内容的查找。例如,内容 “hello world” 的 Hash 值如果是 “100”,则存放到数组的第 100 个单元上去。如果需要快速查找任意内容,如 “hello world” 字符串是否在存储系统中,只需要将其在常数时间内计算 Hash 值,并用 Hash 值查看系统中对应元素即可。该系统“完美地”实现了常数时间内的查找。
然而,令人遗憾的是,当映射后的值限制在一定范围(如总数组的大小)内时,会发现 Hash 冲突的概率会变高,而且范围越小,冲突概率越大。很多时候,存储系统的大小又不能无限扩展,这就造成算法效率的下降。为了提高空间利用率,后来人们基于 Hash 算法的思想设计出了布隆过滤器结构。
更高效的布隆过滤器
布隆过滤器采用了多个 Hash 函数来提高空间利用率。
对同一个给定输入来说,多个 Hash 函数计算出多个地址,分别在位串的这些地址上标记为 1。进行查找时,进行同样的计算过程,并查看对应元素,如果都为 1,则说明较大概率是存在该输入。
布隆过滤器相对单个 Hash 算法查找,大大提高了空间利用率,可以使用较少的空间来表示较大集合的存在关系。
实际上,无论是 Hash,还是布隆过滤器,基本思想是一致的,都是基于内容的编址。Hash 函数存在冲突,布隆过滤器也存在冲突。这就造成了两种方法都存在着误报(False Positive)的情况,但绝对不会漏报(False Negative)。
布隆过滤器在应用中误报率往往很低,例如,在使用 7 个不同 Hash 函数的情况下,记录 100 万个数据,采用 2 MB 大小的位串,整体的误判率将低于 1%。而传统的 Hash 查找算法的误报率将接近 10%。
布隆过滤器(Bloom Filter)的优点
相比于哈希表、链表等数据结构,其空间和时间的优势明显。而且布隆过滤器的插入、查询时间都是常数O(k),也就是说每次想要插入或查询一个元素是否在集合中时,只需要使用k个哈希函数对元素求值,并将对应的比特位标记或检查对应的比特位即可。
布隆过滤器(Bloom Filter)的缺点
一般情况下,无法从布隆过滤器中删除元素。因为在删除元素之前,我们需要确认一个元素是否在集合中,而我们知道布隆过滤器只能给出可能在集合中或者一定不在集合中的回复,而无法给出是否一定在集合中的回复。
7、零知识证明
1)定义
“零知识证明”的定义是:证明者能够在不向验证者提供任何有用的信息的情况下,使验证者相信某个论断是正确的。
举个简单的例子:
A要向B证明自己拥有某个房间的钥匙,假设该房间只能用钥匙打开锁,而其他任何方法都打不开。这时有2个方法:
(一)A把钥匙出示给B,B用这把钥匙打开该房间的锁,从而证明A拥有该房间的正确的钥匙。
(二)B确定该房间内有某一物体,A用自己拥有的钥匙打开该房间的门,然后把物体拿出来出示给B,从而证明自己确实拥有该房间的钥匙。
后面这个方法属于零知识证明。好处在于在整个证明的过程中,B始终不能看到钥匙的样子,从而避免了钥匙的泄露。
零知识证明过程有两个参与方,一方叫证明者,一方叫验证者。证明者掌握着某个秘密,他想让验证者相信他掌握着秘密,但是又不想泄漏这个秘密给验证者。
双方按照一个协议,通过一系列交互,最终验证者会得出一个明确的结论,证明者是或不是掌握这个秘密。
零知识证明是一种更加安全的信息验证或者身份验证机制。安全性和隐私性就是零知识证明的价值所在.
2)基本特性
- 完备性。如果证明方和验证方都是诚实的,并遵循证明过程的每一步,进行正确的计算,那么这个证明一定是成功的,验证方一定能够接受证明方。
- 合理性。没有人能够假冒证明方,使这个证明成功。
- 零知识性。证明过程执行完之后,验证方只获得了“证明方拥有这个知识”这条信息,而没有获得关于这个知识本身的任何一点信息。
3)零知识证明的典范Zcash
在比特币网络中,用户需要将交易明文广播给所有矿工,由他们来校验交易的合法性。但是有些情况下,基于隐私的考虑,又不想把交易的具体内容公布出来。这就形成了一对矛盾。解决这个矛盾的关键思路是:校验一个事件正确与否,并不需要验证者重现整个事件。
对于比特币的例子,一笔转帐交易合法与否,其实只要证明三件事:
- 1.发送的钱属于发送交易的人
- 2.发送者发送的金额等于接收者收到金额
- 3.发送者的钱确实被销毁了
整个证明过程中,矿工其实并不关心具体花掉了多少钱,发送者具体是谁,接受者具体是谁。矿工只关心系统的钱是不是守恒的。
zcash 就是用这个思路实现了隐私交易。
与比特币简单粗暴的“直接撕毁”不同,ZCash采用“备注作废”的手段,达到同样的效果。怎么理解呢?就是在不对原先“支票”作任何处理的前提下,新建一个作废文件列表,录入需要作废的“发票代号”。原先的Alice持有的支票仍旧存在,并没有消失,只是这张支票已经被记入“作废列表”。在确定资产所有权时要同时读取两个列表的信息,能确定Bob拥有资产所有权的判断方法是:作废列表中不存在Bob所持“支票”的代号。
在交易过程中运用 “零知识证明”
对比一下,Alice要向Bob转一个单位的数字货币(BTC/ZEC),即Alice要向Bob转移一个单位的资产所有权。这时有以下两个方法:
(一)比特币中的做法:Alice拥有一张1BTC的支票,要转账给Bob时,先给Bob新建一张1BTC的支票,同时当着Bob的面将自己原先的支票撕毁。
(二)ZCash中的做法:Alice拥有一张1ZEC的支票,要转账给Bob时,先给Bob新建一张1ZEC的支票,然后在一张约定有效的作废列表中,记录下Alice的发票的代号,证明Alice的支票已经失效。
ZCash的方法属于零知识证明。整个交易过程中,Bob并没有见过Alice的支票,但是还是实现了资产所有权的转移。在ZCash的整个交易系统中,在全网中存在的“支票”其实信息都是被加密的,可以通过拥有者的私钥解密,发票代号也是加密的,Alice和Bob的交易还有其他见证者,即负责记录交易信息的矿工。同样道理,矿工也不必看到Alice的支票,只要能确定代号为r1的支票已经作废了就行。
矿工们能获取的信息相当有限,但是这并不影响对矿工对交易有效性的判断。
判断的逻辑相当简单:矿工拿到Alice给的支票代号r1,去作废列表中检索,假如作废列表中已经存在r1,则证明r1所对应的的支票早已失效;若作废列表中并不存在r1,则证明r1对应的支票仍旧有效,此时矿工把r1录入作废列表中,把新生成的支票录入支票列表中。所以记账的过程就是对原有支票登记失效,并存入现有支票票的过程。
在这个过程中,我们不难发现,每笔交易矿工能接收到的东西只有一个发票代号,和一张新的发票,而且这两样东西都是被加密的。所以矿工并不知道转账双方是谁,也不知道转账金额是多少。
4)、零知识证明的优缺点
首先,要实现匿名性,其所需要的证明信息所花费的计算资源就非常多,带来了大量的资源浪费,也导致了其可扩展性面临巨大挑战。
另外,匿名性会带来大量的额外监管问题,一旦有不法份子利用其用户黄、赌、毒等违法领域,将会给追踪与监管带来非常大的挑战,造成一系列社会问题。
尽管技术实现难度最高,但在保护在以太坊网络的隐私性和安全性上,其效果最佳。Vitalik还认为,零知识证明能够被应用于以太坊区块链上几乎所有的场景。