Blake算法从2008年被提出起,已经逐步进化到Blake2及Blake3,该系列算法被广泛应用于数字货币领域,本文以Blake及Blake2为例详细的介绍了该算法。
1 简介
哈希算法 (Hash Algorithm) 是将任意长度的数据映射为固定长度数据的算法,也称为消息摘要。
一般情况下,哈希算法有两个特点:
- 原始数据的细微变化(比如一个位翻转)会导致结果产生巨大差距
- 运算过程不可逆,理论上无法从结果还原输入数据
因此,哈希算法主要用于数据完整性校验和加密/签名。而哈希算法的安全性就在于碰撞难易度,即已知结果,构建出具有相同结果的输入数据的难易度。
2 BLAKE
BLAKE算法于2008年提出,它包含两个版本,一种基于32位word用于产生最长256位的哈希结果,一种基于64位word用于产生最长512位的哈希结果,BLAKE算法核心操作是不断地将8个散列中间结果和16个输入word进行组合,从而产生下一轮组合的8个中间结果。按照最终截断的哈希长度,BLAKE-256和BLAKE-224使用32位字分别产生256位和224位的哈希结果(也称消息摘要),而BLAKE-512和BLAKE-384使用64位字并产生512位和384位哈希结果。算法核心变量如下:
1 typedef struct
2 {
3 uint32_t h[8], s[4], t[2];
4 int buflen, nullt;
5 uint8_t buf[64];
6 } state256;
7
8 typedef state256 state224;
9
10 typedef struct
11 {
12 uint64_t h[8], s[4], t[2];
13 int buflen, nullt;
14 uint8_t buf[128];
15 } state512;
16
17 typedef state512 state384;
18
19 const uint8_t sigma[][16] =
20 {
21 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
22 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
23 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
24 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
25 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
26 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
27 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
28 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
29 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
30 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
31 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
32 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
33 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
34 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
35 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
36 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }
37 };
38
39 const uint32_t u256[16] =
40 {
41 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
42 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
43 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
44 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917
45 };
46
47 const uint64_t u512[16] =
48 {
49 0x243f6a8885a308d3ULL, 0x13198a2e03707344ULL,
50 0xa4093822299f31d0ULL, 0x082efa98ec4e6c89ULL,
51 0x452821e638d01377ULL, 0xbe5466cf34e90c6cULL,
52 0xc0ac29b7c97c50ddULL, 0x3f84d5b5b5470917ULL,
53 0x9216d5d98979fb1bULL, 0xd1310ba698dfb5acULL,
54 0x2ffd72dbd01adfb7ULL, 0xb8e1afed6a267e96ULL,
55 0xba7c9045f12c7f99ULL, 0x24a19947b3916cf7ULL,
56 0x0801f2e2858efc16ULL, 0x636920d871574e69ULL
57 };
58
59
60 static const uint8_t padding[129] =
61 {
62 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
68 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
70 };
blake
blake256核心计算过程如下:
1 void blake256_compress( state256 *S, const uint8_t *block )
2 {
3 uint32_t v[16], m[16], i;
4 #define ROT(x,n) (((x)<<(32-n))|( (x)>>(n)))
5 #define G(a,b,c,d,e) \
6 v[a] += (m[sigma[i][e]] ^ u256[sigma[i][e+1]]) + v[b]; \
7 v[d] = ROT( v[d] ^ v[a],16); \
8 v[c] += v[d]; \
9 v[b] = ROT( v[b] ^ v[c],12); \
10 v[a] += (m[sigma[i][e+1]] ^ u256[sigma[i][e]])+v[b]; \
11 v[d] = ROT( v[d] ^ v[a], 8); \
12 v[c] += v[d]; \
13 v[b] = ROT( v[b] ^ v[c], 7);
14
15 for( i = 0; i < 16; ++i ) m[i] = U8TO32_BIG( block + i * 4 );
16
17 for( i = 0; i < 8; ++i ) v[i] = S->h[i];
18
19 v[ 8] = S->s[0] ^ u256[0];
20 v[ 9] = S->s[1] ^ u256[1];
21 v[10] = S->s[2] ^ u256[2];
22 v[11] = S->s[3] ^ u256[3];
23 v[12] = u256[4];
24 v[13] = u256[5];
25 v[14] = u256[6];
26 v[15] = u256[7];
27
28 /* don't xor t when the block is only padding */
29 if ( !S->nullt )
30 {
31 v[12] ^= S->t[0];
32 v[13] ^= S->t[0];
33 v[14] ^= S->t[1];
34 v[15] ^= S->t[1];
35 }
36
37 for( i = 0; i < 14; ++i )
38 {
39 /* column step */
40 G( 0, 4, 8, 12, 0 );
41 G( 1, 5, 9, 13, 2 );
42 G( 2, 6, 10, 14, 4 );
43 G( 3, 7, 11, 15, 6 );
44 /* diagonal step */
45 G( 0, 5, 10, 15, 8 );
46 G( 1, 6, 11, 12, 10 );
47 G( 2, 7, 8, 13, 12 );
48 G( 3, 4, 9, 14, 14 );
49 }
50
51 for( i = 0; i < 16; ++i ) S->h[i % 8] ^= v[i];
52
53 for( i = 0; i < 8 ; ++i ) S->h[i] ^= S->s[i % 4];
54 }
blake256_compress
BLAKE-224("") =
7dc5313b1c04512a174bd6503b89607aecbee0903d40a8a569c94eed
BLAKE-256("") =
716f6e863f744b9ac22c97ec7b76ea5f5908bc5b2f67c61510bfc4751384ea7a
BLAKE-384("") =
c6cbd89c926ab525c242e6621f2f5fa73aa4afe3d9e24aed727faaadd6af38b620bdb623dd2b4788b1c8086984af8706
BLAKE-512("") =
a8cfbbd73726062df0c6864dda65defe58ef0cc52a5625090fa17601e1eecd1b628e94f396ae402a00acc9eab77b4d4c2e852aaaa25a636d80af3fc7913ef5b8
3 BLAKE2
BLAKE2算法基于BLAKE算法,于2012年被提出,BLAKE2不再向blake round函数中对输入字添加常量,修改了两个旋转常量及padding等,并在BLAKE2b(对应BLAKE-512)中将rounds的数量由16减少为12,在BLAKE2s(对应BLAKE-256)中将rounds数量由14减少为10,同样的,BLAKE2b产生1到64字节的消息摘要,BLAKE2s产生1到32字节的消息摘要,同时这两种算法也由对应的多核并行版本BLAKE2bp(4路并行)和BLAKE2sp(8路并行)。除了以上几种算法变种,BLAKE2还有一种BLAKE2x的变种,这种算法可以产生任意长度的消息摘要,详情请参考相应文档。除了安全性方面的优势,据称BLAKE2算法在Intel CPU第六代微处理架构(Skylake)中的处理速度要优于MD5,SHA-1,SHA-2和SHA-3等算法,如图所示:
BLAKE2源码可以参考:https://github.com/BLAKE2/BLAKE2,类似的,BLAKE2对空字符串的哈希结果如下:
BLAKE2s-224("") =
1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4
BLAKE2s-256("") =
69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9
BLAKE2b-384("") =
b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100
BLAKE2b-512("") =
786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce