区块链100讲:听说,80%的人都搞不懂哈希算法

image

前面的《区块链100讲》介绍了区块链、算力、挖矿等,几乎每一讲都会提到一个词哈希(Hashing)。聊到区块链的时候也少不了会听到“哈希”、“哈希函数”、“哈希算法”,是否是听得一头雾水?别急,这一讲咱们来说讲什么是哈希算法。算法

1

哈希是一种加密算法

哈希函数(Hash Function),也称为散列函数或杂凑函数。哈希函数是一个公开函数,能够将任意长度的消息M映射成为一个长度较短且长度固定的值H(M),称H(M)为哈希值、散列值(Hash Value)、杂凑值或者消息摘要(Message Digest)。它是一种单向密码体制,即一个从明文到密文的不可逆映射,只有加密过程,没有解密过程。缓存

它的函数表达式为:h=H(m)安全

不管输入是什么数字格式、文件有多大,输出都是固定长度的比特串。以比特币使用的Sh256算法为例,不管输入是什么数据文件,输出就是256bit。微信

每一个bit就是一位0或者1,256bit就是256个0或者1二进制数字串,用16进制数字表示的话,就是多少位呢?函数

16等于2的4次方,因此每一位16进制数字能够表明4位bit。那么,256位bit用16进制数字表示,固然是256除以4等于64位。性能

因而你一般看到的哈希值,就是这样的了:学习

00740f40257a13bf03b40f54a9fe398c79a664bb21cfa2870ab07888b21eeba8。区块链

这是从btc.com上随便拷贝的一个哈希值,不放心的话你能够数一下,是否是64位~编码

2

Hash函数的特色

Hash函数具备以下特色。加密

  • 易压缩:对于任意大小的输入x,Hash值的长度很小,在实际应用中,函数H产生的Hash值其长度是固定的。

  • 易计算:对于任意给定的消息,计算其Hash值比较容易。

  • 单向性:对于给定的Hash值,要找到使得在计算上是不可行的,即求Hash的逆很困难。在给定某个哈希函数H和哈希值H(M)的状况下,得出M在计算上是不可行的。即从哈希输出没法倒推输入的原始数值。这是哈希函数安全性的基础。

  • 抗碰撞性:理想的Hash函数是无碰撞的,但在实际算法的设计中很难作到这一点。

    有两种抗碰撞性:一种是弱抗碰撞性,即对于给定的消息,要发现另外一个消息,知足在计算上是不可行的;另外一种是强抗碰撞性,即对于任意一对不一样的消息,使得在计算上也是不可行的。

  • **高灵敏性:**这是从比特位角度出发的,指的是1比特位的输入变化会形成1/2的比特位发生变化。消息M的任何改变都会致使哈希值H(M)发生改变。即若是输入有微小不一样,哈希运算后的输出必定不一样。

3

哈希算法

把网址A,转换成数字1。网址B,转换成数字2。

一个网址X,转换成数字N,根据数字N做为下标,就能够快速地查找出网址X的信息。这个转换的过程就是哈希算法。

好比这里有一万首歌,给你一首新的歌X,要求你确认这首歌是否在那一万首歌以内。

无疑,将一万首歌一个一个比对很是慢。但若是存在一种方式,能将一万首歌的每首数据浓缩到一个数字(称为哈希码)中,因而获得一万个数字,那么用一样的算法计算新的歌X的编码,看看歌X的编码是否在以前那一万个数字中,就能知道歌X是否在那一万首歌中。

做为例子,若是要你组织那一万首歌,一个简单的哈希算法就是让歌曲所占硬盘的字节数做为哈希码。这样的话,你可让一万首歌“按照大小排序”,而后遇到一首新的歌,只要看看新的歌的字节数是否和已有的一万首歌中的某一首的字节数相同,就知道新的歌是否在那一万首歌以内了。

