SHA-3 (Keccak) 海绵结构中的吸收与挤压过程详解
我将为您讲解SHA-3哈希算法(Keccak)中核心的海绵结构(Sponge Construction)及其吸收(Absorbing)与挤压(Squeezing)过程。这是理解SHA-3如何从任意长度消息生成固定长度哈希值的关键。
一、题目描述:SHA-3 海绵结构的工作原理
SHA-3(Secure Hash Algorithm 3)是美国国家标准与技术研究院(NIST)在2015年标准化的新一代密码杂凑算法,其核心结构是“海绵结构”。这是一种灵活的密码学结构,不仅可用于哈希计算,还可用于伪随机数生成、消息认证码等。
海绵结构可以形象地理解为一块海绵:
- 吸收阶段:海绵吸收水(输入消息)。
- 挤压阶段:对海绵施压,挤出固定量的水(输出哈希值)。
整个过程的输入是一个任意长度的消息M,输出是一个固定长度d的哈希值。海绵结构的核心参数有两个:
- 比特率 r(bitrate):每个处理块的大小,表示每次吸收/挤压阶段处理的比特数。
- 容量 c(capacity):安全参数,表示内部状态中不与输入直接混合的部分。c的大小决定了算法的安全强度,通常为哈希输出长度的两倍。
二、解题过程:循序渐进理解海绵结构
步骤1:理解海绵结构的基础——状态与填充
SHA-3的海绵结构内部维护一个状态(state),其总长度b = r + c。对于SHA-3标准,b可以是{25, 50, 100, 200, 400, 800, 1600}比特中的一个,其中最常用的是b=1600比特(SHA3-256、SHA3-512等)。在b=1600比特时,状态可以看作一个5×5×64的三维比特数组(5行,5列,64位深度的“车道”)。
在吸收消息前,需要对消息M进行填充,以确保其长度是比特率r的整数倍。SHA-3使用一个简单的填充规则:pad10*1。具体来说:
- 在消息末尾附加一个比特
1。 - 接着附加零个或多个比特
0,直到消息长度(填充后)达到比r的整数倍少1比特。 - 最后再附加一个比特
1。
例如,如果消息长度已经是r的整数倍,填充规则会附加一个完整的r比特块,其格式为1,接着是r-2个0,最后是1。填充确保了消息的每一位都被处理,且填充块是唯一的。
步骤2:吸收阶段(Absorbing Phase)的详细过程
吸收阶段的目标是将填充后的消息P完全混入内部状态中。步骤如下:
-
初始化状态:将b比特的状态(5×5×64数组)全部初始化为0。
-
消息分块:将填充后的消息P分割成若干个长度为r比特的块:
P = P0 || P1 || ... || Pk-1,其中每个Pi的长度为r比特。 -
迭代吸收:对每一个消息块
Pi(i从0到k-1)依次执行以下操作:
a. 异或操作:将当前状态的前r比特与消息块Pi进行按位异或(XOR)。这里的“前r比特”通常定义为状态数组中索引顺序下的前r个比特。在实现中,我们可以将状态视为一个平面,前r个比特对应于状态数组的起始部分。
b. 置换函数:对整个b比特的状态(即r+c比特)应用Keccak-f[b]置换函数。这是一个复杂的、多轮的非线性变换,目的是充分混淆和扩散状态中的所有比特。
c. 处理完当前消息块后,继续处理下一个消息块Pi+1,重复步骤a和b。用数学公式表示吸收阶段的状态更新为:
S = 0 (初始状态)
for i in 0 to k-1:
S = Keccak-f( S ⊕ (Pi || 0^c) ) // 先将消息块Pi填充c个0到长度b,然后与状态异或,最后进行置换。注意:
Pi || 0^c表示将消息块Pi(r比特)与c个0拼接,构成一个b比特的块,然后与当前的b比特状态S进行异或。
步骤3:挤压阶段(Squeezing Phase)的详细过程
挤压阶段的目标是从最终的状态中提取所需长度的输出哈希值。步骤如下:
-
初始准备:在吸收完所有消息块后,我们得到了一个经过充分混淆的状态S。
-
迭代挤压:
a. 从当前状态S中提取前r比特作为输出块Zi。
b. 如果已提取的比特数(即所有Zi连接起来的长度)小于所需的输出长度d,则对整个状态应用Keccak-f[b]置换函数,然后从新状态中再提取前r比特作为下一个输出块Zi+1。
c. 重复步骤b,直到提取的比特总数至少为d。 -
截断输出:将提取的所有输出块
Z0, Z1, Z2, ...连接起来,然后取前d比特,即得到最终的哈希值。用数学公式表示挤压阶段的输出生成过程为:
Z = 空字符串
while len(Z) < d:
Z = Z || (S的前r比特) // 提取状态前r比特
S = Keccak-f(S) // 应用置换,为下一轮提取准备
最终哈希值 H = Z[0..d-1] // 取前d比特
三、实例与安全设计思想
实例:假设我们使用SHA3-256,其输出长度d=256比特,安全容量c=512比特。在b=1600的常见设置中,比特率r = b - c = 1600 - 512 = 1088比特。这意味着:
- 吸收阶段,每个消息块长度为1088比特(136字节)。
- 每次挤压,最多可提取1088比特的数据。对于256比特输出,只需一次挤压即可。
安全设计思想:
- 容量c决定安全性:海绵结构的安全性(如抗碰撞性、原像攻击)与容量c直接相关。c越大,安全性越高。NIST标准要求c ≥ 2d,以确保哈希函数的安全性等同于暴力破解d/2比特哈希的难度。
- 吸收与挤压的隔离:吸收阶段,外部输入(消息)只能影响状态的前r比特(通过异或),而内部状态的后c比特(容量部分)从不直接与输入混合,这使得攻击者无法完全控制内部状态。在挤压阶段,输出的前r比特是状态的一部分,但后续的r比特输出经过了Keccak-f置换,使得输出看起来是随机的。
- 置换函数Keccak-f:它是一个复杂的、多轮的置换,包含θ、ρ、π、χ、ι五个步骤,确保状态比特之间具有高度的扩散和混淆,使得从输出反推输入或内部状态在计算上不可行。
总结:
SHA-3的海绵结构通过吸收和挤压两个阶段,将任意长度的消息转换为固定长度的哈希值。其安全性源于容量部分的隔离和强大的Keccak-f置换函数。理解这个过程是掌握SHA-3算法的基础,也是理解其与其他哈希结构(如Merkle-Damgård结构)区别的关键。