KECCAK 如何對一個填充為零的狀態數組進行操作?
我試圖在 Java 中實現海綿。狀態開始是一個全為零的空 200 字節數組。在 NIST 的 KMAC 範例文件中,發生了以下情況:
(黑線是pdf分頁符)
我讀這個的方式是,一個帶有一堆零的狀態被發送到 KECCAK,然後返回一個帶有明顯隨機數據的狀態。SHA3/KECCAK 是否將空數據變成隨機數據?我在這裡問正確的問題嗎?任何幫助表示讚賞。
我個人認為Keccak.team 虛擬碼文件對理解 Keccak-p 的工作原理非常有幫助。
正如 DannyNiu 在評論中所說,大多數(全部?)密碼排列都使用“循環常數”。這些常數在 Keccak 狀態中以某種方式混合在一起。
虛擬碼文件以表格形式給出了輪常量:
RC[0] 0x0000000000000001 RC[12] 0x000000008000808B RC[1] 0x0000000000008082 RC[13] 0x800000000000008B RC[2] 0x800000000000808A RC[14] 0x8000000000008089 RC[3] 0x8000000080008000 RC[15] 0x8000000000008003 RC[4] 0x000000000000808B RC[16] 0x8000000000008002 RC[5] 0x0000000080000001 RC[17] 0x8000000000000080 RC[6] 0x8000000080008081 RC[18] 0x000000000000800A RC[7] 0x8000000000008009 RC[19] 0x800000008000000A RC[8] 0x000000000000008A RC[20] 0x8000000080008081 RC[9] 0x0000000000000088 RC[21] 0x8000000000008080 RC[10] 0x0000000080008009 RC[22] 0x0000000080000001 RC[11] 0x000000008000000A RC[23] 0x8000000080008008
並解釋如何使用它們。在 iota 步驟中 $ n^\text{th} $ Keccak-p 輪 $ n^\text{th} $ 圓形常數 $ RC[n] $ 被介紹並異或到第一個單詞,第一車道。
除了輪常數之外,Keccak 置換具有非常好的擴散性:初始狀態中某處的單個位將對許多輸出位做出重大貢獻。
兩者的結合意味著您的 Keccak 排列看起來非常隨機。當然,它不能將零熵變為隨機,因為沒有有限算法可以做到這一點,但 Keccak 的目標是混合事物並使它們看起來是隨機的。
Keccak 置換函式通常會將零輸入(所有位為 0)映射到零輸出,如果不是 iota 步驟,其中狀態的一個字與一個非零常數進行異或。
大約三(24)輪足以完全擴散,即狀態的每一位在三輪後影響每隔一個位。可以說,八次排列完全混合狀態。這意味著如果只有一位為 1,它將迅速擴散到整個狀態,因此 3 輪後大約一半的狀態位為 1。
讓 $ R $ 是可以合理地稱為“正常外觀”的狀態值的集合(根據任何確切的定義),例如所有或幾乎所有位都具有相同的值,或者有規律地重複的短位模式。在所有的 $ 2^{1600} $ 州,那些在 $ R $ 是很小的一部分。任何一個州都不太可能 $ R $ 也映射到輸出 $ R $ . 只要 $ |R| \ll 2^{800} $ (見“生日悖論”)。
這意味著沒有正常外觀的輸入映射到正常外觀的輸出。以及任何給定狀態映射到輸出的機率 $ R $ 可以忽略不計,即輸出看起來總是隨機的,除非有人故意通過計算排列的逆來構造輸入。