一个可靠的哈希算法,应该知足:

  • 对于给定的数据M,很容易算出哈希值X=F(M);

  • 根据X很难反算出M;

  • 很难找到M和N使得F(N)=F(M)

前面提到哈希函数具备抗碰撞性,碰撞性就是指有人实现找出一奇一偶使得哈希结果一致,但这在计算上是不可行的。

首先,把大空间的消息压缩到小空间上,碰撞确定是存在的。假设哈希值长度固定为256位,若是顺序取1,2,…2^256+1, 这2^256+1个输入值,逐一计算其哈希值,确定能找到两个输入值使得其哈希值相同。但不要高兴的太早,由于你得有时间把它算出来,才是你的。

根据生日悖论,若是随机挑选其中的2^128+1输入,则有99.8%的几率发现至少一对碰撞输入。那么对于哈希值长度为256位的哈希函数,平均须要完成2^128次哈希计算,才能找到碰撞对。若是计算机每秒进行10000次哈希计算,须要约10^27年才能完成2^128次哈希计算。在区块链中,哈希函数的抗碰撞性用来作区块和交易的完整性验证,一有篡改就能被识别出来。

前面提到挖矿须要矿工经过随机数不断计算获得小于给定难度值的数值。**难度值(difficulty)**是矿工们挖矿时的重要参考指标,它决定了矿工大约须要通过多少次哈希运算才能产生一个合法的区块。比特币的区块大约每10分钟生成一个,为了让新区块的产生基本保持这个速率,难度值必须根据全网算力的变化进行调整。

哈希函数经过调整难度值来确保每一个区块挖出的时间都大约在10分钟,哈希函数计算的难度值对保证区块链系统的安全意义重大。正如美国的几位计算机科学家在共同所著的书中所写的:“哈希密码是密码学中的瑞士军刀,它们在众多各具特点的应用中找到了一席之地,为了保证安全,不一样的应用会要求不一样的哈希函数特色。事实已经证实,要肯定一系列哈希函数以全面达成可证安全极度困难。”

工做量证实须要有一个目标值。比特币工做量证实的目标值(target)的计算公式以下:

目标值=最大目标值 / 难度值

其中,最大目标值为一个恒定值:

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

**目标值的大小与难度值成反比。**比特币工做量证实的达成就是矿工计算出来的区块哈希值必须小于目标值。

咱们也能够简单理解成,比特币工做量证实的过程,就是经过不停地变换区块头(即尝试不一样的随机值)做为输入进行SHA256哈希运算,找出一个特定格式哈希值的过程(即要求有必定数量的前导0)。而要求的前导0的个数越多,表明难度越大。

4

举个栗子帮助理解

▌场景1、小星和阿呆在篮球场

小星:阿呆,你是否是口渴了,你要不要去买水喝,顺便帮我买一瓶哈。

阿呆:呵呵,你的当心思我还不知道,你本身也口渴了吧,你去,我不去。

小星:哎哎,我们不扯这些没用的,来抛硬币,好很差,正面你去,反面我去,公平吧,如何?

阿呆:好吧。

………

▌场景2、小星与阿呆即时聊天中

阿呆:小星,今天来我家玩,来的路上,有一家披萨店,很好吃,顺便带一点哈。

小星:哦,要不你来我家玩吧,你顺便带上披萨。

阿呆:小星,你居然都这么说了,看来只能抛硬币解决了。

小星:丫的,这个怎么抛,我怎么知道你有没有搞鬼。

阿呆:嗯,那到也是,要不这样。

1.考虑对结果加密

阿呆:我心中想一个数,假设为A,而后A在乘以一个数B,获得结果C。A是个人密钥,我把结果C告诉你。你来猜A是奇数仍是偶数,猜中了,算你赢。

小星:这不行,若是你告诉我C是12,我猜A是奇数,你能够说A是4,B是3。我猜A是偶数,你能够说A是3,B是4。要不你告诉我C是多少的时候,也告诉我B是多少。

