Skip to content

Commit ba7bc6b

Browse files
committed
bash-prg-hash: change rate from bits to bytes calculation
1 parent 85a62da commit ba7bc6b

2 files changed

Lines changed: 29 additions & 39 deletions

File tree

bash-prg-hash/src/lib.rs

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ mod variants;
1616

1717
use bash_f::{STATE_WORDS, bash_f};
1818
use core::{fmt, marker::PhantomData};
19-
use digest::consts::{U16, U24, U32};
2019
use digest::{
2120
ExtendableOutput, ExtendableOutputReset, Reset, Update, XofReader,
22-
typenum::{U1, U2, U128, U192, U256},
21+
typenum::{U1, U2, U16, U24, U32},
2322
};
2423
pub use variants::{Capacity, SecurityLevel};
2524

@@ -28,11 +27,11 @@ const DATA: u8 = 0b000010;
2827
/// Data type codes from Table 3 of STB 34.101.77-2020
2928
const OUT: u8 = 0b000100;
3029

31-
/// bash-prg-hash hasher generic over security level and capacity.
30+
/// `bash-prg-hash` hasher generic over security level and capacity.
3231
///
3332
/// # Generic Parameters
3433
///
35-
/// - `L`: Security level ℓ ∈ {128, 192, 256}. Use `U128`, `U192`, or `U256` from `digest::typenum`.
34+
/// - `L`: Security level ℓ ∈ {128, 192, 256}. Use `U16`, `U24`, or `U32` from `digest::typenum`.
3635
/// - `D`: Capacity d ∈ {1, 2}. Use `U1` or `U2` from `digest::typenum`.
3736
///
3837
/// # Examples
@@ -104,16 +103,8 @@ impl<L: SecurityLevel, D: Capacity> fmt::Debug for BashPrgHash<L, D> {
104103
}
105104
}
106105

