2.3 The ChaCha20 Block Function (ChaCha20ブロック関数)
2.3 The ChaCha20 Block Function (ChaCha20ブロック関数)
ChaChaブロック関数は, 複数のクォーターラウンドを実行することでChaCha状態を変換します。
ChaCha20への入力は次のとおりです:
-
256ビット鍵, 8つの32ビットリトルエンディアン整数の連結として扱われます。
-
96ビットnonce, 3つの32ビットリトルエンディアン整数の連結として扱われます。
-
32ビットブロックカウントパラメータ, 32ビットリトルエンディアン整数として扱われます。
出力は64バイトのランダムに見えるバイト列です。
ここで説明するChaChaアルゴリズムは256ビット鍵を使用します。元のアルゴリズムは128ビット鍵と8ラウンドおよび12ラウンドの変種も指定していますが, これらはこの文書の範囲外です。このセクションでは, ChaChaブロック関数について説明します。
また, 元のChaChaは64ビットnonceと64ビットブロックカウントを持っていたことに注意してください。[RFC5116]のセクション3.2の推奨事項とより一致するように, ここではこれを変更しました。これにより, 単一の(key,nonce)の組み合わせの使用は2^32ブロック, つまり256GBに制限されますが, ほとんどの用途には十分です。単一の鍵が複数の送信者によって使用される場合, 同じnonceを使用しないようにすることが重要です。これは, nonceスペースを分割して, 最初の32ビットが送信者ごとに一意であるようにし, 他の64ビットはカウンタから来るようにすることで保証できます。
ChaCha20状態は次のように初期化されます:
-
最初の4つのワード(0-3)は定数です: 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574。
-
次の8つのワード(4-11)は, リトルエンディアンの順序で4バイトチャンクでバイトを読み取ることにより, 256ビット鍵から取得されます。
-
ワード12はブロックカウンタです。各ブロックは64バイトなので, 32ビットワードは256ギガバイトのデータに十分です。
-
ワード13-15はnonceであり, 同じ鍵に対して繰り返してはなりません。13番目のワードはリトルエンディアン整数として取られた入力nonceの最初の32ビットであり, 15番目のワードは最後の32ビットです。
cccccccc cccccccc cccccccc cccccccc
kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk
kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk
bbbbbbbb nnnnnnnn nnnnnnnn nnnnnnnn
c=constant k=key b=blockcount n=nonce
ChaCha20は20ラウンドを実行し, 「列ラウンド」と「対角ラウンド」を交互に実行します。各ラウンドは4つのクォーターラウンドで構成され, 次のように実行されます。クォーターラウンド1-4は「列」ラウンドの一部であり, 5-8は「対角」ラウンドの一部です:
QUARTERROUND(0, 4, 8, 12)
QUARTERROUND(1, 5, 9, 13)
QUARTERROUND(2, 6, 10, 14)
QUARTERROUND(3, 7, 11, 15)
QUARTERROUND(0, 5, 10, 15)
QUARTERROUND(1, 6, 11, 12)
QUARTERROUND(2, 7, 8, 13)
QUARTERROUND(3, 4, 9, 14)
20ラウンドの終わり(または上記リストの10回の反復)に, 元の入力ワードを出力ワードに追加し, リトルエンディアンの順序でワードを1つずつ並べることによって結果をシリアライズします。
注意: 上記の段落の「加算」は2^32を法として行われます。一部の機械語では, これは32ビットワード上のキャリーレス加算と呼ばれます。
2.3.1 The ChaCha20 Block Function in Pseudocode (疑似コードのChaCha20ブロック関数)
注意: このセクションと他のいくつかのセクションには, 前のセクションで説明したアルゴリズムの疑似コードが含まれています。疑似コードが前のセクションで説明されたアルゴリズムを正確に反映するよう, あらゆる努力が払われました。それでも矛盾が存在する場合, テキストによる説明とテストベクトルが規範です。
inner_block (state):
Qround(state, 0, 4, 8, 12)
Qround(state, 1, 5, 9, 13)
Qround(state, 2, 6, 10, 14)
Qround(state, 3, 7, 11, 15)
Qround(state, 0, 5, 10, 15)
Qround(state, 1, 6, 11, 12)
Qround(state, 2, 7, 8, 13)
Qround(state, 3, 4, 9, 14)
end
chacha20_block(key, counter, nonce):
state = constants | key | counter | nonce
initial_state = state
for i=1 upto 10
inner_block(state)
end
state += initial_state
return serialize(state)
end
パイプ文字("|")は連結を示します。
2.3.2 Test Vector for the ChaCha20 Block Function (ChaCha20ブロック関数のテストベクトル)
テストベクトルとして, ChaCha20ブロック関数への次の入力を使用します:
-
Key = 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f。鍵は, ChaCha状態にコピーする前は特定の構造を持たないオクテットのシーケンスです。
-
Nonce = (00:00:00:09:00:00:00:4a:00:00:00:00)
-
Block Count = 1。
ChaCha状態を設定した後, 次のようになります:
ChaCha state with the key setup. (鍵設定後のChaCha状態)
61707865 3320646e 79622d32 6b206574
03020100 07060504 0b0a0908 0f0e0d0c
13121110 17161514 1b1a1918 1f1e1d1c
00000001 09000000 4a000000 00000000
20ラウンド実行後(10列ラウンドと10「対角ラウンド」をインターリーブ), ChaCha状態は次のようになります:
ChaCha state after 20 rounds (20ラウンド後のChaCha状態)
837778ab e238d763 a67ae21e 5950bb2f
c4f2d0c7 fc62bb2f 8fa018fc 3f5ec7b7
335271c2 f29489f3 eabda8fc 82e46ebd
d19c12b4 b04e16de 9e83d0cb 4e3c50a2
最後に, 元の状態を結果に追加(単純なベクトルまたは行列の加算)すると, 次のようになります:
ChaCha state at the end of the ChaCha20 operation (ChaCha20操作終了時のChaCha状態)
e4e7f110 15593bd1 1fdd0f50 c47120a3
c7f4d1c7 0368c033 9aaa2204 4e6cd4c3
466482d2 09aa9f07 05d7c214 a2028bd9
d19c12b5 b94e16de e883d0cb 4e3c50a2
状態をシリアライズすると, 次のようになります:
Serialized Block: (シリアライズされたブロック)
000 10 f1 e7 e4 d1 3b 59 15 50 0f dd 1f a3 20 71 c4 .....;Y.P.... q.
016 c7 d1 f4 c7 33 c0 68 03 04 22 aa 9a c3 d4 6c 4e ....3.h.."....lN
032 d2 82 64 46 07 9f aa 09 14 c2 d7 05 d9 8b 02 a2 ..dF............
048 b5 12 9c d1 de 16 4e b9 cb d0 83 e8 a2 50 3c 4e ......N......P<N