阿呆:那这不行,告诉你C和B,不等于告诉你A是多少了,还猜个屁。不行得换个方式。

2.不可逆加密

阿呆:小星,你看这样能够不,我想一个A,通过下面的过程:

1.A+123=B 2.B^2=C 3.取C中第2~4位数,组成一个3位数D 4.D/12的结果求余数,获得E

阿呆:我把E和上述计算方式都告诉你,你猜A是奇数仍是偶数,而后我告诉你A是多少,你能够按上述的计算过程来验证我是否有说谎。

小星:嗯,我想一想,假如阿呆你想的A为5,那么:

5+123=128 128^2=16384 D=638 E=638mod12=53

(mod表示除法的求余数)

小星:咦,厉害了,一个A值对应一个惟一的E值,根据E还推算不出来A。你太贱了,好吧,这个算公平,谁撒谎都能被识别出来。

小星:阿呆,你出题吧 ……

这种丢掉一部分信息的加密方式称为“单向加密”,也叫哈希算法。

5

常见的哈希算法

一、SHA-1算法

SHA-1的输入是最大长度小于2<sup>64</sup>位的消息,输入消息以512位的分组为单位进行处理,输出是160位的消息摘要。SHA-1具备实现速度高、容易实现、应用范围广等优势,其算法描述以下。

  • **对输入的消息进行填充:**通过填充后,消息的长度模512应与448同余。填充的方式为第一位是1,余下各位都为0。再将消息被填充前的长度以big-endian的方式附加在上一步留下的最后64位中。该步骤是必须的,即便消息的长度已是所但愿的长度。填充的长度范围是1到512。

  • 初始化缓冲区:能够用160位来存放Hash函数的初始变量、中间摘要及最终摘要,但首先必须进行初始化,对每一个32位的初始变量赋值,即:

image

  • 进入消息处理主循环,处理消息块:一次处理512位的消息块,总共进行4轮处理,每轮进行20次操做,如图所示。这4轮处理具备相似的结构,但每轮所使用的辅助函数和常数都各不相同。每轮的输入均为当前处理的消息分组和缓冲区的当前值A、B、C、D、E,输出仍放在缓冲区以替代旧的A、B、C、D、E的值。第四轮的输出再与第一轮的输入CV<sub>q</sub>相加,以产生CV<sub>q</sub><sub>+1</sub>,其中加法是缓冲区5个字CV<sub>q</sub>中的每一个字与中相应的字模2<sup>32</sup>相加。

image

图 单个512位消息块的处理流程

  • 输出:全部的消息分组都被处理完以后,最后一个分组的输出即为获得的消息摘要值。

SHA-1的步函数如图所示,它是SHA-1最为重要的函数,也是SHA-1中最关键的部件。

image

图 SHA-1的步函数

SHA-1每运行一次步函数,A、B、C、D的值就会依次赋值给B、C、D、E这几个寄存器。同时,A、B、C、D、E的输入值、常数和子消息块在通过步函数运算后就会赋值给A。

image

其中,t是步数,0≤t≤79,W<sub>t</sub>是由当前512位长的分组导出的一个32位的字,K<sub>t</sub>是加法常量。

基本逻辑函数f的输入是3个32位的字,输出是一个32位的字,其函数表示以下。

image

image

对于每一个输入分组导出的消息分组w<sub>t</sub>,前16个消息字w<sub>t</sub>(0≤t≤15)即为消息输入分组对应的16个32位字,其他w<sub>t</sub>(0≤t≤79)可按以下公式获得:

image

其中,ROTL<sub>s</sub>表示左循环移位s位,如图所示。

image

图 SHA-1的80个消息字的产生过程

二、SHA-2算法

