GOST 28147-89 分组密码算法的加/解密轮函数中“模 \(2^{32}\) 加法”与“循环左移”的交互作用详解
好的,作为密码学领域的“大神”,我将为你讲解一个尚未出现在你列表中的、非常具体且关键的算法细节:GOST 28147-89(一个苏联/俄罗斯的国家标准分组密码)在加解密轮函数中,“模 \(2^{32}\) 加法”与“循环左移”这两个操作是如何交互,并共同构成其非线性核心的。这个细节对于理解GOST算法的安全性和设计思路至关重要。
题目背景
GOST 28147-89 是一个64位分组、256位密钥的分组密码。它采用32轮的Feistel网络结构。与其他许多Feistel密码(如DES)不同,GOST的轮函数 \(F\) 非常简洁,但其强度很大程度上依赖于两个操作的结合:
- 模 \(2^{32}\) 加法:将轮密钥与一半的数据块(32位)相加,结果取模 \(2^{32}\)。
- 循环左移:将上一步的结果循环左移11位。
这两步并非简单的拼接,而是有深意的相互作用。我们来一步步解析。
解题过程:从整体到局部,剖析交互作用
第一步:回顾GOST单轮Feistel结构
在每一轮 \(i\) 中:
- 输入数据被分成两个32位的左半部分 \(L_{i-1}\) 和右半部分 \(R_{i-1}\)。
- 轮函数的输出为:
\(L_i = R_{i-1}\)
\(R_i = L_{i-1} \oplus F(R_{i-1}, K_i)\)
其中 \(\oplus\) 是逐位异或,\(K_i\) 是第 \(i\) 轮的32位轮密钥,\(F\) 是轮函数。
现在,我们聚焦于轮函数 \(F(R, K)\) 的内部。
第二步:分解轮函数 \(F\) 的标准步骤
轮函数 \(F\) 处理一个32位的输入 \(R\) 和一个32位的轮密钥 \(K\),其标准描述通常包含以下步骤,但我们要深入理解前两步:
- 模加:计算 \(S = (R + K) \mod 2^{32}\)。这是一个32位整数的加法,忽略溢出进位。
- 拆分成字节:将得到的32位结果 \(S\) 拆分成4个8位字节:\(S = s_3 \| s_2 \| s_1 \| s_0\)。
- S盒代换:每个字节 \(s_j\) 通过一个特定的8进4出S盒(\(S_j\))进行非线性替换,得到4位输出。4个S盒并行工作,共输出4×4=16位。
- 合并与移位:将4个4位输出重新合并成一个16位的中间值,然后循环左移11位。
- 输出:这个移位后的16位结果,就是32位轮函数 \(F\) 的最终输出(注意,输出被截断/视为高16位为0?这里有个关键点,稍后解释)。
等等!这里出现了一个核心困惑点,也是理解“交互作用”的关键。从步骤1到步骤4的描述存在一个“跳跃”。我们仔细分析:
第三步:澄清关键点——循环左移作用于哪个值?
许多标准描述为了简化,会说“将S盒输出的16位结果循环左移11位”。但严格来说,这是不精确的。更准确、更本质的描述是:
- 模加:\(T = (R + K) \mod 2^{32}\)。得到 32位 的 \(T\)。
- S盒处理:将 \(T\) 的4个字节分别通过S盒,每个S盒输出4位,得到 16位 的中间值 \(U\)。
- 循环左移:将 原始的32位值 \(T\) 循环左移11位,得到一个32位的值 \(T^{<<<11}\)。
- 交互与输出:轮函数 \(F\) 的最终输出,并不是简单的 \(U\) 或 \(T^{<<<11}\),而是 将 \(U\) 填充到 \(T^{<<<11}\) 的低16位。
用公式精确表达:
\(F(R, K) = (T^{<<<11}) \ \&\ \text{0xFFFF}\)
其中 \(\&\) 是按位与,0xFFFF 是一个掩码,用于取结果的低16位。
换句话说,“循环左移11位”这个操作,是作用在经过模加后、还未进行S盒处理的32位中间值 \(T\) 上的。而S盒处理的16位结果 \(U\),是用来“覆盖”或“填入”移位后 \(T\) 的低16位。
第四步:深入分析“模加”与“循环左移”的交互作用
现在我们可以清晰地分析这两个操作的交互:
-
模加的“扩散”作用:
- 轮密钥 \(K\) 通过模 \(2^{32}\) 加法,与数据 \(R\) 完全融合。
- 这个加法是线性的,但其产生的进位传播是关键。即使 \(R\) 和 \(K\) 中只有一个比特发生变化,由于进位链,可能导致输出 \(T\) 的多个比特(尤其是低位)发生变化。
- 例如,如果 \(R\) 的最低位变化,可能引起一连串的进位,最终影响 \(T\) 的低若干位。这种变化是非线性的(因为进位逻辑不是简单的线性函数)。
-
循环左移的“破坏对齐”与“跨字节混合”作用:
- 将 \(T\) 循环左移11位,这是一个非常精妙的设计。11位不是一个字节(8位)的整数倍,也不是一个字的整数倍。
- 它的作用是将由模加产生的、可能集中在低位的比特变化(尤其是进位效应),扩散到整个32位字的不同位置,特别是跨越原始的字节边界。
- 具体来说,\(T\) 的低11位(可能是受进位影响最直接的区域)会被移动到高11位。同时,\(T\) 的高21位会被移动到低21位。这使得原来在低字节发生的、由模加带来的复杂变化,被“搅拌”到了中间字节和高字节。
-
两者的协同效应:
- 交互的核心:
模加引入了依赖于密钥和数据的、非线性的比特变化模式(尤其是通过进位)。循环左移则像一个强大的搅拌器,立即将这个变化模式从局部(通常是字的低位)打散到整个字的各个部分,特别是S盒将要处理的各个字节中。 - 如果没有循环左移,模加的效果主要停留在低字节,S盒只处理这些局部变化,密码的整体扩散性会变差。
- 如果没有模加(只用异或),\(T = R \oplus K\) 的变化是线性的,循环左移虽然能扩散比特,但输入变化的模式过于简单,安全性不足。
- 二者结合:模加提供了复杂、非线性的比特变化“原料”,循环左移提供了高效、全局的比特扩散“手段”。这种“先制造复杂局部扰动,再立即全局搅拌”的设计,是GOST轮函数简洁而有效的核心。
- 交互的核心:
第五步:结合S盒看最终输出
最后,这个经过“模加-移位”处理后的32位值 \(T^{<<<11}\),其低16位被S盒的输出 \(U\) 所覆盖。
- \(U\) 本身是高度非线性的(由S盒提供)。
- 而 \(T^{<<<11}\) 的高16位,保留了经过搅拌的、由模加产生的复杂变化信息。
- 取这个混合值的低16位作为 \(F\) 函数的输出,意味着最终输出同时包含了S盒的非线性,以及经过移位扩散后的模加复杂性的影响。
总结
在GOST 28147-89的轮函数中,“模 \(2^{32}\) 加法”与“循环左移11位”的交互作用,构成了一个精妙的非线性扩散对:
- 模加:作为非线性扰动源,利用整数加法的进位传播特性,在输入与密钥的微小变化下,产生不可预测的、非线性的比特变化,主要作用于低位。
- 循环左移:作为全局扩散器,将模加在低位产生的复杂变化模式,通过非对齐的移位(11位),立即打散并重新分布到32位字的各个部分,特别是跨越字节边界,为后续的S盒处理提供了高度混合且依赖于密钥的输入。
这种设计使得GOST在仅使用非常简单的操作和较少轮数(相比同时代算法)的情况下,获得了良好的混淆与扩散效果,是其能够抵御差分和线性密码分析等攻击的重要因素。理解这种底层操作的交互,是深入掌握古典和现代分组密码设计艺术的关键。