Я пытаюсь реализовать SHA-3, используя этот документ и есть вопрос по шагу йоты.
Этот шаг состоит из одного XOR между центральной (0, 0) дорожкой состояния (при необходимости иллюстрация состояния на стр. 8) и круглой константой. Другими словами:
для z в [0, w[:
пусть новое_состояние (0, 0, z) = состояние (0, 0, z) ^ RC [z]
где RC рассматривается как битовая строка.
Константа первого раунда первого раунда равна 1, поэтому будет изменен только один бит. Как видно в этом документ предоставляя тестовые векторы, мы имеем в раунде № 0:
После Чи
00 00 00 00 00 00 00 00 ...
После Йоты
01 00 00 00 00 00 00 00 ... (следующее равно предыдущему)
Однако я кое-чего не понимаю: бит, который меняется в этих тестовых векторах, — восьмой, а наша константа округления — это 1, записанная на w-битах. Если $w=8$ (имеется в виду 200-битное сообщение), все хорошо, но в предыдущей ссылке у нас сообщение 1600 бит, следовательно $w=64$. Как может XOR с этим 64-битным 0...01 изменить восьмой бит дорожки?
РЕДАКТИРОВАТЬ: я добавлю свой код ниже (он все еще работает):
класс Кеккак (объект):
защита __init__(сам):
селф.l = 6
self.w = pow(2, self.l)
self.state = [[[0 для x в диапазоне (5)] для y в диапазоне (5)] для z в диапазоне (self.w)]
self.tmp_state = [[[0 для x в диапазоне (5)] для y в диапазоне (5)] для z в диапазоне (self.w)]
определение init_state (я, S):
для x в диапазоне (5):
для y в диапазоне (5):
для z в диапазоне (self.w):
self.set_state(x, y, z, int(S[self.w*(5*y + x) + z], 2))
определение init_tmp_state (я):
для x в диапазоне (5):
для y в диапазоне (5):
для z в диапазоне (self.w):
self.set_tmp_state (х, у, г, 0)
def index_processing (я, х, у, г):
возврат (z % self.w, (y + 2) % 5, (x + 2) % 5)
def get_state (я, х, у, г):
х, у, г = self.index_processing (х, у, г)
вернуть self.state[x][y][z]
def set_state (я, х, у, г, в):
х, у, г = self.index_processing (х, у, г)
self.state[x][y][z] = v
def get_tmp_state (я, х, у, г):
х, у, г = self.index_processing (х, у, г)
вернуть self.tmp_state[x][y][z]
def set_tmp_state (я, x, y, z, v):
х, у, г = self.index_processing (х, у, г)
self.tmp_state[x][y][z] = v
определение state_to_string (я):
битовая_строка = []
для y в диапазоне (5):
для x в диапазоне (5):
для z в диапазоне (self.w):
bit_string.append(str(self.get_state(x, y, z)))
вернуть ''.join(bit_string)
деф rc(я, т):
если t % 255 == 0:
вернуть 1
R = [1, 0, 0, 0, 0, 0, 0, 0]
для i в диапазоне (1, (t% 255) + 1):
Р = [0] + Р
Р[0] ^= Р[8]
Р[4] ^= Р[8]
Р[5] ^= Р[8]
Р[6] ^= Р[8]
Р = Р[:8]
вернуть R[0]
деф йота(я, я):
RC = [0 для j в диапазоне (self.w)]
для j в диапазоне (self.l + 1):
RC[pow(2, j) - 1] = self.rc(j + 7*i)
для z в диапазоне (self.w):
self.set_state(0, 0, z, self.get_state(0, 0, z) ^ RC[z])
защита test_iota():
initial_state = "0000000000000000D2D2D2D2D2D2D2D20000000000000000E8E8E8E8E8E8E8E83A3A3A3A3A3A3A3A535353535353535300000000000000001D1D1D1D1D1D1D1D4E4E4E4E4E4E4E4E00000000000000004141414141414141E8E8E8E8E8E8E8E80000000000000000414141414141414126262626262626261D1D1D1D1D1D1D1D0000000000000000474747474747474718181818181818184747474747474747E8E8E8E8E8E8E8E835353535353535350000000000000000AFAFAFAFAFAFAFAF1212121212121212"
Initial_state = bin(int(initial_state, 16))[2:].zfill(1600)
кеччак = кеччак ()
keccak.init_state (начальное_состояние)
keccak.iota(0)
результат = keccak.state_to_string()
correct_result = "0100000000000000D2D2D2D2D2D2D2D20000000000000000E8E8E8E8E8E8E8E83A3A3A3A3A3A3A3A535353535353535300000000000000001D1D1D1D1D1D1D1D4E4E4E4E4E4E4E4E00000000000000004141414141414141E8E8E8E8E8E8E8E80000000000000000414141414141414126262626262626261D1D1D1D1D1D1D1D0000000000000000474747474747474718181818181818184747474747474747E8E8E8E8E8E8E8E835353535353535350000000000000000AFAFAFAFAFAFAFAF1212121212121212"
правильный_результат = bin(int(correct_result, 16))[2:].zfill(1600)
print("\tIota:\t" + str(результат == правильный_результат))
печать (результат [0:64] + '\n\n' + правильный_результат [0:64])
Тестовая печать:
Йота: Ложь
1000000000000000000000000000000000000000000000000000000000000000000
000000010000000000000000000000000000000000000000000000000000000000