Tôi đang cố triển khai SHA-3 bằng cách sử dụng tài liệu này và có câu hỏi về bước iota.
Bước này bao gồm một XOR duy nhất giữa làn trung tâm (0, 0) của trạng thái (hình minh họa về trạng thái tr.8 nếu cần) và một hằng số vòng. Nói cách khác:
cho z trong [0, w[:
để new_state(0, 0, z) = trạng thái(0, 0, z) ^ RC[z]
trong đó RC được xem như một chuỗi bit.
Hằng số vòng đầu tiên của vòng đầu tiên là 1, do đó chỉ một bit sẽ bị thay đổi. Như nó có thể được nhìn thấy trong này tài liệu cung cấp các vectơ kiểm tra, chúng tôi có trong vòng # 0:
Sau Chí
00 00 00 00 00 00 00 00 ...
Sau Iota
01 00 00 00 00 00 00 00 ... (sau đây bằng trên)
Tuy nhiên, có một điều tôi không hiểu: bit được thay đổi trong các vectơ thử nghiệm đó là bit thứ tám, nhưng hằng số vòng của chúng tôi là 1 được viết trên w-bit. Nếu $w=8$ (ngụ ý thông báo 200 bit), mọi thứ đều ổn, nhưng trong liên kết trước, chúng tôi có thông báo 1600 bit, do đó $w=64$. Làm cách nào XOR-ing 64-bit 0...01 này có thể thay đổi bit thứ tám của làn đường?
CHỈNH SỬA: Tôi sẽ thêm mã của mình bên dưới (nó vẫn đang hoạt động):
lớp Keccak(đối tượng):
def __init__(bản thân):
tự.l = 6
self.w = pow(2, self.l)
self.state = [[[0 cho x trong dải(5)] cho y trong dải(5)] cho z trong dải(self.w)]
self.tmp_state = [[[0 cho x trong dải(5)] cho y trong dải(5)] cho z trong dải(self.w)]
def init_state(bản thân, S):
cho x trong phạm vi (5):
cho y trong phạm vi (5):
cho z trong phạm vi (self.w):
self.set_state(x, y, z, int(S[self.w*(5*y + x) + z], 2))
def init_tmp_state(bản thân):
cho x trong phạm vi (5):
cho y trong phạm vi (5):
cho z trong phạm vi (self.w):
self.set_tmp_state(x, y, z, 0)
def index_processing(self, x, y, z):
trả về (z % self.w, (y + 2) % 5, (x + 2) % 5)
def get_state(self, x, y, z):
x, y, z = self.index_processing(x, y, z)
trả về self.state[x][y][z]
def set_state(self, x, y, z, v):
x, y, z = self.index_processing(x, y, z)
self.state[x][y][z] = v
def get_tmp_state(self, x, y, z):
x, y, z = self.index_processing(x, y, z)
trả về self.tmp_state[x][y][z]
def set_tmp_state(self, x, y, z, v):
x, y, z = self.index_processing(x, y, z)
self.tmp_state[x][y][z] = v
def state_to_string(bản thân):
bit_string = []
cho y trong phạm vi (5):
cho x trong phạm vi (5):
cho z trong phạm vi (self.w):
bit_string.append(str(self.get_state(x, y, z)))
trả về ''.join(bit_string)
def rc(tự, t):
nếu t % 255 == 0:
trả lại 1
R = [1, 0, 0, 0, 0, 0, 0, 0]
cho tôi trong phạm vi (1, (t % 255) + 1):
R = [0] + R
R[0] ^= R[8]
R[4] ^= R[8]
R[5] ^= R[8]
R[6] ^= R[8]
R = R[:8]
trả lại R[0]
def iota(bản thân, tôi):
RC = [0 cho j trong phạm vi (self.w)]
cho j trong phạm vi (self.l + 1):
RC[pow(2, j) - 1] = self.rc(j + 7*i)
cho z trong phạm vi (self.w):
self.set_state(0, 0, z, self.get_state(0, 0, z) ^ RC[z])
chắc chắn test_iota():
initial_state = "0000000000000000D2D2D2D2D2D2D2D20000000000000000E8E8E8E8E8E8E8E83A3A3A3A3A3A3A3A535353535353535300000000000000001D1D1D1D1D1D1D1D4E4E4E4E4E4E4E4E00000000000000004141414141414141E8E8E8E8E8E8E8E80000000000000000414141414141414126262626262626261D1D1D1D1D1D1D1D0000000000000000474747474747474718181818181818184747474747474747E8E8E8E8E8E8E8E835353535353535350000000000000000AFAFAFAFAFAFAFAF1212121212121212"
initial_state = bin(int(initial_state, 16))[2:].zfill(1600)
keccak = keccak()
keccak.init_state(initial_state)
keccak.iota(0)
kết quả = keccak.state_to_string()
correct_result = "0100000000000000D2D2D2D2D2D2D2D20000000000000000E8E8E8E8E8E8E8E83A3A3A3A3A3A3A3A535353535353535300000000000000001D1D1D1D1D1D1D1D4E4E4E4E4E4E4E4E00000000000000004141414141414141E8E8E8E8E8E8E8E80000000000000000414141414141414126262626262626261D1D1D1D1D1D1D1D0000000000000000474747474747474718181818181818184747474747474747E8E8E8E8E8E8E8E835353535353535350000000000000000AFAFAFAFAFAFAFAF1212121212121212"
true_result = bin(int(true_result, 16))[2:].zfill(1600)
print("\tIota:\t" + str(kết quả == đúng_kết quả))
in(kết quả[0:64] + '\n\n' +true_result[0:64])
Bản in thử nghiệm:
Iota: Sai
100000000000000000000000000000000000000000000000000000000000000000
00000001000000000000000000000000000000000000000000000000000000000