ฉันกำลังพยายามใช้ SHA-3 โดยใช้ เอกสารนี้ และมีคำถามเกี่ยวกับขั้นตอน iota
ขั้นตอนนี้ประกอบด้วย XOR เดียวระหว่างเลนกลาง (0, 0) ของสถานะ (ภาพประกอบของสถานะ p.8 หากจำเป็น) และค่าคงที่แบบกลม ในเงื่อนไขอื่น:
สำหรับ z ใน [0, w[:
ให้ new_state(0, 0, z) = state(0, 0, z) ^ RC[z]
โดยที่ RC ถูกมองว่าเป็นบิตสตริง
ค่าคงที่รอบแรกของรอบแรกคือ 1 ดังนั้นจะเปลี่ยนเพียงบิตเดียว ดังที่เห็นในนี้ เอกสาร ให้เวกเตอร์ทดสอบ เรามีในรอบ #0:
หลังจากที่จิ
00 00 00 00 00 00 00 00 ...
หลังจากที่ไอโอตะ
01 00 00 00 00 00 00 00 ... (ต่อไปนี้เท่ากับด้านบน)
อย่างไรก็ตาม มีบางอย่างที่ฉันไม่เข้าใจ: บิตที่เปลี่ยนในเวกเตอร์ทดสอบเหล่านั้นคือตัวที่ 8 แต่ค่าคงที่รอบของเราคือ 1 ที่เขียนบน w-บิต ถ้า $w=8$ (หมายถึงข้อความ 200 บิต) ทุกอย่างเรียบร้อยดี แต่ในลิงก์ก่อนหน้า เรามีข้อความ 1600 บิต ดังนั้น $w=64$. XOR-ing 64 บิตนี้ 0...01 เปลี่ยนบิตที่แปดของเลนได้อย่างไร
แก้ไข: ฉันจะเพิ่มรหัสของฉันด้านล่าง (ยังอยู่ระหว่างดำเนินการ):
คลาส Keccak (วัตถุ):
def __init__(ตัวเอง):
ตัวเอง.l = 6
self.w = ธาร(2, self.l)
self.state = [[[0 สำหรับ x ในช่วง (5)] สำหรับ y ในช่วง (5)] สำหรับ z ในช่วง (self.w)]
self.tmp_state = [[[0 สำหรับ x ในช่วง (5)] สำหรับ y ในช่วง (5)] สำหรับ z ในช่วง (self.w)]
def 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))
def init_tmp_state (ตัวเอง):
สำหรับ x ในช่วง (5):
สำหรับ y ในช่วง (5):
สำหรับ z ในช่วง (self.w):
self.set_tmp_state(x, y, z, 0)
def index_processing(ตัวเอง, x, y, z):
ผลตอบแทน (z % self.w, (y + 2) % 5, (x + 2) % 5)
def get_state(ตัวเอง, x, y, z):
x, y, z = self.index_processing(x, y, z)
ส่งคืน self.state[x][y][z]
def set_state(ตัวเอง, x, y, z, v):
x, y, z = self.index_processing(x, y, z)
self.state[x][y][z] = v
def get_tmp_state(ตัวเอง, x, y, z):
x, y, z = self.index_processing(x, y, z)
ส่งคืน self.tmp_state[x][y][z]
def set_tmp_state(ตัวเอง, x, y, z, v):
x, y, z = self.index_processing(x, y, z)
self.tmp_state[x][y][z] = v
def state_to_string (ตัวเอง):
bit_string = []
สำหรับ y ในช่วง (5):
สำหรับ x ในช่วง (5):
สำหรับ z ในช่วง (self.w):
bit_string.append(str(self.get_state(x, y, z)))
กลับ ''.join(bit_string)
def rc(ตัวเอง, t):
ถ้า เสื้อ % 255 == 0:
กลับ 1
R = [1, 0, 0, 0, 0, 0, 0, 0]
สำหรับผมในช่วง (1, (t % 255) + 1):
R = [0] + R
ร[0] ^= ร[8]
ร[4] ^= ร[8]
ร[5] ^= ร[8]
ร[6] ^= ร[8]
R = R[:8]
กลับ R[0]
def iota(ตัวเอง ผม):
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])
def test_iota():
initial_state = "0000000000000000D2D2D2D2D2D2D2D20000000000000000E8E8E8E8E8E8E8E83A3A3A3A3A3A3A3A535353535353535300000000000000001D1D1D1D1D1D1D1D4E4E4E4E4E4E4E4E00000000000000004141414141414141E8E8E8E8E8E8E8E80000000000000000414141414141414126262626262626261D1D1D1D1D1D1D1D0000000000000000474747474747474718181818181818184747474747474747E8E8E8E8E8E8E8E835353535353535350000000000000000AFAFAFAFAFAFAFAF1212121212121212"
initial_state = bin(int(initial_state, 16))[2:].zfill(1600)
เค็กคัก = เค็กคัก()
keccak.init_state (initial_state)
keccak.iota(0)
ผลลัพธ์ = keccak.state_to_string()
correct_result = "0100000000000000D2D2D2D2D2D2D2D20000000000000000E8E8E8E8E8E8E8E83A3A3A3A3A3A3A3A535353535353535300000000000000001D1D1D1D1D1D1D1D4E4E4E4E4E4E4E4E00000000000000004141414141414141E8E8E8E8E8E8E8E80000000000000000414141414141414126262626262626261D1D1D1D1D1D1D1D0000000000000000474747474747474718181818181818184747474747474747E8E8E8E8E8E8E8E835353535353535350000000000000000AFAFAFAFAFAFAFAF1212121212121212"
correct_result = bin(int(correct_result, 16))[2:].zfill(1600)
พิมพ์ ("\tIota:\t" + str (ผลลัพธ์ == correct_result))
พิมพ์ (ผลลัพธ์ [0:64] + '\n\n' + correct_result[0:64])
การทดสอบพิมพ์:
Iota: เท็จ
1000000000000000000000000000000000000000000000000000000000000000
000000010000000000000000000000000000000000000000000000000000000