SHA-2系列Hash算法,其输出长度可取SHA-2系列哈希算法的输出长度可取224位、256位、384位、512位,分别对应SHA-22四、SHA-25六、SHA-38四、SHA-512。它还包含另外两个算法:SHA-512/22四、SHA-512/256。比以前的Hash算法具备更强的安全强度和更灵活的输出长度,其中SHA-256是经常使用的算法。下面将对前四种算法进行简单描述。

SHA-256算法

SHA-256算法的输入是最大长度小于2<sup>64</sup>位的消息,输出是256位的消息摘要,输入消息以512位的分组为单位进行处理。算法描述以下。

(1)消息的填充

添加一个“1”和若干个“0”使其长度模512与448同余。在消息后附加64位的长度块,其值为填充前消息的长度。从而产生长度为512整数倍的消息分组,填充后消息的长度最多为2<sup>64</sup>位。

(2)初始化连接变量

连接变量的中间结果和最终结果存储于256位的缓冲区中,缓冲区用8个32位的寄存器A、B、C、D、E、F、G和H表示,输出仍放在缓冲区以代替旧的A、B、C、D、E、F、G、H。首先要对连接变量进行初始化,初始连接变量存储于8个寄存器A、B、C、D、E、F、G和H中:

image

初始连接变量是取自前8个素数(二、三、五、七、十一、1三、1七、19)的平方根的小数部分其二进制表示的前32位。

(3)处理主循环模块

消息块是以512位分组为单位进行处理的,要进行64步循环操做(如图所示)。每一轮的输入均为当前处理的消息分组和获得的上一轮输出的256位缓冲区A、B、C、D、E、F、G、H的值。每一步中均采用了不一样的消息字和常数,下面将给出它们的获取方法。

image

 图 SHA-256的压缩函数

(4)得出最终的Hash值

全部512位的消息块分组都处理完之后,最后一个分组处理后获得的结果即为最终输出的256位的消息摘要。

步函数是SHA-256中最为重要的函数,也是SHA-256中最关键的部件。其运算过程如图所示。

image

 图 SHA-256的步函数

image

根据T<sub>1</sub>、T<sub>2</sub>的值,对寄存器A、E进行更新。A、B、C、E、F、G的输入值则依次赋值给B、C、D、F、G、H。

image

image

K<sub>t</sub>的获取方法是取前64个素数(2,3,5,7,……)立方根的小数部分,将其转换为二进制,而后取这64个数的前64位做为K<sub>t</sub>。其做用是提供了64位随机串集合以消除输入数据里的任何规则性。

对于每一个输入分组导出的消息分组W<sub>t</sub>,前16个消息字W<sub>t</sub>(0≤t≤15)直接按照消息输入分组对应的16个32位字,其余的则按照以下公式来计算得出:

image

图 SHA-256的64个消息字的生成过程

SHA-512算法

SHA-512是SHA-2中安全性能较高的算法,主要由明文填充、消息扩展函数变换和随机数变换等部分组成,初始值和中间计算结果由8个64位的移位寄存器组成。该算法容许输入的最大长度是2<sup>128</sup>位,并产生一个512位的消息摘要,输入消息被分红若干个1024位的块进行处理,具体参数为:消息摘要长度为512位;消息长度小于2<sup>128</sup>位;消息块大小为1024位;消息字大小为64位;步骤数为80步。下图显示了处理消息、输出消息摘要的整个过程,该过程的具体步骤以下。

image

 图 SHA-512的总体结构

  • 消息填充:填充一个“1”和若干个“0”,使其长度模1024与896同余,填充位数为0-1023,填充前消息的长度以一个128位的字段附加到填充消息的后面,其值为填充前消息的长度。

  • 连接变量初始化:连接变量的中间结果和最终结果都存储于512位的缓冲区中,缓冲区用8个64位的寄存器A、B、C、D、E、F、G、H表示。初始连接变量也存储于8个寄存器A、B、C、D、E、F、G、H中,其值为:

image

