SHA-256哈希算法的Sigma函数(σ0, σ1)详解
这是一个关于SHA-256哈希算法核心组件的深度解析题目。我们将聚焦于其压缩函数中使用的两个重要辅助函数:小写Sigma函数 σ0 和小写Sigma函数 σ1。它们是SHA-256算法实现强大扩散性和非线性的关键。
题目描述
在SHA-256压缩函数中,对输入的512位消息块进行处理时,会将16个32位字(W[0] 到 W[15])扩展为64个32位字(W[0] 到 W[63])。在计算第 t 个字 W[t] (其中 16 ≤ t ≤ 63) 时,会使用两个函数:σ0 (sigma0) 和 σ1 (sigma1)。请详细解释这两个函数的定义、输入输出、位运算过程,并阐明它们在消息扩展和整个哈希计算中的作用。
解题过程
我们循序渐进地讲解,先从它们在算法中的位置开始,再深入到细节。
步骤1:定位与上下文——消息扩展(Message Schedule)阶段
SHA-256处理消息时,首先对消息进行填充和分块。每个512位的消息块(16个32位字)会进入压缩函数。压缩函数的第一步,就是将这16个字扩展为64个字(W[0]…W[63]),这个数组称为“消息调度表”。
这个扩展过程的前16个字(W[0]到W[15])直接取自当前的消息块。而从第17个字(W[16])开始,后续的每一个字都由更早的某些字计算得出。σ0 和 σ1 函数就出现在这个计算过程中。
步骤2:函数的形式化定义
对于索引 t (其中 16 ≤ t ≤ 63),W[t] 的计算公式为:
\[W[t] = \sigma_1(W[t-2]) + W[t-7] + \sigma_0(W[t-15]) + W[t-16] \]
这里的“+”是模 \(2^{32}\) 加法。
- 输入:σ0 和 σ1 的输入都是一个32位无符号整数(一个字)。具体来说:
- \(\sigma_0(x)\) 的输入是 \(W[t-15]\)。
- \(\sigma_1(x)\) 的输入是 \(W[t-2]\)。
- 输出:函数的输出也是一个32位无符号整数。
步骤3:位运算详解
这是理解这两个函数的核心。它们由循环右移(Rotate Right, ROTR) 和右移位(Shift Right, SHR) 运算组合而成。
1. σ0 函数 (作用于 W[t-15])
\[\sigma_0(x) = \text{ROTR}^{7}(x) \oplus \text{ROTR}^{18}(x) \oplus \text{SHR}^{3}(x) \]
- ROTR⁷(x):将32位的x循环右移7位。最高7位移动到最低7位,其余位向右移动。
- ROTR¹⁸(x):将x循环右移18位。
- SHR³(x):将x逻辑右移3位。最高3位用0填充,最低3位被丢弃。
- ⊕:表示按位异或(XOR)操作。
2. σ1 函数 (作用于 W[t-2])
\[\sigma_1(x) = \text{ROTR}^{17}(x) \oplus \text{ROTR}^{19}(x) \oplus \text{SHR}^{10}(x) \]
- 原理同 σ0,只是移位常数(7,18,3)换成了(17,19,10)。
为什么要这样设计移位常数?
这些常数(7,18,3,17,19,10)是经过精心选择的,目的是在扩展过程中实现高度的比特扩散(Diffusion)。它们确保输入字中的任何一个比特的变化,都能通过异或运算快速传播到输出字的多个不同位置上。这增加了算法的雪崩效应——即微小的输入改变会导致输出的巨大、不可预测的变化。
步骤4:计算过程示例(以计算W[16]为例)
假设我们已经有了W[0]到W[15]。我们来计算W[16]。
- 取出所需的历史字:
W[1](t-15),W[9](t-7),W[14](t-2),W[0](t-16)。 - 计算中间值:
A = σ1(W[14])= ROTR¹⁷(W[14]) ⊕ ROTR¹⁹(W[14]) ⊕ SHR¹⁰(W[14])B = W[9]C = σ0(W[1])= ROTR⁷(W[1]) ⊕ ROTR¹⁸(W[1]) ⊕ SHR³(W[1])D = W[0]
- 模 \(2^{32}\) 相加:
W[16] = A + B + C + D。- 注意这里的“+”是整数加法,结果超过 \(2^{32}-1\) 的部分会溢出丢弃(即模 \(2^{32}\))。
步骤5:函数的核心作用与安全目标
- 引入非线性与消除线性结构:虽然移位和异或本身是线性运算,但将它们以特定的顺序和常数组合,并嵌入到模加法的迭代中,使得整个扩展过程具有很强的非线性特性。这能有效抵抗针对线性或简单代数结构的密码分析。
- 实现比特扩散:如上所述,移位常数确保输入比特的影响扩散到输出的不同位置。这使得最终生成的64字消息调度表(W数组)的每一位都高度依赖于原始16个字的许多位。
- 打破对称性/规律性:如果没有σ0和σ1,消息扩展将变成一个简单的线性递推,会存在固定的比特位关系,容易遭受固定点攻击和相关攻击。这两个函数破坏了任何潜在的简单规律。
- 提供前向依赖性:W[t] 依赖于4个历史字,其中两个(t-15, t-2)经过了σ函数的“混淆”处理。这保证了即使在压缩函数的主循环开始之前,消息块内部已经进行了充分的混合。
总结
SHA-256中的 σ0 和 σ1 函数,通过精心设计的循环右移、逻辑右移和异或运算,在消息扩展阶段扮演了“局部混淆与扩散器”的角色。它们将线性的移位操作转化为非线性的比特混合过程,确保了消息调度表中的每个扩展字都充满了充分的复杂性和不可预测性,从而为后续的64轮压缩函数主循环奠定了坚实的安全基础,是SHA-256能够抵抗各种密码学攻击的关键设计之一。