CAST-128分组密码算法
字数 3160 2025-12-09 08:33:52

CAST-128分组密码算法

CAST-128是一种对称分组密码算法,采用传统的Feistel网络结构。它的分组长度为64位,密钥长度可变(从40位到128位,以8位递增)。算法由Carlisle Adams和Stafford Tavares设计,以其设计者的首字母命名。CAST-128以其简单、高效和可证明的安全性特性而闻名。算法的核心在于其复杂的轮函数,该函数结合了非线性的S盒、依赖于密钥的旋转和异或操作。今天,我们将详细讲解CAST-128算法的加密过程,重点关注其轮函数的设计。

1. 算法总体结构
CAST-128是一个平衡的Feistel网络密码。对于64位的明文分组,它将其分为两个32位的半块:左半部分 \(L_0\) 和右半部分 \(R_0\)
算法共有16轮(对于长度大于等于80位的密钥)或12轮(对于长度小于80位的密钥)。我们今天以最常见的16轮版本为例。
每一轮的基本操作如下(i 从1到16):

  1. \(R_i = L_{i-1} \oplus F(R_{i-1}, K_i)\) ,其中F是轮函数,\(K_i\) 是第i轮的轮密钥。
  2. \(L_i = R_{i-1}\)
    在16轮之后,最后会交换左右两半,即最终的左右半块是 \((L_{16}, R_{16})\),将它们拼接成64位数据即为密文。

2. 轮函数F的设计
轮函数F是CAST-128的核心。它接收一个32位的输入(来自上一轮的右半块)和一个32位的轮密钥 \(K_i\),输出一个32位的结果。F函数内部又分为三个“类型”的操作,分别称为Type 1, Type 2, Type 3。在16轮中,奇数轮(1,3,5…)和偶数轮(2,4,6…)分别使用Type 1和Type 2,而中间的第3,7,11,15轮(如果你数一下,是第3,7,11,15轮)实际上也使用了Type 1,但算法设计中,第5,9,13轮被指定为Type 3。不过,为了让讲解更清晰,我们聚焦于最核心的Type 1Type 2 结构。它们的区别主要在于轮密钥如何与中间数据结合。

我们先看Type 1轮函数的步骤:

  1. 密钥加法: 将32位的输入数据与32位的轮密钥 \(K_i\) 进行加法运算(模 \(2^{32}\)),得到一个32位的结果I。这个“加法”是模 \(2^{32}\) 的整数加法。
  2. S盒替换: 将上一步得到的32位结果I,从高位到低位(从左到右)分成四个8位字节。我们记作:\(I = [Ia, Ib, Ic, Id]\),其中Ia是最高有效字节。
    然后,用四个不同的8x32位S盒(即输入8位,输出32位)分别对每个字节进行替换:
    • \(S_1\) 处理字节 Ia,得到32位输出 \(S1[Ia]\)
    • \(S_2\) 处理字节 Ib,得到32位输出 \(S2[Ib]\)
    • \(S_3\) 处理字节 Ic,得到32位输出 \(S3[Ic]\)
    • \(S_4\) 处理字节 Id,得到32位输出 \(S4[Id]\)
  3. 组合与非线性混合: 将上述四个32位输出进行组合。具体操作是:
    • \(S1[Ia]\)\(S2[Ib]\) 进行按位异或(XOR),得到中间值A。
    • \(S3[Ic]\)\(S4[Id]\) 进行按位异或(XOR),得到中间值B。
    • 然后,从B中减去A(模 \(2^{32}\)),得到中间值C。
    • 最后,从\(S1[Ia]\)减去 \(S3[Ic]\)(模 \(2^{32}\)),然后与中间值C进行按位异或,得到最终结果D。
  4. 循环移位: 对结果D进行循环左移,移位的位数由轮密钥 \(K_i\) 的最低有效5位(即 \(K_i \mod 32\))决定。这个移位操作是循环左移,即移出的位从右侧补入。移位后的32位数据就是本轮F函数的最终输出。

Type 2轮函数的步骤与Type 1非常相似,但有两个关键区别:

  1. 密钥操作顺序不同: 在Type 2中,首先将输入数据与轮密钥 \(K_i\) 进行按位异或(XOR),而不是加法。
  2. S盒处理顺序不同: 在S盒替换步骤,Type 2使用的顺序是:用 \(S_1\) 处理字节Id, \(S_2\) 处理字节Ic, \(S_3\) 处理字节Ib, \(S_4\) 处理字节Ia。即字节处理顺序是反向的。
    其余的“组合与非线性混合”和“循环移位”步骤与Type 1完全相同。

