#[cfg(any(feature = "alloc", feature = "std"))]
extern crate alloc;
pub const BLOCK_SIZE: usize = 128;
pub const MAX_INPUT_SIZE: usize = 16384;
pub const MAX_BLOCKS: usize = (MAX_INPUT_SIZE + BLOCK_SIZE - 1) / BLOCK_SIZE + 1;
pub const MAX_PADDED_SIZE: usize = MAX_BLOCKS * BLOCK_SIZE;
#[inline]
pub fn padded_length(_message_len: usize) -> usize {
MAX_PADDED_SIZE
}
#[inline]
pub fn pad_message_in_place(
buffer: &mut [u8],
message_len_in_buffer: usize,
offset: usize,
total_message_len: usize,
) {
let bit_len = (total_message_len as u64).wrapping_mul(8);
let pad_start = offset + message_len_in_buffer;
let pad_end = offset + MAX_PADDED_SIZE;
buffer[pad_start] = 0x80;
for i in (pad_start + 1)..pad_end {
buffer[i] = 0;
}
let len_bytes = bit_len.to_le_bytes();
for (i, &byte) in len_bytes.iter().enumerate() {
buffer[pad_end - 8 + i] = byte;
}
}
#[cfg(any(feature = "alloc", feature = "std"))]
pub fn pad_message(message: &[u8]) -> alloc::vec::Vec<u8> {
let padded_len = padded_length(message.len());
let mut result = alloc::vec::Vec::with_capacity(padded_len);
result.extend_from_slice(message);
result.resize(padded_len, 0);
pad_message_in_place(&mut result, message.len(), 0, message.len());
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_padded_length() {
assert_eq!(padded_length(0), MAX_PADDED_SIZE);
assert_eq!(padded_length(1), MAX_PADDED_SIZE);
assert_eq!(padded_length(120), MAX_PADDED_SIZE);
assert_eq!(padded_length(119), MAX_PADDED_SIZE);
assert_eq!(padded_length(128), MAX_PADDED_SIZE);
assert_eq!(padded_length(16384), MAX_PADDED_SIZE);
}
#[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_pad_message_empty() {
let padded = pad_message(b"");
assert_eq!(padded.len(), MAX_PADDED_SIZE);
assert_eq!(padded[0], 0x80);
let len_start = MAX_PADDED_SIZE - 8;
let len_bytes = u64::from_le_bytes([
padded[len_start],
padded[len_start + 1],
padded[len_start + 2],
padded[len_start + 3],
padded[len_start + 4],
padded[len_start + 5],
padded[len_start + 6],
padded[len_start + 7],
]);
assert_eq!(len_bytes, 0);
}
#[test]
#[cfg(any(feature = "alloc", feature = "std"))]
fn test_pad_message_small() {
let message = b"abc";
let padded = pad_message(message);
assert_eq!(padded.len(), MAX_PADDED_SIZE);
assert_eq!(&padded[0..3], message);
assert_eq!(padded[3], 0x80);
let len_start = MAX_PADDED_SIZE - 8;
let len_bytes = u64::from_le_bytes([
padded[len_start],
padded[len_start + 1],
padded[len_start + 2],
padded[len_start + 3],
padded[len_start + 4],
padded[len_start + 5],
padded[len_start + 6],
padded[len_start + 7],
]);
assert_eq!(len_bytes, 24);
}
}