@@ -54,7 +54,8 @@ use std::io::Write;
5454pub struct EncWriter < A : Algorithm , W : Write > {
5555 inner : W ,
5656 algorithm : A ,
57- buffer : Vec < u8 > ,
57+ buffer : Box < [ u8 ] > ,
58+ pos : usize ,
5859 buf_size : usize ,
5960 nonce : Counter < A > ,
6061 aad : [ u8 ; 16 + 1 ] , // TODO: replace with [u8; A::TAG_LEN + 1]
@@ -153,7 +154,14 @@ impl<A: Algorithm, W: Write> EncWriter<A, W> {
153154 /// let aad = Aad::from("Some authenticated but not encrypted data".as_bytes());
154155 ///
155156 /// let mut ciphertext: Vec<u8> = Vec::default(); // Store the ciphertext in memory.
156- /// let mut writer = EncWriter::with_buffer_size(ciphertext, &key, nonce, aad, 64 * 1024).unwrap();
157+ /// let mut writer = EncWriter::with_buffer_size(
158+ /// &mut ciphertext,
159+ /// &key,
160+ /// nonce,
161+ /// aad,
162+ /// 64 * 1024,
163+ /// )
164+ /// .unwrap();
157165 ////
158166 /// // Perform some write and flush operations
159167 /// // ...
@@ -184,7 +192,8 @@ impl<A: Algorithm, W: Write> EncWriter<A, W> {
184192 Ok ( EncWriter {
185193 inner : inner,
186194 algorithm : A :: new ( key. as_ref ( ) ) ,
187- buffer : Vec :: with_capacity ( buf_size + A :: TAG_LEN ) ,
195+ buffer : vec ! [ 0 ; buf_size + A :: TAG_LEN ] . into_boxed_slice ( ) ,
196+ pos : 0 ,
188197 buf_size : buf_size,
189198 nonce : nonce,
190199 aad : associated_data,
@@ -196,19 +205,16 @@ impl<A: Algorithm, W: Write> EncWriter<A, W> {
196205
197206 /// Encrypt and authenticate the buffer and write the ciphertext
198207 /// to the inner writer.
199- fn write_buffer ( & mut self ) -> io:: Result < ( ) > {
200- self . buffer . resize ( self . buffer . len ( ) + A :: TAG_LEN , 0 ) ;
208+ fn write_buffer ( & mut self , len : usize ) -> io:: Result < ( ) > {
201209 let ciphertext = self . algorithm . seal_in_place (
202- & self . nonce . next ( ) ?,
210+ self . nonce . next ( ) ?,
203211 & self . aad ,
204- self . buffer . as_mut_slice ( ) ,
212+ & mut self . buffer [ ..len + A :: TAG_LEN ] ,
205213 ) ?;
206214
207215 self . panicked = true ;
208216 let r = self . inner . write_all ( ciphertext) ;
209217 self . panicked = false ;
210-
211- self . buffer . clear ( ) ;
212218 r
213219 }
214220}
@@ -222,24 +228,29 @@ impl<A: Algorithm, W: Write> Write for EncWriter<A, W> {
222228 let r: io:: Result < usize > = {
223229 let n = buf. len ( ) ;
224230
225- let remaining = self . buf_size - self . buffer . len ( ) ;
231+ let remaining = self . buf_size - self . pos ;
226232 if buf. len ( ) <= remaining {
227- return self . buffer . write_all ( buf) . and ( Ok ( n) ) ;
233+ self . buffer [ self . pos ..self . pos + buf. len ( ) ] . copy_from_slice ( buf) ;
234+ self . pos += buf. len ( ) ;
235+ return Ok ( buf. len ( ) ) ;
228236 }
229237
230- self . buffer . extend_from_slice ( & buf[ ..remaining] ) ;
231- self . write_buffer ( ) ?;
238+ self . buffer [ self . pos ..self . buf_size ] . copy_from_slice ( & buf[ ..remaining] ) ;
239+ self . write_buffer ( self . buf_size ) ?;
240+ self . pos = 0 ;
232241
233242 let buf = & buf[ remaining..] ;
234243 let chunks = buf. chunks ( self . buf_size ) ;
235244 chunks
236245 . clone ( )
237246 . take ( chunks. len ( ) - 1 ) // Since we take only n-1 elements...
238247 . try_for_each ( |chunk| {
239- self . buffer . extend_from_slice ( chunk) ;
240- self . write_buffer ( )
248+ self . buffer [ .. self . buf_size ] . copy_from_slice ( chunk) ;
249+ self . write_buffer ( self . buf_size )
241250 } ) ?;
242- self . buffer . extend_from_slice ( chunks. last ( ) . unwrap ( ) ) ; // ... there is always a last one.
251+ let last = chunks. last ( ) . unwrap ( ) ; // ... thereis always a last one.
252+ self . buffer [ ..last. len ( ) ] . copy_from_slice ( last) ; // ... there is always a last one.
253+ self . pos = last. len ( ) ;
243254 Ok ( n)
244255 } ;
245256 self . errored = r. is_err ( ) ;
@@ -310,21 +321,23 @@ impl<A: Algorithm, W: Write> Drop for EncWriter<A, W> {
310321/// // Use the same associated data (AAD) that was used during encryption.
311322/// let aad = Aad::from("Some authenticated but not encrypted data".as_bytes());
312323///
313- /// // The ciphertext as raw byte array.
314- /// let ciphertext = [15, 69, 209, 72, 77, 11, 165, 233, 108, 135, 157, 217,
315- /// 175, 75, 229, 217, 210, 88, 148, 173, 187, 7, 208, 154,
316- /// 222, 83, 56, 20, 179, 84, 114, 2, 192, 94, 54, 239, 221, 130];
317- ///
318324/// let mut plaintext: Vec<u8> = Vec::default(); // Store the plaintext in memory.
319- /// let mut writer = DecWriter::new(plaintext, &key, nonce, aad);
325+ /// let mut writer = DecWriter::new(&mut plaintext, &key, nonce, aad);
326+ ///
327+ /// // Passing the ciphertext as raw bytes.
328+ /// writer.write(&[14, 95, 207, 89, 77, 7, 174, 168, 96, 128, 148, 207, 224,
329+ /// 86, 236, 153 ,177, 220, 133, 123, 145, 175, 149, 241, 197,
330+ /// 153, 28, 234, 143, 173, 101,243,33]).unwrap();
320331///
321- /// writer.write_all(&ciphertext).unwrap();
322332/// writer.close().unwrap(); // Complete the decryption process explicitly!
333+ ///
334+ /// println!("{}", String::from_utf8_lossy(plaintext.as_slice())); // Let's print the plaintext.
323335/// ```
324336pub struct DecWriter < A : Algorithm , W : Write > {
325337 inner : W ,
326338 algorithm : A ,
327- buffer : Vec < u8 > ,
339+ buffer : Box < [ u8 ] > ,
340+ pos : usize ,
328341 buf_size : usize ,
329342 nonce : Counter < A > ,
330343 aad : [ u8 ; 16 + 1 ] , // TODO: replace with [u8; A::TAG_LEN + 1]
@@ -371,14 +384,18 @@ impl<A: Algorithm, W: Write> DecWriter<A, W> {
371384 /// let aad = Aad::from("Some authenticated but not encrypted data".as_bytes());
372385 ///
373386 /// let mut plaintext: Vec<u8> = Vec::default(); // Store the plaintext in memory.
374- /// let mut writer = DecWriter::new(plaintext, &key, nonce, aad);
387+ /// let mut writer = DecWriter::new(&mut plaintext, &key, nonce, aad);
375388 ///
376389 /// // Perform some write and flush operations
377390 /// // ...
378391 /// // For example:
379- /// writer.write(&[8, 222, 251, 80, 228, 234, 187, 138, 86, 169, 86, 122, 170, 158, 168, 18]).unwrap();
392+ /// writer.write(&[14, 95, 207, 89, 77, 7, 174, 168, 96, 128, 148, 207, 224,
393+ /// 86, 236, 153 ,177, 220, 133, 123, 145, 175, 149, 241, 197,
394+ /// 153, 28, 234, 143, 173, 101,243,33]).unwrap();
380395 ///
381396 /// writer.close().unwrap(); // Complete the decryption process explicitly!
397+ ///
398+ /// println!("{}", String::from_utf8_lossy(plaintext.as_slice())); // Let's print the plaintext.
382399 /// ```
383400 pub fn new ( inner : W , key : & Key < A > , nonce : Nonce < A > , aad : Aad < A > ) -> Self {
384401 Self :: with_buffer_size ( inner, key, nonce, aad, BUF_SIZE ) . unwrap ( )
@@ -418,14 +435,25 @@ impl<A: Algorithm, W: Write> DecWriter<A, W> {
418435 /// let aad = Aad::from("Some authenticated but not encrypted data".as_bytes());
419436 ///
420437 /// let mut plaintext: Vec<u8> = Vec::default(); // Store the plaintext in memory.
421- /// let mut writer = DecWriter::with_buffer_size(plaintext, &key, nonce, aad, 64 * 1024).unwrap();
438+ /// let mut writer = DecWriter::with_buffer_size(
439+ /// &mut plaintext,
440+ /// &key,
441+ /// nonce,
442+ /// aad,
443+ /// 64 * 1024,
444+ /// )
445+ /// .unwrap();
422446 ///
423447 /// // Perform some write and flush operations
424448 /// // ...
425449 /// // For example:
426- /// writer.write(&[8, 222, 251, 80, 228, 234, 187, 138, 86, 169, 86, 122, 170, 158, 168, 18]).unwrap();
450+ /// writer.write(&[14, 95, 207, 89, 77, 7, 174, 168, 96, 128, 148, 207, 224,
451+ /// 86, 236, 153 ,177, 220, 133, 123, 145, 175, 149, 241, 197,
452+ /// 153, 28, 234, 143, 173, 101,243,33]).unwrap();
427453 ///
428- /// writer.close().unwrap(); // Complete the encryption process explicitly!
454+ /// writer.close().unwrap(); // Complete the decryption process explicitly!
455+ ///
456+ /// println!("{}", String::from_utf8_lossy(plaintext.as_slice())); // Let's print the plaintext.
429457 /// ```
430458 pub fn with_buffer_size (
431459 inner : W ,
@@ -451,7 +479,8 @@ impl<A: Algorithm, W: Write> DecWriter<A, W> {
451479 Ok ( DecWriter {
452480 inner : inner,
453481 algorithm : A :: new ( key. as_ref ( ) ) ,
454- buffer : Vec :: with_capacity ( buf_size + A :: TAG_LEN ) ,
482+ buffer : vec ! [ 0 ; buf_size + A :: TAG_LEN ] . into_boxed_slice ( ) ,
483+ pos : 0 ,
455484 buf_size : buf_size,
456485 nonce : nonce,
457486 aad : associated_data,
@@ -463,18 +492,14 @@ impl<A: Algorithm, W: Write> DecWriter<A, W> {
463492
464493 /// Decrypt and verifies the buffer and write the plaintext
465494 /// to the inner writer.
466- fn write_buffer ( & mut self ) -> io:: Result < ( ) > {
467- let plaintext = self . algorithm . open_in_place (
468- & self . nonce . next ( ) ?,
469- & self . aad ,
470- self . buffer . as_mut_slice ( ) ,
471- ) ?;
495+ fn write_buffer ( & mut self , len : usize ) -> io:: Result < ( ) > {
496+ let plaintext =
497+ self . algorithm
498+ . open_in_place ( self . nonce . next ( ) ?, & self . aad , & mut self . buffer [ ..len] ) ?;
472499
473500 self . panicked = true ;
474501 let r = self . inner . write_all ( plaintext) ;
475502 self . panicked = false ;
476-
477- self . buffer . clear ( ) ;
478503 r
479504 }
480505}
@@ -487,24 +512,29 @@ impl<A: Algorithm, W: Write> Write for DecWriter<A, W> {
487512 let r: io:: Result < usize > = {
488513 let n = buf. len ( ) ;
489514
490- let remaining = self . buf_size + A :: TAG_LEN - self . buffer . len ( ) ;
515+ let remaining = self . buf_size + A :: TAG_LEN - self . pos ;
491516 if buf. len ( ) <= remaining {
492- return self . buffer . write_all ( buf) . and ( Ok ( n) ) ;
517+ self . buffer [ self . pos ..self . pos + buf. len ( ) ] . copy_from_slice ( buf) ;
518+ self . pos += buf. len ( ) ;
519+ return Ok ( n) ;
493520 }
494521
495- self . buffer . extend_from_slice ( & buf[ ..remaining] ) ;
496- self . write_buffer ( ) ?;
522+ self . buffer [ self . pos ..] . copy_from_slice ( & buf[ ..remaining] ) ;
523+ self . write_buffer ( self . buf_size + A :: TAG_LEN ) ?;
524+ self . pos = 0 ;
497525
498526 let buf = & buf[ remaining..] ;
499527 let chunks = buf. chunks ( self . buf_size + A :: TAG_LEN ) ;
500528 chunks
501529 . clone ( )
502530 . take ( chunks. len ( ) - 1 ) // Since we take only n-1 elements...
503531 . try_for_each ( |chunk| {
504- self . buffer . extend_from_slice ( chunk) ;
505- self . write_buffer ( )
532+ self . buffer . copy_from_slice ( chunk) ;
533+ self . write_buffer ( self . buf_size + A :: TAG_LEN )
506534 } ) ?;
507- self . buffer . extend_from_slice ( chunks. last ( ) . unwrap ( ) ) ; // ... there is always a last one.
535+ let last = chunks. last ( ) . unwrap ( ) ; // ... there is always a last one.
536+ self . buffer [ ..last. len ( ) ] . copy_from_slice ( last) ;
537+ self . pos = last. len ( ) ;
508538 Ok ( n)
509539 } ;
510540
@@ -575,7 +605,8 @@ impl<A: Algorithm, W: Write> EncWriter<A, W> {
575605 self . closed = true ;
576606 self . aad [ 0 ] = 0x80 ; // For the last fragment change the AAD
577607
578- self . write_buffer ( ) . and_then ( |( ) | self . inner . flush ( ) )
608+ self . write_buffer ( self . pos )
609+ . and_then ( |( ) | self . inner . flush ( ) )
579610 }
580611}
581612
@@ -609,7 +640,8 @@ impl<A: Algorithm, W: Write> DecWriter<A, W> {
609640 }
610641 self . closed = true ;
611642 self . aad [ 0 ] = 0x80 ; // For the last fragment change the AAD
612- self . write_buffer ( ) . and_then ( |( ) | self . inner . flush ( ) )
643+ self . write_buffer ( self . pos )
644+ . and_then ( |( ) | self . inner . flush ( ) )
613645 }
614646}
615647
0 commit comments