初始连接变量采用big-endian方式存储,即字的最高有效字节存储于低地址位置。初始连接变量取自前8个素数的平方根的小数部分其二进制表示的前64位。

  • 主循环操做:以1024位的分组为单位对消息进行处理,要进行80步循环操做。每一次迭代都把512位缓冲区的值A、B、C、D、E、F、G、H做为输入,其值取自上一次迭代压缩的计算结果,每一步计算中均采用了不一样的消息字和常数。

  • 计算最终的Hash值:消息的全部N个1024位的分组都处理完毕以后,第N次迭代压缩输出的512位连接变量即为最终的Hash值。

步函数是SHA-512中最关键的部件,其运算过程相似SHA-256。每一步的计算方程以下所示,B、C、D、F、G、H的更新值分别是A、B、C、E、F、G的输入状态值,同时生成两个临时变量用于更新A、E寄存器。

image

对于80步操做中的每一步t,使用一个64位的消息字W<sub>t</sub>,其值由当前被处理的1024位消息分组M<sub>i</sub>导出,导出方法如图所示。前16个消息字W<sub>t</sub>(0≤t≤15)分别对应消息输入分组以后的16个32位字,其余的则按照以下公式来计算得出:

image

 图 SHA-512的80个消息字生成的过程

其中,

image

式中,ROTR<sup>n</sup>(X)表示对64位的变量x循环右移n位,SHR<sup>n</sup>(X)表示对64位的变量x右移n位。

从图能够看出,在前16步处理中,W<sub>t</sub>的值等于消息分组中相对应的64位字,而余下的64步操做中,其值是由前面的4个值计算获得的,4个值中的两个要进行移位和循环移位操做。

K<sub>t</sub>的获取方法是取前80个素数(2,3,5,7,……)立方根的小数部分,将其转换为二进制,而后取这80个数的前64位做为K<sub>t</sub>,其做用是提供了64位随机串集合以消除输入数据里的任何规则性。

SHA-224与SHA-384

SHA-256和SHA-512是很新的Hash函数,前者定义一个字为32位,后者则定义一个字为64位。实际上两者的结构是相同的,只是在循环运行的次数、使用常数上有所差别。SHA-224及SHA-384则是前述两种Hash函数的截短型,它们利用不一样的初始值作计算。

SHA-224的输入消息长度跟SHA-256的也相同,也是小于2<sup>64</sup>位,其分组的大小也是512位,其处理流程跟SHA-256也基本一致,可是存在以下两个不一样的地方。

  • SHA-224的消息摘要取自A、B、C、D、E、F、G共7个寄存器的比特字,而SHA-256的消息摘要取自A、B、C、D、E、F、G、H共8个寄存器的32比特字。

  • SHA-224的初始连接变量与SHA-256的初始连接变量不一样,它采用高端格式存储,但其初始连接变量的获取方法是取前第9至16个素数(2三、2九、3一、3七、4一、4三、4七、53)的平方根的小数部分其二进制表示的第二个32位,SHA-224的初始连接变量以下:

image

SHA-224的详细计算步骤与SHA-256一致。

SHA-384的输入消息长度跟SHA-512相同,也是小于2<sup>128</sup>位,并且其分组的大小也是1024位,处理流程跟SHA-512也基本一致,可是也有以下两处不一样的地方。

  • SHA-384的384位的消息摘要取自A、B、C、D、E、F共6个64比特字,而SHA-512的消息摘要取自A、B、C、D、E、F、G、H共8个64比特字。

  • SHA-384的初始连接变量与SHA-512的初始连接变量不一样,它也采用高端格式存储,但其初始连接变量的获取方法是取前9至16个素数(2三、2九、3一、3七、4一、4三、4七、53)的平方根的小数部分其二进制表示的前64位,SHA-384的初始连接变量以下:

image

SHA-384的详细计算步骤与SHA-512的相同。

三、SHA-3算法

