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 255.
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+ //!
31+ //! let buf = EagerBuffer::<U0>::default();
32+ //! ```
33+ //! ```compile_fail
34+ //! use block_buffer::{EagerBuffer, array::typenum::U256};
35+ //!
36+ //! let buf = EagerBuffer::<U256>::default();
37+ //! ```
238#![ no_std]
339#![ doc(
440 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" ,
541 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
642) ]
743#![ warn( missing_docs, rust_2018_idioms) ]
844
9- pub use crypto_common :: { array , Block } ;
45+ pub use hybrid_array as array ;
1046
1147use array:: {
1248 typenum:: { Add1 , B1 } ,
1349 Array , ArraySize ,
1450} ;
1551use core:: { fmt, mem:: MaybeUninit , ops:: Add , ptr, slice} ;
16- use crypto_common:: { BlockSizeUser , BlockSizes } ;
1752
1853#[ cfg( feature = "zeroize" ) ]
1954use zeroize:: Zeroize ;
@@ -23,9 +58,6 @@ mod sealed;
2358
2459pub use read:: ReadBuffer ;
2560
26- /// Block with additional one byte
27- type BlockP1 < BlockSize > = Array < u8 , Add1 < BlockSize > > ;
28-
2961/// Trait for buffer kinds.
3062pub trait BufferKind : sealed:: Sealed { }
3163
@@ -59,26 +91,36 @@ impl fmt::Display for Error {
5991}
6092
6193/// Buffer for block processing of data.
62- pub struct BlockBuffer < BS : BlockSizes , K : BufferKind > {
63- buffer : MaybeUninit < Block < Self > > ,
94+ pub struct BlockBuffer < BS : ArraySize , K : BufferKind > {
95+ buffer : MaybeUninit < Array < u8 , BS > > ,
6496 pos : K :: Pos ,
6597}
6698
67- impl < BS : BlockSizes , K : BufferKind > BlockSizeUser for BlockBuffer < BS , K > {
68- type BlockSize = BS ;
99+ impl < BS : ArraySize , K : BufferKind > BlockBuffer < BS , K > {
100+ /// This associated constant is used to assert block size correctness at compile time.
101+ const BLOCK_SIZE_ASSERT : bool = {
102+ if BS :: USIZE == 0 {
103+ panic ! ( "Block size can not be equal to zero!" ) ;
104+ }
105+ if BS :: USIZE > 255 {
106+ panic ! ( "Block size can not be bigger than 255!" ) ;
107+ }
108+ true
109+ } ;
69110}
70111
71- impl < BS : BlockSizes , K : BufferKind > Default for BlockBuffer < BS , K > {
112+ impl < BS : ArraySize , K : BufferKind > Default for BlockBuffer < BS , K > {
72113 #[ inline]
73114 fn default ( ) -> Self {
115+ assert ! ( Self :: BLOCK_SIZE_ASSERT ) ;
74116 let mut buffer = MaybeUninit :: uninit ( ) ;
75117 let mut pos = Default :: default ( ) ;
76118 K :: set_pos ( & mut buffer, & mut pos, 0 ) ;
77119 Self { buffer, pos }
78120 }
79121}
80122
81- impl < BS : BlockSizes , K : BufferKind > Clone for BlockBuffer < BS , K > {
123+ impl < BS : ArraySize , K : BufferKind > Clone for BlockBuffer < BS , K > {
82124 #[ inline]
83125 fn clone ( & self ) -> Self {
84126 // SAFETY: `BlockBuffer` does not implement `Drop` (i.e. it could be a `Copy` type),
@@ -87,7 +129,7 @@ impl<BS: BlockSizes, K: BufferKind> Clone for BlockBuffer<BS, K> {
87129 }
88130}
89131
90- impl < BS : BlockSizes , K : BufferKind > fmt:: Debug for BlockBuffer < BS , K > {
132+ impl < BS : ArraySize , K : BufferKind > fmt:: Debug for BlockBuffer < BS , K > {
91133 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> Result < ( ) , fmt:: Error > {
92134 f. debug_struct ( K :: NAME )
93135 . field ( "pos" , & self . get_pos ( ) )
@@ -97,7 +139,7 @@ impl<BS: BlockSizes, K: BufferKind> fmt::Debug for BlockBuffer<BS, K> {
97139 }
98140}
99141
100- impl < BS : BlockSizes , K : BufferKind > BlockBuffer < BS , K > {
142+ impl < BS : ArraySize , K : BufferKind > BlockBuffer < BS , K > {
101143 /// Create new buffer from slice.
102144 ///
103145 /// # Panics
@@ -112,6 +154,7 @@ impl<BS: BlockSizes, K: BufferKind> BlockBuffer<BS, K> {
112154 /// Returns an error if slice length is not valid for used buffer kind.
113155 #[ inline( always) ]
114156 pub fn try_new ( buf : & [ u8 ] ) -> Result < Self , Error > {
157+ assert ! ( Self :: BLOCK_SIZE_ASSERT ) ;
115158 if !K :: invariant ( buf. len ( ) , BS :: USIZE ) {
116159 return Err ( Error ) ;
117160 }
@@ -126,7 +169,7 @@ impl<BS: BlockSizes, K: BufferKind> BlockBuffer<BS, K> {
126169 /// Digest data in `input` in blocks of size `BlockSize` using
127170 /// the `compress` function, which accepts slice of blocks.
128171 #[ inline]
129- pub fn digest_blocks ( & mut self , mut input : & [ u8 ] , mut compress : impl FnMut ( & [ Block < Self > ] ) ) {
172+ pub fn digest_blocks ( & mut self , mut input : & [ u8 ] , mut compress : impl FnMut ( & [ Array < u8 , BS > ] ) ) {
130173 let pos = self . get_pos ( ) ;
131174 // using `self.remaining()` for some reason
132175 // prevents panic elimination
@@ -186,8 +229,8 @@ impl<BS: BlockSizes, K: BufferKind> BlockBuffer<BS, K> {
186229
187230 /// Pad remaining data with zeros and return resulting block.
188231 #[ inline( always) ]
189- pub fn pad_with_zeros ( & mut self ) -> Block < Self > {
190- let mut res = Block :: < Self > :: default ( ) ;
232+ pub fn pad_with_zeros ( & mut self ) -> Array < u8 , BS > {
233+ let mut res = Array :: < u8 , BS > :: default ( ) ;
191234 let data = self . get_data ( ) ;
192235 res[ ..data. len ( ) ] . copy_from_slice ( data) ;
193236 self . reset ( ) ;
@@ -221,7 +264,7 @@ impl<BS: BlockSizes, K: BufferKind> BlockBuffer<BS, K> {
221264 /// # Panics
222265 /// If `pos` is bigger or equal to block size.
223266 #[ inline]
224- pub fn set ( & mut self , buf : Block < Self > , pos : usize ) {
267+ pub fn set ( & mut self , buf : Array < u8 , BS > , pos : usize ) {
225268 assert ! ( K :: invariant( pos, BS :: USIZE ) ) ;
226269 self . buffer = MaybeUninit :: new ( buf) ;
227270 // SAFETY: we have asserted that `pos` satisfies the invariant and
@@ -271,15 +314,20 @@ impl<BS: BlockSizes, K: BufferKind> BlockBuffer<BS, K> {
271314 }
272315}
273316
274- impl < BS : BlockSizes > BlockBuffer < BS , Eager > {
317+ impl < BS : ArraySize > BlockBuffer < BS , Eager > {
275318 /// Compress remaining data after padding it with `delim`, zeros and
276319 /// the `suffix` bytes. If there is not enough unused space, `compress`
277320 /// will be called twice.
278321 ///
279322 /// # Panics
280323 /// If suffix length is bigger than block size.
281324 #[ inline( always) ]
282- pub fn digest_pad ( & mut self , delim : u8 , suffix : & [ u8 ] , mut compress : impl FnMut ( & Block < Self > ) ) {
325+ pub fn digest_pad (
326+ & mut self ,
327+ delim : u8 ,
328+ suffix : & [ u8 ] ,
329+ mut compress : impl FnMut ( & Array < u8 , BS > ) ,
330+ ) {
283331 if suffix. len ( ) > BS :: USIZE {
284332 panic ! ( "suffix is too long" ) ;
285333 }
@@ -303,28 +351,28 @@ impl<BS: BlockSizes> BlockBuffer<BS, Eager> {
303351 /// Pad message with 0x80, zeros and 64-bit message length using
304352 /// big-endian byte order.
305353 #[ inline]
306- pub fn len64_padding_be ( & mut self , data_len : u64 , compress : impl FnMut ( & Block < Self > ) ) {
354+ pub fn len64_padding_be ( & mut self , data_len : u64 , compress : impl FnMut ( & Array < u8 , BS > ) ) {
307355 self . digest_pad ( 0x80 , & data_len. to_be_bytes ( ) , compress) ;
308356 }
309357
310358 /// Pad message with 0x80, zeros and 64-bit message length using
311359 /// little-endian byte order.
312360 #[ inline]
313- pub fn len64_padding_le ( & mut self , data_len : u64 , compress : impl FnMut ( & Block < Self > ) ) {
361+ pub fn len64_padding_le ( & mut self , data_len : u64 , compress : impl FnMut ( & Array < u8 , BS > ) ) {
314362 self . digest_pad ( 0x80 , & data_len. to_le_bytes ( ) , compress) ;
315363 }
316364
317365 /// Pad message with 0x80, zeros and 128-bit message length using
318366 /// big-endian byte order.
319367 #[ inline]
320- pub fn len128_padding_be ( & mut self , data_len : u128 , compress : impl FnMut ( & Block < Self > ) ) {
368+ pub fn len128_padding_be ( & mut self , data_len : u128 , compress : impl FnMut ( & Array < u8 , BS > ) ) {
321369 self . digest_pad ( 0x80 , & data_len. to_be_bytes ( ) , compress) ;
322370 }
323371
324372 /// Serialize buffer into a byte array.
325373 #[ inline]
326- pub fn serialize ( & self ) -> Block < Self > {
327- let mut res = Block :: < Self > :: default ( ) ;
374+ pub fn serialize ( & self ) -> Array < u8 , BS > {
375+ let mut res = Array :: < u8 , BS > :: default ( ) ;
328376 let data = self . get_data ( ) ;
329377 res[ ..data. len ( ) ] . copy_from_slice ( data) ;
330378 res[ BS :: USIZE - 1 ] = data. len ( ) as u8 ;
@@ -333,7 +381,7 @@ impl<BS: BlockSizes> BlockBuffer<BS, Eager> {
333381
334382 /// Deserialize buffer from a byte array.
335383 #[ inline]
336- pub fn deserialize ( buffer : & Block < Self > ) -> Result < Self , Error > {
384+ pub fn deserialize ( buffer : & Array < u8 , BS > ) -> Result < Self , Error > {
337385 let pos = buffer[ BS :: USIZE - 1 ] as usize ;
338386 if !<Eager as sealed:: Sealed >:: invariant ( pos, BS :: USIZE ) {
339387 return Err ( Error ) ;
@@ -348,15 +396,15 @@ impl<BS: BlockSizes> BlockBuffer<BS, Eager> {
348396 }
349397}
350398
351- impl < BS : BlockSizes > BlockBuffer < BS , Lazy > {
399+ impl < BS : ArraySize > BlockBuffer < BS , Lazy > {
352400 /// Serialize buffer into a byte array.
353401 #[ inline]
354- pub fn serialize ( & self ) -> BlockP1 < BS >
402+ pub fn serialize ( & self ) -> Array < u8 , Add1 < BS > >
355403 where
356404 BS : Add < B1 > ,
357405 Add1 < BS > : ArraySize ,
358406 {
359- let mut res = BlockP1 :: < BS > :: default ( ) ;
407+ let mut res = Array :: < u8 , Add1 < BS > > :: default ( ) ;
360408 res[ 0 ] = self . pos ;
361409 let data = self . get_data ( ) ;
362410 res[ 1 ..] [ ..data. len ( ) ] . copy_from_slice ( data) ;
@@ -365,7 +413,7 @@ impl<BS: BlockSizes> BlockBuffer<BS, Lazy> {
365413
366414 /// Deserialize buffer from a byte array.
367415 #[ inline]
368- pub fn deserialize ( buffer : & BlockP1 < BS > ) -> Result < Self , Error >
416+ pub fn deserialize ( buffer : & Array < u8 , Add1 < BS > > ) -> Result < Self , Error >
369417 where
370418 BS : Add < B1 > ,
371419 Add1 < BS > : ArraySize ,
@@ -386,7 +434,7 @@ impl<BS: BlockSizes> BlockBuffer<BS, Lazy> {
386434}
387435
388436#[ cfg( feature = "zeroize" ) ]
389- impl < BS : BlockSizes , K : BufferKind > Zeroize for BlockBuffer < BS , K > {
437+ impl < BS : ArraySize , K : BufferKind > Zeroize for BlockBuffer < BS , K > {
390438 #[ inline]
391439 fn zeroize ( & mut self ) {
392440 self . buffer . zeroize ( ) ;
0 commit comments