SHA-3 (Keccak) 海绵结构中的轮函数 Keccak-f[b] 详解
题目描述:SHA-3哈希算法(基于Keccak)的核心是一个称为海绵函数的密码结构,而海绵函数的核心又在于其内部的置换函数Keccak-f[b]。这个轮函数是一个对宽度为b比特的内部状态(state)进行混淆和扩散的固定置换,其中SHA-3标准主要使用b=1600(即一个5×5×64的三维位阵列)。请详细解释Keccak-f[1600]轮函数的结构、其包含的五步映射(Theta, Rho, Pi, Chi, Iota)的具体计算过程,以及多轮迭代(共24轮)的目的,确保我能理解这个复杂置换是如何逐步实现的。
解题过程:
我们将循序渐进地拆解Keccak-f[1600]轮函数。整个过程可以理解为对一个大“状态块”反复进行一套固定、可逆的混淆和扩散操作。
第一步:理解内部状态的三维表示
Keccak-f[b]操作的内部状态(State)可以看作是一个三维比特数组,维度为5×5×w,其中w是比特平面(也称为“道”, lane)的宽度。对于SHA-3,b=1600,所以w=b/25=64比特。
- 三维坐标 (x, y, z):
- x (0-4):列坐标。
- y (0-4):行坐标。
- z (0-63):比特在“道”(lane)内的深度坐标。一个道A[x][y]就是一个64比特的字,其中z=0是最低位(LSB),z=63是最高位(MSB)。
- 切片 (Slice) 和 薄片 (Sheet):
- 所有满足相同z坐标的比特位构成了一个5×5的二维切片。
- 所有满足相同x坐标的比特位构成了一个5×w的薄片。
- 目标:轮函数的目的就是让这个三维状态的每一个比特都高度依赖于其他所有比特,实现充分的混淆和扩散。
第二步:认识轮函数的主循环(24轮)
Keccak-f[1600] 轮函数是固定执行的24轮(确切地,轮数nr由w决定,nr=12+2l,w=2^l,SHA-3中l=6,所以nr=12+26=24轮)迭代。每轮(记为索引i_r,从0到23)都包含相同的五个步骤,但每轮的常量(Iota步骤使用)不同。
- 公式:
State = Rnd(State, i_r),其中Rnd表示一轮操作。 - Rnd函数分解:
Rnd(State, i_r) = Iota( Chi( Pi( Rho( Theta(State) ) ), i_r ) )。计算顺序是:Theta → Rho → Pi → Chi → Iota。
接下来,我们深入每一步。我们用A[x][y][z]表示变换前的比特,A'[x][y][z]表示变换后的比特。
第三步:五步映射详解
步骤1:Theta (θ) 步骤
- 目标:为状态引入列奇偶性扩散,让一个比特的变化快速影响到同切片和其他切片中的大量比特。
- 计算过程:
- 计算列的奇偶和:对于每一列(x, z),计算其5个比特(y从0到4)的奇偶和(即XOR和)。
C[x][z] = A[x][0][z] ⊕ A[x][1][z] ⊕ A[x][2][z] ⊕ A[x][3][z] ⊕ A[x][4][z]。C[x]是一个长度为w=64的向量。 - 计算列扩散向量D:
D[x][z] = C[x-1][z] ⊕ C[x+1][z-1]。这里的x-1,x+1是对5取模,z-1是对w=64取模。C[x+1][z-1]可以看作是将C[x+1]向量循环右移1位再与C[x-1]异或。 - 应用到整个状态:将得到的
D[x][z]与原始的每个比特进行异或。A'[x][y][z] = A[x][y][z] ⊕ D[x][z]。
- 计算列的奇偶和:对于每一列(x, z),计算其5个比特(y从0到4)的奇偶和(即XOR和)。
- 效果:一个比特的变化会改变其所在列的
C[x][z],进而影响D[x][z]和D[x±2][z±1],最终波及到同一切片内(相同z)的五列以及相邻切片内(相邻z)的两列。实现了良好的长距离扩散。
步骤2:Rho (ρ) 步骤
- 目标:在每一个“道”(lane,即
A[x][y]这个64比特字)内部引入比特位的循环移位,打乱z轴方向(深度方向)的比特位置关系。它不改变每个道内的比特值,只改变其顺序。 - 计算过程:
- 固定移位偏移表:对于每个坐标(x, y),有一个预定义的循环左移(ROL)偏移量
r[x][y]。这个表是固定的,与w无关。例如,A[0][0]不移位(偏移0),A[1][0]循环左移1位,A[2][0]循环左移62位,A[3][0]循环左移28位,等等。 - 移位操作:
A'[x][y] = A[x][y] <<< r[x][y]。这里<<<表示对64比特字的循环左移。
- 固定移位偏移表:对于每个坐标(x, y),有一个预定义的循环左移(ROL)偏移量
- 效果:将Theta步骤产生的沿z轴的扩散进一步扩散到整个道内,增加了算法的非线性扩散路径的复杂性。
步骤3:Pi (π) 步骤
- 目标:重新排列25个“道”(lanes)在5×5矩阵中的位置。它是一个固定的置换,不改变道内的比特值。
- 计算过程:
- 固定置换规则:
A'[x][y] = A[(x + 3y) mod 5][x]。这是对道位置的置换。
- 固定置换规则:
- 效果:将原来在固定位置的道移动到新的位置。这打乱了在Theta步骤中建立的列间依赖关系,使得后续步骤(Chi)的运算混合来自不同原始列和行的比特。它是一个线性变换,增加了结构的扩散性。
步骤4:Chi (χ) 步骤
- 目标:这是Keccak-f中唯一的非线性步骤。它对每一行(固定y)的5个比特(x从0到4)进行一个依赖于局部邻域的非线性变换。
- 计算过程:
- 按行操作:对于每一行(y固定)和每一个深度位置z,对5个比特进行操作。
- 非线性公式:
A'[x][y][z] = A[x][y][z] ⊕ ( ( NOT A[x+1][y][z] ) AND A[x+2][y][z] )。这里的x+1和x+2都是对5取模。NOT是比特取反,AND是比特与操作。
- 效果:引入了非线性,这对于抵抗线性密码分析和差分密码分析至关重要。它可以被看作是一个5比特输入的S盒,具有良好的密码学性质(如高非线性度、低差分均匀性)。
步骤5:Iota (ι) 步骤
- 目标:在状态中加入一个与轮数相关的常量(轮常量RC),破坏状态的对称性,防止在输入为全0或具有某种对称性时,经过多轮变换后仍保持对称性(即防止产生不动点或短周期)。
- 计算过程:
- 生成轮常量RC:有一个基于线性反馈移位寄存器(LFSR)的算法来生成一个64比特的轮常量
RC[i_r]。每轮的RC都不同,只有最低的几位(具体与LFSR的阶有关)可能为1,其余为0。 - 应用常量:只修改状态中的一个特定道
A[0][0](即x=0, y=0的那个64比特字)。A'[0][0] = A[0][0] ⊕ RC[i_r]。
- 生成轮常量RC:有一个基于线性反馈移位寄存器(LFSR)的算法来生成一个64比特的轮常量
- 效果:这是一个非常简单的操作,但至关重要。它确保每一轮变换都是不同的,即使输入状态是全0,经过第一轮Iota步骤后也会被改变,从而启动整个混淆扩散过程。没有这一步,算法在面对某些特殊输入时会变得脆弱。
第四步:整合理解与总结
- 迭代过程:初始状态(可能是消息吸收后的状态)经过上述五个步骤完成第一轮。然后将得到的新状态作为输入,进行第二轮,但使用的
RC[1]与第一轮的RC[0]不同。如此重复24轮。 - 设计哲学:这五步是一个精心设计的组合:
- Theta 和 Pi 主要是线性扩散层,负责在三维状态的各个方向(x, y, z)上快速传播变化。
- Rho 是线性搅乱层,在道内增加比特位置的混乱度。
- Chi 是非线性层,提供算法的抗攻击核心强度。
- Iota 是轮常量加层,破坏对称性,增加算法的“不对称性”和轮间差异。
- 安全性:经过24轮(这个轮数是经过充分安全评估的)这样的迭代,输入状态的任何微小差异都会被放大并影响到最终状态的几乎所有比特。这种设计使得Keccak-f[1600]具有很高的安全边际,能够抵抗已知的各种密码学攻击(如差分、线性、代数攻击等)。
- 可逆性:Keccak-f的所有五个步骤(包括Chi,其逆运算存在)都是可逆的,因此整个轮函数也是一个置换(双射)。这对于海绵结构的正确性很重要,但哈希函数的安全性依赖于它的正向计算难度,而非可逆性。
通过以上分解,你应该能理解Keccak-f[1600]轮函数是如何通过一系列结构化、互补的步骤,对内部状态进行强力混淆和扩散,从而为SHA-3哈希算法提供坚实的安全性基础。