Încerc să implementez SHA-3 folosind acest document și aveți o întrebare despre pasul iota.
Acest pas constă într-un singur XOR între banda centrală (0, 0) a stării (ilustrarea stării p.8 dacă este necesar) și o constantă rotundă. În alți termeni:
pentru z în [0, w[:
fie stare_noua(0, 0, z) = stare(0, 0, z) ^ RC[z]
unde RC este văzut ca un șir de biți.
Constanta primei runde a primei runde este 1, astfel doar un bit va fi schimbat. După cum se poate vedea în aceasta document furnizând vectori de testare, avem în runda #0:
După Chi
00 00 00 00 00 00 00 00 ...
După Iota
01 00 00 00 00 00 00 00 ... (următoarele sunt egale cu cele de mai sus)
Totuși, există ceva ce nu înțeleg: bitul care este modificat în acei vectori de test este al optulea, dar constanta noastră rotundă este un 1 scris pe w-biți. Dacă $w=8$ (implicând un mesaj de 200 de biți), totul este în regulă, dar în linkul anterior, avem un mesaj de 1600 de biți, deci $w=64$. Cum poate XOR-ing acest 64 de biți 0...01 schimba al optulea bit al benzii?
EDIT: Îmi voi adăuga codul mai jos (încă este în lucru):
clasa Keccak(obiect):
def __init__(self):
sine.l = 6
self.w = pow(2, self.l)
self.state = [[[0 pentru x în interval(5)] pentru y în interval (5)] pentru z în interval(self.w)]
self.tmp_state = [[[0 pentru x în interval (5)] pentru y în interval (5)] pentru z în interval (self.w)]
def init_state(self, S):
pentru x în intervalul (5):
pentru y în intervalul (5):
pentru z în interval (self.w):
self.set_state(x, y, z, int(S[self.w*(5*y + x) + z], 2))
def init_tmp_state(self):
pentru x în intervalul (5):
pentru y în intervalul (5):
pentru z în interval (self.w):
self.set_tmp_state(x, y, z, 0)
def index_processing(self, x, y, z):
returnare (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)
returnează starea de sine[x][y][z]
def set_state(self, x, y, z, v):
x, y, z = self.index_processing(x, y, z)
starea de sine[x][y][z] = v
def get_tmp_state(self, x, y, z):
x, y, z = self.index_processing(x, y, z)
returnează 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(self):
șir_biți = []
pentru y în intervalul (5):
pentru x în intervalul (5):
pentru z în interval (self.w):
bit_string.append(str(self.get_state(x, y, z)))
returnează ''.join(bit_string)
def rc(self, t):
dacă t % 255 == 0:
întoarce 1
R = [1, 0, 0, 0, 0, 0, 0, 0]
pentru i în domeniul (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]
returnează R[0]
def iota(self, i):
RC = [0 pentru j în interval (self.w)]
pentru j în interval (self.l + 1):
RC[pow(2, j) - 1] = self.rc(j + 7*i)
pentru z în interval (self.w):
self.set_state(0, 0, z, self.get_state(0, 0, z) ^ RC[z])
def test_iota():
initial_state = "0000000000000000D2D2D2D2D2D2D2D20000000000000000E8E8E8E8E8E8E8E83A3A3A3A3A3A3A3A535353535353535300000000000000001D1D1D1D1D1D1D1D4E4E4E4E4E4E4E4E00000000000000004141414141414141E8E8E8E8E8E8E8E80000000000000000414141414141414126262626262626261D1D1D1D1D1D1D1D0000000000000000474747474747474718181818181818184747474747474747E8E8E8E8E8E8E8E835353535353535350000000000000000AFAFAFAFAFAFAFAF1212121212121212"
stare_inițială = bin(int(stare_inițială, 16))[2:].zfill(1600)
keccak = Keccak()
keccak.init_state(initial_state)
keccak.iota(0)
rezultat = keccak.state_to_string()
correct_result = "0100000000000000D2D2D2D2D2D2D2D20000000000000000E8E8E8E8E8E8E8E83A3A3A3A3A3A3A3A535353535353535300000000000000001D1D1D1D1D1D1D1D4E4E4E4E4E4E4E4E00000000000000004141414141414141E8E8E8E8E8E8E8E80000000000000000414141414141414126262626262626261D1D1D1D1D1D1D1D0000000000000000474747474747474718181818181818184747474747474747E8E8E8E8E8E8E8E835353535353535350000000000000000AFAFAFAFAFAFAFAF1212121212121212"
rezultat_corect = bin(int(rezultat_corec, 16))[2:].zfill(1600)
print("\tIota:\t" + str(rezultat == rezultat_correct))
print(rezultat[0:64] + „\n\n” + rezultat_correct[0:64])
Testul se imprimă:
Iota: Fals
10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000100000000000000000000000000000000000000000000000000000000000