Skip to content

Commit ac65c94

Browse files
committed
block-buffer: remove dependency on crypto-common
1 parent b5d80a2 commit ac65c94

File tree

8 files changed

+108
-72
lines changed

8 files changed

+108
-72
lines changed

.github/workflows/block-buffer.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,10 @@ jobs:
3939
targets: ${{ matrix.target }}
4040
- run: cargo build --target ${{ matrix.target }}
4141

42-
# TODO(tarcieri): re-enable after next `crypto-common` release
43-
#minimal-versions:
44-
# uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
45-
# with:
46-
# working-directory: ${{ github.workflow }}
42+
minimal-versions:
43+
uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master
44+
with:
45+
working-directory: ${{ github.workflow }}
4746

4847
test:
4948
runs-on: ubuntu-latest

Cargo.lock

Lines changed: 1 addition & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

block-buffer/CHANGELOG.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
- Optional implementation of the `Zeroize` trait ([#963])
1212

1313
### Changed
14-
- Supported block sizes are now bounded by the `crypto_common::BlockSizes` trait,
15-
which is implemented for types from `U1` to `U255` ([#823])
14+
- Block sizes must be bigger than 0 and smaller than 256.
15+
This is enforced using compile-time monomorphization errors. ([#1115])
1616
- Size of `EagerBuffer` is equal to buffer size, while previously it was equal
1717
to buffer size plus one byte ([#823])
18-
- Edition changed to 2021 and MSRV bumped to 1.56 ([#823])
18+
- Edition changed to 2021 and MSRV bumped to 1.81 ([#823], [#1116])
1919

2020
### Removed
2121
- `EagerBuffer::set_data` method. Use the `ReadBuffer` type instead. ([#823])
2222

2323
[#823]: https://github.com/RustCrypto/utils/pull/823
2424
[#963]: https://github.com/RustCrypto/utils/pull/963
25+
[#1115]: https://github.com/RustCrypto/utils/pull/1115
26+
[#1115]: https://github.com/RustCrypto/utils/pull/1116
2527

2628
## 0.10.3 (2022-09-04)
2729
### Added

block-buffer/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ readme = "README.md"
1313
rust-version = "1.81"
1414

1515
[dependencies]
16-
crypto-common = "0.2.0-rc.1"
16+
hybrid-array = "0.2.0-rc.10"
1717
zeroize = { version = "1.4", optional = true, default-features = false }
1818

1919
[dev-dependencies]

block-buffer/src/lib.rs

Lines changed: 78 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,54 @@
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

1147
use array::{
1248
typenum::{Add1, B1},
1349
Array, ArraySize,
1450
};
1551
use core::{fmt, mem::MaybeUninit, ops::Add, ptr, slice};
16-
use crypto_common::{BlockSizeUser, BlockSizes};
1752

1853
#[cfg(feature = "zeroize")]
1954
use zeroize::Zeroize;
@@ -23,9 +58,6 @@ mod sealed;
2358

2459
pub use read::ReadBuffer;
2560

26-
/// Block with additional one byte
27-
type BlockP1<BlockSize> = Array<u8, Add1<BlockSize>>;
28-
2961
/// Trait for buffer kinds.
3062
pub 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

Comments
 (0)