区块[db:标签]技术的一个重要组件是将哈希函数用于许多操作。哈希是一种将哈希函数应用于数据的方法,其为几乎任何大小的输入(例如,文件,文本或图像)计算相对独特的输出(称为消息digest,或仅仅是digest)。它允许个人独立地获取输入数据、散列数据并得出相同的结果 – 证明数据没有变化。即使对输入的最小改变(例如,改变单个位)也将导致完全不同的输出。表1显示了这方面的简单例子。
哈希函数具有以下重要的安全属性:
- 它们具有逆向抗性。这意味着它们是单向的; 在给定一些输出值的情况下计算正确的输入值在计算上是不可行的(例如,给定digest,找到x使得hash(x)=digest)。
- 它们具有第二逆向抗性。这意味着无法找到哈希到特定输出的输入。更具体地,设计哈希函数以便在给定特定输入的情况下,找到产生相同输出的第二输入(例如,给定x,找到y使得hash(x)=hash(y))在计算上是不可行的。可用的唯一方法是穷举搜索输入空间,但这没有任何成功的可能。
- 它们具有抗冲击性。这意味着找不到两个散列到同一输出的输入。更具体地,找到产生相同digest的任何两个输入在计算上是不可行的(例如,找到hash(x)=hash(y)的x和y)。
在许多区块链实现中使用的特定哈希函数是安全哈希算法(SHA),其输出大小为256位(SHA-256)。许多计算机在硬件中支持该算法,使其计算速度快。SHA-256的输出为32字节(1字节= 8位,32字节= 256位),通常显示为64字符的十六进制字符串(参见下面的表1)。
这意味着有2256≈1077,或115,792,089,237,316,195,423,570,985,008,687,907,853,269,984,665,640,564,039,457,584,007,913,129,639,936可能的digest值。SHA-256的算法以及其他算法在联邦信息处理标准(FIPS)180-4 [中规定。NIST Secure Hashing网站包含所有NIST批准的散列算法的FIPS规范。
输入文本 |
SHA-256 digest结果 |
1 | 0x6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b |
2 | 0xd4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35 |
Hello, World! | 0xdffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f |
由于存在无限数量的可能输入值和有限数量的可能输出digest值,因此很可能发生冲突,其中hash(x)= hash(y)(即两个不同的哈希值)输入产生相同的digest)。据说SHA-256具有抗冲突能力,因为要在SHA-256中发现碰撞,人们必须平均执行该算法大约2128次(即340次无衰减,或者更确切地说是340,282,366,920,938,463,463,374,607,431,768,211,456;大约3.402 x 1038) 。
从这个角度来看,2015年整个比特币网络的哈希率(每秒哈希值)为每秒300万亿哈希(300,000,000,000,000,000 / s)。按照这个速度,整个比特币网络需要大约35,942,991,748,521(大约3.6 x 1013)年来制造碰撞(注意宇宙估计为1.37 x 1010年)。即使产生相同digest的任何此类输入x和y,两个输入也很可能在区块链网络的上下文中无效(即,x和y都是有效的事务)。
在区块链网络中,哈希函数用于许多任务,例如:
- 地址推导。
- 创建唯一标识符。
- 保护块数据 – 发布节点将对块数据进行哈希,创建将存储在块头中的digest。
- 保护块头 – 发布节点将对块头进行哈希。如果区块链网络使用工作证明共识模型,则发布节点将需要使用不同的随机数值对块头进行哈希,直到满足拼图要求为止。当前块头的散列digest将包含在下一个块的头中时,它将保护当前块头数据。
因为块头包括块数据的哈希表示,所以当块头digest存储在下一个块中时,块数据本身也是安全的。
区块链技术中使用了许多哈希函数族(SHA-256不是唯一的),例如Keccak(由NIST选择作为创建SHA-3哈希标准的竞赛的获胜者),以及作为RIPEMD-160。