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 };