SHA-3 (Keccak) 海绵结构中的吸收与挤压过程详解
字数 2903 2025-12-19 13:07:14

SHA-3 (Keccak) 海绵结构中的吸收与挤压过程详解

题目描述

我们今天要讲解的,是SHA-3哈希算法家族的核心——Keccak海绵结构中的关键两步:吸收(Absorbing)和挤压(Squeezing)。SHA-3是美国国家标准与技术研究院(NIST)在2012年选定的新一代密码哈希标准,其安全性建立在海绵结构(Sponge Construction)之上。与之前基于Merkle-Damgård结构的哈希算法(如SHA-256)不同,海绵结构提供了更大的灵活性,不仅可用于哈希,还可用于伪随机数生成、认证加密等。

简单来说,海绵结构就像一个真正的海绵:

  1. 吸收:将输入的消息“水分”全部吸入海绵内部,填满其内部状态。
  2. 挤压:然后将海绵“拧干”,按需输出任意长度的结果(如哈希值)。

理解这两个过程,是掌握SHA-3工作原理的关键。我们将一步步拆解这个过程,从最基础的概念开始。

解题过程(原理讲解)

第一步:理解海绵结构的基本参数

在讲解过程前,必须先了解Keccak使用的几个核心参数。Keccak内部有一个状态(State),它是一个三维的比特数组,尺寸为5×5×w,其中w是2的幂(在SHA3-256中,w=64)。但我们更常从速率和容量的角度来看它:

  • 状态宽度(b):状态的总比特数。b = 5 * 5 * w。SHA3标准中,b∈{25, 50, 100, 200, 400, 800, 1600}。最常用的是b=1600(对应w=64)。
  • 速率(r):在每次“吸收”操作中,与输入消息进行混合的比特数。它控制了数据吞吐的速度。
  • 容量(c):状态中不与输入直接混合的比特数。c = b - r。它决定了算法的安全等级,抵抗碰撞和原像攻击的安全强度约为c/2。

例如,对于SHA3-256

  • b = 1600 bits
  • r = 1088 bits
  • c = 512 bits
    这意味着它的安全强度是256位(c/2=256)。

初始状态:在开始处理消息前,一个5×5×w的全零数组被初始化。

第二步:吸收(Absorbing)阶段详解

吸收阶段的目标,是将任意长度的输入消息M,分块填充到海绵的内部状态中。

  1. 填充(Padding)

    • 首先,输入消息M需要进行填充,以确保其总长度是速率r的整数倍。Keccak使用一个简单的填充规则pad10*1
    • 这个规则是:在消息末尾先添加一个比特1,然后添加若干个比特0(可能为0个),最后再添加一个比特1。添加的0的个数,要使得填充后的消息总长度是r的整数倍。
    • 举例:假设r=8 bits(仅为示例简化),消息M=0110 001(7 bits)。我们需要填充到8的倍数。填充过程:M || 1 || 000... || 1。计算:0110 001 + 1 = 0110 0011,长度已是8,所以不需要添加0,直接在末尾再加最后一个1。最终填充后消息为0110 0011 1,长度为9,不是8的倍数?等等,这里计算有误,我们重新规范一下。
    • 规范示例pad10*1确保填充后的比特串长度为 r 的整数倍。填充内容为:1, 然后是 0*(任意多个,包括0个),最后是 1。更准确的描述是,在消息后添加一个比特1,然后添加最少个数的比特0,使得总长度等于 (n * r) - 1,其中n是某个整数,然后再添加一个比特1。这样,最终长度就是 n * r。对于上面的例子(M=0110001,7 bits, r=8),我们需要填充到8的倍数(比如8)。7 bits的消息,要变成8 bits,需要加1 bit。添加的这1 bit,按照规则,就是1(它既是开头的1,也是结尾的1,因为没有空间放中间的0了)。所以填充后是 0110001 1,长度8 bits,正好是r=8的1倍。
  2. 分块处理

    • 填充后的消息P被分割成若干个长度为r比特的数据块:P = P0, P1, ..., Pk-1。
  3. 吸收循环

    • 海绵结构初始化时,内部状态S是一个5x5xw的全零数组。
    • 对于第一个分块P0:将P0(r bits)与状态S的最前面的r个比特(对应于速率部分)进行按位异或(XOR) 操作。状态的后面c个比特(容量部分)保持不变。
    • 应用置换函数f:然后,对整个状态S(b bits)应用Keccak的核心置换函数f(在b=1600时,称为Keccak-f[1600])。这个函数非常复杂,由12+2l轮(l=log2(w),对于w=64,l=6,共24轮)的θ、ρ、π、χ、ι五个步骤组成,目的是对状态进行充分的混淆和扩散。
    • 对于后续分块Pi (i>0):重复上述过程。将下一个分块Pi与经过上一轮置换后的状态的前r个比特进行XOR,然后再对整个状态应用置换函数f
    • 这个过程一直持续到所有消息分块都被“吸收”进海绵。

    简单记忆:吸收 = (XOR一个分块 -> 对整个状态应用f) , 重复直到所有分块处理完。

    吸收阶段结束后,海绵的内部状态已经包含了整个输入消息的信息(被充分搅拌混淆)。

