⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rfc2144.txt

📁 RFC文档
💻 TXT
📖 第 1 页 / 共 3 页
字号:
组织:中国互动出版网(http://www.china-pub.com/)
RFC文档中文翻译计划(http://www.china-pub.com/compters/emook/aboutemook.htm)
E-mail:ouyang@china-pub.com
译者:王安鹏(anpengwang    anpengwang@263.net)
译文发布时间:2001-8-22
版权:本中文翻译文档版权归中国互动出版网所有。可以用于非商业用途自由转载,但必须
保留本文档的翻译及版权信息。


Network Working Group                                         C. Adams
Request for Comments: 2144                        Entrust Technologies
Category: Informational                                       May 1997

CAST-128加密算法
(RFC2144——The CAST-128 Encryption Algorithm )

本备忘录的状态
本备忘录为Internet社区提供信息,但没有定义任何类型的Internet标准。本备忘录的
发布没有限制。

摘要
Internet社区需要一种不受限制的加密算法,这种算法的密码长度应该允许在较大范围
内变动,以便用于各种不同的加密应用程序和协议中提供安全性。
本文档描述了一种已经存在的算法,可以满足这些要求。内容包括:密码和密钥安排算
法(第二节)的描述,置换箱(附录A)以及一组测试向量(附录B)。
目录
1	简介	1
2	算法的描述	2
2.1	循环密钥对	2
2.2	不同的循环	2
2.3	置换箱(Substitution Boxes)	3
2.4	密钥表	3
2.4.1. 掩码子钥与旋转子钥	4
2.5	可变的密钥长度	5
2.6	CAST5对象标识符	5
2.7	讨论	6
3	知识产权的问题	6
4	安全性的问题	6
5	参考	6
6	作者地址	7
7	附录A  置换箱(S-Boxes)	7
8	附录B. 测试向量	13

1	简介
本文档描述了CAST-128加密算法,这是一种类似于DES的置换组合网路
(Substitution-Permutation Network,SPN)加密系统,对于微分密码分析、线性密码分析、
密码相关分析具有较好的抵抗力。这种加密还有其他的几个理想的特点,包括雪崩、严格的
雪崩标准(SAC)、位独立标准(BIC)、没有互补属性也不存在软弱或者半软弱的密钥。因
此对于整个Internet社区——要求密码强壮、容易获取的加密算法——而言,这是一种能够
满足一般应用的很好的选择。
Adams[Adams]详细地讨论了CAST设计过程,对于这种算法的分析也可以在网上找到
(比如,[Web1]或[Web2])。

2	算法的描述
CAST-128属于称为Feistel加密的一类加密算法,因此所有的操作都类似于数据加密标
准(DES)。完整的加密算法分下面四步给出。
输入:明文m1...m64; 密钥 K = k1...k128
输出:密文c1...c64
1)(密钥表)从K计算出16对子钥(Kmi, Kri)(参见2.1到2.4节);
2)(L0,R0) <-- (m1...m64)(把明文分为左右两半,L0=m1…m32,R0=m33…m64);
3)(循环16次)对于i从1到16,按下述方法计算Li和Ri:
      Li = Ri-1;
      Ri = Li-1 ^ f(Ri-1,Kmi,Kri), 其中f在第2.2节中定义。(f根据i的不同,可以是
Type 1、Type 2或者Type 3)
4)c1...c64 <-- (R16,L16) (交换最终得到的L16和R16并连接在一起构成密文。)
解密算法与上述加密算法一致,只不过循环(因此还有子钥对)是按照相反的顺序从
(R16,L16)计算出(L0,R0)。
可以使用附录B中的测试向量验证该算法的正确性。

2.1	循环密钥对
CAST-128在每次循环中使用以对子钥:32位量Km作为“掩码”,5位量Kr用作“旋
转码”。

2.2	不同的循环
CAST-128使用三种不同的循环函数,如下所示(其中“D”是输入函数f的数据,“Ia”
到“Id”分别表示I中从高到低的4个字节)。注意“+”和“-”是以2**32为模的加减法,
“^”是位异或,“<<<”表示循环左移操作。
       Type 1:  I = ((Kmi + D) <<< Kri)
                f = ((S1[Ia] ^ S2[Ib]) - S3[Ic]) + S4[Id]
       Type 2:  I = ((Kmi ^ D) <<< Kri)
                f = ((S1[Ia] - S2[Ib]) + S3[Ic]) ^ S4[Id]
       Type 3:  I = ((Kmi - D) <<< Kri)
                f = ((S1[Ia] + S2[Ib]) ^ S3[Ic]) - S4[Id]
   循环1、4、7、10、13和16 使用f 函数Type 1;
   循环2、5、8、11和14 使用f函数Type 2;
   循环3、6、9、12和15使用f 函数Type 3。

