Skip to content

Commit 2a3aa24

Browse files
author
Ruslan Piasetskyi
committed
digest: implement SerializableState for RtVariableCoreWrapper
1 parent 893c534 commit 2a3aa24

File tree

1 file changed

+68
-2
lines changed

1 file changed

+68
-2
lines changed

digest/src/core_api/rt_variable.rs

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ use crate::MacMarker;
44
use crate::{HashMarker, InvalidBufferSize};
55
use crate::{InvalidOutputSize, Reset, Update, VariableOutput, VariableOutputReset};
66
use block_buffer::BlockBuffer;
7-
use core::fmt;
8-
use crypto_common::typenum::{IsLess, Le, NonZero, Unsigned, U256};
7+
use core::{convert::TryInto, fmt, mem::size_of_val, ops::Add};
8+
use crypto_common::{
9+
generic_array::ArrayLength,
10+
typenum::{IsLess, Le, NonZero, Sum, Unsigned, U256, U9},
11+
DeserializeStateError, SerializableState, SerializedState,
12+
};
913

1014
/// Wrapper around [`VariableOutputCore`] which selects output size
1115
/// at run time.
@@ -145,6 +149,68 @@ where
145149
}
146150
}
147151

152+
impl<T> SerializableState for RtVariableCoreWrapper<T>
153+
where
154+
T: VariableOutputCore + UpdateCore + SerializableState,
155+
T::BlockSize: IsLess<U256>,
156+
Le<T::BlockSize, U256>: NonZero,
157+
T::SerializedStateSize: Add<U9>,
158+
<T::SerializedStateSize as Add<U9>>::Output: Add<T::BlockSize>,
159+
<<T::SerializedStateSize as Add<U9>>::Output as Add<T::BlockSize>>::Output: ArrayLength<u8>,
160+
{
161+
type SerializedStateSize = Sum<Sum<T::SerializedStateSize, U9>, T::BlockSize>;
162+
163+
fn serialize(&self) -> SerializedState<Self> {
164+
let mut serialized_state = SerializedState::<Self>::default();
165+
let serialization_buffer = serialized_state.as_mut_slice();
166+
167+
let serialized_core = self.core.serialize();
168+
let (buffer, serialization_buffer) =
169+
serialization_buffer.split_at_mut(serialized_core.len());
170+
buffer.copy_from_slice(serialized_core.as_slice());
171+
172+
let pos = self.buffer.get_pos().try_into().unwrap();
173+
let (buffer, serialization_buffer) = serialization_buffer.split_at_mut(size_of_val(&pos));
174+
buffer[0] = pos;
175+
176+
let data = self.buffer.clone().pad_with_zeros().clone();
177+
let (buffer, serialization_buffer) = serialization_buffer.split_at_mut(data.len());
178+
buffer.copy_from_slice(data.as_slice());
179+
180+
let output_size = self.output_size.try_into().unwrap();
181+
serialization_buffer[0] = output_size;
182+
183+
serialized_state
184+
}
185+
186+
fn deserialize(
187+
serialized_state: &SerializedState<Self>,
188+
) -> Result<Self, DeserializeStateError> {
189+
let serialization_buffer = serialized_state.as_slice();
190+
191+
let (buffer, serialization_buffer) =
192+
serialization_buffer.split_at(T::SerializedStateSize::USIZE);
193+
let serialized_core = SerializedState::<T>::from_slice(buffer);
194+
195+
let (buffer, serialization_buffer) = serialization_buffer.split_at(1);
196+
let pos = buffer[0].into();
197+
if pos > T::BlockSize::USIZE {
198+
return Err(DeserializeStateError);
199+
}
200+
201+
let (block_buffer, serialization_buffer) =
202+
serialization_buffer.split_at(T::BlockSize::USIZE);
203+
204+
let output_size = serialization_buffer[0].into();
205+
206+
Ok(Self {
207+
core: T::deserialize(serialized_core)?,
208+
buffer: BlockBuffer::new(&block_buffer[..pos]),
209+
output_size,
210+
})
211+
}
212+
}
213+
148214
#[cfg(feature = "std")]
149215
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
150216
impl<T> std::io::Write for RtVariableCoreWrapper<T>

0 commit comments

Comments
 (0)