Twofish:128bit的分组密码

1Twofish密码概述

Twofish分组密码是Bruce Schneier等人提交给AES的成果,作为5个候选密码的其中一种。它符合所有NIST的标准——128位明文数据;128位,192,256位可变密钥长度;在各种平台上高效;等等。它可用于设计具有各种同步和错误扩展属性的流密码,单向散列函数,消息认证码(MAC)和伪随机数生成器。Twofish分组密码是基于双射F函数的16轮Feistel网络。其中F函数由四个与密钥相关的8乘8位S盒、一个GF(28)上的固定4乘4最大距离可分离矩阵(MDS)、伪Hadamard变换、按位旋转和精心设计的密钥表构成。

Twofish密码的设计符合NIDT的AES设计标准。具体来说,它们是:

(1)128位对称分组密码

(2)密钥长度可为128位,192位和256位

(3)没有弱键

(4)无论是在Inter Pentium Pro(奔腾)还是其他软件和硬件平台上都高效

(5)设计灵活:可以接受额外的密钥长度(对于上面没有定义的密钥大小,密钥在末尾用零字节填充到定义的下一个更大的长度);并适用于流密码、单向散列函数和MAC

(6)具有可变轮数的变体

(7)设计简单,既便于分析,又便于实施

Twofish密码实现的目标如下:

(1)少于280个选择的明文和2N(N是密钥长度)时间时,16轮Twofish(无输出处理)应该没有选择明文攻击(chosen-plaintext attack)

(2)少于264个选择的明文和2N/2(N是密钥长度)时间时,12轮Twofish(无输出处理)应该没有相关密钥攻击(related-key attcak)

2Twofish密码的相关技术

2.1Feistel网络

Fiestel网络是一种将任何函数(通常称为F函数)转换为置换的常规方法,它是绝大部分分组密码算法的基础。

Fiestel网络的基本组成部分是F函数,F函数是输入字符串到输出字符串之间的基于密钥的映射。通常F函数是非线性的并且可能不是满射:

F : {0,1}n/2× {0,1}N → {0,1}n/2

其中n是Fiestel网络中的分组大小,F函数将n/2位的分组以及N位密钥作为输入,产生一个n/2位的输出。在每一次迭代中,源分组作为F函数的输入,同时F函数的输出与目标分组进行异或运算,之后,这两个分组交换位置进入到下一轮当中。

Twofish使用的就是一个使用双射F函数的Feistel网络。

2.2S盒

S盒是一个用于绝大多数分组密码算法中的表驱动非线性置换操作。Twofish使用四个不同的,双射的基于密钥的8 × 8的S盒,这些S盒使用两个固定的8 × 8位置换和密钥构建。

2.3MDS矩阵

在一个域上的最大距离差分(MDS)编码是一个从 a 元素到 b 元素的线性映射, 它产生了一个 a+b 元素的复合向量,它的性质是对于任何的非零向量中的非零元素的最小数目最少是 b +1 。 也就是说, 任何两个有MDS 映射产生的不同向量之间的“ 距离”(不同元素的数目)至少是 b +1。 很容易就可以得出这两个不同向量之间没有映射可以有更大的最小举例。MDS 映射可以通过有 a×b 元素组成的 MDS 矩阵表示。 一个 a×b 矩阵是 MDS 的充分条件是所有通过丢弃行或列获得的正子矩阵都是非奇异的。

在 Twofish 中, 使用了一个基于 GF(28)的 4×4 的 MDS 矩阵。

2.4伪Hadamard变换

一个 Pseudo-Hadamard 变换(PHT)是一个可以在软件中快速运行的简单的混合操作。 给出两个输入 a 和 b, 32 位的PHT 运算的形式如下:

a’= (a+b) mod 232

b’= (a+2b) mod 232

Twofish 使用 32 位的 PHT 混合来自两个并行g 函数的输出。

2.5Whitening

Whitening是一项在第一次迭代之前和最后一次迭代之后对密钥进行异或运算的技术。此技术充分的提高了搜索密钥攻击的复杂性。

Twofish 在第一次 Feistel 迭代之前对 128 位的子钥进行异或, 并在最后一次 Feistel 迭代中对另 128 位子钥进行同样的运算。这些子钥按照与迭代中的子钥相同的方法进行计算, 但不用在加密的其他过程之中。

2.6密钥产生

密钥产生的意思是将密钥转化为加密过程需要使用的迭代密钥。Twofish 需要大量的密钥信息并使用了一种复杂的密钥产生方法。 为了便于分析密钥产生使用了与迭代函数同样原始的函数。

3Twofish基本原理

Twofish 使用了 16 轮 Feistel 结构迭代并在输入输出部分附加了whitening技术。 唯一的非 Feistel 元素是一位循环移位操作。这种循环移位操作可以移入到 F 函数之中, 这样的网络就成为了一个纯粹的 Feistel 网络。 但这样做就需要在输出序列进行whitening处理之前附加进行一次字循环移位。

Twofish算法的全过程如下图1所示:

明文被分成了32位一组的四个部分,它们分别与四个密钥字进行异或,在Whitening完成后接下来进行16次迭代运算。在每一次迭代的过程中,左边的两个字用来作为g函数的输入(其中之一首先进行8位的循环左移位)。g函数由4个8 × 8的基于密钥的S盒组成,之后是一个基于MDS矩阵的非线性的混合。两个g函数的结果使用PHT进行结合,并添加两个密钥字。这个两个结果与在右方的两个部分进行异或。右方的这两组字符串一个在异或前循环左移1位,另一个在异或后循环右移1位。之后,左右两个部分进行交换,再进入到下一次的迭代当中。经过所有迭代后,最后一次迭代不进行交换。然后的四组字符串分别与另外四个密码字符串进行异或操作。经过以上步骤后,产生与明文相对应的密文。

图1 Twofish算法流程图

具体来讲,首先16个字节的明文p0,…,p15被分成4个32位的字P0,…,P5,使用小端规范:

 

    在输入whitening处理阶段,这些字与扩展的4个密钥字进行异或:

 

     在16轮的每一轮中,前面的两个字作为F函数的输入(轮数也作为输入)。第三个字与F函数的第一个输出进行异或,然后循环右移1位;第四个字循环左移1位之后与F函数的第二个输出进行异或。然后,交换左右部分的位置。

     这个步骤如下:

 

     ROR和ROL函数是将其第一个参数(一个32位字)循环右移或循环左移其第二个参数的位数的函数。

     最后一轮的输出不进行交换直接与四个扩展密钥字进行异或而得到密文C:


     这4个字的密文最后被存储为16个字节C0,…,C15,使用与明文相同的小端规范:

 

3.1函数F

函数F是64位值上与密钥相关的置换。F函数具有三个参数,两个输入字R0、R1及用于选择子项的轮数r。步骤如下:

3.2函数g

函数g构成了Twofish的核心。输入字X被分为4个字节,每个字节通过自己的密钥相关S盒。S盒是双射的,8位输入8位输出。这四个结果被解释为

GF(28)上长度为4的矢量,并乘以4 × 4的MDS矩阵,得到的向量是g函数结果(32位字)。

si是与密钥相关的S盒,Z是g函数的结果。



猜你喜欢

转载自blog.csdn.net/LeoCrytal/article/details/80077879