1Twofish密码概述
Twofish分组密码是Bruce Schneier等人提交给AES的成果,作为5个候选密码的其中一种。它符合所有NIST的标准--128位明文数据; 128位,192,256位可变密钥长度;在各种平台上高效;等等它可用于设计具有各种同步和错误扩展属性的流密码,单向散列函数,消息认证码(MAC)和伪随机数生成器.Twofish分组密码是基于双射F函数的16轮Feistel网络。其中F函数由四个与密钥相关的乘8位S盒,一个GF(2 8)上的固定4乘4最大距离可分离矩阵(MDS),伪Hadamard变换,按位旋转和精心设计的密钥表构成。
Twofish的密码的设计符合NIDT的AES设计标准具体来说,它们是:
(1)128位对称分组密码
(2)密钥长度可为128位,192位和256位
(3)没有弱键
(4)无论是在Inter Pentium Pro(奔腾)还是其他软件和硬件平台上都高效
(5)设计灵活:可以接受额外的密钥长度(对于上面没有定义的密钥大小,密钥在末尾用零字节填充到定义的下一个更大的长度);并适用于流密码,单向散列函数和MAC
(6)具有可变轮数的变体
(7)设计简单,既便于分析,又便于实施
Twofish的密码实现的目标如下:
(1)少于2 80个选择的明文和2 N(N是密钥长度)时间时,16轮Twofish(无输出处理)应该没有选择明文攻击(selected-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
其中Ñ是Fiestel网络中的分组大小,F函数将N / 2位的分组以及Ñ位密钥作为输入,产生一个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(2 8)的4×4的MDS矩阵。
2.4伪阿达玛变换
给出两个输入a和b,32位的PHT运算的形式如下:一个可以在软件中快速运行的简单的混合操作。
a'=(a + b)mod 2 32
b'=(a + 2b)mod 2 32
Twofish使用32位的PHT混合来自两个并行g函数的输出。
2.5Whitening
美白是一项在第一次迭代之前和最后一次迭代之后对密钥进行异或运算的技术。此技术充分的提高了搜索密钥攻击的复杂性。
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个字节C 0,...,C 15,使用与明文相同的小端规范:

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

3.2函数克
函数克构成了Twofish的的核心。输入字X被分为4个字节,每个字节通过自己的密钥相关小号盒.S盒是双射的,8位输入8位输出。这四个结果被解释为
GF(2 8)上长度为4的矢量,并乘以4×4的MDS矩阵,得到的向量是g函数结果(32位字)。

小号我是与密钥相关的小号盒,Z是克函数的结果。