2012-11-28 68 views
4

我试图按照1998 paper of Bruce Schneider中所述的步骤执行Twofish密码。不过,我已经在关键扩张方面失败了。Twofish密钥扩展

我试着用纸1对1的细节复制到蟒蛇,结果如下:

#! /usr/bin/python3.2 

def expandKey256 (key): 
    m = [0] * (32) 
    for i in range (32): 
     m [i] = (key >> (i * 8)) & 0xff 
     #m [31 - i] = (key >> (i * 8)) & 0xff 
    print ('m = {}\n'.format ([hex (b) for b in m])) 

    M = [0] * 8 
    for i in range (8): 
     for j in range (4): 
      M [i] += m [4 * i + j] * 2 ** (8 * j) 
    print ('M = {}\n'.format ([hex (b) for b in M])) 

    Me = [M [0], M [2], M [4], M [6] ] 
    Mo = [M [1], M [3], M [5], M [7] ] 
    print ('Me = {}\n'.format ([hex (b) for b in Me])) 
    print ('Mo = {}\n'.format ([hex (b) for b in Mo])) 

    RS = [ [0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E], 
     [0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5], 
     [0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19], 
     [0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03] ] 

    s = [ [0] * 4] * 4 
    S = [0] * 4 
    for i in range (4): 
     for j in range (4): 
      for k in range (8): 
       s [i] [j] += m [8 * i + k] * RS [j] [k] 
       s [i] [j] &= 0xff 
      S [i] += s [i] [j] * 2 ** (8 * j) 
    for i in range (4): 
     print ('S{} = {}'.format (i, hex (S [i]))) 

expandKey256 (0xABCDEFFEDCBA00112233445566778899AABBCCDDEEFF) 

然而,作为test vectors指定我的输出是不一样的。我已经尝试以相反的方式读取字节(注释行),但无济于事。

这些测试向量的结果:

B89FF6F2 
B255BC4B 
45661061 
8E4447F7 

而这些都是我的

S0 = 0x612a646d 
S1 = 0x527cc87a 
S2 = 0x1482c008 
S3 = 0xa4d128ce 

任何人都可以看到我的错误?

+2

目前存在针对Python的Twofish实现;当然你可以得到其中的一个,为它和你的实现添加丰富的打印语句,并找出你出错的地方? – kindall

+0

python常用的做法是'expandKey256(key)'被写入时没有空格,'expandKey256(key)'http://www.python.org/dev/peps/pep-0008/#whitespace-in-expressions-和声明 – monkut

回答

6

至少这行

s = [ [0] * 4] * 4 

可能不是做什么,你觉得它在做什么。它不是做同样的事

s = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 

但我没有经过所有的代码。

编辑

显然OP需要更多的证据。这里从IDLE一些输出表示差

>>> s = [ [0] * 4] * 4 
>>> s 
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
>>> s[0][0] += 1 
>>> s 
[[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]] 
>>> s = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
>>> s 
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
>>> s[0][0] += 1 
>>> s 
[[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] 
>>> 

表达s = [ [0] * 4] * 4创建包含零的另一列表的列表,然后使3多个参考到列表的副本。它相当于v = [0]*4; s=[v,v,v,v]

+0

我不明白为什么这个答案变成了投票。在你的python3.2 shell中输入'[[0] * 4] * 4'并查看结果。编辑:也在python2.7 – Hyperboreus

+0

@Hyperboreus:好的。输入之后,执行s [0] [0] + = 1,然后查看s。 –

+0

非常感谢。 Upvote从我。 – Hyperboreus