@@ -159,6 +159,20 @@ mod real_chacha {
159
159
chacha_bytes
160
160
}
161
161
162
+ /// Encrypts `src` into `dest` using a single block from a ChaCha stream. Passing `dest` as
163
+ /// `src` in a second call will decrypt it.
164
+ pub fn encrypt_single_block (
165
+ key : & [ u8 ; 32 ] , nonce : & [ u8 ; 16 ] , dest : & mut [ u8 ] , src : & [ u8 ]
166
+ ) {
167
+ debug_assert_eq ! ( dest. len( ) , src. len( ) ) ;
168
+ debug_assert ! ( dest. len( ) <= 32 ) ;
169
+
170
+ let block = ChaCha20 :: get_single_block ( key, nonce) ;
171
+ for i in 0 ..dest. len ( ) {
172
+ dest[ i] = block[ i] ^ src[ i] ;
173
+ }
174
+ }
175
+
162
176
fn expand ( key : & [ u8 ] , nonce : & [ u8 ] ) -> ChaChaState {
163
177
let constant = match key. len ( ) {
164
178
16 => b"expand 16-byte k" ,
@@ -290,6 +304,13 @@ mod fuzzy_chacha {
290
304
[ 0 ; 32 ]
291
305
}
292
306
307
+ pub fn encrypt_single_block (
308
+ _key : & [ u8 ; 32 ] , _nonce : & [ u8 ; 16 ] , dest : & mut [ u8 ] , src : & [ u8 ]
309
+ ) {
310
+ debug_assert_eq ! ( dest. len( ) , src. len( ) ) ;
311
+ debug_assert ! ( dest. len( ) <= 32 ) ;
312
+ }
313
+
293
314
pub fn process ( & mut self , input : & [ u8 ] , output : & mut [ u8 ] ) {
294
315
output. copy_from_slice ( input) ;
295
316
}
@@ -618,4 +639,27 @@ mod test {
618
639
619
640
assert_eq ! ( ChaCha20 :: get_single_block( & key, & nonce_16bytes) , block_bytes) ;
620
641
}
642
+
643
+ #[ test]
644
+ fn encrypt_single_block ( ) {
645
+ let key = [
646
+ 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 ,
647
+ 0x08 , 0x09 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f ,
648
+ 0x10 , 0x11 , 0x12 , 0x13 , 0x14 , 0x15 , 0x16 , 0x17 ,
649
+ 0x18 , 0x19 , 0x1a , 0x1b , 0x1c , 0x1d , 0x1e , 0x1f ,
650
+ ] ;
651
+ let nonce = [
652
+ 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 ,
653
+ 0x09 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f ,
654
+ ] ;
655
+ let bytes = [ 1 ; 32 ] ;
656
+
657
+ let mut encrypted_bytes = [ 0 ; 32 ] ;
658
+ ChaCha20 :: encrypt_single_block ( & key, & nonce, & mut encrypted_bytes, & bytes) ;
659
+
660
+ let mut decrypted_bytes = [ 0 ; 32 ] ;
661
+ ChaCha20 :: encrypt_single_block ( & key, & nonce, & mut decrypted_bytes, & encrypted_bytes) ;
662
+
663
+ assert_eq ! ( bytes, decrypted_bytes) ;
664
+ }
621
665
}
0 commit comments