Skip to content

Commit

Permalink
whirlpool: Implement SerializableState for WhirlpoolCore
Browse files Browse the repository at this point in the history
  • Loading branch information
Ruslan Piasetskyi committed Sep 8, 2022
1 parent ea952a4 commit 9876bfc
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 4 deletions.
57 changes: 53 additions & 4 deletions whirlpool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,32 @@ use whirlpool_asm as compress;

use compress::compress;

use core::fmt;
use core::{convert::TryInto, fmt};
use digest::{
block_buffer::Eager,
core_api::{
AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore,
OutputSizeUser, Reset, UpdateCore,
},
typenum::{Unsigned, U64},
crypto_common::{DeserializeStateError, SerializableState, SerializedState},
generic_array::{
sequence::{Concat, Split},
GenericArray,
},
typenum::{Unsigned, U32, U64, U96},
HashMarker, Output,
};

/// Core Whirlpool hasher state.
#[derive(Clone)]
pub struct WhirlpoolCore {
bit_len: [u64; 4],
state: [u64; 8],
bit_len: [u64; BITLEN_LEN],
state: [u64; STATE_LEN],
}

const STATE_LEN: usize = 8;
const BITLEN_LEN: usize = 4;

impl HashMarker for WhirlpoolCore {}

impl BlockSizeUser for WhirlpoolCore {
Expand Down Expand Up @@ -156,6 +164,47 @@ impl fmt::Debug for WhirlpoolCore {
}
}

impl SerializableState for WhirlpoolCore {
type SerializedStateSize = U96;

fn serialize(&self) -> SerializedState<Self> {
let mut serialized_state = GenericArray::<_, U64>::default();

for (val, chunk) in self.state.iter().zip(serialized_state.chunks_exact_mut(8)) {
chunk.copy_from_slice(&val.to_le_bytes());
}

let mut serialized_bit_len = GenericArray::<_, U32>::default();
for (val, chunk) in self
.bit_len
.iter()
.zip(serialized_bit_len.chunks_exact_mut(8))
{
chunk.copy_from_slice(&val.to_le_bytes());
}

serialized_state.concat(serialized_bit_len)
}

fn deserialize(
serialized_state: &SerializedState<Self>,
) -> Result<Self, DeserializeStateError> {
let (serialized_state, serialized_bit_len) = Split::<_, U64>::split(serialized_state);

let mut state = [0; STATE_LEN];
for (val, chunk) in state.iter_mut().zip(serialized_state.chunks_exact(8)) {
*val = u64::from_le_bytes(chunk.try_into().unwrap());
}

let mut bit_len = [0; BITLEN_LEN];
for (val, chunk) in bit_len.iter_mut().zip(serialized_bit_len.chunks_exact(8)) {
*val = u64::from_le_bytes(chunk.try_into().unwrap());
}

Ok(Self { state, bit_len })
}
}

/// Whirlpool hasher state.
pub type Whirlpool = CoreWrapper<WhirlpoolCore>;

Expand Down
19 changes: 19 additions & 0 deletions whirlpool/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ use whirlpool::{Digest, Whirlpool};

digest::new_test!(whirlpool_main, "whirlpool", Whirlpool, fixed_reset_test);

#[rustfmt::skip]
digest::hash_serialization_test!(
whirlpool_serialization,
Whirlpool,
hex!("
44b95aeb60cdf5910f83d556a3382cd8
58f03d791dfb7675125d6ede083dc917
47be004f1982289c065eb53491e06729
f5935532c376541ca78e23ed572516a9
00000000000000000000000000000000
00000000000000000002000000000000
01130000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00
")
);

#[test]
#[rustfmt::skip]
fn whirlpool_rand() {
Expand Down

0 comments on commit 9876bfc

Please sign in to comment.