11//! Fixed size buffer for block processing of data.
2+ //!
3+ //! # Examples
4+ //! ```
5+ //! use block_buffer::{EagerBuffer, array::typenum::U4};
6+ //!
7+ //! let mut buf = EagerBuffer::<U4>::default();
8+ //!
9+ //! let mut accum = Vec::new();
10+ //! let msg1: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
11+ //! let msg2: &[u8] = &[10, 11, 12];
12+ //!
13+ //! buf.digest_blocks(msg1, |blocks| accum.extend_from_slice(blocks));
14+ //! buf.digest_blocks(msg2, |blocks| accum.extend_from_slice(blocks));
15+ //!
16+ //! assert_eq!(accum.len(), 3);
17+ //! assert_eq!(accum[0], [0, 1, 2, 3]);
18+ //! assert_eq!(accum[1], [4, 5, 6, 7]);
19+ //! assert_eq!(accum[2], [8, 9, 10, 11]);
20+ //!
21+ //! let padded_block = buf.pad_with_zeros();
22+ //! assert_eq!(padded_block, [12, 0, 0, 0]);
23+ //! ```
24+ //!
25+ //! Note that block size used with buffers MUST be bigger than zero and smaller than 256.
26+ //! You will get a compilation error with an invalid block size:
27+ //!
28+ //! ```compile_fail
29+ //! use block_buffer::{EagerBuffer, array::typenum::U0};
30+ //! let buf = EagerBuffer::<U0>::default();
31+ //! ```
32+ //! ```compile_fail
33+ //! use block_buffer::{EagerBuffer, array::typenum::U256};
34+ //! let buf = EagerBuffer::<U256>::default();
35+ //! ```
236#![ no_std]
337#![ doc(
438 html_logo_url = "https://github.com/RustCrypto/media/6ee8e381/logo.svg" ,
539 html_favicon_url = "https://github.com/RustCrypto/media/6ee8e381/logo.svg"
640) ]
741#![ warn( missing_docs, rust_2018_idioms) ]
842
9- pub use crypto_common :: { array , Block } ;
43+ pub use hybrid_array as array ;
1044
1145use array:: {
1246 typenum:: { Add1 , B1 } ,
1347 Array , ArraySize ,
1448} ;
1549use core:: { fmt, mem:: MaybeUninit , ops:: Add , ptr, slice} ;
16- use crypto_common:: { BlockSizeUser , BlockSizes } ;
1750
1851#[ cfg( feature = "zeroize" ) ]
1952use zeroize:: Zeroize ;
@@ -23,9 +56,6 @@ mod sealed;
2356
2457pub use read:: ReadBuffer ;
2558
26- /// Block with additional one byte
27- type BlockP1 < BlockSize > = Array < u8 , Add1 < BlockSize > > ;
28-
2959/// Trait for buffer kinds.
3060pub trait BufferKind : sealed:: Sealed { }
3161
@@ -59,26 +89,36 @@ impl fmt::Display for Error {
5989}
6090
6191/// Buffer for block processing of data.
62- pub struct BlockBuffer < BS : BlockSizes , K : BufferKind > {
63- buffer : MaybeUninit < Block < Self > > ,
92+ pub struct BlockBuffer < BS : ArraySize , K : BufferKind > {
93+ buffer : MaybeUninit < Array < u8 , BS > > ,
6494 pos : K :: Pos ,
6595}
6696
67- impl < BS : BlockSizes , K : BufferKind > BlockSizeUser for BlockBuffer < BS , K > {
68- type BlockSize = BS ;
97+ impl < BS : ArraySize , K : BufferKind > BlockBuffer < BS , K > {
98+ /// This associated constant is used to assert block size correctness at compile time.
99+ const BLOCK_SIZE_ASSERT : bool = {
100+ if BS :: USIZE == 0 {
101+ panic ! ( "Block size can not be equal to zero!" ) ;
102+ }
103+ if BS :: USIZE > 255 {
104+ panic ! ( "Block size can not be bigger than 255!" ) ;
105+ }
106+ true
107+ } ;
69108}
70109
71- impl < BS : BlockSizes , K : BufferKind > Default for BlockBuffer < BS , K > {
110+ impl < BS : ArraySize , K : BufferKind > Default for BlockBuffer < BS , K > {
72111 #[ inline]
73112 fn default ( ) -> Self {
113+ assert ! ( Self :: BLOCK_SIZE_ASSERT ) ;
74114 let mut buffer = MaybeUninit :: uninit ( ) ;
75115 let mut pos = Default :: default ( ) ;
76116 K :: set_pos ( & mut buffer, & mut pos, 0 ) ;
77117 Self { buffer, pos }
78118 }
79119}
80120
81- impl < BS : BlockSizes , K : BufferKind > Clone for BlockBuffer < BS , K > {
121+ impl < BS : ArraySize , K : BufferKind > Clone for BlockBuffer < BS , K > {
82122 #[ inline]
83123 fn clone ( & self ) -> Self {
84124 // SAFETY: `BlockBuffer` does not implement `Drop` (i.e. it could be a `Copy` type),
@@ -87,7 +127,7 @@ impl<BS: BlockSizes, K: BufferKind> Clone for BlockBuffer<BS, K> {
87127 }
88128}
89129
90- impl < BS : BlockSizes , K : BufferKind > fmt:: Debug for BlockBuffer < BS , K > {
130+ impl < BS : ArraySize , K : BufferKind > fmt:: Debug for BlockBuffer < BS , K > {
91131 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> Result < ( ) , fmt:: Error > {
92132 f. debug_struct ( K :: NAME )
93133 . field ( "pos" , & self . get_pos ( ) )
@@ -97,7 +137,7 @@ impl<BS: BlockSizes, K: BufferKind> fmt::Debug for BlockBuffer<BS, K> {
97137 }
98138}
99139
100- impl < BS : BlockSizes , K : BufferKind > BlockBuffer < BS , K > {
140+ impl < BS : ArraySize , K : BufferKind > BlockBuffer < BS , K > {
101141 /// Create new buffer from slice.
102142 ///
103143 /// # Panics
@@ -112,6 +152,7 @@ impl<BS: BlockSizes, K: BufferKind> BlockBuffer<BS, K> {
112152 /// Returns an error if slice length is not valid for used buffer kind.
113153 #[ inline( always) ]
114154 pub fn try_new ( buf : & [ u8 ] ) -> Result < Self , Error > {
155+ assert ! ( Self :: BLOCK_SIZE_ASSERT ) ;
115156 if !K :: invariant ( buf. len ( ) , BS :: USIZE ) {
116157 return Err ( Error ) ;
117158 }
@@ -126,7 +167,7 @@ impl<BS: BlockSizes, K: BufferKind> BlockBuffer<BS, K> {
126167 /// Digest data in `input` in blocks of size `BlockSize` using
127168 /// the `compress` function, which accepts slice of blocks.
128169 #[ inline]
129- pub fn digest_blocks ( & mut self , mut input : & [ u8 ] , mut compress : impl FnMut ( & [ Block < Self > ] ) ) {
170+ pub fn digest_blocks ( & mut self , mut input : & [ u8 ] , mut compress : impl FnMut ( & [ Array < u8 , BS > ] ) ) {
130171 let pos = self . get_pos ( ) ;
131172 // using `self.remaining()` for some reason
132173 // prevents panic elimination
@@ -186,8 +227,8 @@ impl<BS: BlockSizes, K: BufferKind> BlockBuffer<BS, K> {
186227
187228 /// Pad remaining data with zeros and return resulting block.
188229 #[ inline( always) ]
189- pub fn pad_with_zeros ( & mut self ) -> Block < Self > {
190- let mut res = Block :: < Self > :: default ( ) ;
230+ pub fn pad_with_zeros ( & mut self ) -> Array < u8 , BS > {
231+ let mut res = Array :: < u8 , BS > :: default ( ) ;
191232 let data = self . get_data ( ) ;
192233 res[ ..data. len ( ) ] . copy_from_slice ( data) ;
193234 self . reset ( ) ;
@@ -221,7 +262,7 @@ impl<BS: BlockSizes, K: BufferKind> BlockBuffer<BS, K> {
221262 /// # Panics
222263 /// If `pos` is bigger or equal to block size.
223264 #[ inline]
224- pub fn set ( & mut self , buf : Block < Self > , pos : usize ) {
265+ pub fn set ( & mut self , buf : Array < u8 , BS > , pos : usize ) {
225266 assert ! ( K :: invariant( pos, BS :: USIZE ) ) ;
226267 self . buffer = MaybeUninit :: new ( buf) ;
227268 // SAFETY: we have asserted that `pos` satisfies the invariant and
@@ -271,15 +312,20 @@ impl<BS: BlockSizes, K: BufferKind> BlockBuffer<BS, K> {
271312 }
272313}
273314
274- impl < BS : BlockSizes > BlockBuffer < BS , Eager > {
315+ impl < BS : ArraySize > BlockBuffer < BS , Eager > {
275316 /// Compress remaining data after padding it with `delim`, zeros and
276317 /// the `suffix` bytes. If there is not enough unused space, `compress`
277318 /// will be called twice.
278319 ///
279320 /// # Panics
280321 /// If suffix length is bigger than block size.
281322 #[ inline( always) ]
282- pub fn digest_pad ( & mut self , delim : u8 , suffix : & [ u8 ] , mut compress : impl FnMut ( & Block < Self > ) ) {
323+ pub fn digest_pad (
324+ & mut self ,
325+ delim : u8 ,
326+ suffix : & [ u8 ] ,
327+ mut compress : impl FnMut ( & Array < u8 , BS > ) ,
328+ ) {
283329 if suffix. len ( ) > BS :: USIZE {
284330 panic ! ( "suffix is too long" ) ;
285331 }
@@ -303,28 +349,28 @@ impl<BS: BlockSizes> BlockBuffer<BS, Eager> {
303349 /// Pad message with 0x80, zeros and 64-bit message length using
304350 /// big-endian byte order.
305351 #[ inline]
306- pub fn len64_padding_be ( & mut self , data_len : u64 , compress : impl FnMut ( & Block < Self > ) ) {
352+ pub fn len64_padding_be ( & mut self , data_len : u64 , compress : impl FnMut ( & Array < u8 , BS > ) ) {
307353 self . digest_pad ( 0x80 , & data_len. to_be_bytes ( ) , compress) ;
308354 }
309355
310356 /// Pad message with 0x80, zeros and 64-bit message length using
311357 /// little-endian byte order.
312358 #[ inline]
313- pub fn len64_padding_le ( & mut self , data_len : u64 , compress : impl FnMut ( & Block < Self > ) ) {
359+ pub fn len64_padding_le ( & mut self , data_len : u64 , compress : impl FnMut ( & Array < u8 , BS > ) ) {
314360 self . digest_pad ( 0x80 , & data_len. to_le_bytes ( ) , compress) ;
315361 }
316362
317363 /// Pad message with 0x80, zeros and 128-bit message length using
318364 /// big-endian byte order.
319365 #[ inline]
320- pub fn len128_padding_be ( & mut self , data_len : u128 , compress : impl FnMut ( & Block < Self > ) ) {
366+ pub fn len128_padding_be ( & mut self , data_len : u128 , compress : impl FnMut ( & Array < u8 , BS > ) ) {
321367 self . digest_pad ( 0x80 , & data_len. to_be_bytes ( ) , compress) ;
322368 }
323369
324370 /// Serialize buffer into a byte array.
325371 #[ inline]
326- pub fn serialize ( & self ) -> Block < Self > {
327- let mut res = Block :: < Self > :: default ( ) ;
372+ pub fn serialize ( & self ) -> Array < u8 , BS > {
373+ let mut res = Array :: < u8 , BS > :: default ( ) ;
328374 let data = self . get_data ( ) ;
329375 res[ ..data. len ( ) ] . copy_from_slice ( data) ;
330376 res[ BS :: USIZE - 1 ] = data. len ( ) as u8 ;
@@ -333,7 +379,7 @@ impl<BS: BlockSizes> BlockBuffer<BS, Eager> {
333379
334380 /// Deserialize buffer from a byte array.
335381 #[ inline]
336- pub fn deserialize ( buffer : & Block < Self > ) -> Result < Self , Error > {
382+ pub fn deserialize ( buffer : & Array < u8 , BS > ) -> Result < Self , Error > {
337383 let pos = buffer[ BS :: USIZE - 1 ] as usize ;
338384 if !<Eager as sealed:: Sealed >:: invariant ( pos, BS :: USIZE ) {
339385 return Err ( Error ) ;
@@ -348,15 +394,15 @@ impl<BS: BlockSizes> BlockBuffer<BS, Eager> {
348394 }
349395}
350396
351- impl < BS : BlockSizes > BlockBuffer < BS , Lazy > {
397+ impl < BS : ArraySize > BlockBuffer < BS , Lazy > {
352398 /// Serialize buffer into a byte array.
353399 #[ inline]
354- pub fn serialize ( & self ) -> BlockP1 < BS >
400+ pub fn serialize ( & self ) -> Array < u8 , Add1 < BS > >
355401 where
356402 BS : Add < B1 > ,
357403 Add1 < BS > : ArraySize ,
358404 {
359- let mut res = BlockP1 :: < BS > :: default ( ) ;
405+ let mut res = Array :: < u8 , Add1 < BS > > :: default ( ) ;
360406 res[ 0 ] = self . pos ;
361407 let data = self . get_data ( ) ;
362408 res[ 1 ..] [ ..data. len ( ) ] . copy_from_slice ( data) ;
@@ -365,7 +411,7 @@ impl<BS: BlockSizes> BlockBuffer<BS, Lazy> {
365411
366412 /// Deserialize buffer from a byte array.
367413 #[ inline]
368- pub fn deserialize ( buffer : & BlockP1 < BS > ) -> Result < Self , Error >
414+ pub fn deserialize ( buffer : & Array < u8 , Add1 < BS > > ) -> Result < Self , Error >
369415 where
370416 BS : Add < B1 > ,
371417 Add1 < BS > : ArraySize ,
@@ -386,7 +432,7 @@ impl<BS: BlockSizes> BlockBuffer<BS, Lazy> {
386432}
387433
388434#[ cfg( feature = "zeroize" ) ]
389- impl < BS : BlockSizes , K : BufferKind > Zeroize for BlockBuffer < BS , K > {
435+ impl < BS : ArraySize , K : BufferKind > Zeroize for BlockBuffer < BS , K > {
390436 #[ inline]
391437 fn zeroize ( & mut self ) {
392438 self . buffer . zeroize ( ) ;
0 commit comments