From 1d7c9cfaef607503545ad0a1ec2838472609e80d Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 11 Aug 2026 12:05:09 +0200 Subject: [PATCH 1/3] blake2: implement SerializableState --- blake2/src/lib.rs | 13 ++++--- blake2/src/macros.rs | 92 ++++++++++++++++++++++++++++++++++++++++++++ blake2/src/simd.rs | 15 ++++++++ 3 files changed, 114 insertions(+), 6 deletions(-) diff --git a/blake2/src/lib.rs b/blake2/src/lib.rs index d2ce5524..9a205229 100644 --- a/blake2/src/lib.rs +++ b/blake2/src/lib.rs @@ -16,10 +16,13 @@ use digest::{ AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, OutputSizeUser, TruncSide, UpdateCore, VariableOutputCore, VariableOutputCoreCustomized, }, - block_buffer::{Lazy, LazyBuffer}, - common::{InvalidLength, Key, KeyInit, KeySizeUser}, - consts::{U4, U16, U32, U64, U128}, - typenum::{IsLessOrEqual, True, Unsigned}, + block_buffer::{Lazy, LazyBuffer, SerializedBufferSize}, + common::{ + InvalidLength, Key, KeyInit, KeySizeUser, + hazmat::{DeserializeStateError, SerializableState, SerializedState}, + }, + consts::{U4, U8, U16, U32, U64, U128}, + typenum::{IsLessOrEqual, Sum, True, Unsigned}, }; #[cfg(feature = "reset")] use digest::{FixedOutputReset, Reset}; @@ -56,7 +59,6 @@ blake2_impl!( digest::buffer_ct_variable!( /// BLAKE2b generic over output size. pub struct Blake2b(Blake2bVarCore); - exclude: SerializableState; max_size: U64; ); @@ -104,7 +106,6 @@ blake2_impl!( digest::buffer_ct_variable!( /// BLAKE2s generic over output size. pub struct Blake2s(Blake2sVarCore); - exclude: SerializableState; max_size: U32; ); diff --git a/blake2/src/macros.rs b/blake2/src/macros.rs index ea0f2653..fd94fd02 100644 --- a/blake2/src/macros.rs +++ b/blake2/src/macros.rs @@ -267,6 +267,43 @@ macro_rules! blake2_impl { #[cfg(feature = "zeroize")] impl ZeroizeOnDrop for $name {} + + impl SerializableState for $name { + // Note: using `$bytes` here instead of + // `Prod<<$vec as SerializableState>::SerializedStateSize, U2>` because the latter + // would require $vec to be a public type (but e.g. u64x4 is crate-private). + #[cfg(not(feature = "reset"))] + type SerializedStateSize = Sum<$bytes, U8>; + #[cfg(feature = "reset")] + type SerializedStateSize = Sum, $bytes>; + + fn serialize(&self) -> SerializedState { + let mut serialized_state = SerializedState::::default(); + let vecsz = <$vec as SerializableState>::SerializedStateSize::USIZE; + let tsz = U8::USIZE; + serialized_state[..vecsz].copy_from_slice(&self.h[0].serialize()); + serialized_state[vecsz..(2*vecsz)].copy_from_slice(&self.h[1].serialize()); + serialized_state[(2*vecsz)..(2*vecsz+tsz)].copy_from_slice(&self.t.serialize()); + #[cfg(feature = "reset")] + serialized_state[(2*vecsz+tsz)..(3*vecsz+tsz)].copy_from_slice(&self.h0[0].serialize()); + #[cfg(feature = "reset")] + serialized_state[(3*vecsz+tsz)..(4*vecsz+tsz)].copy_from_slice(&self.h0[1].serialize()); + serialized_state + } + + fn deserialize(serialized_state: &SerializedState) -> Result { + let vecsz = <$vec as SerializableState>::SerializedStateSize::USIZE; + let tsz = U8::USIZE; + let h_0 = SerializableState::deserialize(&serialized_state[..vecsz].try_into().unwrap())?; + let h_1 = SerializableState::deserialize(&serialized_state[vecsz..(2*vecsz)].try_into().unwrap())?; + let t = SerializableState::deserialize(&serialized_state[(2*vecsz)..(2*vecsz+tsz)].try_into().unwrap())?; + #[cfg(feature = "reset")] + let h0_0 = SerializableState::deserialize(&serialized_state[(2*vecsz+tsz)..(3*vecsz+tsz)].try_into().unwrap())?; + #[cfg(feature = "reset")] + let h0_1 = SerializableState::deserialize(&serialized_state[(3*vecsz+tsz)..(4*vecsz+tsz)].try_into().unwrap())?; + Ok(Self { h: [h_0, h_1], t, #[cfg(feature = "reset")] h0: [h0_0, h0_1] }) + } + } }; } @@ -471,5 +508,60 @@ macro_rules! blake2_mac_impl { OutSize: ArraySize + IsLessOrEqual<$max_size, Output = True> { } + + impl SerializableState for $name where + OutSize: ArraySize + IsLessOrEqual<$max_size, Output = True> { + #[cfg(not(feature = "reset"))] + type SerializedStateSize = Sum<<$hash as SerializableState>::SerializedStateSize, SerializedBufferSize<<$hash as BlockSizeUser>::BlockSize, Lazy>>; + #[cfg(feature = "reset")] + type SerializedStateSize = Sum::SerializedStateSize, SerializedBufferSize<<$hash as BlockSizeUser>::BlockSize, Lazy>>, Sum<::KeySize, digest::consts::U1>>; + + fn serialize(&self) -> SerializedState { + let mut serialized_state = SerializedState::::default(); + let coresz = <$hash as SerializableState>::SerializedStateSize::USIZE; + let buffersz = ::BlockSize, Lazy>>::USIZE; + + serialized_state[..coresz].copy_from_slice(&self.core.serialize()); + serialized_state[coresz..(coresz + buffersz)].copy_from_slice(&self.buffer.serialize()); + + #[cfg(feature = "reset")] + { + let boolsz = digest::consts::U1::USIZE; + let keyblocksz = ::KeySize::USIZE; + if let Some(key_block) = self.key_block { + serialized_state[(coresz + buffersz)..(coresz + buffersz + boolsz)].copy_from_slice(&1u8.serialize()); + serialized_state[(coresz + buffersz + boolsz)..(coresz + buffersz + boolsz + keyblocksz)].copy_from_slice(&key_block); + } else { + serialized_state[(coresz + buffersz)..(coresz + buffersz + boolsz)].copy_from_slice(&0u8.serialize()); + } + } + + serialized_state + } + + fn deserialize(serialized_state: &SerializedState) -> Result { + let coresz = <$hash as SerializableState>::SerializedStateSize::USIZE; + let buffersz = ::BlockSize, Lazy>>::USIZE; + + let core = SerializableState::deserialize(&serialized_state[..coresz].try_into().unwrap())?; + let buffer = LazyBuffer::<<$hash as BlockSizeUser>::BlockSize>::deserialize( + &serialized_state[coresz..(coresz + buffersz)].try_into().unwrap() + ).map_err(|_| DeserializeStateError)?; + + #[cfg(feature = "reset")] + let key_block = { + let boolsz = digest::consts::U1::USIZE; + let keyblocksz = ::KeySize::USIZE; + let present: u8 = SerializableState::deserialize(&serialized_state[(coresz + buffersz)..(coresz + buffersz + boolsz)].try_into().unwrap())?; + if present != 0 { + Some(serialized_state[(coresz + buffersz + boolsz)..(coresz + buffersz + boolsz + keyblocksz)].try_into().unwrap()) + } else { + None + } + }; + + Ok(Self { core, buffer, #[cfg(feature = "reset")] key_block, _out: Default::default() }) + } + } }; } diff --git a/blake2/src/simd.rs b/blake2/src/simd.rs index f68f02aa..c47bc38c 100644 --- a/blake2/src/simd.rs +++ b/blake2/src/simd.rs @@ -1,5 +1,7 @@ use core::ops::{Add, BitXor, Shl, Shr}; +use digest::{common::hazmat::{DeserializeStateError, SerializableState, SerializedState}}; + #[cfg(feature = "zeroize")] use digest::zeroize::Zeroize; @@ -181,6 +183,19 @@ macro_rules! impl_vector4 { self.3.zeroize(); } } + + impl SerializableState for $vec { + type SerializedStateSize = <[$word; 4] as SerializableState>::SerializedStateSize; + + fn serialize(&self) -> SerializedState { + [self.0, self.1, self.2, self.3].serialize() + } + + fn deserialize(serialized_state: &SerializedState) -> Result { + let deserialized: [$word; 4] = <[$word; 4] as SerializableState>::deserialize(serialized_state)?; + Ok($vec(deserialized[0], deserialized[1], deserialized[2], deserialized[3])) + } + } }; } From 3cfa160cd205f0664d0dafc3fdad2c280d12f77a Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 11 Aug 2026 12:05:37 +0200 Subject: [PATCH 2/3] blake2: add tests for SerializableState --- .../data/blake2b_128_reset_serialization.bin | Bin 0 -> 265 bytes .../tests/data/blake2b_128_serialization.bin | Bin 0 -> 201 bytes .../data/blake2b_256_reset_serialization.bin | Bin 0 -> 265 bytes .../tests/data/blake2b_256_serialization.bin | Bin 0 -> 201 bytes .../data/blake2b_512_reset_serialization.bin | Bin 0 -> 265 bytes .../tests/data/blake2b_512_serialization.bin | Bin 0 -> 201 bytes .../blake2b_mac_512_reset_serialization.bin | Bin 0 -> 330 bytes .../data/blake2b_mac_512_serialization.bin | Bin 0 -> 201 bytes .../data/blake2s_128_reset_serialization.bin | Bin 0 -> 137 bytes .../tests/data/blake2s_128_serialization.bin | Bin 0 -> 105 bytes .../data/blake2s_256_reset_serialization.bin | Bin 0 -> 137 bytes .../tests/data/blake2s_256_serialization.bin | Bin 0 -> 105 bytes .../blake2s_mac_256_reset_serialization.bin | Bin 0 -> 170 bytes .../data/blake2s_mac_256_serialization.bin | Bin 0 -> 105 bytes blake2/tests/serializable.rs | 106 ++++++++++++++++++ 15 files changed, 106 insertions(+) create mode 100644 blake2/tests/data/blake2b_128_reset_serialization.bin create mode 100644 blake2/tests/data/blake2b_128_serialization.bin create mode 100644 blake2/tests/data/blake2b_256_reset_serialization.bin create mode 100644 blake2/tests/data/blake2b_256_serialization.bin create mode 100644 blake2/tests/data/blake2b_512_reset_serialization.bin create mode 100644 blake2/tests/data/blake2b_512_serialization.bin create mode 100644 blake2/tests/data/blake2b_mac_512_reset_serialization.bin create mode 100644 blake2/tests/data/blake2b_mac_512_serialization.bin create mode 100644 blake2/tests/data/blake2s_128_reset_serialization.bin create mode 100644 blake2/tests/data/blake2s_128_serialization.bin create mode 100644 blake2/tests/data/blake2s_256_reset_serialization.bin create mode 100644 blake2/tests/data/blake2s_256_serialization.bin create mode 100644 blake2/tests/data/blake2s_mac_256_reset_serialization.bin create mode 100644 blake2/tests/data/blake2s_mac_256_serialization.bin create mode 100644 blake2/tests/serializable.rs diff --git a/blake2/tests/data/blake2b_128_reset_serialization.bin b/blake2/tests/data/blake2b_128_reset_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..6576b795edcad73a3f08689dbaa640913fdc9443 GIT binary patch literal 265 zcmeZgyx7jtU43~MxM?1k(E z`Dk))AihBP96Rlv4A$A%dmVqTzS%5asaPj0dG7jtU43~MxM?1k(E f`m=z>XdMc9lIMCAVA~f-cRYzIJ2ympK57cm%dy3$CQ6XpYv=!n#smn vef3{@vFX{``XIhQ`5Zg#o($I6*?S#-ufEwVU#VCpEP3`pG@~%opn;+Qid{e% literal 0 HcmV?d00001 diff --git a/blake2/tests/data/blake2b_256_serialization.bin b/blake2/tests/data/blake2b_256_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..51cc00361c32e83bc10b78453518541b72d8f3e3 GIT binary patch literal 201 zcmXSV7$|P*dx=k@^oE?@zsr+moQawh@h0@w5|vGYkyqmu@=6}EV?1ZomF&52iB#gV g$2;!L-qBd{f>m=z>XdMc9lIMCAb?RA$`~jL04WC`HUIzs literal 0 HcmV?d00001 diff --git a/blake2/tests/data/blake2b_512_reset_serialization.bin b/blake2/tests/data/blake2b_512_reset_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..329c004b9808a5f72163e5d234b7ad9214f282ae GIT binary patch literal 265 zcmazo@l5bIIy0T)S3~H5h3RwJmz2F`y7S}xiR(hCY9Hq7U)J*Qsn-sdRA=4%iW6Hmx&v`Z<&1B=P vzWOh{*z{~|eGp%ue2$%VPX_Dk?7fb^SKn-wuT-oPmOT3)no$^P&_GcD{^3EV literal 0 HcmV?d00001 diff --git a/blake2/tests/data/blake2b_512_serialization.bin b/blake2/tests/data/blake2b_512_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..8f0c8c5a7ef2e667ae346f9643d808333d85901d GIT binary patch literal 201 zcmazo@l5bIIy0T)S3~H5h3RwJmz2F`y7S}xiR(hCY9Hq7U)J*Qsn-sdRA=4%Idu+VAk$v1)>w-PSFsd%k8{nyh_wCFS|luyqD+9JjuE zcslC*$#=6SJjl{$nDHgXL+4xrBLf(Cbng9>{){urdiklA)^+K-wSP?cSM)j0=A)Tx zywz9#r5Br?t*sB@3zW~X)9%S&ot?ec@%QSR&GMCsb;6QoA4Gc#Qx8B~L?X%PL?HkG Dp*LCl literal 0 HcmV?d00001 diff --git a/blake2/tests/data/blake2b_mac_512_serialization.bin b/blake2/tests/data/blake2b_mac_512_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..1fcb813d3102820284f0a18e9f2a573a1a744504 GIT binary patch literal 201 zcmeC~N&QzXSD$u6ajjT<{iNx~`0h_Mu+3k*CFiKwUd0X0$KL!+ek-5#!F5OdJD&+T jp>J=?{j{zxnU?U|Ja^lQ^92ly3}E0TOf>*8kW>-?mX0U# literal 0 HcmV?d00001 diff --git a/blake2/tests/data/blake2s_128_reset_serialization.bin b/blake2/tests/data/blake2s_128_reset_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..de74eeb15d45727edb51313cec3dbe807726d1ce GIT binary patch literal 137 zcmX^7GUAWliL?Kun{LE^zQMTO?cgsd|F@DAUsT>nxNo`h(SZR1%Aav$x2{XyUGzE6 g#_Fs8()u92z@7}&*{g3h%S)bp5X~qIRY)!c02v=5wg3PC literal 0 HcmV?d00001 diff --git a/blake2/tests/data/blake2s_128_serialization.bin b/blake2/tests/data/blake2s_128_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..d70a85f5c1e3eb0dd57dbcdb2d1b89fc10a245c2 GIT binary patch literal 105 ycmX^7GUAWliL?Kun{LE^zQMTO?cgsd|F@DAUsT>nxNo`h(SZR17=@t>aw!1E7!y#ObtJ>UhV1NMkXB^qB>(X}@ea^G7 f`s%;5K8P={CxdnN>YL5-l4l=8GYUf$l1l*qkRlsS literal 0 HcmV?d00001 diff --git a/blake2/tests/data/blake2s_256_serialization.bin b/blake2/tests/data/blake2s_256_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..8fba7ef1914868305a8389e25e26ad98c7b3f1b4 GIT binary patch literal 105 xcmXSJ7V1=4=6=#vJ(OkQVKWA!@|j+X#ObtJ>UhV1NKdVJL%K3II203>*Le literal 0 HcmV?d00001 diff --git a/blake2/tests/data/blake2s_mac_256_reset_serialization.bin b/blake2/tests/data/blake2s_mac_256_reset_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..a3e8a66e7f766a86dafd6bd62bf13221932b1293 GIT binary patch literal 170 zcmYe?mbN-X!k|?$_)<&V#m7@-$;!l*NmbVPaO4&3(pQ^*fB^#Bk8xzTu1nut^f}MQ k>Z||K`XIi*o($I6t8X^TOP+lYtu0JEfEtNPF**?d0MQsI*Z=?k literal 0 HcmV?d00001 diff --git a/blake2/tests/data/blake2s_mac_256_serialization.bin b/blake2/tests/data/blake2s_mac_256_serialization.bin new file mode 100644 index 0000000000000000000000000000000000000000..d884eccc27bebc1dd215fc1d6b80e792740711b9 GIT binary patch literal 105 zcmeyT9367>m&N}rx#wrgC&u!WZn)pZYH;_=`pBG(tLG>)H!whemN3x(ssoJz0C0{I A{Qv*} literal 0 HcmV?d00001 diff --git a/blake2/tests/serializable.rs b/blake2/tests/serializable.rs new file mode 100644 index 00000000..63dcf460 --- /dev/null +++ b/blake2/tests/serializable.rs @@ -0,0 +1,106 @@ +#[cfg(not(feature = "reset"))] +mod serialization_tests { + use digest::hash_serialization_test; + use crate::hash_mac_serialization_test; + + hash_serialization_test!(blake2b_128_serialization, blake2::Blake2b128); + hash_serialization_test!(blake2b_256_serialization, blake2::Blake2b256); + hash_serialization_test!(blake2b_512_serialization, blake2::Blake2b512); + hash_mac_serialization_test!(blake2b_mac_512_serialization, blake2::Blake2bMac512, 64); + hash_serialization_test!(blake2s_128_serialization, blake2::Blake2s128); + hash_serialization_test!(blake2s_256_serialization, blake2::Blake2s256); + hash_mac_serialization_test!(blake2s_mac_256_serialization, blake2::Blake2sMac256, 32); +} + +#[cfg(feature = "reset")] +mod serialization_tests { + use digest::hash_serialization_test; + use crate::hash_mac_serialization_test; + + hash_serialization_test!(blake2b_128_reset_serialization, blake2::Blake2b128); + hash_serialization_test!(blake2b_256_reset_serialization, blake2::Blake2b256); + hash_serialization_test!(blake2b_512_reset_serialization, blake2::Blake2b512); + hash_mac_serialization_test!(blake2b_mac_512_reset_serialization, blake2::Blake2bMac512, 64); + hash_serialization_test!(blake2s_128_reset_serialization, blake2::Blake2s128); + hash_serialization_test!(blake2s_256_reset_serialization, blake2::Blake2s256); + hash_mac_serialization_test!(blake2s_mac_256_reset_serialization, blake2::Blake2sMac256, 32); +} + +#[macro_export] +macro_rules! hash_mac_serialization_test { + ($name:ident, $hasher:ty, $keysize:literal $(,)?) => { + #[test] + fn $name() { + use digest::{ + common::hazmat::SerializableState, + typenum::Unsigned, + Mac, + array::Array, + }; + use blake2::digest::KeyInit; + + let mut h = <$hasher>::new(&Array::try_from(&[0x42u8; $keysize] as &[u8]).unwrap()); + + // in absence of other sizes we can use as reference (BlockSizeUser can't be accessed + // for blake2 Mac hashers), use the state size + digest::Update::update(&mut h, &[0x13; <$hasher as SerializableState>::SerializedStateSize::USIZE + 1]); + + let serialized_state = h.serialize(); + let expected = include_bytes!(concat!("data/", stringify!($name), ".bin")); + assert_eq!(serialized_state.as_slice(), expected); + + let mut h = <$hasher>::deserialize(&serialized_state).unwrap(); + + digest::Update::update(&mut h, &[0x13; <$hasher as SerializableState>::SerializedStateSize::USIZE + 1]); + let output1 = h.finalize(); + + let mut h = <$hasher>::new(&Array::try_from(&[0x42u8; $keysize] as &[u8]).unwrap()); + digest::Update::update(&mut h, &[0x13; 2 * (<$hasher as SerializableState>::SerializedStateSize::USIZE + 1)]); + let output2 = h.finalize(); + + assert_eq!(output1, output2); + } + }; +} + +macro_rules! gen_test_file { + ($name:ident) => {{ + use digest::Digest; + use digest::common::{BlockSizeUser, hazmat::SerializableState}; + use blake2::digest::typenum::Unsigned; + + let mut a = blake2::$name::new(); + digest::Update::update(&mut a, &[0x13; ::BlockSize::USIZE + 1]); + let serialized = a.serialize(); + let name = stringify!($name); + std::fs::write(format!("./tests/data/blake2{}_{}{}_serialization.bin", &name[6..7], &name[(name.len()-3)..], (if cfg!(feature = "reset") { "_reset" } else { "" })), serialized).unwrap(); + }}; +} + +macro_rules! gen_test_file_mac { + ($name:ident, $keysize:literal) => {{ + use digest::array::Array; + use digest::common::hazmat::SerializableState; + use blake2::digest::{KeyInit, typenum::Unsigned}; + + let mut a = blake2::$name::new(&Array::try_from(&[0x42u8; $keysize] as &[u8]).unwrap()); + digest::Update::update(&mut a, &[0x13; ::SerializedStateSize::USIZE + 1]); + let serialized = a.serialize(); + let name = stringify!($name); + std::fs::write(format!("./tests/data/blake2{}_mac_{}{}_serialization.bin", &name[6..7], &name[(name.len()-3)..], (if cfg!(feature = "reset") { "_reset" } else { "" })), serialized).unwrap(); + }}; +} + +/// Generates the data files used in the tests above. Remove #[ignore] to regenerate the data. +/// Needs to be executed twice, with feature="reset" enabled and disabled. +#[test] +#[ignore] +fn gen_test_files() { + gen_test_file!(Blake2b128); + gen_test_file!(Blake2b256); + gen_test_file!(Blake2b512); + gen_test_file_mac!(Blake2bMac512, 64); + gen_test_file!(Blake2s128); + gen_test_file!(Blake2s256); + gen_test_file_mac!(Blake2sMac256, 32); +} From 84b3603c43614325eee6b211219866941509aff3 Mon Sep 17 00:00:00 2001 From: Stypox Date: Tue, 11 Aug 2026 12:20:10 +0200 Subject: [PATCH 3/3] blake2: cargo fmt --- blake2/src/macros.rs | 121 +++++++++++++++++++++++++++-------- blake2/src/simd.rs | 16 +++-- blake2/tests/serializable.rs | 82 ++++++++++++++++++------ 3 files changed, 168 insertions(+), 51 deletions(-) diff --git a/blake2/src/macros.rs b/blake2/src/macros.rs index fd94fd02..2e2bb2ad 100644 --- a/blake2/src/macros.rs +++ b/blake2/src/macros.rs @@ -282,26 +282,51 @@ macro_rules! blake2_impl { let vecsz = <$vec as SerializableState>::SerializedStateSize::USIZE; let tsz = U8::USIZE; serialized_state[..vecsz].copy_from_slice(&self.h[0].serialize()); - serialized_state[vecsz..(2*vecsz)].copy_from_slice(&self.h[1].serialize()); - serialized_state[(2*vecsz)..(2*vecsz+tsz)].copy_from_slice(&self.t.serialize()); + serialized_state[vecsz..(2 * vecsz)].copy_from_slice(&self.h[1].serialize()); + serialized_state[(2 * vecsz)..(2 * vecsz + tsz)] + .copy_from_slice(&self.t.serialize()); #[cfg(feature = "reset")] - serialized_state[(2*vecsz+tsz)..(3*vecsz+tsz)].copy_from_slice(&self.h0[0].serialize()); + serialized_state[(2 * vecsz + tsz)..(3 * vecsz + tsz)] + .copy_from_slice(&self.h0[0].serialize()); #[cfg(feature = "reset")] - serialized_state[(3*vecsz+tsz)..(4*vecsz+tsz)].copy_from_slice(&self.h0[1].serialize()); + serialized_state[(3 * vecsz + tsz)..(4 * vecsz + tsz)] + .copy_from_slice(&self.h0[1].serialize()); serialized_state } - fn deserialize(serialized_state: &SerializedState) -> Result { + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { let vecsz = <$vec as SerializableState>::SerializedStateSize::USIZE; let tsz = U8::USIZE; - let h_0 = SerializableState::deserialize(&serialized_state[..vecsz].try_into().unwrap())?; - let h_1 = SerializableState::deserialize(&serialized_state[vecsz..(2*vecsz)].try_into().unwrap())?; - let t = SerializableState::deserialize(&serialized_state[(2*vecsz)..(2*vecsz+tsz)].try_into().unwrap())?; + let h_0 = + SerializableState::deserialize(&serialized_state[..vecsz].try_into().unwrap())?; + let h_1 = SerializableState::deserialize( + &serialized_state[vecsz..(2 * vecsz)].try_into().unwrap(), + )?; + let t = SerializableState::deserialize( + &serialized_state[(2 * vecsz)..(2 * vecsz + tsz)] + .try_into() + .unwrap(), + )?; #[cfg(feature = "reset")] - let h0_0 = SerializableState::deserialize(&serialized_state[(2*vecsz+tsz)..(3*vecsz+tsz)].try_into().unwrap())?; + let h0_0 = SerializableState::deserialize( + &serialized_state[(2 * vecsz + tsz)..(3 * vecsz + tsz)] + .try_into() + .unwrap(), + )?; #[cfg(feature = "reset")] - let h0_1 = SerializableState::deserialize(&serialized_state[(3*vecsz+tsz)..(4*vecsz+tsz)].try_into().unwrap())?; - Ok(Self { h: [h_0, h_1], t, #[cfg(feature = "reset")] h0: [h0_0, h0_1] }) + let h0_1 = SerializableState::deserialize( + &serialized_state[(3 * vecsz + tsz)..(4 * vecsz + tsz)] + .try_into() + .unwrap(), + )?; + Ok(Self { + h: [h_0, h_1], + t, + #[cfg(feature = "reset")] + h0: [h0_0, h0_1], + }) } } }; @@ -509,58 +534,98 @@ macro_rules! blake2_mac_impl { { } - impl SerializableState for $name where - OutSize: ArraySize + IsLessOrEqual<$max_size, Output = True> { + impl SerializableState for $name + where + OutSize: ArraySize + IsLessOrEqual<$max_size, Output = True>, + { #[cfg(not(feature = "reset"))] - type SerializedStateSize = Sum<<$hash as SerializableState>::SerializedStateSize, SerializedBufferSize<<$hash as BlockSizeUser>::BlockSize, Lazy>>; + type SerializedStateSize = Sum< + <$hash as SerializableState>::SerializedStateSize, + SerializedBufferSize<<$hash as BlockSizeUser>::BlockSize, Lazy>, + >; #[cfg(feature = "reset")] - type SerializedStateSize = Sum::SerializedStateSize, SerializedBufferSize<<$hash as BlockSizeUser>::BlockSize, Lazy>>, Sum<::KeySize, digest::consts::U1>>; + type SerializedStateSize = Sum< + Sum< + <$hash as SerializableState>::SerializedStateSize, + SerializedBufferSize<<$hash as BlockSizeUser>::BlockSize, Lazy>, + >, + Sum<::KeySize, digest::consts::U1>, + >; fn serialize(&self) -> SerializedState { let mut serialized_state = SerializedState::::default(); let coresz = <$hash as SerializableState>::SerializedStateSize::USIZE; - let buffersz = ::BlockSize, Lazy>>::USIZE; + let buffersz = + ::BlockSize, Lazy>>::USIZE; serialized_state[..coresz].copy_from_slice(&self.core.serialize()); - serialized_state[coresz..(coresz + buffersz)].copy_from_slice(&self.buffer.serialize()); + serialized_state[coresz..(coresz + buffersz)] + .copy_from_slice(&self.buffer.serialize()); #[cfg(feature = "reset")] { let boolsz = digest::consts::U1::USIZE; let keyblocksz = ::KeySize::USIZE; if let Some(key_block) = self.key_block { - serialized_state[(coresz + buffersz)..(coresz + buffersz + boolsz)].copy_from_slice(&1u8.serialize()); - serialized_state[(coresz + buffersz + boolsz)..(coresz + buffersz + boolsz + keyblocksz)].copy_from_slice(&key_block); + serialized_state[(coresz + buffersz)..(coresz + buffersz + boolsz)] + .copy_from_slice(&1u8.serialize()); + serialized_state[(coresz + buffersz + boolsz) + ..(coresz + buffersz + boolsz + keyblocksz)] + .copy_from_slice(&key_block); } else { - serialized_state[(coresz + buffersz)..(coresz + buffersz + boolsz)].copy_from_slice(&0u8.serialize()); + serialized_state[(coresz + buffersz)..(coresz + buffersz + boolsz)] + .copy_from_slice(&0u8.serialize()); } } serialized_state } - fn deserialize(serialized_state: &SerializedState) -> Result { + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { let coresz = <$hash as SerializableState>::SerializedStateSize::USIZE; - let buffersz = ::BlockSize, Lazy>>::USIZE; + let buffersz = + ::BlockSize, Lazy>>::USIZE; - let core = SerializableState::deserialize(&serialized_state[..coresz].try_into().unwrap())?; + let core = SerializableState::deserialize( + &serialized_state[..coresz].try_into().unwrap(), + )?; let buffer = LazyBuffer::<<$hash as BlockSizeUser>::BlockSize>::deserialize( - &serialized_state[coresz..(coresz + buffersz)].try_into().unwrap() - ).map_err(|_| DeserializeStateError)?; + &serialized_state[coresz..(coresz + buffersz)] + .try_into() + .unwrap(), + ) + .map_err(|_| DeserializeStateError)?; #[cfg(feature = "reset")] let key_block = { let boolsz = digest::consts::U1::USIZE; let keyblocksz = ::KeySize::USIZE; - let present: u8 = SerializableState::deserialize(&serialized_state[(coresz + buffersz)..(coresz + buffersz + boolsz)].try_into().unwrap())?; + let present: u8 = SerializableState::deserialize( + &serialized_state[(coresz + buffersz)..(coresz + buffersz + boolsz)] + .try_into() + .unwrap(), + )?; if present != 0 { - Some(serialized_state[(coresz + buffersz + boolsz)..(coresz + buffersz + boolsz + keyblocksz)].try_into().unwrap()) + Some( + serialized_state[(coresz + buffersz + boolsz) + ..(coresz + buffersz + boolsz + keyblocksz)] + .try_into() + .unwrap(), + ) } else { None } }; - Ok(Self { core, buffer, #[cfg(feature = "reset")] key_block, _out: Default::default() }) + Ok(Self { + core, + buffer, + #[cfg(feature = "reset")] + key_block, + _out: Default::default(), + }) } } }; diff --git a/blake2/src/simd.rs b/blake2/src/simd.rs index c47bc38c..99d3d3bb 100644 --- a/blake2/src/simd.rs +++ b/blake2/src/simd.rs @@ -1,6 +1,6 @@ use core::ops::{Add, BitXor, Shl, Shr}; -use digest::{common::hazmat::{DeserializeStateError, SerializableState, SerializedState}}; +use digest::common::hazmat::{DeserializeStateError, SerializableState, SerializedState}; #[cfg(feature = "zeroize")] use digest::zeroize::Zeroize; @@ -191,9 +191,17 @@ macro_rules! impl_vector4 { [self.0, self.1, self.2, self.3].serialize() } - fn deserialize(serialized_state: &SerializedState) -> Result { - let deserialized: [$word; 4] = <[$word; 4] as SerializableState>::deserialize(serialized_state)?; - Ok($vec(deserialized[0], deserialized[1], deserialized[2], deserialized[3])) + fn deserialize( + serialized_state: &SerializedState, + ) -> Result { + let deserialized: [$word; 4] = + <[$word; 4] as SerializableState>::deserialize(serialized_state)?; + Ok($vec( + deserialized[0], + deserialized[1], + deserialized[2], + deserialized[3], + )) } } }; diff --git a/blake2/tests/serializable.rs b/blake2/tests/serializable.rs index 63dcf460..926aa266 100644 --- a/blake2/tests/serializable.rs +++ b/blake2/tests/serializable.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "reset"))] mod serialization_tests { - use digest::hash_serialization_test; use crate::hash_mac_serialization_test; + use digest::hash_serialization_test; hash_serialization_test!(blake2b_128_serialization, blake2::Blake2b128); hash_serialization_test!(blake2b_256_serialization, blake2::Blake2b256); @@ -14,16 +14,24 @@ mod serialization_tests { #[cfg(feature = "reset")] mod serialization_tests { - use digest::hash_serialization_test; use crate::hash_mac_serialization_test; + use digest::hash_serialization_test; hash_serialization_test!(blake2b_128_reset_serialization, blake2::Blake2b128); hash_serialization_test!(blake2b_256_reset_serialization, blake2::Blake2b256); hash_serialization_test!(blake2b_512_reset_serialization, blake2::Blake2b512); - hash_mac_serialization_test!(blake2b_mac_512_reset_serialization, blake2::Blake2bMac512, 64); + hash_mac_serialization_test!( + blake2b_mac_512_reset_serialization, + blake2::Blake2bMac512, + 64 + ); hash_serialization_test!(blake2s_128_reset_serialization, blake2::Blake2s128); hash_serialization_test!(blake2s_256_reset_serialization, blake2::Blake2s256); - hash_mac_serialization_test!(blake2s_mac_256_reset_serialization, blake2::Blake2sMac256, 32); + hash_mac_serialization_test!( + blake2s_mac_256_reset_serialization, + blake2::Blake2sMac256, + 32 + ); } #[macro_export] @@ -31,19 +39,17 @@ macro_rules! hash_mac_serialization_test { ($name:ident, $hasher:ty, $keysize:literal $(,)?) => { #[test] fn $name() { - use digest::{ - common::hazmat::SerializableState, - typenum::Unsigned, - Mac, - array::Array, - }; use blake2::digest::KeyInit; + use digest::{Mac, array::Array, common::hazmat::SerializableState, typenum::Unsigned}; let mut h = <$hasher>::new(&Array::try_from(&[0x42u8; $keysize] as &[u8]).unwrap()); // in absence of other sizes we can use as reference (BlockSizeUser can't be accessed // for blake2 Mac hashers), use the state size - digest::Update::update(&mut h, &[0x13; <$hasher as SerializableState>::SerializedStateSize::USIZE + 1]); + digest::Update::update( + &mut h, + &[0x13; <$hasher as SerializableState>::SerializedStateSize::USIZE + 1], + ); let serialized_state = h.serialize(); let expected = include_bytes!(concat!("data/", stringify!($name), ".bin")); @@ -51,11 +57,17 @@ macro_rules! hash_mac_serialization_test { let mut h = <$hasher>::deserialize(&serialized_state).unwrap(); - digest::Update::update(&mut h, &[0x13; <$hasher as SerializableState>::SerializedStateSize::USIZE + 1]); + digest::Update::update( + &mut h, + &[0x13; <$hasher as SerializableState>::SerializedStateSize::USIZE + 1], + ); let output1 = h.finalize(); let mut h = <$hasher>::new(&Array::try_from(&[0x42u8; $keysize] as &[u8]).unwrap()); - digest::Update::update(&mut h, &[0x13; 2 * (<$hasher as SerializableState>::SerializedStateSize::USIZE + 1)]); + digest::Update::update( + &mut h, + &[0x13; 2 * (<$hasher as SerializableState>::SerializedStateSize::USIZE + 1)], + ); let output2 = h.finalize(); assert_eq!(output1, output2); @@ -65,29 +77,61 @@ macro_rules! hash_mac_serialization_test { macro_rules! gen_test_file { ($name:ident) => {{ + use blake2::digest::typenum::Unsigned; use digest::Digest; use digest::common::{BlockSizeUser, hazmat::SerializableState}; - use blake2::digest::typenum::Unsigned; let mut a = blake2::$name::new(); - digest::Update::update(&mut a, &[0x13; ::BlockSize::USIZE + 1]); + digest::Update::update( + &mut a, + &[0x13; ::BlockSize::USIZE + 1], + ); let serialized = a.serialize(); let name = stringify!($name); - std::fs::write(format!("./tests/data/blake2{}_{}{}_serialization.bin", &name[6..7], &name[(name.len()-3)..], (if cfg!(feature = "reset") { "_reset" } else { "" })), serialized).unwrap(); + std::fs::write( + format!( + "./tests/data/blake2{}_{}{}_serialization.bin", + &name[6..7], + &name[(name.len() - 3)..], + (if cfg!(feature = "reset") { + "_reset" + } else { + "" + }) + ), + serialized, + ) + .unwrap(); }}; } macro_rules! gen_test_file_mac { ($name:ident, $keysize:literal) => {{ + use blake2::digest::{KeyInit, typenum::Unsigned}; use digest::array::Array; use digest::common::hazmat::SerializableState; - use blake2::digest::{KeyInit, typenum::Unsigned}; let mut a = blake2::$name::new(&Array::try_from(&[0x42u8; $keysize] as &[u8]).unwrap()); - digest::Update::update(&mut a, &[0x13; ::SerializedStateSize::USIZE + 1]); + digest::Update::update( + &mut a, + &[0x13; ::SerializedStateSize::USIZE + 1], + ); let serialized = a.serialize(); let name = stringify!($name); - std::fs::write(format!("./tests/data/blake2{}_mac_{}{}_serialization.bin", &name[6..7], &name[(name.len()-3)..], (if cfg!(feature = "reset") { "_reset" } else { "" })), serialized).unwrap(); + std::fs::write( + format!( + "./tests/data/blake2{}_mac_{}{}_serialization.bin", + &name[6..7], + &name[(name.len() - 3)..], + (if cfg!(feature = "reset") { + "_reset" + } else { + "" + }) + ), + serialized, + ) + .unwrap(); }}; }