Skip to content

Commit 9fbd4f9

Browse files
authored
crypto-common: add SerializableState trait (#1369)
This trait is used for saving the internal state of the object and restoring the object from the serialized state.
1 parent dcae306 commit 9fbd4f9

File tree

6 files changed

+615
-10
lines changed

6 files changed

+615
-10
lines changed

crypto-common/src/lib.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,20 @@ pub use hybrid_array as array;
2121
pub use hybrid_array::typenum;
2222

2323
use core::fmt;
24-
use hybrid_array::{typenum::Unsigned, Array, ArraySize, ByteArray};
24+
use hybrid_array::{
25+
typenum::{Diff, Sum, Unsigned},
26+
Array, ArraySize, ByteArray,
27+
};
2528

2629
#[cfg(feature = "rand_core")]
2730
use rand_core::CryptoRngCore;
2831

32+
mod serializable_state;
33+
pub use serializable_state::{
34+
AddSerializedStateSize, DeserializeStateError, SerializableState, SerializedState,
35+
SubSerializedStateSize,
36+
};
37+
2938
/// Block on which [`BlockSizeUser`] implementors operate.
3039
pub type Block<B> = ByteArray<<B as BlockSizeUser>::BlockSize>;
3140

@@ -41,6 +50,12 @@ pub type Key<B> = ByteArray<<B as KeySizeUser>::KeySize>;
4150
/// Initialization vector (nonce) used by [`IvSizeUser`] implementors.
4251
pub type Iv<B> = ByteArray<<B as IvSizeUser>::IvSize>;
4352

53+
/// Alias for `AddBlockSize<A, B> = Sum<T, B::BlockSize>`
54+
pub type AddBlockSize<T, B> = Sum<T, <B as BlockSizeUser>::BlockSize>;
55+
56+
/// Alias for `SubBlockSize<A, B> = Diff<T, B::BlockSize>`
57+
pub type SubBlockSize<T, B> = Diff<T, <B as BlockSizeUser>::BlockSize>;
58+
4459
/// Types which process data in blocks.
4560
pub trait BlockSizeUser {
4661
/// Size of the block in bytes.
Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
use crate::array::{
2+
self,
3+
typenum::{Diff, Prod, Sum, Unsigned, U1, U16, U2, U4, U8},
4+
ArraySize, ByteArray,
5+
};
6+
use core::{convert::TryInto, default::Default, fmt};
7+
8+
/// Serialized internal state.
9+
pub type SerializedState<T> = ByteArray<<T as SerializableState>::SerializedStateSize>;
10+
11+
/// Alias for `AddSerializedStateSize<T, S> = Sum<T, S::SerializedStateSize>`
12+
pub type AddSerializedStateSize<T, S> = Sum<T, <S as SerializableState>::SerializedStateSize>;
13+
14+
/// Alias for `SubSerializedStateSize<T, S> = Diff<T, S::SerializedStateSize>`
15+
pub type SubSerializedStateSize<T, S> = Diff<T, <S as SerializableState>::SerializedStateSize>;
16+
17+
/// The error type returned when an object cannot be deserialized from the state.
18+
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
19+
pub struct DeserializeStateError;
20+
21+
impl fmt::Display for DeserializeStateError {
22+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
23+
f.write_str("Deserialization error")
24+
}
25+
}
26+
27+
#[cfg(feature = "std")]
28+
impl std::error::Error for DeserializeStateError {}
29+
30+
/// Types which can serialize the internal state and be restored from it.
31+
///
32+
/// # SECURITY WARNING
33+
///
34+
/// Serialized state may contain sensitive data.
35+
pub trait SerializableState
36+
where
37+
Self: Sized,
38+
{
39+
/// Size of serialized internal state.
40+
type SerializedStateSize: ArraySize;
41+
42+
/// Serialize and return internal state.
43+
fn serialize(&self) -> SerializedState<Self>;
44+
/// Create an object from serialized internal state.
45+
fn deserialize(serialized_state: &SerializedState<Self>)
46+
-> Result<Self, DeserializeStateError>;
47+
}
48+
49+
macro_rules! impl_seializable_state_unsigned {
50+
($type: ty, $type_size: ty) => {
51+
impl SerializableState for $type {
52+
type SerializedStateSize = $type_size;
53+
54+
fn serialize(&self) -> SerializedState<Self> {
55+
self.to_le_bytes().into()
56+
}
57+
58+
fn deserialize(
59+
serialized_state: &SerializedState<Self>,
60+
) -> Result<Self, DeserializeStateError> {
61+
Ok(<$type>::from_le_bytes((*serialized_state).into()))
62+
}
63+
}
64+
};
65+
}
66+
67+
impl_seializable_state_unsigned!(u8, U1);
68+
impl_seializable_state_unsigned!(u16, U2);
69+
impl_seializable_state_unsigned!(u32, U4);
70+
impl_seializable_state_unsigned!(u64, U8);
71+
impl_seializable_state_unsigned!(u128, U16);
72+
73+
macro_rules! impl_serializable_state_u8_array {
74+
($($n: ty),*) => {
75+
$(
76+
impl SerializableState for [u8; <$n>::USIZE] {
77+
type SerializedStateSize = $n;
78+
79+
fn serialize(&self) -> SerializedState<Self> {
80+
(*self).into()
81+
}
82+
83+
fn deserialize(
84+
serialized_state: &SerializedState<Self>,
85+
) -> Result<Self, DeserializeStateError> {
86+
Ok((*serialized_state).into())
87+
}
88+
}
89+
)*
90+
};
91+
}
92+
93+
macro_rules! impl_serializable_state_type_array {
94+
($type: ty, $type_size: ty, $n: ty) => {
95+
impl SerializableState for [$type; <$n>::USIZE] {
96+
type SerializedStateSize = Prod<$n, $type_size>;
97+
98+
fn serialize(&self) -> SerializedState<Self> {
99+
let mut serialized_state = SerializedState::<Self>::default();
100+
for (val, chunk) in self
101+
.iter()
102+
.zip(serialized_state.chunks_exact_mut(<$type_size>::USIZE))
103+
{
104+
chunk.copy_from_slice(&val.to_le_bytes());
105+
}
106+
107+
serialized_state
108+
}
109+
110+
fn deserialize(
111+
serialized_state: &SerializedState<Self>,
112+
) -> Result<Self, DeserializeStateError> {
113+
let mut array = [0; <$n>::USIZE];
114+
for (val, chunk) in array
115+
.iter_mut()
116+
.zip(serialized_state.chunks_exact(<$type_size>::USIZE))
117+
{
118+
*val = <$type>::from_le_bytes(chunk.try_into().unwrap());
119+
}
120+
Ok(array)
121+
}
122+
}
123+
};
124+
}
125+
126+
macro_rules! impl_serializable_state_u16_array {
127+
($($n: ty),*) => {
128+
$(
129+
impl_serializable_state_type_array!(u16, U2, $n);
130+
)*
131+
};
132+
}
133+
134+
macro_rules! impl_serializable_state_u32_array {
135+
($($n: ty),*) => {
136+
$(
137+
impl_serializable_state_type_array!(u32, U4, $n);
138+
)*
139+
};
140+
}
141+
142+
macro_rules! impl_serializable_state_u64_array {
143+
($($n: ty),*) => {
144+
$(
145+
impl_serializable_state_type_array!(u64, U8, $n);
146+
)*
147+
};
148+
}
149+
150+
macro_rules! impl_serializable_state_u128_array {
151+
($($n: ty),*) => {
152+
$(
153+
impl_serializable_state_type_array!(u128, U8, $n);
154+
)*
155+
};
156+
}
157+
158+
impl_serializable_state_u8_array! {
159+
array::typenum::U1,
160+
array::typenum::U2,
161+
array::typenum::U3,
162+
array::typenum::U4,
163+
array::typenum::U5,
164+
array::typenum::U6,
165+
array::typenum::U7,
166+
array::typenum::U8,
167+
array::typenum::U9,
168+
array::typenum::U10,
169+
array::typenum::U11,
170+
array::typenum::U12,
171+
array::typenum::U13,
172+
array::typenum::U14,
173+
array::typenum::U15,
174+
array::typenum::U16,
175+
array::typenum::U17,
176+
array::typenum::U18,
177+
array::typenum::U19,
178+
array::typenum::U20,
179+
array::typenum::U21,
180+
array::typenum::U22,
181+
array::typenum::U23,
182+
array::typenum::U24,
183+
array::typenum::U25,
184+
array::typenum::U26,
185+
array::typenum::U27,
186+
array::typenum::U28,
187+
array::typenum::U29,
188+
array::typenum::U30,
189+
array::typenum::U31,
190+
array::typenum::U32,
191+
array::typenum::U33,
192+
array::typenum::U34,
193+
array::typenum::U35,
194+
array::typenum::U36,
195+
array::typenum::U37,
196+
array::typenum::U38,
197+
array::typenum::U39,
198+
array::typenum::U40,
199+
array::typenum::U41,
200+
array::typenum::U42,
201+
array::typenum::U43,
202+
array::typenum::U44,
203+
array::typenum::U45,
204+
array::typenum::U46,
205+
array::typenum::U47,
206+
array::typenum::U48,
207+
array::typenum::U49,
208+
array::typenum::U50,
209+
array::typenum::U51,
210+
array::typenum::U52,
211+
array::typenum::U53,
212+
array::typenum::U54,
213+
array::typenum::U55,
214+
array::typenum::U56,
215+
array::typenum::U57,
216+
array::typenum::U58,
217+
array::typenum::U59,
218+
array::typenum::U60,
219+
array::typenum::U61,
220+
array::typenum::U62,
221+
array::typenum::U63,
222+
array::typenum::U64,
223+
array::typenum::U96,
224+
array::typenum::U128,
225+
array::typenum::U192,
226+
array::typenum::U256,
227+
array::typenum::U384,
228+
array::typenum::U448,
229+
array::typenum::U512,
230+
array::typenum::U768,
231+
array::typenum::U896,
232+
array::typenum::U1024,
233+
array::typenum::U2048,
234+
array::typenum::U4096,
235+
array::typenum::U8192
236+
}
237+
238+
impl_serializable_state_u16_array! {
239+
array::typenum::U1,
240+
array::typenum::U2,
241+
array::typenum::U3,
242+
array::typenum::U4,
243+
array::typenum::U5,
244+
array::typenum::U6,
245+
array::typenum::U7,
246+
array::typenum::U8,
247+
array::typenum::U9,
248+
array::typenum::U10,
249+
array::typenum::U11,
250+
array::typenum::U12,
251+
array::typenum::U13,
252+
array::typenum::U14,
253+
array::typenum::U15,
254+
array::typenum::U16,
255+
array::typenum::U17,
256+
array::typenum::U18,
257+
array::typenum::U19,
258+
array::typenum::U20,
259+
array::typenum::U21,
260+
array::typenum::U22,
261+
array::typenum::U23,
262+
array::typenum::U24,
263+
array::typenum::U25,
264+
array::typenum::U26,
265+
array::typenum::U27,
266+
array::typenum::U28,
267+
array::typenum::U29,
268+
array::typenum::U30,
269+
array::typenum::U31,
270+
array::typenum::U32,
271+
array::typenum::U48,
272+
array::typenum::U96,
273+
array::typenum::U128,
274+
array::typenum::U192,
275+
array::typenum::U256,
276+
array::typenum::U384,
277+
array::typenum::U448,
278+
array::typenum::U512,
279+
array::typenum::U2048,
280+
array::typenum::U4096
281+
}
282+
283+
impl_serializable_state_u32_array! {
284+
array::typenum::U1,
285+
array::typenum::U2,
286+
array::typenum::U3,
287+
array::typenum::U4,
288+
array::typenum::U5,
289+
array::typenum::U6,
290+
array::typenum::U7,
291+
array::typenum::U8,
292+
array::typenum::U9,
293+
array::typenum::U10,
294+
array::typenum::U11,
295+
array::typenum::U12,
296+
array::typenum::U13,
297+
array::typenum::U14,
298+
array::typenum::U15,
299+
array::typenum::U16,
300+
array::typenum::U24,
301+
array::typenum::U32,
302+
array::typenum::U48,
303+
array::typenum::U64,
304+
array::typenum::U96,
305+
array::typenum::U128,
306+
array::typenum::U192,
307+
array::typenum::U256,
308+
array::typenum::U512,
309+
array::typenum::U1024,
310+
array::typenum::U2048
311+
}
312+
313+
impl_serializable_state_u64_array! {
314+
array::typenum::U1,
315+
array::typenum::U2,
316+
array::typenum::U3,
317+
array::typenum::U4,
318+
array::typenum::U5,
319+
array::typenum::U6,
320+
array::typenum::U7,
321+
array::typenum::U8,
322+
array::typenum::U12,
323+
array::typenum::U16,
324+
array::typenum::U24,
325+
array::typenum::U32,
326+
array::typenum::U48,
327+
array::typenum::U64,
328+
array::typenum::U96,
329+
array::typenum::U128,
330+
array::typenum::U256,
331+
array::typenum::U512,
332+
array::typenum::U1024
333+
}
334+
335+
impl_serializable_state_u128_array! {
336+
array::typenum::U1,
337+
array::typenum::U2,
338+
array::typenum::U3,
339+
array::typenum::U4,
340+
array::typenum::U6,
341+
array::typenum::U8,
342+
array::typenum::U12,
343+
array::typenum::U16,
344+
array::typenum::U24,
345+
array::typenum::U32,
346+
array::typenum::U48,
347+
array::typenum::U64,
348+
array::typenum::U128,
349+
array::typenum::U256,
350+
array::typenum::U512
351+
}

0 commit comments

Comments
 (0)