SM3密码杂凑算法

  1. 1. 填充
  2. 2. 迭代过程
  3. 3. 消息扩展
  4. 4. 压缩函数

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

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wind.kaisa@gmail.com

💰

×

Help us with donation