第三步:挤压(Squeezing)阶段详解

挤压阶段的目标,是从已经“吸饱”消息的海绵状态中,输出我们最终需要的哈希值。

  1. 初始化输出:在吸收完最后一个消息分块后,我们得到了一个最终状态S_final。

  2. 输出循环

    • 首次输出:从当前状态S_final中,直接取出前r个比特(速率部分),作为输出的第一部分Z0。
    • 检查输出长度:我们需要的哈希输出长度是d bits(例如SHA3-256中d=256)。如果r >= d,那么Z0的前d个比特就是最终的哈希值,挤压阶段立即结束。
    • 需要更多输出:如果d > r(例如在需要很长输出时),则:
      • 对当前状态再次应用置换函数f,得到一个新状态。
      • 从这个新状态中,取出前r个比特,作为输出的下一部分Z1。
      • 将Z0, Z1, ... 连接起来,直到总长度至少为d bits。
    • 截断:最后,将所有输出的比特块连接后,截取前d个比特,作为最终的哈希值。

    简单记忆:挤压 = 读取前r位作为输出 -> 如果需要更多,就应用f再读取前r位 -> 重复 -> 最后截断到所需长度d。

总结与图示

整个海绵结构的过程可以用一个清晰的流程图表示:

输入消息M
     |
     V
填充:M -> P (P = M || pad10*1,长度为 r 的整数倍)
     |
     V
分割:P = P0 || P1 || ... || Pk-1
     |
     V
初始化状态 S = 0^b
     |
     V
[吸收阶段开始]
对于 i 从 0 到 k-1:
    S = S ⊕ (Pi || 0^c)  // 将Pi与S的前r位XOR,c位容量部分与0 XOR(即不变)
    S = f(S)             // 对完整的b位状态应用置换函数
[吸收阶段结束]
     |
     V
[挤压阶段开始]
Z = 空字符串
while (输出Z的长度 < d):
    Z = Z || (S的前r个比特) // 从当前状态读取r位
    S = f(S)               // 应用置换函数获取下一个状态
[挤压阶段结束]
     |
     V
最终哈希值 = Z 的前 d 个比特

核心要点

  1. 吸收是“吃进去并搅拌”,通过XOR混合消息,通过f函数扩散混淆。
  2. 挤压是“挤出来”,直接读取状态的一部分作为输出,如果不够就再“拧”(应用f)一下,再读。
  3. 容量c是关键:它从未被直接输出,像是一个秘密的“内存”,保证了攻击者无法轻易地反向计算或构造碰撞。这是海绵结构安全性的基石。

通过以上步骤,SHA-3海绵结构就能够以简洁而安全的方式,将任意长度的输入,变换为固定长度的哈希输出。这种结构的美妙之处在于其统一性和灵活性,速率r和容量c的参数化使其能适配不同的安全和性能需求。

