Рейтинг:2

Уточнение по поводу йота-функции SHA-3

флаг cn

Я пытаюсь реализовать 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
kelalaka avatar
флаг in
Рисунок 2, положение индексов не стандартное. [0,0,1] — центр переднего среза. Поэтому при печати это будет напечатано.
Katoptriss avatar
флаг cn
Я также думал, что, возможно, испортил индексацию, но я проверил свои функции string_to_state и state_to_string, используя разделы 3.1.2 и 3.1.3, и они оказались правильными. Но я также не думаю, что проблема может возникнуть откуда-то еще, кроме как оттуда. Я отредактирую, чтобы добавить свой код. Кроме того, в разделе 3.1.3 битовая строка, полученная из состояния, сначала создается путем объединения состояния (0, 0, 0) с состоянием (0, 0, 63): не означает ли это, что бит изменился, а затем напечатан восьмой, в состоянии (0, 0, 7)?
Katoptriss avatar
флаг cn
Мне только что пришла в голову мысль: может быть, это просто глупая проблема с порядком байтов? Но функции pi и khi, которые я написал, проходят свои тесты и дают ожидаемый результат, поэтому я не знаю об изменении порядка следования байтов. на всякий случай попробую.
Katoptriss avatar
флаг cn
Что ж, кажется, ответ заключался в том, что это не порядок байтов как таковой, а скорее «побитовый порядок следования байтов», когда биты должны быть взяты в обратном порядке. Странный. Но я должен был прочитать стандарт более внимательно.
kelalaka avatar
флаг in
Прежде чем начать, следует прочитать весь документ.
kelalaka avatar
флаг in
Вы можете ответить на свой вопрос, это нормально!

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.