白乐天

道阻且长,行则将至。

详解SM4

SM4简介

SM4是中国国家密码管理局(GM/T 0002-2012)发布的商用分组密码算法,属于对称加密算法。

类型:对称分组加密

分组长度:128位(16字节)

密钥长度:128位(16字节)

迭代轮数:32轮

设计结构:基于Feistel网络结构,但实际采用更高效的非线性迭代结构

加密流程

明文处理

将128位明文分为4个32位字(大端序存储):X0,X1,X2,X3

32轮迭代加密

轮函数

每轮的操作公式如下:

1
2
3
X{i+4}=Xi⊕T(X{i+1}⊕X{i+2}⊕X{i+3}⊕rki)

// rki会在后面密钥调度中提到,这里理解为轮秘钥

也可以把这个公式理解为轮函数F

1
X{i+4} = F(Xi,X{i+1},X{i+2},X{i+3}) = Xi⊕T(X{i+1}⊕X{i+2}⊕X{i+3}⊕rki)

核心函数T

S盒置换(非线性层)

将T函数的输入X{i+1}⊕X{i+2}⊕X{i+3}⊕rki32位拆分为4个8位字节,每个字节通过固定S盒替换(查表),得到32位的结果B.

线性变换L(扩散层)

对S盒的32位输出B进行循环左移和异或

1
L(B)=B⊕(B⋘2)⊕(B⋘10)⊕(B⋘18)⊕(B⋘24)

更新寄存器

1
X{i+4}=Xi⊕L(B)

反序合并

最终输出密文时,将X32,X33,X34,X35反序排列并合并为128位。

示例:

1
2
3
4
X32=0x12345678(字A)
X33=0x9ABCDEF0(字B)
X34=0x11223344(字C)
X35=0x55667788(字D)

取逆序字:D=0x55667788, C=0x11223344, B=0x9ABCDEF0, A=0x12345678

按大端序合并

1
cipher = 0x55667788112233449ABCDEF012345678

密钥调度

通过密钥调度生成32个轮秘钥(每轮一个,32位)。

主密钥拆分

首先将128位主密钥分为4个32位字:MK0,MK1,MK2,MK3

固定常数FK

1
2
3
4
FK0=0xA3B1BAC6,
FK1=0x56AA3350,
FK2=0x677D9197,
FK3=0xB27022DC.

固定参数CK

生成中间密钥

每个MKiFKi异或,得到初始密钥K0K3

迭代生成轮秘钥

通过32轮迭代生成后续的K4K35

1
2
3
4
5
6
7
8
9
├─迭代32轮:
│ for i = 0 to 31:
│ 计算中间值 = K_{i+1} ⊕ K_{i+2} ⊕ K_{i+3} ⊕ CK_i
│ │
│ ├─S盒置换(4字节查表)
│ │
│ └─线性变换L'(循环左移13、23位后异或)
│ 生成 K_{i+4} = K_i ⊕ T'(中间值)
│ 保存 rk_i = K_{i+4}

T’函数

与加密过程中的T函数类似,S盒置换与加密算法中的S盒算法相同,有区别的是线性替换L’

线性变换L′

1
L′(B)=B⊕(B⋘13)⊕(B⋘23)

流程总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
主密钥 (128位)

├─拆分为 MK₀, MK₁, MK₂, MK₃

├─异或 FK₀-FK₃ → 生成 K₀-K₃

├─迭代32轮:
│ for i = 0 to 31:
│ 计算中间值 = K_{i+1} ⊕ K_{i+2} ⊕ K_{i+3} ⊕ CK_i
│ │
│ ├─S盒置换(4字节查表)
│ │
│ └─线性变换L'(循环左移13、23位后异或)
│ 生成 K_{i+4} = K_i ⊕ T'(中间值)
│ 保存 rk_i = K_{i+4}

└─输出轮密钥 rk_0, rk_1, ..., rk_31