SHA-3算法总体采用Sponge结构,分为吸取和榨取两个阶段。SHA-3的核心置换f做用在5×5×64的三维矩阵上。整个f共有24轮,每轮包括5个环节θ、ρ、π、χ、τ。算法的5个环节分别做用于三维矩阵的不一样维度之上。θ环节是做用在列上的线性运算;ρ环节是做用在每一道上的线性运算,将每一道上的64比特进行循环移位操做;π环节是将每道上的元素总体移到另外一道上的线性运算;χ环节是做用在每一行上的非线性运算,至关于将每一行上的5比特替换为另外一个5比特;τ环节是加常数环节。

目前,公开文献对SHA-3算法的安全性分析主要是从如下几个方面来展开的。

  • 对SHA-3算法的碰撞攻击、原像攻击和第二原像攻击。

  • 对SHA-3算法核心置换的分析,这类分析主要针对算法置换与随机置换的区分来展开。

  • 对SHA-3算法的差分特性进行展开,主要研究的是SHA-3置换的高几率差分链,并构筑差分区分器。

Keccak算法的立体加密思想和海绵结构,使SHA-3优于SHA-2,甚至AES。Sponge函数可创建从任意长度输入到任意长度输出的映射。

四、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<sup>80</sup>次计算,其计算强度大大提升。RIPEMD-160的设计充分吸收了MD四、MD五、RIPEMD-128的一些性能,使其具备更好的抗强碰撞能力。它旨在替代128位Hash函数MD四、MD5和RIPEMD。

RIPEMD-160使用160位的缓存区来存放算法的中间结果和最终的Hash值。这个缓存区由5个32位的寄存器A、B、C、D、E构成。寄存器的初始值以下所示:

image

数据存储时采用低位字节存放在低地址上的形式。

处理算法的核心是一个有10个循环的压缩函数模块,其中每一个循环由16个处理步骤组成。在每一个循环中使用不一样的原始逻辑函数,算法的处理分为两种不一样的状况,在这两种状况下,分别以相反的顺序使用5个原始逻辑函数。每个循环都以当前分组的消息字和160位的缓存值A、B、C、D、E为输入获得新的值。每一个循环使用一个额外的常数,在最后一个循环结束后,两种状况的计算结果A、B、C、D、E和A′、B′、C′、D′、E′及连接变量的初始值通过一次相加运算产生最终的输出。对全部的512位的分组处理完成以后,最终产生的160位输出即为消息摘要。

除了128位和160位的版本以外,RIPEMD算法也存在256位和320位的版本,它们共同构成RIPEMD家族的四个成员:RIPEMD-12八、RIPEMD-160、RIPEMD-25六、RIPEMD-320。其中128位版本的安全性已经受到质疑,256位和320位版本减小了意外碰撞的可能性,可是相比于RIPEMD-128和RIPEMD-160,它们不具备较高水平的安全性,由于他们只是在128位和160位的基础上,修改了初始参数和s-box来达到输出为256位和320位的目的。

内容来源:

公众号:区块链及加密货币研究、EXV星球、区块链艾迪生

华章图书:《连接将来:迎接区块链与数字资产的新时代》《区块链开发指南》

补充阅读:区块链100讲:从村里的帐原本看什么是区块链

区块链100讲:区块链为何叫“区块”“链”?

区块链100讲:总被提起的拜占庭问题究竟是什么鬼?

区块链100讲:世界银行说,比特币给各国央行打了个样

区块链100讲:用来抨击区块链的算力浪费,究竟是浪费了什么?

区块链100讲:知乎千赞回答讲清挖矿过程

区块链100讲:单挑or群殴,两种挖矿方式你要怎么选?

区块链最全书单|深聊了50个微信群,学习区块链必读这20本书

看了400多份白皮书,回归本质谈区块链技术(附所有白皮书下载连接)

如下是咱们的社区介绍,欢迎各类合做、交流、学习:)

image

相关文章
相关标签/搜索