107-
impl<D: Capacity> digest::CollisionResistance for BashPrgHash<U128, D> {
108-
type CollisionResistance = U16;
109-
}
110-
111-
impl<D: Capacity> digest::CollisionResistance for BashPrgHash<U192, D> {
112-
type CollisionResistance = U24;
113-
}
114-
115-
impl<D: Capacity> digest::CollisionResistance for BashPrgHash<U256, D> {
116-
type CollisionResistance = U32;
106+
impl<L: SecurityLevel, D: Capacity> digest::CollisionResistance for BashPrgHash<L, D> {
107+
type CollisionResistance = L;
117108
}
118109

119110
#[cfg(feature = "zeroize")]
@@ -138,8 +129,8 @@ impl<L: SecurityLevel, D: Capacity> digest::zeroize::ZeroizeOnDrop for BashPrgHa
138129

139130
impl<L: SecurityLevel, D: Capacity> BashPrgHash<L, D> {
140131
/// Calculate buffer size r = 1536 - 2dℓ (in bytes)
141-
const fn rate_bytes() -> usize {
142-
(1536 - 2 * D::USIZE * L::USIZE) / 8
132+
const fn rate() -> usize {
133+
192 - 2 * D::USIZE * L::USIZE
143134
}
144135

145136
fn new_customized(header: &[u8]) -> Self {
@@ -225,8 +216,8 @@ impl<L: SecurityLevel, D: Capacity> BashPrgHash<L, D> {
225216
for (i, &byte) in header.iter().enumerate() {
226217
Self::modify_byte(&mut self.state, 1 + i, |b| *b = byte);
227218
}
228-
// Step 6: S[1472...) <- <ℓ/4 + d>_64.
229-
self.state[23] = (L::USIZE / 4 + D::USIZE) as u64;
219+
// Step 6: S[1472...) <- <ℓ/4 + d>_64, where ℓ in bits = L*8
220+
self.state[23] = (L::USIZE * 2 + D::USIZE) as u64;
230221
}
231222

232223
/// `commit[ℓ, d](t)` (Section 8.4.2)
@@ -235,8 +226,8 @@ impl<L: SecurityLevel, D: Capacity> BashPrgHash<L, D> {
235226
let tag = (t << 2) | 0x01;
236227
Self::modify_byte(&mut self.state, usize::from(self.offset), |b| *b ^= tag);
237228
// Step 2: S[r] <- S[r] xor 1, where r = 1536 - 2 d ℓ (bit index).
238-
let r_bit_in_byte = (Self::rate_bytes() * 8) % 8;
239-
Self::modify_byte(&mut self.state, Self::rate_bytes(), |b| {
229+
let r_bit_in_byte = (Self::rate() * 8) % 8;
230+
Self::modify_byte(&mut self.state, Self::rate(), |b| {
240231
*b ^= 1u8 << (7 - r_bit_in_byte)
241232
});
242233
// Step 3: S <- bash-f(S).
@@ -250,13 +241,11 @@ impl<L: SecurityLevel, D: Capacity> BashPrgHash<L, D> {
250241
// Steps 2-3: process X in blocks of length up to r - pos.
251242
let mut input = data;
252243
while !input.is_empty() {
253-
let to_absorb = input
254-
.len()
255-
.min(Self::rate_bytes() - usize::from(self.offset));
244+
let to_absorb = input.len().min(Self::rate() - usize::from(self.offset));
256245
// S[pos...pos+|X_i|) <- S[pos...pos+|X_i|) xor X_i, pos <- pos + |X_i|.
257246
Self::xor_in(&mut self.state, &mut self.offset, &input[..to_absorb]);
258247
input = &input[to_absorb..];
259-
if usize::from(self.offset) == Self::rate_bytes() {
248+
if usize::from(self.offset) == Self::rate() {
260249
// If pos = r, then S <- bash-f(S), pos <- 0.
261250
bash_f(&mut self.state);
262251
self.offset = 0;
@@ -275,14 +264,14 @@ impl<L: SecurityLevel, D: Capacity> BashPrgHashReader<L, D> {
275264
fn squeeze(&mut self, output: &mut [u8]) {
276265
let mut remaining = output;
277266
while !remaining.is_empty() {
278-
if usize::from(self.offset) == BashPrgHash::<L, D>::rate_bytes() {
267+
if usize::from(self.offset) == BashPrgHash::<L, D>::rate() {
279268
// If pos = r, then S <- bash-f(S), pos <- 0.
280269
bash_f(&mut self.state);
281270
self.offset = 0;
282271
}
283272
let to_squeeze = remaining
284273
.len()
285-
.min(BashPrgHash::<L, D>::rate_bytes() - usize::from(self.offset));
274+
.min(BashPrgHash::<L, D>::rate() - usize::from(self.offset));
286275
// Y_i <- S[pos...pos+|Y_i|), pos <- pos + |Y_i|.
287276
BashPrgHash::<L, D>::extract_bytes(
288277
&self.state,
@@ -315,14 +304,14 @@ impl<L: SecurityLevel, D: Capacity> Drop for BashPrgHashReader<L, D> {
315304
}
316305

317306
/// bash-prg-hash with ℓ = 128 and d = 1
318-
pub type BashPrgHash1281 = BashPrgHash<U128, U1>;
307+
pub type BashPrgHash1281 = BashPrgHash<U16, U1>;
319308
/// bash-prg-hash with ℓ = 128 and d = 2
320-
pub type BashPrgHash1282 = BashPrgHash<U128, U2>;
309+
pub type BashPrgHash1282 = BashPrgHash<U16, U2>;
321310
/// bash-prg-hash with ℓ = 192 and d = 1
322-
pub type BashPrgHash1921 = BashPrgHash<U192, U1>;
311+
pub type BashPrgHash1921 = BashPrgHash<U24, U1>;
323312
/// bash-prg-hash with ℓ = 192 and d = 2
324-
pub type BashPrgHash1922 = BashPrgHash<U192, U2>;
313+
pub type BashPrgHash1922 = BashPrgHash<U24, U2>;
325314
/// bash-prg-hash with ℓ = 256 and d = 1
326-
pub type BashPrgHash2561 = BashPrgHash<U256, U1>;
315+
pub type BashPrgHash2561 = BashPrgHash<U32, U1>;
327316
/// bash-prg-hash with ℓ = 256 and d = 2
328-
pub type BashPrgHash2562 = BashPrgHash<U256, U2>;
317+
pub type BashPrgHash2562 = BashPrgHash<U32, U2>;

bash-prg-hash/src/variants.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use digest::typenum::{U1, U2, U128, U192, U256, Unsigned};
1+
use digest::consts::U24;
2+
use digest::typenum::{U1, U2, U16, U32, Unsigned};
23

34
mod sealed {
45
/// Sealed trait to prevent external implementations of SecurityLevel.
@@ -27,14 +28,14 @@ pub trait SecurityLevel: sealed::SecurityLevel + Unsigned {}
2728
pub trait Capacity: sealed::Capacity + Unsigned {}
2829

2930
// Security level implementations
30-
impl sealed::SecurityLevel for U128 {}
31-
impl SecurityLevel for U128 {}
31+
impl sealed::SecurityLevel for U16 {}
32+
impl SecurityLevel for U16 {}
3233

33-
impl sealed::SecurityLevel for U192 {}
34-
impl SecurityLevel for U192 {}
34+
impl sealed::SecurityLevel for U24 {}
35+
impl SecurityLevel for U24 {}
3536

36-
impl sealed::SecurityLevel for U256 {}
37-
impl SecurityLevel for U256 {}
37+
impl sealed::SecurityLevel for U32 {}
38+
impl SecurityLevel for U32 {}
3839

3940
// Capacity implementations
4041
impl sealed::Capacity for U1 {}

0 commit comments

Comments
 (0)