@@ -4,8 +4,12 @@ use crate::MacMarker;
4
4
use crate :: { HashMarker , InvalidBufferSize } ;
5
5
use crate :: { InvalidOutputSize , Reset , Update , VariableOutput , VariableOutputReset } ;
6
6
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
+ } ;
9
13
10
14
/// Wrapper around [`VariableOutputCore`] which selects output size
11
15
/// at run time.
@@ -145,6 +149,68 @@ where
145
149
}
146
150
}
147
151
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
+
148
214
#[ cfg( feature = "std" ) ]
149
215
#[ cfg_attr( docsrs, doc( cfg( feature = "std" ) ) ) ]
150
216
impl < T > std:: io:: Write for RtVariableCoreWrapper < T >
0 commit comments