SM4分组密码算法的轮密钥加(Round Key Addition)运算详解
SM4是一种由中国国家密码管理局发布的商用分组密码算法,属于对称加密算法。分组长度为128位,密钥长度也为128位,采用32轮非平衡Feistel结构。今天我们来深入剖析其中每轮都会执行的关键操作之一:轮密钥加运算。这个步骤虽然概念上简单,但它是算法安全性不可或缺的基石。
一、题目描述与背景
在SM4的每一轮加密中,输入一个32位的字(4字节),这个字会与本轮的32位轮密钥进行一种特定的运算。这个过程,我们称之为“轮密钥加”或“密钥加变换”。我们需要理解:
- 这个运算的具体操作是什么?
- 它在整个轮函数中处于什么位置?起什么作用?
- 它的数学本质和安全性考量是什么?
二、轮密钥加在SM4轮函数中的位置
首先,我们回顾一下SM4一轮的完整流程,以帮助我们准确定位轮密钥加运算。SM4的每一轮处理一个32位的输入\(X_{i}\) (i=0,1,...,31),并生成一个32位的输出\(X_{i+4}\),作为下一轮的输入之一。
对于一个给定的轮次 \(r\) (r=0,1,...,31),假设当前的输入状态为 \((X_{r}, X_{r+1}, X_{r+2}, X_{r+3})\),其中每个 \(X\) 都是32位字。轮函数 \(F\) 作用于这四个字,生成新的 \(X_{r+4}\):
\(X_{r+4} = F(X_r, X_{r+1}, X_{r+2}, X_{r+3}, RK_r)\)
这里的 \(RK_r\) 就是第 \(r\) 轮的轮密钥,同样是一个32位字。
轮函数 \(F\) 的内部展开如下:
X_{r+4} = X_r ⊕ T( X_{r+1} ⊕ X_{r+2} ⊕ X_{r+3} ⊕ RK_r )
请注意这个公式的核心部分:X_{r+1} ⊕ X_{r+2} ⊕ X_{r+3} ⊕ RK_r。这里就包含了我们的主角——轮密钥加运算。
三、轮密钥加运算的详细步骤
轮密钥加并非一个独立的步骤,而是作为轮函数 \(T\) 的输入准备的一部分。我们可以把它分解为几个清晰的子步骤:
-
中间状态合并:
首先,将 \(X_{r+1}, X_{r+2}, X_{r+3}\) 这三个32位的状态字进行按位异或(XOR,符号为⊕)运算。
Tmp = X_{r+1} ⊕ X_{r+2} ⊕ X_{r+3}
这一步的目的是将上一轮的部分状态信息混合在一起。 -
引入轮密钥(轮密钥加的核心):
接着,将上一步得到的Tmp与本轮的轮密钥 \(RK_r\) 进行异或(XOR)运算。
Tmp' = Tmp ⊕ RK_r
这就是“轮密钥加”的本质操作。 虽然在算法标准中可能没有单独为这一步命名,但它是将密钥材料“加”(通过异或)入数据流的关键环节。 -
非线性与线性变换:
得到的Tmp‘将作为轮函数 \(T\) 的输入。\(T\) 是一个可逆变换,由两个子变换构成:- 非线性变换 τ:将32位的
Tmp‘分成4个8位的字节,每个字节独立地通过一个固定的8输入8输出的S盒(查表)进行替换。这步提供了算法的混淆特性,打破了数据与密钥之间的线性关系。 - 线性变换 L:将非线性变换后的32位结果,通过一个固定的线性变换(循环左移和异或组合)来提供扩散特性,使得一个字节的改变能快速影响到整个字。
- 非线性变换 τ:将32位的
-
最终异或(反馈):
最后,将线性变换 \(L\) 的输出结果,与最开始的 \(X_r\) 进行异或,得到本轮的新状态字 \(X_{r+4}\)。
X_{r+4} = X_r ⊕ L( τ( Tmp‘ ) )
小结一下轮密钥加的精确定义: 在SM4的每一轮中,轮密钥加特指将中间状态 (X_{r+1} ⊕ X_{r+2} ⊕ X_{r+3}) 与轮密钥 \(RK_r\) 进行异或的那个操作。其结果是后续非线性变换 \(T\) 的直接输入。
四、轮密钥加的数学本质与安全性作用
-
数学本质:
轮密钥加是在有限域GF(2)上的向量加法,等同于逐位的异或运算。这是一种非常高效且可逆的运算。其逆运算就是它自身:如果A ⊕ B = C,那么C ⊕ B = A。这个性质对解密至关重要。 -
在算法中的作用与安全性贡献:
- 注入密钥依赖性:这是加密过程引入密钥的主要入口。如果没有这一步,整个加密过程将不依赖于密钥,任何人都可以计算,完全失去保密性。
- 提供(每一轮的)密钥白化:轮密钥加将当前状态与一个伪随机的轮密钥混合,使得在攻击者不知道密钥的情况下,中间状态看起来是完全随机的,增加了密码分析的难度。
- 对抗线性与差分密码分析:轮密钥的异或操作改变了数据的值,使得攻击者难以准确追踪数据在通过S盒(非线性)和线性变换L之前的差分或线性关系。它是确保算法抵抗这些强大分析手段的重要设计之一。
- 确保可逆性(解密):SM4的解密过程与加密过程结构完全相同,唯一的区别是轮密钥使用的顺序是逆序的。正是因为轮密钥加运算的逆运算是其自身(只需用同一个密钥再异或一次),才使得这种对称性得以实现。解密时,最后一轮的输出状态,经过反向的轮密钥加(使用逆序的轮密钥)和相同的T变换,能够一步步恢复出明文。
五、一个简化的单字节示例
为了更直观,我们用一个极度简化的模型来看(实际SM4是32位操作):
假设某一刻, X_{r+1} ⊕ X_{r+2} ⊕ X_{r+3} 计算后得到的 Tmp 的一个字节是 0x3A (二进制 0011 1010)。
本轮的轮密钥 \(RK_r\) 对应的字节是 0xB5 (二进制 1011 0101)。
轮密钥加运算(字节层面):
Tmp’ = Tmp ⊕ RK_r = 0x3A ⊕ 0xB5
计算过程:
Tmp: 0011 1010 (0x3A)
⊕ RK_r: 1011 0101 (0xB5)
—————————————
Tmp‘: 1000 1111 (0x8F)
这个结果 0x8F 随后会被送入S盒进行非线性替换。
解密时的逆向操作:
在解密端,当我们需要从后续状态逆向计算时,我们会再次得到这个 Tmp‘ (0x8F)。为了恢复出加密前的 Tmp (0x3A),我们只需要再次与同一个轮密钥字节进行异或:
Tmp = Tmp‘ ⊕ RK_r = 0x8F ⊕ 0xB5 = 0x3A。
完美还原。
六、总结
SM4的轮密钥加运算虽然形式简单——仅仅是按位异或,但其地位举足轻重:
- 定位:它是每轮轮函数 \(T\) 的输入准备阶段的最后一步,将
(X_{r+1} ⊕ X_{r+2} ⊕ X_{r+3})与RK_r异或。 - 功能:它是向数据路径中注入密钥依赖性的核心机制,提供了密钥白化,并与其他变换(非线性S盒τ和线性变换L)协同工作,共同构筑了算法对抗密码分析的安全屏障。
- 特性:其可逆性(自逆)是实现SM4加解密过程对称性、仅通过轮密钥逆序即可解密的关键。
理解了这个基础而关键的运算,就能更深刻地把握SM4这类Feistel结构密码算法中,密钥是如何一步步与明文交互,最终产生看似随机密文的过程。