
RIPEMD-160是一种基于Merkle-Damgård结构的加密哈希函数,它是比特币标准之一。RIPEMD-160是RIPEMD算法的增强版本,RIPEMD算法可以产生128位(128 bits)的哈希摘要,而RIPEMD-160算法可以产生出160位的输出。压缩过程的函数由80个阶段组成,这80个阶段由5个代码块组成,每个代码块运行16次。上文所述的80个阶段会运行两次,在最后使用模32加法合并来生成结果。
填充
压缩功能被用于处理16个32位无符号字节。所以,想要执行压缩功能,就需要将消息大小填充为512(16*32)位的倍数,并将字节流输入填充为32位的字节。填充方案与MD4相同,使用Merkle-Damgård以防止长度扩展攻击。填充的过程包括将一个1添加到消息末尾,以及将消息长度(以位为单位)添加到填充后的块的末尾。字节首先被推入字下方。以下是将消息填充到单词中的 4 个示例,以显示不同消息长度的可能结果:
然后,应将消息的长度添加到倒数第二个元素(长度被保存为跨最后2个字的64位值,但消息不太可能会有这么长;32位对于比特币软件肯定就足够了。)
压缩功能
压缩函数由可变子块组成,消息块会经过该子块16次。可变子块有5种不同的变体,故子块总共运行80次。这个过程会进行两次,最后得到的数据将在底部相遇,如果存在下一个子块的话,则将数据移动到下一个子块,如果没有,则将数据添加到哈希寄存器。可以通过改变非线性函数的设计、每轮读取消息块的顺序、左旋转的量和常数k,来改变可变子块。子块的设计和压缩功能的整体布局如下图所示。
压缩函数的子块
完整的压缩功能
此过程的伪代码如下:
for(i := 0 to blocks - 1) { aLeft := h0 bLeft := h1 cLeft := h2 dLeft := h3 eLeft := h4 aRight := h0 bRight := h1 cRight := h2 dRight := h3 eRight := h4 for(int j := 0 to 79) { t := rotleft(s[j]) (aLeft + f(bLeft, cLeft, dLeft) + X[r[i]]) + eLeft aLeft := eLeft; eLeft := dLeft dLeft := rotleft(10) (c) cLeft := bLeft bLeft := t Do same for right } t := h1 + cLeft + dRight h1 := h2 + dLeft + eRight h2 := h3 + eLeft + aRight h3 := h4 + aLeft + bRight h4 := h0 + bLeft + cRight h0 := t }
非线性函数以相反的方向运行。函数被设计为,在左侧自上至下运行,在右侧自下至上运行。函数的具体形式为(Java操作语法):
- x ^ y ^ z
- (x & y) | (~x & z)
- (x | ~y) ^ z
- (x & z) | (y & ~z)
- z ^ (y | ~z)
左边的k值,从上到下是:
- 0x00000000
- 0x5A827999
- 0x6ED9EBA1
- 0X8F1BBCDC
- 0XA953FD4E
右边的k值,从上到下是:
- 0x50A28BE6
- 0x5C4DD124
- 0x6D703EF3
- 0x7A6D76E9
- 0x00000000
从数组X列中选择单词,并放置在左侧区域的顺序是(二维数组中的每个子数组代表一轮。在顶部的数组,代表顶部的轮,在底部的数组,代表底部的轮):
{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, //Round 1 {7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8}, //Round 2 {3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12}, //Round 3 {1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2}, //Round 4 {4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13}} //Round 5
从数组X列中选择单词,并放置在右侧区域的顺序是(遵循与上述相同的模式):
{{5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12}, //Round 1 {6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2}, //Round 2 {15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13}, //Round 3 {8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14}, //Round 4 {12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11}} //Round 5
左侧向左手方向旋转后的顺序是:
{{11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8}, //Round 1 {7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12}, //Round 2 {11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5}, //Round 3 {11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12}, //Round 4 {9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6}} //Round 5
左侧向右手方向旋转后的顺序是:
{{8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6}, //Round 1 {9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11}, //Round 2 {9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5}, //Round 3 {15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8}, //Round 4 {8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11}}; //Round 5