3. 轮密钥生成(简要概述)
为了完整性,我们简述轮密钥如何生成。CAST-128有一个复杂的密钥扩展算法,它将用户密钥(40-128位)扩展为16个32位的轮密钥 \(K_1\)\(K_{16}\)

  1. 密钥填充: 将用户密钥填充或截断为128位。如果不足128位,高位用0填充。
  2. 分割: 将128位密钥分成四个32位的子密钥:\(K_a, K_b, K_c, K_d\)
  3. 密钥表生成: 利用一个预定义的、复杂的密钥扩展函数(涉及模加、循环移位、以及使用与主算法不同的另一组S盒),以上述四个子密钥为基础,生成一系列中间值,最终导出16个轮密钥。这个过程的细节非常繁琐,但其核心思想是确保轮密钥之间具有高度的非线性和独立性,并且密钥的每一位都影响多个轮密钥。

4. 总结加密流程
现在,让我们串联起完整的加密过程:

  1. 输入: 64位明文P,用户密钥K。
  2. 初始化
    • 执行密钥扩展,生成16个32位轮密钥 \(K_1\)\(K_{16}\)
    • 将明文P分为 \(L_0\)(高32位)和 \(R_0\)(低32位)。
  3. 16轮迭代(i从1到16):
    • 根据轮数i决定使用Type 1(奇数轮)还是Type 2(偶数轮)的F函数,计算 \(F(R_{i-1}, K_i)\)
    • \(R_i = L_{i-1} \oplus F(R_{i-1}, K_i)\)
    • \(L_i = R_{i-1}\)
  4. 最终输出: 完成16轮后,输出为 \((L_{16}, R_{16})\)。注意这里没有像标准Feistel网络那样在末尾进行一次交换。将 \(L_{16}\)\(R_{16}\) 直接拼接成64位,即为密文C。

5. 解密过程
解密过程与加密过程完全对称,因为Feistel网络具有自反性。唯一的不同是轮密钥的使用顺序是反的

  1. 将64位密文C分为 \(R_{16}\)\(L_{16}\)
  2. 对于i从16下降到1:
    • \(R_{i-1} = L_i\)
    • \(L_{i-1} = R_i \oplus F(R_{i-1}, K_i)\)。 (注意,这里的 \(R_{i-1}\) 就是上一步刚得到的值,而F函数使用的是与加密时相同的第i轮密钥 \(K_i\))。
  3. 最终得到 \((L_0, R_0)\),拼接后即得原始明文。

通过上述步骤,你可以看到CAST-128如何通过其精心设计的、结合了模加/减、异或、大S盒和依赖于密钥的循环移位的轮函数,在Feistel框架下实现了高度的非线性和扩散,从而保证了其安全性。其密钥扩展过程也确保了即使较短的密钥也能被充分混合。

