SM3密码杂凑算法 - Tue, Oct 5, 2021
SM3密码杂凑算法
1. 填充
假设消息m 的长度为l 比特。首先将比特“1”添加到消息的末尾,再添加k 个“0”,k是满足l + 1 + k ≡ 448mod512 的最小的非负整数。然后再添加一个64位比特串,该比特串是长度l的二进制表示。
其中将bit转byte有$448bit = 56byte$,$512bit = 64byte$。 \(l + 1 + k \equiv 448 mod 512\) 等于 \(l + 1 + k \equiv 56 mod 64\) 若\(a \equiv b \mod p\),则对于任意的c,都有\((a + c) \equiv (b + c) \mod p\)。
$$k \equiv (56 - 1 - l) \mod 64 \qquad 0 \le k \le 63$$// 填充go语言实现
// 1 byte end marker :: 0-63 padding bytes :: 8 byte length
tmp := [1 + 63 + 8]byte{0x80}
pad := (55 - len) % 64 // calculate number of padding bytes
binary.BigEndian.PutUint64(tmp[1+pad:], len<<3) // append length in bits
Write(tmp[:1+pad+8])
2. 迭代过程
将填充后的消息m′按512比特进行分组:m′ = B(0)B (1)· · · B(n−1)。
for i := 0; i <= len(p)-BlockSize; i += BlockSize {
// eliminate bounds checks on p
q := p[i:]
q = q[:BlockSize:BlockSize]
}
3. 消息扩展
- a) 将消息分组B(i)划分为16个字W0, W1, · · ·, W15。
for j := 0; j < 16; j++ {
w0[j] = binary.BigEndian.Uint32(q[4*j : 4*(j+1)])
}
- b) $$ FOR \quad j=16 \quad TO \quad 67 \\\\ \qquad W_j ← P1(W_{j−16} ⊕ W_{j−9} ⊕ (W_{j−3} ≪ 15)) ⊕ (W_{j−13} ≪ 7) ⊕ W_{j−6} \\\\ ENDFOR $$
for j := 16; j < 68; j++ {
w0[j] = P1(w0[j-16]^w0[j-9]^bits.RotateLeft32(w0[j-3], 15)) ^ bits.RotateLeft32(w0[j-13], 7) ^ w0[j-6]
}
- c) $$ FOR \quad j=0 \quad TO \quad 63 \\\\ \qquad W1_j = W_j ⊕ W_{j+4} \\\\ ENDFOR $$
for j := 0; j < 64; j++ {
w1[j] = w0[j] ^ w0[j+4]
}
4. 压缩函数
A, B, C, D, E, F, G, H := a, b, c, d, e, f, g, h
for j := 0; j < 16; j++ {
SS1 := bits.RotateLeft32(bits.RotateLeft32(A, 12)+E+bits.RotateLeft32(0x79cc4519, j), 7)
SS2 := SS1 ^ bits.RotateLeft32(A, 12)
TT1 := FF0(A, B, C) + D + SS2 + w1[j]
TT2 := GG0(E, F, G) + H + SS1 + w0[j]
D = C
C = bits.RotateLeft32(B, 9)
B = A
A = TT1
H = G
G = bits.RotateLeft32(F, 19)
F = E
E = P0(TT2)
}
for j := 16; j < 64; j++ {
SS1 := bits.RotateLeft32(bits.RotateLeft32(A, 12)+E+bits.RotateLeft32(0x7a879d8a, j), 7)
SS2 := SS1 ^ bits.RotateLeft32(A, 12)
TT1 := FF1(A, B, C) + D + SS2 + w1[j]
TT2 := GG1(E, F, G) + H + SS1 + w0[j]
D = C
C = bits.RotateLeft32(B, 9)
B = A
A = TT1
H = G
G = bits.RotateLeft32(F, 19)
F = E
E = P0(TT2)
}
a, b, c, d, e, f, g, h = a^A, b^B, c^C, d^D, e^E, f^F, g^G, h^H