SHA-3 (Keccak) 海绵结构中的 $\iota$ (Iota) 步骤详解
字数 3487 2025-12-19 01:53:36
SHA-3 (Keccak) 海绵结构中的 \(\iota\) (Iota) 步骤详解
题目描述
SHA-3 哈希算法采用海绵(Sponge)结构,其核心置换函数是 Keccak-f[b],其中 b 是状态宽度(对于 SHA3-256,b=1600 比特)。Keccak-f 由 24 轮迭代组成,每轮包括五个步骤,记作 θ (Theta)、ρ (Rho)、π (Pi)、χ (Chi) 和 ι (Iota)。本题目要求详解其中的 \(\iota\) (Iota) 步骤,包括它的作用、在每一轮中的具体计算方式、使用的轮常数(round constant)的生成规则,以及它在整个算法安全性和性能中扮演的角色。
解题过程
-
理解 SHA-3 海绵结构的背景
- SHA-3 是美国国家标准与技术研究院 (NIST) 在 2012 年选定的新一代安全哈希算法标准,其基础是 Keccak 算法。
- 与 MD-SHA 家族(如 SHA-256)的 Merkle-Damgård 结构不同,SHA-3 使用“海绵结构”。这个结构可以吸收任意长度的输入,并挤出任意长度的输出(哈希值),其核心是一个固定的、可逆的、公开的、随机性良好的置换(permutation) 函数,即 Keccak-f[b]。
- Keccak-f[b] 对一个宽度为 b 比特的内部状态(state)进行变换。b 可以是 25、50、100、200、400、800 或 1600。SHA-3 标准家族(SHA3-224, 256, 384, 512, SHAKE128, SHAKE256)统一使用 b=1600。
- Keccak-f[1600] 将状态视为一个 5x5x64 的三维比特数组:5 行(y=0 到 4),5 列(x=0 到 4),64 个比特平面(z=0 到 63)。我们可以把它想象成一个 5x5 的“片(lane)”,每个“片”是 64 比特长的一个字。
-
Keccak-f 单轮的结构
- Keccak-f[1600] 的一轮操作 R 可以表示为:
R = ι ◦ χ ◦ π ◦ ρ ◦ θ
即,输入状态先经过 θ,然后是 ρ,接着是 π,然后是 χ,最后是 ι,得到输出状态。 - 这五个步骤中,前四个(θ, ρ, π, χ)在每一轮中执行的逻辑是完全相同的。唯独 \(\iota\) 步骤,它在每一轮中会与一个不同的、称为“轮常数(round constant, rc)”的 64 比特值进行异或操作。 这使得每一轮的操作都略有不同,打破了置换的完全对称性和周期性,这对于算法抵抗密码学攻击(如固定点攻击、对称攻击等)至关重要。
- Keccak-f[1600] 的一轮操作 R 可以表示为:
-
深入剖析 \(\iota\) (Iota) 步骤
- 作用:ι 步骤是整个轮函数中唯一与轮序号(round index)相关的步骤。它负责向状态中注入一个与轮数相关的常量,打破置换函数在 24 轮中的完全对称性,增加算法的“不对称性”和“随机性”,从而提升密码学安全性。
- 计算位置:在每一轮的末尾执行。其输入是经过 χ 步骤处理后的状态 A。
- 计算对象:ι 步骤只修改状态数组中的单个“片”(lane),具体是位于 (x, y) = (0, 0) 的那个 64 比特的字,记为 A[0][0]。
- 计算操作:一个简单的按位异或 (XOR) 操作。
A[0][0] = A[0][0] ⊕ RC[i]
其中:i是当前轮数的索引,从 0 开始计数。Keccak-f[1600] 共有 24 轮,所以 i 的取值范围是 0 到 23。RC[i]是第 i 轮的轮常数,是一个 64 比特的值。
- 视觉化:想象 5x5 的 64 比特数组,只有最左上角(第0行,第0列)的那个 64 比特字会发生变化,其他 24 个字保持不变。变化方式是将这个字与一个预先计算好的常量
RC[i]进行异或。
-
轮常数 RC[i] 的生成详解
- 轮常数并非随机选取,而是由一个确定性的、简单的线性反馈移位寄存器 (LFSR) 规则生成的,目的是确保其“比特位看起来足够随机”,但计算又极其高效。
- RC 的比特生成定义在一个 8 比特的寄存器上。对于每一轮 i,其轮常数
RC[i]是一个 64 比特的数,但只有最低的若干位可能为 1,其他高位均为 0。具体哪些位为 1 由以下算法确定:- 令
rc为一个 8 比特的寄存器,所有位初始化为 0。 - 对于每一轮
i(从 0 到 23),执行以下操作来生成该轮的RC[i]:
a. 重置 rc:rc被重新初始化为一个 8 比特的零向量,但有一个例外:其最低有效位 (LSB, 位置 0) 被设置为 1。即rc = 0b00000001(二进制)。
b. LFSR迭代:对j从 1 循环到 7(共7次):
* 计算比特t。如果rc的第 0 位为 1,则t = 1,否则t = 0。
* 将rc寄存器整体向右移动一位(相当于除以2,高位补0)。
* 将rc新的第 7 位(最高有效位,MSB)与t进行异或。这是因为 Keccak 使用的 LFSR 反馈多项式是 x^8 + x^6 + x^5 + x^4 + 1。这个操作就是模拟了这个多项式。
c. 映射到 64 比特:经过上述 7 次移位/异或操作后,rc寄存器中的 8 比特值(我们称它为rc_byte)就生成了。RC[i]是一个 64 比特的字,其中只有那些满足2^j - 1(j 是整数)的比特位置,其值才可能被设置为rc_byte中对应的比特。更精确的官方定义是:对于 z 从 0 到 63(比特位索引),如果 z 是 2 的整数次幂减 1 (即 z ∈ {0, 1, 3, 7, 15, 31, 63}),则RC[i][z] = rc_byte[z],否则RC[i][z] = 0。
d. 结果:RC[i]是一个大部分位为 0 的 64 位数,只在特定的几个位置(z=0,1,3,7,15,31,63)可能有 1。这使得硬件实现中,只需用少量逻辑门对 A[0][0] 的这几个特定位进行翻转(XOR 1 就是取反)。
- 令
-
示例与验证
- 我们可以手动或编程计算前几轮的 RC 值。例如:
- 轮 0 (i=0):
RC[0]最低 64 位是0x0000000000000001(只有 z=0 位是 1) - 轮 1 (i=1):
RC[1]是0x0000000000008082(z=1 和 z=7 位是 1,因为 0x8082 二进制是 1000 0000 1000 0010,对应 z=1,7 的比特为1,在 64 位表示中高位补0)。
- 轮 0 (i=0):
- 在实现 SHA-3 时,通常会将这些 24 个轮常数预先计算好,存储在一个常量数组中,运行时直接查表使用,效率极高。
- 我们可以手动或编程计算前几轮的 RC 值。例如:
-
\(\iota\) 步骤的安全性意义
- 打破对称性:没有 ι 步骤,Keccak-f 的每一轮将是完全相同的。攻击者可能会利用这种高度对称性,结合状态的代数结构,构造出更简单的等效表示或找到短周期,从而减弱置换的伪随机性。ι 步骤通过每轮注入不同的常数,确保了 24 轮变换各不相同,极大地增加了攻击的复杂性。
- 防止固定点:轮常数的注入使得状态全为零(0)的状态不太可能成为轮函数的固定点(即 R(A) = A),也避免了其他简单模式成为固定点,这对于哈希函数的安全性很重要。
- 与 χ 步骤协同:ι 步骤在非线性极强的 χ 步骤之后执行。χ 是 Keccak-f 中唯一的非线性(与、或、非运算)步骤。在 χ 之后立即注入轮常数,可以将这个局部(单个片)的、由常数引起的微小差异,通过后续的轮迭代(特别是下一轮的 θ 步骤,它进行列奇偶性计算,具有很好的比特扩散性)迅速扩散到整个状态。
总结
ι 步骤是 Keccak-f 轮函数中看似最简单(仅对一个 64 比特字做异或)、但安全上极为重要的一步。它通过一个基于 LFSR 生成的、与轮序号相关的常数,破坏了置换的完全对称性,为整个海绵结构提供了必需的“非对称扰动源”,是 SHA-3 算法能够抵抗多种密码分析攻击的关键设计之一。其计算开销极低,体现了 Keccak 设计“在保证安全的前提下力求简洁高效”的哲学。