CAST-128分组密码算法 CAST-128是一种对称分组密码算法,采用传统的Feistel网络结构。它的分组长度为64位,密钥长度可变(从40位到128位,以8位递增)。算法由Carlisle Adams和Stafford Tavares设计,以其设计者的首字母命名。CAST-128以其简单、高效和可证明的安全性特性而闻名。算法的核心在于其复杂的轮函数,该函数结合了非线性的S盒、依赖于密钥的旋转和异或操作。今天,我们将详细讲解CAST-128算法的 加密过程 ,重点关注其轮函数的设计。 1. 算法总体结构 CAST-128是一个平衡的Feistel网络密码。对于64位的明文分组,它将其分为两个32位的半块:左半部分 \( L_ 0 \) 和右半部分 \( R_ 0 \)。 算法共有 16轮 (对于长度大于等于80位的密钥)或 12轮 (对于长度小于80位的密钥)。我们今天以最常见的16轮版本为例。 每一轮的基本操作如下(i 从1到16): \( R_ i = L_ {i-1} \oplus F(R_ {i-1}, K_ i) \) ,其中F是轮函数,\( K_ i \) 是第i轮的轮密钥。 \( L_ i = R_ {i-1} \)。 在16轮之后,最后会 不 交换左右两半,即最终的左右半块是 \( (L_ {16}, R_ {16}) \),将它们拼接成64位数据即为密文。 2. 轮函数F的设计 轮函数F是CAST-128的核心。它接收一个32位的输入(来自上一轮的右半块)和一个32位的轮密钥 \( K_ i \),输出一个32位的结果。F函数内部又分为三个“类型”的操作,分别称为Type 1, Type 2, Type 3。在16轮中,奇数轮(1,3,5…)和偶数轮(2,4,6…)分别使用Type 1和Type 2,而中间的第3,7,11,15轮(如果你数一下,是第3,7,11,15轮)实际上也使用了Type 1,但算法设计中,第5,9,13轮被指定为Type 3。不过,为了让讲解更清晰,我们聚焦于最核心的 Type 1 和 Type 2 结构。它们的区别主要在于轮密钥如何与中间数据结合。 我们先看 Type 1轮函数 的步骤: 密钥加法 : 将32位的输入数据与32位的轮密钥 \( K_ i \) 进行 加法 运算(模 \( 2^{32} \)),得到一个32位的结果I。这个“加法”是模 \( 2^{32} \) 的整数加法。 S盒替换 : 将上一步得到的32位结果I,从高位到低位(从左到右)分成 四个8位字节 。我们记作:\( I = [ Ia, Ib, Ic, Id ] \),其中Ia是最高有效字节。 然后,用四个不同的8x32位S盒(即输入8位,输出32位)分别对每个字节进行替换: \( S_ 1 \) 处理字节 Ia,得到32位输出 \( S1[ Ia ] \)。 \( S_ 2 \) 处理字节 Ib,得到32位输出 \( S2[ Ib ] \)。 \( S_ 3 \) 处理字节 Ic,得到32位输出 \( S3[ Ic ] \)。 \( S_ 4 \) 处理字节 Id,得到32位输出 \( S4[ Id ] \)。 组合与非线性混合 : 将上述四个32位输出进行组合。具体操作是: \( S1[ Ia] \) 和 \( S2[ Ib] \) 进行 按位异或 (XOR),得到中间值A。 \( S3[ Ic] \) 和 \( S4[ Id] \) 进行 按位异或 (XOR),得到中间值B。 然后,从B中 减去 A(模 \( 2^{32} \)),得到中间值C。 最后,从\( S1[ Ia] \) 中 减去 \( S3[ Ic] \)(模 \( 2^{32} \)),然后与中间值C进行 按位异或 ,得到最终结果D。 循环移位 : 对结果D进行 循环左移 ,移位的位数由轮密钥 \( K_ i \) 的最低有效5位(即 \( K_ i \mod 32 \))决定。这个移位操作是 循环左移 ,即移出的位从右侧补入。移位后的32位数据就是本轮F函数的最终输出。 Type 2轮函数 的步骤与Type 1非常相似,但有两个关键区别: 密钥操作顺序不同 : 在Type 2中,首先将输入数据与轮密钥 \( K_ i \) 进行 按位异或 (XOR),而不是加法。 S盒处理顺序不同 : 在S盒替换步骤,Type 2使用的顺序是:用 \( S_ 1 \) 处理字节Id, \( S_ 2 \) 处理字节Ic, \( S_ 3 \) 处理字节Ib, \( S_ 4 \) 处理字节Ia。即字节处理顺序是 反向 的。 其余的“组合与非线性混合”和“循环移位”步骤与Type 1完全相同。 3. 轮密钥生成(简要概述) 为了完整性,我们简述轮密钥如何生成。CAST-128有一个复杂的密钥扩展算法,它将用户密钥(40-128位)扩展为16个32位的轮密钥 \( K_ 1 \) 到 \( K_ {16} \)。 密钥填充 : 将用户密钥填充或截断为128位。如果不足128位,高位用0填充。 分割 : 将128位密钥分成四个32位的子密钥:\( K_ a, K_ b, K_ c, K_ d \)。 密钥表生成 : 利用一个预定义的、复杂的密钥扩展函数(涉及模加、循环移位、以及使用与主算法不同的另一组S盒),以上述四个子密钥为基础,生成一系列中间值,最终导出16个轮密钥。这个过程的细节非常繁琐,但其核心思想是确保轮密钥之间具有高度的非线性和独立性,并且密钥的每一位都影响多个轮密钥。 4. 总结加密流程 现在,让我们串联起完整的加密过程: 输入 : 64位明文P,用户密钥K。 初始化 : 执行密钥扩展,生成16个32位轮密钥 \( K_ 1 \) 到 \( K_ {16} \)。 将明文P分为 \( L_ 0 \)(高32位)和 \( R_ 0 \)(低32位)。 16轮迭代 (i从1到16): 根据轮数i决定使用Type 1(奇数轮)还是Type 2(偶数轮)的F函数,计算 \( F(R_ {i-1}, K_ i) \)。 \( R_ i = L_ {i-1} \oplus F(R_ {i-1}, K_ i) \)。 \( L_ i = R_ {i-1} \)。 最终输出 : 完成16轮后,输出为 \( (L_ {16}, R_ {16}) \)。注意这里 没有 像标准Feistel网络那样在末尾进行一次交换。将 \( L_ {16} \) 和 \( R_ {16} \) 直接拼接成64位,即为密文C。 5. 解密过程 解密过程与加密过程完全对称,因为Feistel网络具有自反性。唯一的不同是 轮密钥的使用顺序是反的 。 将64位密文C分为 \( R_ {16} \) 和 \( L_ {16} \)。 对于i从16下降到1: \( R_ {i-1} = L_ i \)。 \( L_ {i-1} = R_ i \oplus F(R_ {i-1}, K_ i) \)。 (注意,这里的 \( R_ {i-1} \) 就是上一步刚得到的值,而F函数使用的是与加密时 相同 的第i轮密钥 \( K_ i \))。 最终得到 \( (L_ 0, R_ 0) \),拼接后即得原始明文。 通过上述步骤,你可以看到CAST-128如何通过其精心设计的、结合了模加/减、异或、大S盒和依赖于密钥的循环移位的轮函数,在Feistel框架下实现了高度的非线性和扩散,从而保证了其安全性。其密钥扩展过程也确保了即使较短的密钥也能被充分混合。