好的,让我们来看一个尚未讲解的算法。这次,我们聚焦于一个经典而又精巧的轻量级分组密码算法。
Speck 轻量级分组密码算法的轮函数设计
题目描述:
Speck是一种轻量级分组密码算法,由美国国家安全局(NSA)于2013年公布。它是一族算法,支持多种分组和密钥长度组合(例如,Speck64/128表示分组长度为64位,密钥长度为128位)。其设计目标是同时兼顾在硬件和软件平台上的高性能与高效率。Speck的结构基于ARX结构(Addition模2^n, Rotation循环移位, XOR异或),这使得其轮函数设计非常简洁。请你详细解析Speck算法的轮函数是如何设计的,包括其内部运算步骤、设计原理,并说明每一步的作用。
解题过程(循序渐进讲解):
为了让讲解清晰,我们以一个具体且常见的实例——Speck64/128为例。它的分组长度为64位,密钥长度为128位,总轮数为27轮。
第一步:理解基本框架与符号
- 分组拆分:Speck将输入的64位明文(或中间状态)分为两个等长的字(Word)。每个字的长度为 n = 32位(因为64/2=32)。
- 我们用
(X_i, Y_i)来表示第i轮加密后的两个32位字。(X_0, Y_0)就是明文(P_L, P_R)。
- 我们用
- 密钥拓展:Speck使用一个密钥扩展算法,从128位的主密钥(K)生成27个轮密钥
(K_0, K_1, ..., K_26),每个轮密钥也是32位(一个字的长度)。 - ARX操作:轮函数的核心是三种非常基础的CPU指令,这也是其高效的原因:
- A: Addition(加法),这里特指模 2^n 加法(即普通32位整数加法,忽略进位溢出)。我们用符号
⊞表示。 - R: Rotation(循环移位)。右移用
≫或ROR,左移用≪或ROL。 - X: XOR(按位异或)。我们用符号
⊕表示。
- A: Addition(加法),这里特指模 2^n 加法(即普通32位整数加法,忽略进位溢出)。我们用符号
第二步:轮函数的具体步骤(一轮加密)
对于第 i 轮(i 从0开始计数),输入是上一轮的 (X_i, Y_i) 和本轮对应的轮密钥 K_i,输出是 (X_{i+1}, Y_{i+1})。一轮加密过程可以用以下两步方程精确描述:
-
对左半部分(X_i)进行变换:
X_{i+1} = ((X_i ≫ α) ⊞ Y_i) ⊕ K_i
这一行代码做了以下事情:X_i ≫ α: 将X_i循环右移α位(对于Speck64,参数α = 8)。这一步是非线性扩散的主要来源。循环移位打乱了位的顺序。(X_i ≫ α) ⊞ Y_i: 将移位后的X_i与Y_i做模加。模加运算提供了重要的非线性特性,并且与异或和移位结合,能产生复杂的代数关系。... ⊕ K_i: 最后再与轮密钥K_i进行异或。这是密钥引入的地方,确保每一轮的状态都与密钥相关。
-
对右半部分(Y_i)进行变换:
Y_{i+1} = (Y_i ≪ β) ⊕ X_{i+1}
这一行代码做了以下事情:Y_i ≪ β: 将Y_i循环左移β位(对于Speck64,参数β = 3)。同样是为了扩散。(Y_i ≪ β) ⊕ X_{i+1}: 将移位后的Y_i与刚刚计算出的新X_{i+1}进行异或。这里非常关键!X_{i+1}包含了本轮密钥和模加运算的结果,通过异或操作,其影响被迅速传播到Y_{i+1}中。
第三步:轮函数示意图与数据流
我们可以用下面的伪代码/图示来理解一轮的数据流:
初始: (X_i, Y_i), K_i
步骤1: temp_X = ROR(X_i, α) // X_i 循环右移α位
步骤2: new_X = (temp_X + Y_i) ⊕ K_i // 模加后异或轮密钥,得到 X_{i+1}
步骤3: temp_Y = ROL(Y_i, β) // Y_i 循环左移β位
步骤4: new_Y = temp_Y ⊕ new_X // 异或上一步的new_X,得到 Y_{i+1}
输出: (X_{i+1}, Y_{i+1}) = (new_X, new_Y)
整个过程形成了一个紧密的耦合:Y_i 参与到 X_{i+1} 的计算中,而计算出的 X_{i+1} 又立即影响到 Y_{i+1}。这种设计确保了状态的两个部分在每一轮中都充分混合。
第四步:设计原理与每步作用的深度解析
-
非线性的来源:
- 模加(⊞):这是Speck非线性性的核心。与纯粹的异或相比,模加运算的进位机制创造了复杂的非线性布尔函数,能有效抵抗线性密码分析和差分密码分析。
- 循环移位(ROR/ROL):移位操作本身是线性的,但它改变了数据位的对齐方式,使得模加和异或运算作用于不同的位组合上,与模加结合后增强了整体非线性扩散效果。
-
扩散(Diffusion)的实现:
- 跨字扩散:
Y_i通过模加影响X_{i+1},X_{i+1}又通过异或影响Y_{i+1}。单轮之内,两个状态字就相互影响了两次,扩散速度极快。 - 字内扩散:循环移位
≫ α和≪ β确保了在一个字内部,高位和低位的比特能在后续的模加/异或中相互作用。参数α和β的选择(如8和3)通常互为质数且与字长 n (32) 互质,以实现最大周期和最优扩散。
- 跨字扩散:
-
简洁性与性能:
- ARX结构:只使用加法、移位、异或这三种在所有CPU上都极其高效的指令,没有复杂的S盒查表操作。这使得Speck在软件实现(尤其是微控制器)上速度极快,代码体积小,在硬件实现上面积小、功耗低。
- 自逆结构的舍弃:与一些Feistel结构(如DES)不同,Speck的加密和解密轮函数并不对称。解密需要对应的逆操作(模减、反向移位)。这种不对称性换来了更高的单轮加密强度和更少的轮数需求。
-
密钥加(Key Addition):
- 轮密钥
K_i是通过模加之后再进行异或引入的。这种顺序很重要。如果先异或再模加,在某些简化模型下安全性会变弱。目前的顺序能更好地将密钥的影响通过模加的进位传播开来。
- 轮密钥
总结:
Speck的轮函数是一个ARX设计的典范。它通过精心编排的模加、循环移位、异或序列,在单轮内实现了高度的非线性和快速的交叉扩散。其设计舍弃了对称的自逆性和传统的S盒,以追求在资源受限环境中无与伦比的性能与安全性的平衡。((X≫8)+Y)⊕K 和 (Y≪3)⊕X_new 这两个简洁的等式,构成了其强大安全性的基石。