2.3	置换箱(Substitution Boxes)
CAST-128使用8个置换箱:置换箱(s-box)S1、S2、S3和S4是循环置换箱,S5、S6、
S7和S8是密钥表置换箱。尽管8个置换箱总共需要8K字节的内存,但是要注意在实际加
密/解密过程中只需要4K字节,因为子钥的产生通常在输入数据之前就完成了。
置换箱S1-S8的内容参见附录A。

2.4	密钥表
假设128位的密钥是x0x1x2x3x4x5x6x7x8x9xAxBxCxDxExF,其中x0是最高位的字节,
xF是最低位的字节。
令z0…zF是中间(临时)字节。
令S[i]表示置换箱i,“^”代表异或加。
按照下述公式从密钥x0x1x2x3x4x5x6x7x8x9xAxBxCxDxExF生成子钥:
   z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
   z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
   z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
   zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
   K1  = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]
   K2  = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6]
   K3  = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9]
   K4  = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC]
   x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
   x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
   x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
   xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
   K5  = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8]
   K6  = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD]
   K7  = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]
   K8  = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7]
   z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
   z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
   z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
   zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
   K9  = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9]
   K10 = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC]
   K11 = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]
   K12 = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6]
   x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
   x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
   x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
   xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
   K13 = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]
   K14 = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7]
   K15 = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8]
   K16 = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD]

   [剩下的一半与上面给出的一样,从最后生成的x0..xF产生密钥 K17 - K32。]

   z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
   z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
   z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
   zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
   K17 = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]
   K18 = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6]
   K19 = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9]
   K20 = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC]
   x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
   x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
   x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
   xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
   K21 = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8]
   K22 = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD]
   K23 = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]
   K24 = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7]
   z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8]
   z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA]
   z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9]
   zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB]
   K25 = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9]
   K26 = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC]
   K27 = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]
   K28 = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6]
   x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0]
   x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2]
   x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1]
   xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3]
   K29 = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]
   K30 = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7]
   K31 = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8]
   K32 = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD]

2.4.1. 掩码子钥与旋转子钥
令Km1, ..., Km16为32位的掩码子钥(每次循环使用一个);
令Kr1, … , Kr16为32位的旋转子钥(每次循环使用一个,只是用最低的5位);
   for (i=1; i<=16; i++)  { Kmi = Ki;  Kri = K16+i; }

2.5	可变的密钥长度
CAST-128加密算法被设计为密码长度是可变的,从40位到128位,每次递增8位(就
是说,密码长度可以是40、48、56、64…112、120、128位)。对于不同的密码长度,分别
采用不同的规范:
1)	密码长度从40到80(含80),按照上述算法操作,但是采用12循环而不是16。
2)	如果密码长度大于80位,采用完整的16次循环。
3)	如果密码长度小于128位,则在最低位补0直到128位(因为CAST-128密钥表假
定输入的密码是128位的。)
尽管CAST-128支持上述12种长度的密码,但在典型的应用中发现40、64、80和128
位是最有用的密码长度。因此,只要支持这四种长度的子集对于大多数应用就足够了。
为了避免在使用不同的密码长度操作时发生混淆,CAST-128被认为与名CAST5是同
义的,这样在后面加上密码长度就不会发生歧义了。这样,比方说使用40位密码的CAST-128
就被表示为CAST5-40;如果明确地使用128位密码,应该使用名称CAST5-128。

2.6	CAST5对象标识符
如果需要在协议中的算法协商中,或者其它需要使用对象标识符的上下文中使用
CAST,可以使用以下定义的OID。

algorithms OBJECT IDENTIFIER ::=
   { iso(1) memberBody(2) usa(840) nt(113533) nsn(7) algorithms(66) }

cast5CBC OBJECT IDENTIFIER ::= { algorithms cast5CBC(10) }

    Parameters ::= SEQUENCE {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -