2.3 The ChaCha20 Block Function (La fonction de bloc ChaCha20)
2.3 The ChaCha20 Block Function (La fonction de bloc ChaCha20)
La fonction de bloc ChaCha transforme un état ChaCha en exécutant plusieurs quarts de tour.
Les entrées de ChaCha20 sont:
-
Une clé de 256 bits, traitée comme une concaténation de huit entiers little-endian de 32 bits.
-
Un nonce de 96 bits, traité comme une concaténation de trois entiers little-endian de 32 bits.
-
Un paramètre de compteur de blocs de 32 bits, traité comme un entier little-endian de 32 bits.
La sortie est 64 octets d'apparence aléatoire.
L'algorithme ChaCha décrit ici utilise une clé de 256 bits. L'algorithme original spécifiait également des clés de 128 bits et des variantes à 8 et 12 tours, mais celles-ci sont hors de portée de ce document. Dans cette section, nous décrivons la fonction de bloc ChaCha.
Notez également que le ChaCha original avait un nonce de 64 bits et un compteur de blocs de 64 bits. Nous avons modifié cela ici pour être plus cohérent avec les recommandations de la Section 3.2 de [RFC5116]. Cela limite l'utilisation d'une seule combinaison (clé,nonce) à 2^32 blocs, soit 256 Go, mais c'est suffisant pour la plupart des utilisations. Dans les cas où une seule clé est utilisée par plusieurs expéditeurs, il est important de s'assurer qu'ils n'utilisent pas les mêmes nonces. Ceci peut être assuré en partitionnant l'espace de nonce de sorte que les premiers 32 bits soient uniques par expéditeur, tandis que les 64 autres bits proviennent d'un compteur.
L'état ChaCha20 est initialisé comme suit:
-
Les quatre premiers mots (0-3) sont des constantes: 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574.
-
Les huit mots suivants (4-11) sont tirés de la clé de 256 bits en lisant les octets dans l'ordre little-endian, par morceaux de 4 octets.
-
Le mot 12 est un compteur de blocs. Puisque chaque bloc fait 64 octets, un mot de 32 bits suffit pour 256 gigaoctets de données.
-
Les mots 13-15 sont un nonce, qui NE DOIT PAS être répété pour la même clé. Le 13ème mot est les premiers 32 bits du nonce d'entrée pris comme un entier little-endian, tandis que le 15ème mot est les derniers 32 bits.
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 exécute 20 tours, alternant entre "tours de colonnes" et "tours de diagonales". Chaque tour consiste en quatre quarts de tour, et ils sont exécutés comme suit. Les quarts de tour 1-4 font partie d'un tour de "colonne", tandis que 5-8 font partie d'un tour de "diagonale":
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)
À la fin de 20 tours (ou 10 itérations de la liste ci-dessus), nous ajoutons les mots d'entrée originaux aux mots de sortie, et sérialisons le résultat en séquençant les mots un par un dans l'ordre little-endian.
Note: l'"addition" dans le paragraphe ci-dessus est effectuée modulo 2^32. Dans certains langages machine, cela s'appelle addition sans report sur un mot de 32 bits.
2.3.1 The ChaCha20 Block Function in Pseudocode (La fonction de bloc ChaCha20 en pseudocode)
Note: Cette section et quelques autres contiennent du pseudocode pour l'algorithme expliqué dans une section précédente. Tous les efforts ont été faits pour que le pseudocode reflète fidèlement l'algorithme tel que décrit dans la section précédente. Si un conflit est toujours présent, l'explication textuelle et les vecteurs de test sont normatifs.
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
Où le caractère pipe ("|") dénote la concaténation.
2.3.2 Test Vector for the ChaCha20 Block Function (Vecteur de test pour la fonction de bloc ChaCha20)
Pour un vecteur de test, nous utiliserons les entrées suivantes pour la fonction de bloc 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. La clé est une séquence d'octets sans structure particulière avant que nous la copiions dans l'état ChaCha.
-
Nonce = (00:00:00:09:00:00:00:4a:00:00:00:00)
-
Block Count = 1.
Après avoir configuré l'état ChaCha, il ressemble à ceci:
ChaCha state with the key setup. (État ChaCha avec la configuration de clé)
61707865 3320646e 79622d32 6b206574
03020100 07060504 0b0a0908 0f0e0d0c
13121110 17161514 1b1a1918 1f1e1d1c
00000001 09000000 4a000000 00000000
Après avoir exécuté 20 tours (10 tours de colonnes entrelacés avec 10 "tours de diagonales"), l'état ChaCha ressemble à ceci:
ChaCha state after 20 rounds (État ChaCha après 20 tours)
837778ab e238d763 a67ae21e 5950bb2f
c4f2d0c7 fc62bb2f 8fa018fc 3f5ec7b7
335271c2 f29489f3 eabda8fc 82e46ebd
d19c12b4 b04e16de 9e83d0cb 4e3c50a2
Enfin, nous ajoutons l'état original au résultat (simple addition vectorielle ou matricielle), donnant ceci:
ChaCha state at the end of the ChaCha20 operation (État ChaCha à la fin de l'opération ChaCha20)
e4e7f110 15593bd1 1fdd0f50 c47120a3
c7f4d1c7 0368c033 9aaa2204 4e6cd4c3
466482d2 09aa9f07 05d7c214 a2028bd9
d19c12b5 b94e16de e883d0cb 4e3c50a2
Après avoir sérialisé l'état, nous obtenons ceci:
Serialized Block: (Bloc sérialisé)
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