@@ -101,7 +101,7 @@ impl CryptoRng for StdRng {}
101101#[ cfg( test) ]
102102mod test {
103103 use crate :: rngs:: StdRng ;
104- use crate :: { RngCore , SeedableRng } ;
104+ use crate :: { Rng , RngCore , SeedableRng } ;
105105
106106 #[ test]
107107 fn test_stdrng_construction ( ) {
@@ -114,11 +114,172 @@ mod test {
114114 let target = [ 10719222850664546238 , 14064965282130556830 ] ;
115115
116116 let mut rng0 = StdRng :: from_seed ( seed) ;
117+
117118 let x0 = rng0. next_u64 ( ) ;
118119
119120 let mut rng1 = StdRng :: from_rng ( & mut rng0) ;
120121 let x1 = rng1. next_u64 ( ) ;
121122
122123 assert_eq ! ( [ x0, x1] , target) ;
123124 }
125+
126+ #[ test]
127+ fn test_chacha_true_values_1 ( ) {
128+ // Source: Strombergson 2013, Test Vectors for the Stream Cipher ChaCha
129+ // draft-strombergson-chacha-test-vectors-01
130+ // https://datatracker.ietf.org/doc/html/draft-strombergson-chacha-test-vectors-01
131+ // Converted to LE u128 form (four u128 to one block).
132+ // TC: all zero key and IV, rounds 12, 256-bit key
133+
134+ let seed = [ 0u8 ; 32 ] ;
135+ let mut rng = StdRng :: from_seed ( seed) ;
136+
137+ let mut results = [ 0u128 ; 8 ] ;
138+ rng. fill ( & mut results) ;
139+ let expected = [
140+ 0xd583265f12ce1f8153f955076a9af49b ,
141+ 0x5f15ae2ea589007e1474e049bbc32904 ,
142+ 0x798cfaac3428e82cc0e37ad279f86405 ,
143+ 0xbe2613412fe80b611969dea02c9f623a ,
144+ 0x3d17e08c3371fc86fe743e204188d50b ,
145+ 0xb489c04c21851515cccbbd19b7eb28c6 ,
146+ 0x43c88c1b97b802c611f14ca1cd8d2542 ,
147+ 0x1693e617b0a64427c0515190ca461ee9 ,
148+ ] ;
149+ assert_eq ! ( results, expected) ;
150+
151+ assert_eq ! ( rng. 0 . get_word_pos( ) , 32 ) ;
152+ }
153+
154+ #[ test]
155+ fn test_chacha_true_values_2 ( ) {
156+ // Source: Strombergson 2013, Test Vectors for the Stream Cipher ChaCha
157+ // TC2: single bit set in key, all zero IV, rounds 12, 256-bit key
158+
159+ let mut seed = [ 0u8 ; 32 ] ;
160+ seed[ 0 ] = 1 ;
161+ let mut rng = StdRng :: from_seed ( seed) ;
162+
163+ let mut results = [ 0u128 ; 8 ] ;
164+ rng. fill ( & mut results) ;
165+ let expected = [
166+ 0x9a225cdf090f0eef6b0565d596e0512 ,
167+ 0x10dd4d0bff1802930f5d5290278c2449 ,
168+ 0xfefdfe067d7a109ee254a4d9392200a6 ,
169+ 0xc029dc60c972179bf2f944a0eb0f21f0 ,
170+ 0x2a37692ab05e660e2404c6cbc566730c ,
171+ 0xc8a72980b8c4c72a0978bb6fb279f97a ,
172+ 0xaf15ba8e302e43907dfcbb17c23b5154 ,
173+ 0xa9177125baafe601560d10ef48eb5ac6 ,
174+ ] ;
175+ assert_eq ! ( results, expected) ;
176+
177+ assert_eq ! ( rng. 0 . get_word_pos( ) , 32 ) ;
178+ }
179+
180+ #[ test]
181+ fn test_chacha_true_values_3 ( ) {
182+ // Source: Strombergson 2013, Test Vectors for the Stream Cipher ChaCha
183+ // TC3: all zero key, single bit set in IV, rounds 12, 256-bit key
184+
185+ let seed = [ 0u8 ; 32 ] ;
186+ let mut rng = StdRng :: from_seed ( seed) ;
187+ rng. 0 . set_stream ( 1 ) ;
188+
189+ let mut results = [ 0u128 ; 8 ] ;
190+ rng. fill ( & mut results) ;
191+ let expected = [
192+ 0x3de08d69eff7ba6d4b8c827bf8bdb864 ,
193+ 0x6929e19be5ad36988f411457633fb3f8 ,
194+ 0xa5995d1de898cb9efccf8ef3a053c946 ,
195+ 0xf1d8f021fb3f31ee4b9450a9a8ffced ,
196+ 0x28886a59a2b923fe42c422f2a7b49d55 ,
197+ 0x23c72a9150a17ca76e8963134fee2251 ,
198+ 0x67b7d07029cb2037e802f6a024bf0bf ,
199+ 0x6fa2523bbd836d3a01c8137c82b91afc ,
200+ ] ;
201+ assert_eq ! ( results, expected) ;
202+
203+ assert_eq ! ( rng. 0 . get_word_pos( ) , 32 ) ;
204+ }
205+
206+ #[ test]
207+ fn test_chacha_true_values_8 ( ) {
208+ // Source: Strombergson 2013, Test Vectors for the Stream Cipher ChaCha
209+ // TC8: key: 'All your base are belong to us!', IV: IETF2013, rounds 12, 256-bit key
210+
211+ #[ rustfmt:: skip]
212+ let seed = [
213+ 0xc4 , 0x6e , 0xc1 , 0xb1 , 0x8c , 0xe8 , 0xa8 , 0x78 ,
214+ 0x72 , 0x5a , 0x37 , 0xe7 , 0x80 , 0xdf , 0xb7 , 0x35 ,
215+ 0x1f , 0x68 , 0xed , 0x2e , 0x19 , 0x4c , 0x79 , 0xfb ,
216+ 0xc6 , 0xae , 0xbe , 0xe1 , 0xa6 , 0x67 , 0x97 , 0x5d ,
217+ ] ;
218+ let iv = [ 0x1a , 0xda , 0x31 , 0xd5 , 0xcf , 0x68 , 0x82 , 0x21 ] ;
219+ let mut rng = StdRng :: from_seed ( seed) ;
220+ rng. 0 . set_stream ( u64:: from_le_bytes ( iv) ) ;
221+
222+ let mut results = [ 0u128 ; 8 ] ;
223+ rng. fill ( & mut results) ;
224+ let expected = [
225+ 0x10c08b11dc3be7b4066dbc8427078214 ,
226+ 0xc19c7e1f25aa8669e018a96c7876793c ,
227+ 0x207c8db0992e2d24b483ee160a9a74b2 ,
228+ 0xabfb0f9db3b1613b28876c46bc802b09 ,
229+ 0x5495b60d624f9e9b32dbebc16b114bd9 ,
230+ 0x31d66e96ad465a970c3d47689b3d8e4a ,
231+ 0x3c11e5a1df7a04d8c7ead50a53ff2ae4 ,
232+ 0x2ba4a57be08f1cac89d1f183b8e3f391 ,
233+ ] ;
234+ assert_eq ! ( results, expected) ;
235+
236+ assert_eq ! ( rng. 0 . get_word_pos( ) , 32 ) ;
237+ }
238+
239+ #[ test]
240+ fn test_chacha_counter ( ) {
241+ // Source: rand_chacha implementation
242+ // We test six blocks: counter=u32::MAX, four blocks from 2^32 (backends
243+ // which yield four blocks at a time may need to handle this specially)
244+ // and the first block after this wrap-logic completes.
245+ // Test: all zero key and IV, block set to u32::MAX, rounds 12, 256-bit key
246+
247+ let seed = [ 0u8 ; 32 ] ;
248+ let mut rng = StdRng :: from_seed ( seed) ;
249+ let block = u32:: MAX ;
250+ let words_per_block = 16 ;
251+ rng. 0 . set_word_pos ( ( block as u128 ) * words_per_block) ;
252+
253+ let mut results = [ 0u128 ; 4 * 6 ] ;
254+ rng. fill ( & mut results) ;
255+ let expected = [
256+ 0xf106e2fcbb524248292ac9f150afa6d7 ,
257+ 0x12032ef6c183b50a83a3309513dd017d ,
258+ 0x2c93ff300438eaed6c958a9aa1619382 ,
259+ 0x74fc0624270ab858508377945edb52d0 ,
260+ 0xe5f4f4a8b8810524264d8911dc537bcc ,
261+ 0x18a6a6cbdc1f823fb1231280056740af ,
262+ 0xabdae0a44b1f45edbccc83dcd3f8638a ,
263+ 0xad6b649f12f70de567cc39740dbb8a22 ,
264+ 0x37512785327825dc30ecfaf37a38f5a0 ,
265+ 0x5af852d2df0dc286c2dd19af39b54e39 ,
266+ 0xb04dc185c27497ac9f4a4f6769d1b5d ,
267+ 0x816492be66439cecd2498c9865284377 ,
268+ 0x724fe95e0b6cbb8a55b707c06166147f ,
269+ 0xe3e7cda19d92b5318024abb34aa31329 ,
270+ 0x1a3594d7283c077017cd511144bf3db3 ,
271+ 0x99ab26cf14f38b11d78e413bdce6424c ,
272+ 0x553deaed89d3bf630de05408c0f655e8 ,
273+ 0x86c46a5676fef18f0dc0dff3ee16507c ,
274+ 0xd33d6cf5ade97b000b29e3ce614faf51 ,
275+ 0x5b62dcc48c0fc60326afc5783c40d40c ,
276+ 0x44eedc777ed030f43d382d4921eba244 ,
277+ 0xa2d66a5893ade34a0d17c706e8d89dba ,
278+ 0xd229d1f3a07526e47cabd035135012fd ,
279+ 0xefae0722059b654dea6945547e535052 ,
280+ ] ;
281+ assert_eq ! ( results, expected) ;
282+
283+ assert_eq ! ( rng. 0 . get_word_pos( ) , ( block as u128 ) * words_per_block + 96 ) ;
284+ }
124285}
0 commit comments