RC6加密算法的轮函数设计
RC6是一种对称分组密码算法,由Rivest、Sidhu等人设计,是AES的候选算法之一。它的核心是一个参数化的轮函数,具有灵活性和较高的安全性。RC6-w/r/b版本中,w是字长(比特),r是轮数,b是密钥长度(字节)。最常用的版本是RC6-32/20/16,即字长32比特,20轮,密钥128比特。我们今天重点讲解它的轮函数设计。我会从轮函数中用到的数据表示和基本操作开始,一步步拆解它的完整流程。
第一步:理解RC6的基本数据块表示和核心操作
RC6加密的明文分组长度为128比特(对于RC6-32版本),在运算中,它被均匀分为4个32比特的字,我们记为A、B、C、D。所以初始状态是:
(A, B, C, D) = (明文块的前32比特, 第二个32比特, 第三个32比特, 第四个32比特)。
轮函数的核心是依赖于几个基本运算,这些运算都是在32比特字上进行的:
- 模2^32加法和减法:记为 a + b 和 a - b。
- 逐位异或:记为 a ⊕ b。
- 模2^32乘法:记为 a × b。
- 循环移位:这是RC6算法的关键特色操作。循环左移记为
a <<< b,循环右移记为a >>> b。这里的移位位数并不是一个固定值,而是由另一个字的低5位(即lg(w) = 5,因为2^5=32)决定的。即:a <<< (b的低5位):将a循环左移,移动的位数等于b这个值本身的低5比特所表示的数值(范围0-31)。a >>> (d的低5位):将a循环右移,移动的位数等于d的低5比特。
第二步:密钥扩展生成轮密钥数组S
在讲解轮函数之前,需要先简要了解轮密钥的生成,因为轮函数会用到它们。RC6使用一个由2r+4个字(每个字w比特)组成的轮密钥数组S[0, 1, ..., 2r+3]。密钥扩展算法(Key Expansion)将用户密钥b字节扩展成这个数组S。这个过程涉及一个魔法常数P_w和Q_w(基于自然对数和黄金比例的奇数),并使用了模2^32加法和逻辑运算。这里我们只需知道,在轮函数执行时,我们会按顺序使用S[0], S[1], ... S[2r+3]这些轮密钥。
第三步:详细拆解一轮RC6轮函数(以第i轮为例)
假设我们当前处于第i轮(i从1到r),输入是四个字(A, B, C, D)。一轮操作结束后,输出新的(A, B, C, D)作为下一轮的输入。我们用S[0], S[1], ...表示轮密钥数组。
一轮RC6轮函数(Round Function)的执行步骤如下,它对称地处理B和D,并使用A和C作为它们循环移位的控制字:
-
B的变换:
- 首先,计算
u = (B × (2B + 1)) <<< 5。- 这里
(2B + 1)是B左移一位(即乘以2)再加1。这个乘法B × (2B+1)产生一个32位结果。 - 然后,将这个结果循环左移5位。注意,这里的移位位数是固定的5位,而不是由其他字决定的。这个操作是RC6非线性性的主要来源之一。
- 这里
- 然后,计算
t = (D × (2D + 1)) <<< 5。这是为下一步D的变换做准备,但它的值t会用于B的更新。 - 最后,更新B:
B = ((A ⊕ u) <<< t的低5位) + S[2i]。A ⊕ u:将A与上一步计算出的u进行异或。<<< t的低5位:将异或结果循环左移,移位位数由t的低5位决定。+ S[2i]:将移位后的结果加上第2i个轮密钥。
- 首先,计算
-
D的变换:
- 首先,计算
t = (D × (2D + 1)) <<< 5。(与上一步为计算B准备的t相同)。 - 然后,更新D:
D = ((C ⊕ t) <<< u的低5位) + S[2i+1]。C ⊕ t:将C与t进行异或。<<< u的低5位:将异或结果循环左移,移位位数由u的低5位决定。+ S[2i+1]:将移位后的结果加上第2i+1个轮密钥。
- 首先,计算
-
寄存器轮换:
完成B和D的更新后,四个字(A, B, C, D)进行一次循环左移,即:(A, B, C, D) = (B, C, D, A)。
这确保了下一轮中,原来不同位置的字会扮演新的角色(A, C成为控制字,B, D成为被变换字)。
重要观察:在一轮中,核心的非线性运算(x × (2x+1)) <<< 5只在B和D上各计算一次,得到u和t。然后u和t既被用作更新B和D的一部分,也通过它们的低5位相互控制对方更新步骤中的循环移位量。这种数据相关的移位是RC6的关键设计,极大地增加了密码的扩散性和对分析攻击的抵抗力。
第四步:加密过程的完整流程框架
现在,我们将轮函数放入完整的加密流程中,让你看到轮函数是如何被迭代调用的。
-
初始化:
- 输入明文,分为四个字:
A, B, C, D。 - 将轮密钥
S[0]加到B上:B = B + S[0]。 - 将轮密钥
S[1]加到D上:D = D + S[1]。
- 输入明文,分为四个字:
-
主轮迭代(r轮):
- 对于
i = 1到r,执行我们在第三步中描述的一轮操作。 - 记住,每一轮结束后,(A, B, C, D) 四个字会循环左移一次。
- 对于
-
最终化:
- 经过r轮后,再进行一次寄存器轮换,使得状态恢复到类似初始的(A, B, C, D)顺序(尽管值已完全改变)。
- 然后,将轮密钥
S[2r+2]加到A上:A = A + S[2r+2]。 - 将轮密钥
S[2r+3]加到C上:C = C + S[2r+3]。 - 最终的(A, B, C, D)连接起来,就是128比特的密文。
解密过程是加密过程的严格逆过程,需要逆序使用轮密钥,并执行逆操作(减法代替加法,循环右移代替循环左移等)。
总结一下RC6轮函数设计的精髓:
它的核心在于(x × (2x+1)) <<< 5这个非线性变换,以及用这个变换的结果来控制另一个字变换时的循环移位位数。这种数据依赖的旋转(Data-Dependent Rotation)使得算法在软件实现上非常高效(一次乘法和几次移位/加法),同时提供了很强的抗线性密码分析和差分密码分析的能力。其简洁而强大的轮函数设计,是RC6成为优秀分组密码算法的关键。