SM4

SM4

HuAmI Lv3

SM4 Encryption

Design Purpose

国际算法 国产对应
AES SM4
RSA / ECC SM2
SHA-256 SM3

显而易见,为了对标国外的加密算法,我国自主研发的 SM4 等系列算法在安全按等级上具有不降级和同等效力。拥有我国自主研发的加密算法并同时应用于我国实际商业等领域中具有重要意义。


Introduction

项目 参数
算法类型 对称分组密码
分组长度 128 bit(16 字节)
密钥长度 128 bit(16 字节)
轮数 32 轮
结构 非平衡 Feistel 结构(SPN 思想)

Process

  1. 输入明文

    • 长度:128 bit

    • 拆分为 4 个 32 bit 数据:

      1
      X_i, X_{i+1}, X_{i+2}, X_{i+3}
    • 不足 128 bit → 模式填充

      示例:11 字节明文补 5 字节

      1
      41 42 43 44 45 46 47 48 49 4A 4B 05 05 05 05 05

  1. 主密钥处理
  • 主密钥 MK:128 bit → 分成 4 个 32 bit:

    1
    MK = (MK0, MK1, MK2, MK3)
  • 系统参数 FK {FK0,FK1,FK2,FK3} :固定常量,用来打乱主密钥初始结构

  • 初始处理:

    1
    2
    3
    4
    K0 = MK0 ⊕ FK0
    K1 = MK1 ⊕ FK1
    K2 = MK2 ⊕ FK2
    K3 = MK3 ⊕ FK3
  • 我们得到密钥扩展的起始状态K_i:

    1
    K_i = MK_i ⊕ FK_i   (i=0,1,2,3)

CK 是什么?

CK(Constant Key) 是:

  • 32 个固定常量
  • 每一轮密钥生成使用 一个 CK[i]
  • 总共 32 轮 → 32 个 CK
1
CK0, CK1, CK2, … , CK31

接下里做了个这么个操作:


原始公式

K(i+4) = Ki ⊕ T′ ( K(i+1) ⊕ K(i+2) ⊕ K(i+3) ⊕ CKi)

好的,我们把这一条公式 逐步拆分来看,理解 CK 在轮密钥生成中的作用:


拆分步骤

① 取出三个 K 值

  • 当前已有的中间密钥值:

    1
    K(i+1), K(i+2), K(i+3)
  • 这些是上一轮或初始化阶段得到的。


② 与 CK 常量异或

  • 每一轮都有一个固定常量 CK(i)。

  • 把它与三个 K 值异或:

    1
    Temp = K(i+1) ⊕ K(i+2) ⊕ K(i+3) ⊕ CK(i)
  • 结果是一个 32 位数。


③ 进行 T′ 变换

T′ 变换的具体操作

  1. S 盒替换

    • 把输入的 32 位字(由 4 个字节组成)逐字节送入 SM4 的 S 盒。

    • 得到新的 32 位字 B′。

    • 对 Temp 进行非线性变换 T′:

      • S 盒替换:把 Temp 的每个字节送入 S 盒,得到新的 32 位数。

        S盒:主要是映射的关系;比如在下图S盒中0x52经过S盒运算的结果就是0x81

        img

        上述S盒按照国密白皮书所用S盒(统一)

      • 线性变换:对替换结果做循环移位和异或,进一步扩散。

    • 得到结果:

      1
      T′(Temp)
  2. 线性变换 L′

    • 对 B′ 做循环移位和异或:

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

  • 这里 ⋘n 表示循环左移 n 位。

​ 3. 组合结果

  • 最终:

T′(X)=L′(Sbox(X))


④ 与 K(i) 异或

  • 把 T′(Temp) 与 K(i) 异或:

    1
    K(i+4) = K(i) ⊕ T′(Temp)
  • 得到新的 K 值。


⑤ 生成轮密钥

  • 每一轮得到一个新的 K(i+4)。

  • 经过 32 轮,就生成了 K4 ~ K35。

  • 这 32 个值就是轮密钥:

    1
    rk0, rk1, …, rk31

Conclusion:

  • Step 1:取 K(i+1), K(i+2), K(i+3)
  • Step 2:与 CK(i) 异或 → Temp
  • Step 3:Temp 经过 T′(S 盒 + 线性变换)
  • Step 4:结果与 K(i) 异或 → K(i+4)
  • Step 5:重复 32 次 → 得到所有轮密钥 rk0 ~ rk31
  1. 保存结果
    • 把计算出的 Ki+4 作为新的中间值加入序列。
    • 现在你有 K0,K1,K2,K3,K4。
  2. 继续迭代
    • 用同样的公式计算 K5:

​ K5=K1⊕T′(K2⊕K3⊕K4⊕CK1)

  • 然后再算 K6,K7,…,直到得到 K35。
  • 从 K4 到 K35,一共 32 个值。
  • 这 32 个就是加密迭代中用到的轮密钥:

​ rk0=K4,rk1=K5,…,rk31=K35

  1. 进入加密迭代
  • 轮密钥准备好后,就进入 SM4 的 32 轮加密过程。
  • 每一轮用一个 rki,结合 T 变换(S 盒 + L 线性变换)更新数据块。

3.加密迭代

  • 输入明文分组 M=(X0,X1,X2,X3),每个 32 位。
  • 进行 32 轮迭代:

Xi+4=Xi⊕T(Xi+1⊕Xi+2⊕Xi+3⊕rki)

其中:

  • T = S 盒替换 + L 线性变换(s盒依旧是那个s盒)
  • L 的移位参数是 2、10、18、24 位

线性变换 L 是:

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

4.加密输出

  • 加密完成后,取最后四个字:

(X35,X34,X33,X32)

  • 这就是最终的 密文分组(128 位)。

  • 注意顺序是反过来的,这是标准规定的。

    img


  • Title: SM4
  • Author: HuAmI
  • Created at : 2026-03-20 12:15:57
  • Updated at : 2026-03-25 19:50:32
  • Link: https://redefine.ohevan.com/2026/03/20/SM4/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments