参考官方文档
https://oscca.gov.cn/sca/xxgk/2010-12/17/1002389/files/302a3ada057c4a73830536d03e683110.pdf

SM3加密过程

以abc为例子

字符串 “abc” 的ASCII码为:
a = 0x61 = 01100001
b = 0x62 = 01100010
c = 0x63 = 01100011
所以,”abc” 的二进制表示为:
01100001 01100010 01100011
24位

消息填充

  1. 添加比特1
    当前为: 01100001 01100010 01100011 1
    当前位数: 25 位

  2. 补 “0” 直到长度满足 (长度 % 512) = 448
    当前为: 01100001 01100010 01100011 1 0…0000(448-25 = 423个0)
    当前位数: 448位

  3. 添加64位的长度信息
    abc共24位,用64位标识24即0000000000000018 H
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00011000
    当前为: 01100001 01100010 01100011 1 0…000 0…000 00011000
    当前位数: 512位

  4. 以512位一组分组
    因为这里只有512位,所以一组即可B0

消息扩展

扩展为(W0, W1, …, W67 和 W‘0, W’1, …, W‘63)
一个W占32位,共132个W

前16个W(W0-15)就是填充完的消息

j Wj 十六进制 说明
0 W0 61626380 “abc” + 1个比特1
1 W1 00000000 补零
2 W2 00000000 补零
3 W3 00000000 补零
4 W4 00000000 补零
5 W5 00000000 补零
6 W6 00000000 补零
7 W7 00000000 补零
8 W8 00000000 补零
9 W9 00000000 补零
10 W10 00000000 补零
11 W11 00000000 补零
12 W12 00000000 补零
13 W13 00000000 补零
14 W14 00000000 补零
15 W15 00000018 原始长度24比特

扩展生成 W16 到 W67

1
2
3
FOR j=16 TO 67 
Wj ←P1(Wj−16 ⊕Wj−9 ⊕(Wj−3 ≪15))⊕(Wj−13 ≪ 7)⊕Wj−6
ENDFOR

其中P1具体实现为

1
P1(X) = X ⊕ (X ≪ 15) ⊕ (X ≪ 23)

扩展生成 W’0 到 W’63

1
2
3
FOR j=0 TO 63
W′j = Wj ⊕Wj+4 //Wi与Wi+4互相异或
ENDFOR

此时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
W0W1...W67
61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000018
9092e200 00000000 000c0606 719c70ed 00000000 8001801f 939f7da9 00000000
2c6fa1f9 adaaef14 00000000 0001801e 9a965f89 49710048 23ce86a1 b2d12f1b
e1dae338 f8061807 055d68be 86cfd481 1f447d83 d9023dbf 185898e0 e0061807
050df55c cde0104c a5b9c955 a7df0184 6e46cd08 e3babdf8 70caa422 0353af50
a92dbca1 5f33cfd2 e16f6e89 f70fe941 ca5462dc 85a90152 76af6296 c922bdb2
68378cf5 97585344 09008723 86faee74 2ab908b0 4a64bc50 864e6e08 f07e6590
325c8f78 accb8011 e11db9dd b99c0545

W′0W′1...W′63
61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000018 9092e200 00000000 000c0606 719c70f5
9092e200 8001801f 93937baf 719c70ed 2c6fa1f9 2dab6f0b 939f7da9 0001801e
b6f9fe70 e4dbef5c 23ce86a1 b2d0af05 7b4cbcb1 b177184f 2693ee1f 341efb9a
fe9e9ebb 210425b8 1d05f05e 66c9cc86 1a4988df 14e22df3 bde151b5 47d91983
6b4b3854 2e5aadb4 d5736d77 a48caed4 c76b71a9 bc89722a 91a5caab f45c4611
6379de7d da9ace80 97c00c1f 3e2d54f3 a263ee29 12f15216 7fafe5b5 4fd853c6
428e8445 dd3cef14 8f4ee92b 76848be4 18e587c8 e6af3c41 6753d7d5 49e260d5

压缩函数

IV =7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e

令A,B,C,D,E,F,G,H = IV

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FOR j=0 TO 63
SS1 ← ((A ≪ 12) + E + (Tj ≪ j)) ≪ 7
SS2 ← SS1 ⊕ (A ≪ 12)
TT1 ← FFj (A, B, C) + D + SS2 + W′j
TT2 ← GGj (E, F, G) + H + SS1 + Wj
D ← C
C ← B ≪ 9
B ← A
A ← TT1
H ← G
G ← F ≪ 19
F ← E
E ← P0(TT2)
ENDFOR
V(i+1) ← ABCDEFGH ⊕ V(i)

其中

1
2
3
Tj =
79cc4519 (0 ≤ j ≤ 15)
7a879d8a (16 ≤ j ≤ 63)
1
P0(X) = X ⊕ (X ≪ 9) ⊕ (X ≪ 17)
1
2
3
4
5
6
7
FFj (X, Y, Z)= 
X ⊕ Y ⊕ Z (0 ≤ j ≤ 15)
(X ∧ Y ) ∨ (X ∧ Z) ∨ (Y ∧ Z ) (16 ≤ j ≤ 63)

GGj (X, Y, Z) =
X ⊕ Y ⊕ Z (0 ≤ j ≤ 15)
(X ∧ Y ) ∨ ( ¬X∧ Z) (16 ≤ j ≤ 63)

最后结果

经过压缩函数得到新的ABCDEFGH
A = 66c7f0f4
B = 62eeedd9
C = d1f2d46b
D = dc10e4e2
E = 4167c487
F = 5cf2f7a2
G = 297da02b
H = 8f4ba8e0

即结果为 66c7f0f4 62eeedd9 d1f2d46b dc10e4e2 4167c487 5cf2f7a2 297da02b 8f4ba8e0