Skip to main content

nam_blstrs/
serde_impl.rs

1use core::convert::TryFrom;
2use core::fmt;
3use core::marker::PhantomData;
4
5use group::{Curve, prime::PrimeCurveAffine};
6use serde::{
7    Deserialize, Deserializer, Serialize, Serializer,
8    de::{Error as DeserializeError, SeqAccess, Visitor},
9    ser::SerializeTuple,
10};
11
12use crate::{
13    G1Affine, G1Projective, G2Affine, G2Projective, Gt, MillerLoopResult, Scalar, fp::Fp, fp2::Fp2,
14    fp6::Fp6, fp12::Fp12,
15};
16
17const ERR_CODE: &str = "deserialized bytes don't encode a group element";
18
19impl Serialize for G1Projective {
20    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
21        self.to_affine().serialize(s)
22    }
23}
24
25impl<'de> Deserialize<'de> for G1Projective {
26    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
27        Ok(G1Affine::deserialize(d)?.to_curve())
28    }
29}
30
31impl Serialize for G1Affine {
32    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
33        serialize_affine(self, s)
34    }
35}
36
37impl<'de> Deserialize<'de> for G1Affine {
38    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
39        deserialize_affine(d)
40    }
41}
42
43impl Serialize for G2Projective {
44    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
45        self.to_affine().serialize(s)
46    }
47}
48
49impl<'de> Deserialize<'de> for G2Projective {
50    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
51        Ok(G2Affine::deserialize(d)?.to_curve())
52    }
53}
54
55impl Serialize for G2Affine {
56    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
57        serialize_affine(self, s)
58    }
59}
60
61impl<'de> Deserialize<'de> for G2Affine {
62    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
63        deserialize_affine(d)
64    }
65}
66
67/// Serialize a group element using its compressed representation.
68fn serialize_affine<S: Serializer, C: PrimeCurveAffine>(c: &C, s: S) -> Result<S::Ok, S::Error> {
69    let compressed_bytes = c.to_bytes();
70    let len = compressed_bytes.as_ref().len();
71    let mut tup = s.serialize_tuple(len)?;
72    for byte in compressed_bytes.as_ref() {
73        tup.serialize_element(byte)?;
74    }
75    tup.end()
76}
77
78/// Deserializes the compressed representation of a group element.
79fn deserialize_affine<'de, D: Deserializer<'de>, C: PrimeCurveAffine>(d: D) -> Result<C, D::Error> {
80    struct TupleVisitor<C> {
81        _ph: PhantomData<C>,
82    }
83
84    impl<'de, C: PrimeCurveAffine> Visitor<'de> for TupleVisitor<C> {
85        type Value = C;
86
87        fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
88            let len = C::Repr::default().as_ref().len();
89            write!(f, "a tuple of {} bytes", len)
90        }
91
92        #[inline]
93        fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<C, A::Error> {
94            let mut compressed = C::Repr::default();
95            for (i, byte) in compressed.as_mut().iter_mut().enumerate() {
96                let len_err = || DeserializeError::invalid_length(i, &self);
97                *byte = seq.next_element()?.ok_or_else(len_err)?;
98            }
99            let opt = C::from_bytes(&compressed);
100            if opt.is_some().into() {
101                Ok(opt.unwrap())
102            } else {
103                Err(DeserializeError::custom(ERR_CODE))
104            }
105        }
106    }
107
108    let len = C::Repr::default().as_ref().len();
109    d.deserialize_tuple(len, TupleVisitor { _ph: PhantomData })
110}
111
112impl Serialize for Scalar {
113    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
114        let bytes = self.to_bytes_le();
115        let u64s = [
116            u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[0..8]).unwrap()),
117            u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[8..16]).unwrap()),
118            u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[16..24]).unwrap()),
119            u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[24..32]).unwrap()),
120        ];
121        u64s.serialize(s)
122    }
123}
124
125impl<'de> Deserialize<'de> for Scalar {
126    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
127        let deser = <[u64; 4]>::deserialize(d)?;
128        match Scalar::from_u64s_le(&deser).into() {
129            Some(scalar) => Ok(scalar),
130            None => Err(D::Error::custom(ERR_CODE)),
131        }
132    }
133}
134
135impl Serialize for Fp {
136    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
137        let bytes = self.to_bytes_le();
138        let u64s = [
139            u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[0..8]).unwrap()),
140            u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[8..16]).unwrap()),
141            u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[16..24]).unwrap()),
142            u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[24..32]).unwrap()),
143            u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[32..40]).unwrap()),
144            u64::from_le_bytes(<[u8; 8]>::try_from(&bytes[40..48]).unwrap()),
145        ];
146        u64s.serialize(s)
147    }
148}
149
150impl<'de> Deserialize<'de> for MillerLoopResult {
151    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
152        let fp12 = Fp12::deserialize(d)?;
153        Ok(MillerLoopResult(fp12))
154    }
155}
156
157impl Serialize for MillerLoopResult {
158    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
159        self.0.serialize(s)
160    }
161}
162
163impl<'de> Deserialize<'de> for Gt {
164    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
165        let fp12 = Fp12::deserialize(d)?;
166        Ok(Gt(fp12))
167    }
168}
169
170impl Serialize for Gt {
171    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
172        self.0.serialize(s)
173    }
174}
175
176#[derive(Serialize, Deserialize)]
177struct Fp2Ser {
178    c0: Fp,
179    c1: Fp,
180}
181
182#[derive(Serialize, Deserialize)]
183struct Fp6Ser {
184    c0: Fp2,
185    c1: Fp2,
186    c2: Fp2,
187}
188
189#[derive(Serialize, Deserialize)]
190struct Fp12Ser {
191    c0: Fp6,
192    c1: Fp6,
193}
194
195impl Serialize for Fp2 {
196    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
197        Fp2Ser {
198            c0: self.c0(),
199            c1: self.c1(),
200        }
201        .serialize(s)
202    }
203}
204
205impl Serialize for Fp12 {
206    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
207        Fp12Ser {
208            c0: self.c0(),
209            c1: self.c1(),
210        }
211        .serialize(s)
212    }
213}
214
215impl Serialize for Fp6 {
216    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
217        Fp6Ser {
218            c0: self.c0(),
219            c1: self.c1(),
220            c2: self.c2(),
221        }
222        .serialize(s)
223    }
224}
225
226impl<'de> Deserialize<'de> for Fp {
227    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
228        let deser = <[u64; 6]>::deserialize(d)?;
229        match Fp::from_u64s_le(&deser).into() {
230            Some(fp) => Ok(fp),
231            None => Err(D::Error::custom(ERR_CODE)),
232        }
233    }
234}
235
236impl<'de> Deserialize<'de> for Fp2 {
237    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
238        let Fp2Ser { c0, c1 } = Fp2Ser::deserialize(d)?;
239        Ok(Fp2::new(c0, c1))
240    }
241}
242
243impl<'de> Deserialize<'de> for Fp6 {
244    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
245        let Fp6Ser { c0, c1, c2 } = Fp6Ser::deserialize(d)?;
246        Ok(Fp6::new(c0, c1, c2))
247    }
248}
249
250impl<'de> Deserialize<'de> for Fp12 {
251    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
252        let Fp12Ser { c0, c1 } = Fp12Ser::deserialize(d)?;
253        Ok(Fp12::new(c0, c1))
254    }
255}
256
257#[cfg(test)]
258mod tests {
259    use super::*;
260
261    use core::fmt::Debug;
262
263    use ff::Field;
264    use group::{Curve, Group};
265    use rand_core::SeedableRng;
266    use rand_xorshift::XorShiftRng;
267
268    fn test_roundtrip<T: Serialize + for<'a> Deserialize<'a> + Debug + PartialEq>(t: &T) {
269        // dbg!(t);
270        let ser = serde_json::to_vec(t).unwrap();
271        assert_eq!(*t, serde_json::from_slice(&ser).unwrap());
272    }
273
274    #[test]
275    fn serde_g1() {
276        let mut rng = XorShiftRng::from_seed([
277            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
278            0xbc, 0xe5,
279        ]);
280
281        for _ in 0..100 {
282            let g = G1Projective::random(&mut rng);
283            test_roundtrip(&g);
284            test_roundtrip(&g.to_affine());
285        }
286
287        let g = G1Projective::identity();
288        test_roundtrip(&g);
289        assert_eq!(
290            serde_json::from_slice::<G1Projective>(&hex::decode("5b3139322c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c305d").unwrap()).unwrap(),
291            g
292        );
293        test_roundtrip(&g.to_affine());
294        assert_eq!(
295            serde_json::from_slice::<G1Affine>(&hex::decode("5b3139322c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c305d").unwrap()).unwrap(),
296            g.to_affine(),
297        );
298
299        let g = G1Projective::generator();
300        test_roundtrip(&g);
301        assert_eq!(
302            serde_json::from_slice::<G1Projective>(&hex::decode("5b3135312c3234312c3231312c3136372c34392c3135312c3231352c3134382c33382c3134392c39392c3134302c37392c3136392c3137322c31352c3139352c3130342c3134302c37392c3135312c3131362c3138352c352c3136312c37382c35382c36332c32332c32372c3137322c38382c3130382c38352c3233322c36332c3234392c3132322c32362c3233392c3235312c35382c3234302c31302c3231392c33342c3139382c3138375d").unwrap()).unwrap(),
303            g
304        );
305        test_roundtrip(&g.to_affine());
306        assert_eq!(
307            serde_json::from_slice::<G1Affine>(&hex::decode("5b3135312c3234312c3231312c3136372c34392c3135312c3231352c3134382c33382c3134392c39392c3134302c37392c3136392c3137322c31352c3139352c3130342c3134302c37392c3135312c3131362c3138352c352c3136312c37382c35382c36332c32332c32372c3137322c38382c3130382c38352c3233322c36332c3234392c3132322c32362c3233392c3235312c35382c3234302c31302c3231392c33342c3139382c3138375d").unwrap()).unwrap(),
308            g.to_affine(),
309        );
310    }
311
312    #[test]
313    fn serde_g2() {
314        let mut rng = XorShiftRng::from_seed([
315            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
316            0xbc, 0xe5,
317        ]);
318
319        for _ in 0..100 {
320            let g = G2Projective::random(&mut rng);
321            test_roundtrip(&g);
322            test_roundtrip(&g.to_affine());
323        }
324
325        let g = G2Projective::identity();
326        test_roundtrip(&g);
327        assert_eq!(
328            serde_json::from_slice::<G2Projective>(&hex::decode("5b3139322c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c305d").unwrap()).unwrap(),
329            g
330        );
331        test_roundtrip(&g.to_affine());
332        assert_eq!(
333            serde_json::from_slice::<G2Affine>(&hex::decode("5b3139322c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c302c305d").unwrap()).unwrap(),
334            g.to_affine(),
335        );
336
337        let g = G2Projective::generator();
338        test_roundtrip(&g);
339        assert_eq!(
340            serde_json::from_slice::<G2Projective>(&hex::decode("5b3134372c3232342c34332c39362c38322c3131332c3135392c39362c3132352c3137322c3231312c3136302c3133362c33392c37392c3130312c38392c3130372c3230382c3230382c3135332c33322c3138322c32362c3138312c3231382c39372c3138372c3232302c3132372c38302c37332c35312c37362c3234312c31382c31392c3134382c39332c38372c3232392c3137322c3132352c352c39332c342c34332c3132362c322c37342c3136322c3137382c3234302c3134332c31302c3134352c33382c382c352c33392c34352c3139372c31362c38312c3139382c3232382c3132322c3231322c3235302c36342c35392c322c3138302c38312c31312c3130302c3132322c3232372c3230392c3131392c31312c3137322c332c33382c3136382c352c3138372c3233392c3231322c3132382c38362c3230302c3139332c33332c3138392c3138345d").unwrap()).unwrap(),
341            g
342        );
343        test_roundtrip(&g.to_affine());
344        assert_eq!(
345            serde_json::from_slice::<G2Affine>(&hex::decode("5b3134372c3232342c34332c39362c38322c3131332c3135392c39362c3132352c3137322c3231312c3136302c3133362c33392c37392c3130312c38392c3130372c3230382c3230382c3135332c33322c3138322c32362c3138312c3231382c39372c3138372c3232302c3132372c38302c37332c35312c37362c3234312c31382c31392c3134382c39332c38372c3232392c3137322c3132352c352c39332c342c34332c3132362c322c37342c3136322c3137382c3234302c3134332c31302c3134352c33382c382c352c33392c34352c3139372c31362c38312c3139382c3232382c3132322c3231322c3235302c36342c35392c322c3138302c38312c31312c3130302c3132322c3232372c3230392c3131392c31312c3137322c332c33382c3136382c352c3138372c3233392c3231322c3132382c38362c3230302c3139332c33332c3138392c3138345d").unwrap()).unwrap(),
346            g.to_affine()
347        );
348    }
349
350    #[test]
351    fn serde_scalar() {
352        let mut rng = XorShiftRng::from_seed([
353            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
354            0xbc, 0xe5,
355        ]);
356        for _ in 0..100 {
357            let f = Scalar::random(&mut rng);
358            test_roundtrip(&f);
359        }
360
361        let f = Scalar::ZERO;
362        test_roundtrip(&f);
363        // The hex string "5b302c302c302c305d" encodes the unicode string "[0,0,0,0]" where each
364        // byte in the hex string encodes a unicode character: 0x58 = "[", 0x30 = "0", 0x2c = ",",
365        // and 0x5d = "]".
366        assert_eq!(
367            serde_json::from_slice::<Scalar>(&hex::decode("5b302c302c302c305d").unwrap()).unwrap(),
368            f
369        );
370
371        let f = Scalar::ONE;
372        test_roundtrip(&f);
373        assert_eq!(
374            serde_json::from_slice::<Scalar>(&hex::decode("5b312c302c302c305d").unwrap()).unwrap(),
375            f
376        );
377    }
378
379    #[test]
380    fn serde_fp() {
381        let mut rng = XorShiftRng::from_seed([
382            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
383            0xbc, 0xe5,
384        ]);
385
386        for _ in 0..100 {
387            let f = Fp::random(&mut rng);
388            test_roundtrip(&f);
389        }
390
391        let f = Fp::ZERO;
392        test_roundtrip(&f);
393        assert_eq!(
394            serde_json::from_slice::<Fp>(&hex::decode("5b302c302c302c302c302c305d").unwrap())
395                .unwrap(),
396            f
397        );
398
399        let f = Fp::ONE;
400        test_roundtrip(&f);
401        assert_eq!(
402            serde_json::from_slice::<Fp>(&hex::decode("5b312c302c302c302c302c305d").unwrap())
403                .unwrap(),
404            f
405        );
406    }
407
408    #[test]
409    fn serde_fp12() {
410        let mut rng = XorShiftRng::from_seed([
411            0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06,
412            0xbc, 0xe5,
413        ]);
414        for _ in 0..100 {
415            let f = Fp12::random(&mut rng);
416            test_roundtrip(&f);
417        }
418
419        let f = Fp12::ZERO;
420        test_roundtrip(&f);
421        assert_eq!(
422            serde_json::from_slice::<Fp12>(&hex::decode("7b226330223a7b226330223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d2c226331223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d2c226332223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d7d2c226331223a7b226330223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d2c226331223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d2c226332223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d7d7d").unwrap()).unwrap(),
423            f
424        );
425
426        let f = Fp12::ONE;
427        test_roundtrip(&f);
428        assert_eq!(
429            serde_json::from_slice::<Fp12>(&hex::decode("7b226330223a7b226330223a7b226330223a5b312c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d2c226331223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d2c226332223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d7d2c226331223a7b226330223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d2c226331223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d2c226332223a7b226330223a5b302c302c302c302c302c305d2c226331223a5b302c302c302c302c302c305d7d7d7d").unwrap()).unwrap(),
430            f
431        );
432    }
433}