diff --git a/jh/CHANGELOG.md b/jh/CHANGELOG.md index 29be5c236..5822252fa 100644 --- a/jh/CHANGELOG.md +++ b/jh/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.2.1 (UNRELEASED) +### Changed +- Implementation of the `SerializableState` trait ([#889]) + +[#889]: https://github.com/RustCrypto/hashes/pull/889 + ## 0.2.0 (2026-03-27) ### Added - `alloc` crate feature ([#678]) diff --git a/jh/src/block_api.rs b/jh/src/block_api.rs index 0c606d3dc..919565cfd 100644 --- a/jh/src/block_api.rs +++ b/jh/src/block_api.rs @@ -6,7 +6,8 @@ use digest::{ AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, Eager, OutputSizeUser, TruncSide, UpdateCore, VariableOutputCore, }, - typenum::{U64, Unsigned}, + common::hazmat::{DeserializeStateError, SerializableState, SerializedState}, + typenum::{U64, U128, U136, Unsigned}, }; use crate::consts; @@ -89,6 +90,33 @@ impl fmt::Debug for JhCore { } } +impl SerializableState for JhCore { + type SerializedStateSize = U136; + + #[inline] + fn serialize(&self) -> SerializedState { + let mut serialized_state = SerializedState::::default(); + let (state_dst, block_len_dst) = serialized_state.split_at_mut(128); + + state_dst.copy_from_slice(self.state.finalize()); + block_len_dst.copy_from_slice(&self.block_len.to_le_bytes()); + + serialized_state + } + + #[inline] + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + let (serialized_state, serialized_block_len) = serialized_state.split::(); + + Ok(Self { + state: Compressor::new(serialized_state.0), + block_len: u64::from_le_bytes(serialized_block_len.0), + }) + } +} + impl Drop for JhCore { fn drop(&mut self) { #[cfg(feature = "zeroize")] diff --git a/jh/src/lib.rs b/jh/src/lib.rs index 96e14aaf6..9f8af1dcb 100644 --- a/jh/src/lib.rs +++ b/jh/src/lib.rs @@ -22,20 +22,20 @@ use digest::{ digest::buffer_fixed!( /// JH-224 hasher. pub struct Jh224(CtOutWrapper); - impl: BaseFixedTraits AlgorithmName Default Clone HashMarker Reset FixedOutputReset; + impl: FixedHashTraits; ); digest::buffer_fixed!( /// JH-256 hasher. pub struct Jh256(CtOutWrapper); - impl: BaseFixedTraits AlgorithmName Default Clone HashMarker Reset FixedOutputReset; + impl: FixedHashTraits; ); digest::buffer_fixed!( /// JH-384 hasher. pub struct Jh384(CtOutWrapper); - impl: BaseFixedTraits AlgorithmName Default Clone HashMarker Reset FixedOutputReset; + impl: FixedHashTraits; ); digest::buffer_fixed!( /// JH-512 hasher. pub struct Jh512(CtOutWrapper); - impl: BaseFixedTraits AlgorithmName Default Clone HashMarker Reset FixedOutputReset; + impl: FixedHashTraits; ); diff --git a/jh/tests/data/jh224_serialization.bin b/jh/tests/data/jh224_serialization.bin new file mode 100644 index 000000000..826a6e9f5 Binary files /dev/null and b/jh/tests/data/jh224_serialization.bin differ diff --git a/jh/tests/data/jh256_serialization.bin b/jh/tests/data/jh256_serialization.bin new file mode 100644 index 000000000..ee0bfd0ab Binary files /dev/null and b/jh/tests/data/jh256_serialization.bin differ diff --git a/jh/tests/data/jh384_serialization.bin b/jh/tests/data/jh384_serialization.bin new file mode 100644 index 000000000..7cd02c8b0 Binary files /dev/null and b/jh/tests/data/jh384_serialization.bin differ diff --git a/jh/tests/data/jh512_serialization.bin b/jh/tests/data/jh512_serialization.bin new file mode 100644 index 000000000..f9b287ff4 Binary files /dev/null and b/jh/tests/data/jh512_serialization.bin differ diff --git a/jh/tests/mod.rs b/jh/tests/mod.rs index c200b1729..1b7aeba40 100644 --- a/jh/tests/mod.rs +++ b/jh/tests/mod.rs @@ -1,4 +1,4 @@ -use digest::{dev::fixed_test, new_test}; +use digest::{dev::fixed_test, hash_serialization_test, new_test}; new_test!(jh224_long_kat, jh::Jh224, fixed_test); new_test!(jh256_long_kat, jh::Jh256, fixed_test); @@ -9,3 +9,8 @@ new_test!(jh224_short_kat, jh::Jh224, fixed_test); new_test!(jh256_short_kat, jh::Jh256, fixed_test); new_test!(jh384_short_kat, jh::Jh384, fixed_test); new_test!(jh512_short_kat, jh::Jh512, fixed_test); + +hash_serialization_test!(jh224_serialization, jh::Jh224); +hash_serialization_test!(jh256_serialization, jh::Jh256); +hash_serialization_test!(jh384_serialization, jh::Jh384); +hash_serialization_test!(jh512_serialization, jh::Jh512);