@@ -159,6 +159,20 @@ mod real_chacha {
159159			chacha_bytes
160160		} 
161161
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+ 
162176		fn  expand ( key :  & [ u8 ] ,  nonce :  & [ u8 ] )  -> ChaChaState  { 
163177			let  constant = match  key. len ( )  { 
164178				16  => b"expand 16-byte k" , 
@@ -290,6 +304,13 @@ mod fuzzy_chacha {
290304			[ 0 ;  32 ] 
291305		} 
292306
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+ 
293314		pub  fn  process ( & mut  self ,  input :  & [ u8 ] ,  output :  & mut  [ u8 ] )  { 
294315			output. copy_from_slice ( input) ; 
295316		} 
@@ -618,4 +639,27 @@ mod test {
618639
619640		assert_eq ! ( ChaCha20 :: get_single_block( & key,  & nonce_16bytes) ,  block_bytes) ; 
620641	} 
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+ 	} 
621665} 
0 commit comments