KECCAKは、ゼロで満たされた状態配列でどのように動作しますか?
Javaでスポンジを実装しようとしています。状態は、すべてゼロの空の200バイト配列として始まります。NISTのKMACサンプルドキュメントでは、次のことが発生します。


(黒い線はPDF改ページです)
Imがこれを読み取る方法は、ゼロの束を持つ状態が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
そしてそれらがどのように使用されるかを説明します。のイオタステップで$n^\text{th}$ Keccak-pラウンド、 $n^\text{th}$ ラウンド定数 $RC[n]$ 導入され、最初の単語、最初のレーンにXORされます。
ラウンド定数とは別に、Keccak順列は非常に優れた拡散を示します。初期状態のどこかにある単一ビットは、多くの出力ビットに大きく影響します。
両方の組み合わせは、Keccak順列が非常にランダムに見えることを意味します。もちろん、ゼロエントロピーをランダムに変えることはできません。有限のアルゴリズムではそれができないためですが、Keccakの目標は、物事を混ぜ合わせてランダムに見せることです。
Keccak置換関数は、通常、ゼロ入力(すべてのビットが0)をゼロ出力にマップします。ただし、状態の1ワードがゼロ以外の定数とXORされるiotaステップの場合はそうではありません。
完全に拡散するには、約3ラウンド(24ラウンド中)で十分です。つまり、状態のすべてのビットが3ラウンド後に他のすべてのビットに影響を与えます。順列は状態を8回完全に混合すると言うことができます。つまり、1ビットだけが1の場合、状態全体にすばやく拡散するため、3ラウンド後に状態ビットの約半分が1になります。
しましょう $R$合理的に「通常の外観」と呼ぶことができる状態値のセットである(正確な定義が何であれ)。たとえば、すべてまたはほぼすべてのビットが同じ値を持っているか、短いビットパターンが定期的に繰り返されます。すべての中で$2^{1600}$ 州、 $R$非常に小さな割合です。の状態はほとんどありません$R$ でも出力にマッピングされます $R$。これは、$|R| \ll 2^{800}$ (「誕生日のパラドックス」を参照)。
これは、通常の出力にマップされる通常の入力がないことを意味します。そして、任意の状態が出力にマップされる確率$R$ は無視できます。つまり、誰かが順列の逆数を計算して入力を意図的に作成する場合を除いて、出力は常にランダムに見えます。