@@ -13,6 +13,14 @@ use {crate::Random, rand_core::CryptoRngCore};
13
13
#[ cfg( all( feature = "alloc" , feature = "rand_core" ) ) ]
14
14
use crate :: RandomBits ;
15
15
16
+ #[ cfg( feature = "serde" ) ]
17
+ use crate :: Zero ;
18
+ #[ cfg( feature = "serde" ) ]
19
+ use serdect:: serde:: {
20
+ de:: { Error , Unexpected } ,
21
+ Deserialize , Deserializer , Serialize , Serializer ,
22
+ } ;
23
+
16
24
/// Wrapper type for odd integers.
17
25
///
18
26
/// These are frequently used in cryptography, e.g. as a modulus.
@@ -153,6 +161,30 @@ impl Odd<BoxedUint> {
153
161
}
154
162
}
155
163
164
+ #[ cfg( feature = "serde" ) ]
165
+ impl < ' de , T : Deserialize < ' de > + Integer + Zero > Deserialize < ' de > for Odd < T > {
166
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
167
+ where
168
+ D : Deserializer < ' de > ,
169
+ {
170
+ let value: T = T :: deserialize ( deserializer) ?;
171
+ Option :: < Self > :: from ( Self :: new ( value) ) . ok_or ( D :: Error :: invalid_value (
172
+ Unexpected :: Other ( "even" ) ,
173
+ & "a non-zero odd value" ,
174
+ ) )
175
+ }
176
+ }
177
+
178
+ #[ cfg( feature = "serde" ) ]
179
+ impl < T : Serialize + Zero > Serialize for Odd < T > {
180
+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
181
+ where
182
+ S : Serializer ,
183
+ {
184
+ self . 0 . serialize ( serializer)
185
+ }
186
+ }
187
+
156
188
#[ cfg( test) ]
157
189
mod tests {
158
190
#[ cfg( feature = "alloc" ) ]
@@ -175,4 +207,68 @@ mod tests {
175
207
let two = Odd :: new ( BoxedUint :: from ( 2u8 ) ) ;
176
208
assert ! ( bool :: from( two. is_none( ) ) ) ;
177
209
}
210
+
211
+ #[ cfg( feature = "serde" ) ]
212
+ mod serde_tests {
213
+ use crate :: { Odd , U128 , U64 } ;
214
+ use alloc:: string:: ToString ;
215
+ use bincode:: ErrorKind ;
216
+
217
+ #[ test]
218
+ fn roundtrip ( ) {
219
+ let uint = Odd :: new ( U64 :: from_u64 ( 0x00123 ) ) . unwrap ( ) ;
220
+ let ser = bincode:: serialize ( & uint) . unwrap ( ) ;
221
+ let deser = bincode:: deserialize :: < Odd < U64 > > ( & ser) . unwrap ( ) ;
222
+
223
+ assert_eq ! ( uint, deser) ;
224
+ }
225
+
226
+ #[ test]
227
+ fn even_values_do_not_deserialize ( ) {
228
+ let two = U128 :: from_u64 ( 0x2 ) ;
229
+ let two_ser = bincode:: serialize ( & two) . unwrap ( ) ;
230
+ assert ! ( matches!(
231
+ * bincode:: deserialize:: <Odd <U128 >>( & two_ser) . unwrap_err( ) ,
232
+ ErrorKind :: Custom ( mess) if mess == "invalid value: even, expected a non-zero odd value"
233
+ ) )
234
+ }
235
+
236
+ #[ test]
237
+ fn zero_does_not_deserialize ( ) {
238
+ let zero = U64 :: ZERO ;
239
+ let zero_ser = bincode:: serialize ( & zero) . unwrap ( ) ;
240
+
241
+ assert ! ( matches!(
242
+ * bincode:: deserialize:: <Odd <U64 >>( & zero_ser) . unwrap_err( ) ,
243
+ ErrorKind :: Custom ( mess) if mess == "invalid value: even, expected a non-zero odd value"
244
+ ) )
245
+ }
246
+
247
+ #[ test]
248
+ fn cannot_deserialize_into_bigger_type ( ) {
249
+ let three = Odd :: new ( U64 :: from_u64 ( 0x3 ) ) . unwrap ( ) ;
250
+ let three_ser = bincode:: serialize ( & three) . unwrap ( ) ;
251
+ let error_message = bincode:: deserialize :: < Odd < U128 > > ( & three_ser)
252
+ . unwrap_err ( )
253
+ . to_string ( ) ;
254
+
255
+ assert_eq ! ( & error_message, "io error: unexpected end of file" ) ;
256
+ }
257
+
258
+ // @reviewers: I expected an error when deserializing an Odd<U128> into an Odd<U64>, instead I get a truncated number. Is this a big or known limitation?
259
+ #[ test]
260
+ fn silently_coerces_bigger_type_into_smaller_type ( ) {
261
+ let three = Odd :: new ( U128 :: from_u128 ( 0x77777777777777773333333333333333 ) ) . unwrap ( ) ;
262
+
263
+ let three_ser = bincode:: serialize ( & three) . unwrap ( ) ;
264
+
265
+ // This doesn't fail, which is unexpected
266
+ let smaller = bincode:: deserialize :: < Odd < U64 > > ( & three_ser) . unwrap ( ) ;
267
+
268
+ assert_eq ! (
269
+ smaller,
270
+ Odd :: new( U64 :: from_u64( 0x3333333333333333 ) ) . unwrap( )
271
+ ) ;
272
+ }
273
+ }
178
274
}
0 commit comments