SHA-3 (Keccak) 海绵结构中的吸收与挤压过程详解 题目描述 我们今天要讲解的,是SHA-3哈希算法家族的核心——Keccak海绵结构中的关键两步:吸收(Absorbing)和挤压(Squeezing)。SHA-3是美国国家标准与技术研究院(NIST)在2012年选定的新一代密码哈希标准,其安全性建立在海绵结构(Sponge Construction)之上。与之前基于Merkle-Damgård结构的哈希算法(如SHA-256)不同,海绵结构提供了更大的灵活性,不仅可用于哈希,还可用于伪随机数生成、认证加密等。 简单来说,海绵结构就像一个真正的海绵: 吸收 :将输入的消息“水分”全部吸入海绵内部,填满其内部状态。 挤压 :然后将海绵“拧干”,按需输出任意长度的结果(如哈希值)。 理解这两个过程,是掌握SHA-3工作原理的关键。我们将一步步拆解这个过程,从最基础的概念开始。 解题过程(原理讲解) 第一步:理解海绵结构的基本参数 在讲解过程前,必须先了解Keccak使用的几个核心参数。Keccak内部有一个状态(State),它是一个三维的比特数组,尺寸为5×5×w,其中w是2的幂(在SHA3-256中,w=64)。但我们更常从速率和容量的角度来看它: 状态宽度(b) :状态的总比特数。b = 5 * 5 * w。SHA3标准中,b∈{25, 50, 100, 200, 400, 800, 1600}。最常用的是b=1600(对应w=64)。 速率(r) :在每次“吸收”操作中,与输入消息进行混合的比特数。它控制了数据吞吐的速度。 容量(c) :状态中不与输入直接混合的比特数。c = b - r。它决定了算法的安全等级,抵抗碰撞和原像攻击的安全强度约为c/2。 例如,对于 SHA3-256 : b = 1600 bits r = 1088 bits c = 512 bits 这意味着它的安全强度是256位(c/2=256)。 初始状态 :在开始处理消息前,一个5×5×w的全零数组被初始化。 第二步:吸收(Absorbing)阶段详解 吸收阶段的目标,是将任意长度的输入消息M,分块填充到海绵的内部状态中。 填充(Padding) : 首先,输入消息M需要进行填充,以确保其总长度是速率r的整数倍。Keccak使用一个简单的填充规则 pad10*1 。 这个规则是:在消息末尾先添加一个比特 1 ,然后添加若干个比特 0 (可能为0个),最后再添加一个比特 1 。添加的 0 的个数,要使得填充后的消息总长度是r的整数倍。 举例 :假设r=8 bits(仅为示例简化),消息M= 0110 001 (7 bits)。我们需要填充到8的倍数。填充过程: M || 1 || 000... || 1 。计算: 0110 001 + 1 = 0110 0011 ,长度已是8,所以不需要添加 0 ,直接在末尾再加最后一个 1 。最终填充后消息为 0110 0011 1 ,长度为9,不是8的倍数?等等,这里计算有误,我们重新规范一下。 规范示例 : pad10*1 确保填充后的比特串长度为 r 的整数倍。填充内容为: 1 , 然后是 0 * (任意多个,包括0个),最后是 1 。更准确的描述是,在消息后添加一个比特 1 ,然后添加最少个数的比特 0 ,使得总长度等于 (n * r) - 1 ,其中n是某个整数,然后再添加一个比特 1 。这样,最终长度就是 n * r 。对于上面的例子(M= 0110001 ,7 bits, r=8),我们需要填充到8的倍数(比如8)。7 bits的消息,要变成8 bits,需要加1 bit。添加的这1 bit,按照规则,就是 1 (它既是开头的1,也是结尾的1,因为没有空间放中间的0了)。所以填充后是 0110001 1 ,长度8 bits,正好是r=8的1倍。 分块处理 : 填充后的消息P被分割成若干个长度为r比特的数据块:P = P0, P1, ..., Pk-1。 吸收循环 : 海绵结构初始化时,内部状态S是一个5x5xw的全零数组。 对于第一个分块P0 :将P0(r bits)与状态S的最前面的r个比特(对应于速率部分)进行 按位异或(XOR) 操作。状态的后面c个比特(容量部分)保持不变。 应用置换函数f :然后,对整个状态S(b bits)应用Keccak的核心置换函数 f (在b=1600时,称为Keccak-f[ 1600 ])。这个函数非常复杂,由12+2l轮(l=log2(w),对于w=64,l=6,共24轮)的θ、ρ、π、χ、ι五个步骤组成,目的是对状态进行充分的混淆和扩散。 对于后续分块Pi (i>0) :重复上述过程。将下一个分块Pi与 经过上一轮置换后 的状态的前r个比特进行XOR,然后再对整个状态应用置换函数 f 。 这个过程一直持续到所有消息分块都被“吸收”进海绵。 简单记忆 :吸收 = (XOR一个分块 -> 对整个状态应用f) , 重复直到所有分块处理完。 吸收阶段结束后,海绵的内部状态已经包含了整个输入消息的信息(被充分搅拌混淆)。 第三步:挤压(Squeezing)阶段详解 挤压阶段的目标,是从已经“吸饱”消息的海绵状态中,输出我们最终需要的哈希值。 初始化输出 :在吸收完最后一个消息分块后,我们得到了一个最终状态S_ final。 输出循环 : 首次输出 :从当前状态S_ final中, 直接取出 前r个比特(速率部分),作为输出的第一部分Z0。 检查输出长度 :我们需要的哈希输出长度是d bits(例如SHA3-256中d=256)。如果r >= d,那么Z0的前d个比特就是最终的哈希值,挤压阶段立即结束。 需要更多输出 :如果d > r(例如在需要很长输出时),则: 对当前状态 再次应用 置换函数 f ,得到一个新状态。 从这个新状态中,取出前r个比特,作为输出的下一部分Z1。 将Z0, Z1, ... 连接起来,直到总长度 至少 为d bits。 截断 :最后,将所有输出的比特块连接后, 截取 前d个比特,作为最终的哈希值。 简单记忆 :挤压 = 读取前r位作为输出 -> 如果需要更多,就应用f再读取前r位 -> 重复 -> 最后截断到所需长度d。 总结与图示 整个海绵结构的过程可以用一个清晰的流程图表示: 核心要点 : 吸收是“吃进去并搅拌” ,通过XOR混合消息,通过 f 函数扩散混淆。 挤压是“挤出来” ,直接读取状态的一部分作为输出,如果不够就再“拧”(应用 f )一下,再读。 容量c是关键 :它从未被直接输出,像是一个秘密的“内存”,保证了攻击者无法轻易地反向计算或构造碰撞。这是海绵结构安全性的基石。 通过以上步骤,SHA-3海绵结构就能够以简洁而安全的方式,将任意长度的输入,变换为固定长度的哈希输出。这种结构的美妙之处在于其统一性和灵活性,速率r和容量c的参数化使其能适配不同的安全和性能需求。