Ключевое расширение Twofish

Я пытаюсь реализовать шифр Twofish шаг за шагом, как описано в статье 1998 года Брюса Шнайдера< /а>. Тем не менее, я уже терплю неудачу в расширении ключа.

Я попытался скопировать детали бумаги 1-к-1 в python со следующим результатом:

#! /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 (0x0123456789ABCDEFFEDCBA987654321000112233445566778899AABBCCDDEEFF)

Однако мой вывод отличается от указанного в тестовых векторах. Я уже пытался читать байты наоборот (закомментированная строка), но безрезультатно.

Это результаты тестового вектора:

B89FF6F2
B255BC4B
45661061
8E4447F7

А это мои:

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

Может ли кто-нибудь увидеть мою ошибку?


person Hyperboreus    schedule 28.11.2012    source источник
comment
Существуют рабочие реализации Twofish для Python; конечно, вы могли бы получить один из них, добавить множество операторов печати как к нему, так и к вашей реализации, и выяснить, где вы ошиблись?   -  person kindall    schedule 29.11.2012
comment
это обычная практика в python, что expandKey256 (key) пишется без пробела, expandKey256(key) python.org/dev/peps/pep-0008/   -  person monkut    schedule 29.11.2012


Ответы (1)


По крайней мере, эта строка

s = [ [0] * 4] * 4

вероятно, не делает то, что вы думаете, что он делает. Это не то же самое, что

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

Однако я не прошел через весь код.

РЕДАКТИРОВАТЬ

Очевидно, ОП нуждается в дополнительных доказательствах. Вот некоторый вывод из 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]

person President James K. Polk    schedule 29.11.2012
comment
Я не понимаю, почему за этот ответ проголосовали. Введите [[0]*4]*4 в оболочку python3.2 и посмотрите результат. РЕДАКТИРОВАТЬ: также на python2.7 - person Hyperboreus; 29.11.2012
comment
@Гиперборей: хорошо. После того, как вы наберете его, выполните s[0][0] += 1, а затем посмотрите на s. - person President James K. Polk; 29.11.2012