Skip to main content

indy_crypto/pair/
amcl.rs

1use errors::prelude::*;
2
3use amcl::bn254::big::BIG;
4
5use amcl::bn254::rom::{
6    CURVE_GX,
7    CURVE_GY,
8    CURVE_ORDER,
9    CURVE_PXA,
10    CURVE_PYA,
11    CURVE_PXB,
12    CURVE_PYB,
13    MODBYTES
14};
15
16use amcl::bn254::ecp::ECP;
17use amcl::bn254::ecp2::ECP2;
18use amcl::bn254::fp12::FP12;
19use amcl::bn254::fp2::FP2;
20use amcl::bn254::pair::{ate, g1mul, g2mul, gtpow, fexp};
21use amcl::rand::RAND;
22
23use rand::os::OsRng;
24use rand::Rng;
25use std::fmt::{Debug, Formatter, Error};
26
27#[cfg(feature = "serialization")]
28use serde::ser::{Serialize, Serializer, Error as SError};
29#[cfg(feature = "serialization")]
30use serde::de::{Deserialize, Deserializer, Visitor, Error as DError};
31#[cfg(feature = "serialization")]
32use std::fmt;
33
34#[cfg(test)]
35use std::cell::RefCell;
36
37#[cfg(test)]
38thread_local! {
39  pub static PAIR_USE_MOCKS: RefCell<bool> = RefCell::new(false);
40}
41
42#[cfg(test)]
43pub struct PairMocksHelper {}
44
45#[cfg(test)]
46impl PairMocksHelper {
47    pub fn inject() {
48        PAIR_USE_MOCKS.with(|use_mocks| {
49            *use_mocks.borrow_mut() = true;
50        });
51    }
52
53    pub fn is_injected() -> bool {
54        PAIR_USE_MOCKS.with(|use_mocks| {
55            return *use_mocks.borrow();
56        })
57    }
58}
59
60#[cfg(not(test))]
61fn random_mod_order() -> IndyCryptoResult<BIG> {
62    _random_mod_order()
63}
64
65#[cfg(test)]
66fn random_mod_order() -> IndyCryptoResult<BIG> {
67    if PairMocksHelper::is_injected() {
68        Ok(BIG::from_hex("22EB5716FB01F2122DE924466542B923D8C96F16C9B5FE2C00B7D7DC1499EA50".to_string()))
69    }
70    else {
71        _random_mod_order()
72    }
73}
74
75fn _random_mod_order() -> IndyCryptoResult<BIG> {
76    let entropy_bytes = 128;
77    let mut seed = vec![0; entropy_bytes];
78    let mut os_rng = OsRng::new().unwrap();
79    os_rng.fill_bytes(&mut seed.as_mut_slice());
80    let mut rng = RAND::new();
81    rng.clean();
82    // AMCL recommends to initialise from at least 128 bytes, check doc for `RAND.seed`
83    rng.seed(entropy_bytes, &seed);
84    Ok(BIG::randomnum(&BIG::new_ints(&CURVE_ORDER), &mut rng))
85}
86
87#[derive(Copy, Clone, PartialEq)]
88pub struct PointG1 {
89    point: ECP
90}
91
92impl PointG1 {
93    pub const BYTES_REPR_SIZE: usize = MODBYTES * 4;
94
95    /// Creates new random PointG1
96    pub fn new() -> IndyCryptoResult<PointG1> {
97        // generate random point from the group G1
98        let point_x = BIG::new_ints(&CURVE_GX);
99        let point_y = BIG::new_ints(&CURVE_GY);
100        let mut gen_g1 = ECP::new_bigs(&point_x, &point_y);
101
102        let point = g1mul(&mut gen_g1, &mut random_mod_order()?);
103
104        Ok(PointG1 {
105            point: point
106        })
107    }
108
109    /// Creates new infinity PointG1
110    pub fn new_inf() -> IndyCryptoResult<PointG1> {
111        let mut r = ECP::new();
112        r.inf();
113        Ok(PointG1 {
114            point: r
115        })
116    }
117
118    /// Checks infinity
119    pub fn is_inf(&self) -> IndyCryptoResult<bool> {
120        Ok(self.point.is_infinity())
121    }
122
123    /// PointG1 ^ GroupOrderElement
124    pub fn mul(&self, e: &GroupOrderElement) -> IndyCryptoResult<PointG1> {
125        let mut r = self.point;
126        let mut bn = e.bn;
127        Ok(PointG1 {
128            point: g1mul(&mut r, &mut bn)
129        })
130    }
131
132    /// PointG1 * PointG1
133    pub fn add(&self, q: &PointG1) -> IndyCryptoResult<PointG1> {
134        let mut r = self.point;
135        let mut point = q.point;
136        r.add(&mut point);
137        Ok(PointG1 {
138            point: r
139        })
140    }
141
142    /// PointG1 / PointG1
143    pub fn sub(&self, q: &PointG1) -> IndyCryptoResult<PointG1> {
144        let mut r = self.point;
145        let mut point = q.point;
146        r.sub(&mut point);
147        Ok(PointG1 {
148            point: r
149        })
150    }
151
152    /// 1 / PointG1
153    pub fn neg(&self) -> IndyCryptoResult<PointG1> {
154        let mut r = self.point;
155        r.neg();
156        Ok(PointG1 {
157            point: r
158        })
159    }
160
161    pub fn to_string(&self) -> IndyCryptoResult<String> {
162        Ok(self.point.to_hex())
163    }
164
165    pub fn from_string(str: &str) -> IndyCryptoResult<PointG1> {
166        Ok(PointG1 {
167            point: ECP::from_hex(str.to_string())
168        })
169    }
170
171    pub fn to_bytes(&self) -> IndyCryptoResult<Vec<u8>> {
172        let mut vec = vec![0u8; Self::BYTES_REPR_SIZE];
173        self.point.tobytes(&mut vec, false);
174        Ok(vec)
175    }
176
177    pub fn from_bytes(b: &[u8]) -> IndyCryptoResult<PointG1> {
178        if b.len() != Self::BYTES_REPR_SIZE {
179            return Err(err_msg(IndyCryptoErrorKind::InvalidStructure, "Invalid len of bytes representation for PointG1"));
180        }
181        Ok(
182            PointG1 {
183                point: ECP::frombytes(b)
184            }
185        )
186    }
187
188    pub fn from_hash(hash: &[u8]) -> IndyCryptoResult<PointG1> {
189        let mut el = GroupOrderElement::from_bytes(hash)?;
190        let mut point = ECP::new_big(&el.bn);
191
192        while point.is_infinity() {
193            el.bn.inc(1);
194            point = ECP::new_big(&el.bn);
195        }
196
197        Ok(PointG1 {
198            point: point
199        })
200    }
201}
202
203impl Debug for PointG1 {
204    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
205        write!(f, "PointG1 {{ point: {} }}", self.point.to_hex())
206    }
207}
208
209#[cfg(feature = "serialization")]
210impl Serialize for PointG1 {
211    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
212        serializer.serialize_newtype_struct("PointG1", &self.to_string().map_err(SError::custom)?)
213    }
214}
215
216#[cfg(feature = "serialization")]
217impl<'a> Deserialize<'a> for PointG1 {
218    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'a> {
219        struct PointG1Visitor;
220
221        impl<'a> Visitor<'a> for PointG1Visitor {
222            type Value = PointG1;
223
224            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
225                formatter.write_str("expected PointG1")
226            }
227
228            fn visit_str<E>(self, value: &str) -> Result<PointG1, E>
229                where E: DError
230            {
231                Ok(PointG1::from_string(value).map_err(DError::custom)?)
232            }
233        }
234
235        deserializer.deserialize_str(PointG1Visitor)
236    }
237}
238
239#[derive(Copy, Clone, PartialEq)]
240pub struct PointG2 {
241    point: ECP2
242}
243
244impl PointG2 {
245    pub const BYTES_REPR_SIZE: usize = MODBYTES * 4;
246
247    /// Creates new random PointG2
248    pub fn new() -> IndyCryptoResult<PointG2> {
249        let point_xa = BIG::new_ints(&CURVE_PXA);
250        let point_xb = BIG::new_ints(&CURVE_PXB);
251        let point_ya = BIG::new_ints(&CURVE_PYA);
252        let point_yb = BIG::new_ints(&CURVE_PYB);
253
254        let point_x = FP2::new_bigs(&point_xa, &point_xb);
255        let point_y = FP2::new_bigs(&point_ya, &point_yb);
256
257        let mut gen_g2 = ECP2::new_fp2s(&point_x, &point_y);
258
259        let point = g2mul(&mut gen_g2, &mut random_mod_order()?);
260
261        Ok(PointG2 {
262            point: point
263        })
264    }
265
266    /// Creates new infinity PointG2
267    pub fn new_inf() -> IndyCryptoResult<PointG2> {
268        let mut point = ECP2::new();
269        point.inf();
270
271        Ok(PointG2 {
272            point: point
273        })
274    }
275
276    /// PointG2 * PointG2
277    pub fn add(&self, q: &PointG2) -> IndyCryptoResult<PointG2> {
278        let mut r = self.point;
279        let mut point = q.point;
280        r.add(&mut point);
281
282        Ok(PointG2 {
283            point: r
284        })
285    }
286
287    /// PointG2 / PointG2
288    pub fn sub(&self, q: &PointG2) -> IndyCryptoResult<PointG2> {
289        let mut r = self.point;
290        let mut point = q.point;
291        r.sub(&mut point);
292
293        Ok(PointG2 {
294            point: r
295        })
296    }
297
298    /// PointG2 ^ GroupOrderElement
299    pub fn mul(&self, e: &GroupOrderElement) -> IndyCryptoResult<PointG2> {
300        let mut r = self.point;
301        let mut bn = e.bn;
302        Ok(PointG2 {
303            point: g2mul(&mut r, &mut bn)
304        })
305    }
306
307    pub fn to_string(&self) -> IndyCryptoResult<String> {
308        Ok(self.point.to_hex())
309    }
310
311    pub fn from_string(str: &str) -> IndyCryptoResult<PointG2> {
312        Ok(PointG2 {
313            point: ECP2::from_hex(str.to_string())
314        })
315    }
316
317    pub fn to_bytes(&self) -> IndyCryptoResult<Vec<u8>> {
318        let mut vec = vec![0u8; Self::BYTES_REPR_SIZE];
319        self.point.tobytes(&mut vec);
320        Ok(vec)
321    }
322
323    pub fn from_bytes(b: &[u8]) -> IndyCryptoResult<PointG2> {
324        if b.len() != Self::BYTES_REPR_SIZE {
325            return Err(err_msg(IndyCryptoErrorKind::InvalidStructure, "Invalid len of bytes representation for PoingG2"));
326        }
327        Ok(
328            PointG2 {
329                point: ECP2::frombytes(b)
330            }
331        )
332    }
333}
334
335impl Debug for PointG2 {
336    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
337        write!(f, "PointG2 {{ point: {} }}", self.point.to_hex())
338    }
339}
340
341#[cfg(feature = "serialization")]
342impl Serialize for PointG2 {
343    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
344        serializer.serialize_newtype_struct("PointG2", &self.to_string().map_err(SError::custom)?)
345    }
346}
347
348#[cfg(feature = "serialization")]
349impl<'a> Deserialize<'a> for PointG2 {
350    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'a> {
351        struct PointG2Visitor;
352
353        impl<'a> Visitor<'a> for PointG2Visitor {
354            type Value = PointG2;
355
356            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
357                formatter.write_str("expected PointG2")
358            }
359
360            fn visit_str<E>(self, value: &str) -> Result<PointG2, E>
361                where E: DError
362            {
363                Ok(PointG2::from_string(value).map_err(DError::custom)?)
364            }
365        }
366
367        deserializer.deserialize_str(PointG2Visitor)
368    }
369}
370
371#[derive(Copy, Clone, PartialEq)]
372pub struct GroupOrderElement {
373    bn: BIG
374}
375
376impl GroupOrderElement {
377    pub const BYTES_REPR_SIZE: usize = MODBYTES;
378
379    pub fn new() -> IndyCryptoResult<GroupOrderElement> {
380        // returns random element in 0, ..., GroupOrder-1
381        Ok(GroupOrderElement {
382            bn: random_mod_order()?
383        })
384    }
385
386    pub fn new_from_seed(seed: &[u8]) -> IndyCryptoResult<GroupOrderElement> {
387        // returns random element in 0, ..., GroupOrder-1
388        if seed.len() != MODBYTES {
389            return Err(err_msg(IndyCryptoErrorKind::InvalidStructure, format!("Invalid len of seed: expected {}, actual {}", MODBYTES, seed.len())));
390        }
391        let mut rng = RAND::new();
392        rng.clean();
393        rng.seed(seed.len(), seed);
394
395        Ok(GroupOrderElement {
396            bn: BIG::randomnum(&BIG::new_ints(&CURVE_ORDER), &mut rng)
397        })
398    }
399
400    /// (GroupOrderElement ^ GroupOrderElement) mod GroupOrder
401    pub fn pow_mod(&self, e: &GroupOrderElement) -> IndyCryptoResult<GroupOrderElement> {
402        let mut base = self.bn;
403        let mut pow = e.bn;
404        Ok(GroupOrderElement {
405            bn: base.powmod(&mut pow, &BIG::new_ints(&CURVE_ORDER))
406        })
407    }
408
409    /// (GroupOrderElement + GroupOrderElement) mod GroupOrder
410    pub fn add_mod(&self, r: &GroupOrderElement) -> IndyCryptoResult<GroupOrderElement> {
411        let mut sum = self.bn;
412        sum.add(&r.bn);
413        sum.rmod(&BIG::new_ints(&CURVE_ORDER));
414        Ok(GroupOrderElement {
415            bn: sum
416        })
417    }
418
419    /// (GroupOrderElement - GroupOrderElement) mod GroupOrder
420    pub fn sub_mod(&self, r: &GroupOrderElement) -> IndyCryptoResult<GroupOrderElement> {
421        //need to use modneg if sub is negative
422        let mut diff = self.bn;
423        diff.sub(&r.bn);
424        let mut zero = BIG::new();
425        zero.zero();
426
427        if diff < zero {
428            return Ok(GroupOrderElement {
429                bn: BIG::modneg(&mut diff, &BIG::new_ints(&CURVE_ORDER))
430            });
431        }
432
433        Ok(GroupOrderElement {
434            bn: diff
435        })
436    }
437
438    /// (GroupOrderElement * GroupOrderElement) mod GroupOrder
439    pub fn mul_mod(&self, r: &GroupOrderElement) -> IndyCryptoResult<GroupOrderElement> {
440        let mut base = self.bn;
441        let mut r = r.bn;
442        Ok(GroupOrderElement {
443            bn: BIG::modmul(&mut base, &mut r, &BIG::new_ints(&CURVE_ORDER))
444        })
445    }
446
447    /// 1 / GroupOrderElement
448    pub fn inverse(&self) -> IndyCryptoResult<GroupOrderElement> {
449        let mut bn = self.bn;
450        bn.invmodp(&BIG::new_ints(&CURVE_ORDER));
451
452        Ok(GroupOrderElement {
453            bn: bn
454        })
455    }
456
457    /// - GroupOrderElement mod GroupOrder
458    pub fn mod_neg(&self) -> IndyCryptoResult<GroupOrderElement> {
459        let mut r = self.bn;
460        r = BIG::modneg(&mut r, &BIG::new_ints(&CURVE_ORDER));
461        Ok(GroupOrderElement {
462            bn: r
463        })
464    }
465
466    pub fn to_string(&self) -> IndyCryptoResult<String> {
467        let mut bn = self.bn;
468        Ok(bn.to_hex())
469    }
470
471    pub fn from_string(str: &str) -> IndyCryptoResult<GroupOrderElement> {
472        Ok(GroupOrderElement {
473            bn: BIG::from_hex(str.to_string())
474        })
475    }
476
477    pub fn to_bytes(&self) -> IndyCryptoResult<Vec<u8>> {
478        let mut bn = self.bn;
479        let mut vec = vec![0u8; Self::BYTES_REPR_SIZE];
480        bn.tobytes(&mut vec);
481        Ok(vec)
482    }
483
484    pub fn from_bytes(b: &[u8]) -> IndyCryptoResult<GroupOrderElement> {
485        if b.len() > Self::BYTES_REPR_SIZE {
486            return Err(err_msg(IndyCryptoErrorKind::InvalidStructure, "Invalid len of bytes representation for GroupOrderElement"));
487        }
488        let mut vec = b.to_vec();
489        let len = vec.len();
490        if len < MODBYTES {
491            let diff = MODBYTES - len;
492            let mut result = vec![0; diff];
493            result.append(&mut vec);
494            return Ok(
495                GroupOrderElement {
496                    bn: BIG::frombytes(&result)
497                }
498            );
499        }
500        Ok(
501            GroupOrderElement {
502                bn: BIG::frombytes(b)
503            }
504        )
505    }
506}
507
508impl Debug for GroupOrderElement {
509    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
510        let mut bn = self.bn;
511        write!(f, "GroupOrderElement {{ bn: {} }}", bn.to_hex())
512    }
513}
514
515#[cfg(feature = "serialization")]
516impl Serialize for GroupOrderElement {
517    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
518        serializer.serialize_newtype_struct("GroupOrderElement", &self.to_string().map_err(SError::custom)?)
519    }
520}
521
522#[cfg(feature = "serialization")]
523impl<'a> Deserialize<'a> for GroupOrderElement {
524    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'a> {
525        struct GroupOrderElementVisitor;
526
527        impl<'a> Visitor<'a> for GroupOrderElementVisitor {
528            type Value = GroupOrderElement;
529
530            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
531                formatter.write_str("expected GroupOrderElement")
532            }
533
534            fn visit_str<E>(self, value: &str) -> Result<GroupOrderElement, E>
535                where E: DError
536            {
537                Ok(GroupOrderElement::from_string(value).map_err(DError::custom)?)
538            }
539        }
540
541        deserializer.deserialize_str(GroupOrderElementVisitor)
542    }
543}
544
545#[derive(Copy, Clone, PartialEq)]
546pub struct Pair {
547    pair: FP12
548}
549
550impl Pair {
551    pub const BYTES_REPR_SIZE: usize = MODBYTES * 16;
552    /// e(PointG1, PointG2)
553    pub fn pair(p: &PointG1, q: &PointG2) -> IndyCryptoResult<Pair> {
554        let mut p_new = *p;
555        let mut q_new = *q;
556        let mut result = fexp(&ate(&mut q_new.point, &mut p_new.point));
557        result.reduce();
558
559        Ok(Pair {
560            pair: result
561        })
562    }
563
564    /// e() * e()
565    pub fn mul(&self, b: &Pair) -> IndyCryptoResult<Pair> {
566        let mut base = self.pair;
567        let mut b = b.pair;
568        base.mul(&mut b);
569        base.reduce();
570        Ok(Pair {
571            pair: base
572        })
573    }
574
575    /// e() ^ GroupOrderElement
576    pub fn pow(&self, b: &GroupOrderElement) -> IndyCryptoResult<Pair> {
577        let mut base = self.pair;
578        let mut b = b.bn;
579
580        Ok(Pair {
581            pair: gtpow(&mut base, &mut b)
582        })
583    }
584
585    /// 1 / e()
586    pub fn inverse(&self) -> IndyCryptoResult<Pair> {
587        let mut r = self.pair;
588        r.conj();
589        Ok(Pair {
590            pair: r
591        })
592    }
593
594    pub fn to_string(&self) -> IndyCryptoResult<String> {
595        Ok(self.pair.to_hex())
596    }
597
598    pub fn from_string(str: &str) -> IndyCryptoResult<Pair> {
599        Ok(Pair {
600            pair: FP12::from_hex(str.to_string())
601        })
602    }
603
604    pub fn to_bytes(&self) -> IndyCryptoResult<Vec<u8>> {
605        let mut r = self.pair;
606        let mut vec = vec![0u8; Self::BYTES_REPR_SIZE];
607        r.tobytes(&mut vec);
608        Ok(vec)
609    }
610}
611
612impl Debug for Pair {
613    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
614        write!(f, "Pair {{ pair: {} }}", self.pair.to_hex())
615    }
616}
617
618#[cfg(feature = "serialization")]
619impl Serialize for Pair {
620    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
621        serializer.serialize_newtype_struct("Pair", &self.to_string().map_err(SError::custom)?)
622    }
623}
624
625#[cfg(feature = "serialization")]
626impl<'a> Deserialize<'a> for Pair {
627    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'a> {
628        struct PairVisitor;
629
630        impl<'a> Visitor<'a> for PairVisitor {
631            type Value = Pair;
632
633            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
634                formatter.write_str("expected Pair")
635            }
636
637            fn visit_str<E>(self, value: &str) -> Result<Pair, E>
638                where E: DError
639            {
640                Ok(Pair::from_string(value).map_err(DError::custom)?)
641            }
642        }
643
644        deserializer.deserialize_str(PairVisitor)
645    }
646}
647
648#[cfg(test)]
649mod tests {
650    use super::*;
651
652    #[test]
653    fn group_order_element_new_from_seed_works_for_invalid_seed_len() {
654        let err = GroupOrderElement::new_from_seed(&[0, 1, 2]).unwrap_err();
655        assert_eq!(err.kind(), IndyCryptoErrorKind::InvalidStructure);
656    }
657
658    #[test]
659    fn pairing_definition_bilinearity() {
660        let a = GroupOrderElement::new().unwrap();
661        let b = GroupOrderElement::new().unwrap();
662        let p = PointG1::new().unwrap();
663        let q = PointG2::new().unwrap();
664        let left = Pair::pair(&p.mul(&a).unwrap(), &q.mul(&b).unwrap()).unwrap();
665        let right = Pair::pair(&p, &q).unwrap().pow(&a.mul_mod(&b).unwrap()).unwrap();
666        assert_eq!(left, right);
667    }
668
669    #[test]
670    fn point_g1_infinity_test() {
671        let p = PointG1::new_inf().unwrap();
672        let q = PointG1::new().unwrap();
673        let result = p.add(&q).unwrap();
674        assert_eq!(q, result);
675    }
676
677    #[test]
678    fn point_g1_infinity_test2() {
679        let p = PointG1::new().unwrap();
680        let inf = p.sub(&p).unwrap();
681        let q = PointG1::new().unwrap();
682        let result = inf.add(&q).unwrap();
683        assert_eq!(q, result);
684    }
685
686    #[test]
687    fn point_g2_infinity_test() {
688        let p = PointG2::new_inf().unwrap();
689        let q = PointG2::new().unwrap();
690        let result = p.add(&q).unwrap();
691        assert_eq!(q, result);
692    }
693
694    #[test]
695    fn inverse_for_pairing() {
696        let p1 = PointG1::new().unwrap();
697        let q1 = PointG2::new().unwrap();
698        let p2 = PointG1::new().unwrap();
699        let q2 = PointG2::new().unwrap();
700        let pair1 = Pair::pair(&p1, &q1).unwrap();
701        let pair2 = Pair::pair(&p2, &q2).unwrap();
702        let pair_result = pair1.mul(&pair2).unwrap();
703        let pair3 = pair_result.mul(&pair1.inverse().unwrap()).unwrap();
704        assert_eq!(pair2, pair3);
705    }
706}
707
708#[cfg(feature = "serialization")]
709#[cfg(test)]
710mod serialization_tests {
711    use super::*;
712
713    extern crate serde_json;
714
715    #[derive(Serialize, Deserialize, Debug, PartialEq)]
716    struct TestGroupOrderElementStructure {
717        field: GroupOrderElement
718    }
719
720    #[derive(Serialize, Deserialize, Debug, PartialEq)]
721    struct TestPointG1Structure {
722        field: PointG1
723    }
724
725    #[derive(Serialize, Deserialize, Debug, PartialEq)]
726    struct TestPointG2Structure {
727        field: PointG2
728    }
729
730    #[derive(Serialize, Deserialize, Debug, PartialEq)]
731    struct TestPairStructure {
732        field: Pair
733    }
734
735    #[test]
736    fn from_bytes_to_bytes_works_for_group_order_element() {
737        let vec = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 116, 221, 243, 243, 0, 77, 170, 65, 179, 245, 119, 182, 251, 185, 78, 98];
738        let bytes = GroupOrderElement::from_bytes(&vec).unwrap();
739        let result = bytes.to_bytes().unwrap();
740        assert_eq!(vec, result);
741    }
742
743    #[test]
744    fn serialize_deserialize_works_for_group_order_element() {
745        let structure = TestGroupOrderElementStructure {
746            field: GroupOrderElement::from_string("09181F00DD41F2F92026FC20E189DE31926EEE6E05C6A17E676556E08075C6111").unwrap()
747        };
748        let deserialized: TestGroupOrderElementStructure = serde_json::from_str(&serde_json::to_string(&structure).unwrap()).unwrap();
749
750        assert_eq!(structure, deserialized);
751    }
752
753    #[test]
754    fn serialize_deserialize_works_for_point_g1() {
755        let structure = TestPointG1Structure {
756            field: PointG1::from_string("1 09181F00DD41F2F92026FC20E189DE31926EEE6E05C6A17E676556E08075C6 1 09BC971251F977993486B19600760C4F972925D98934EA6B2D0BEC671398C0 1 095E45DDF417D05FB10933FFC63D474548B7FFFF7888802F07FFFFFF7D07A8").unwrap()
757        };
758
759        let deserialized: TestPointG1Structure = serde_json::from_str(&serde_json::to_string(&structure).unwrap()).unwrap();
760
761        assert_eq!(structure, deserialized);
762    }
763
764    #[test]
765    fn deserialize_works_for_point_g2() {
766        let structure = TestPointG2Structure {
767            field: PointG2::from_string("1 16027A65C15E16E00BFCAD948F216B5CFBE07B98876D8889A5DEE03DE7C57B 1 0EC9DBC2286A9485A0DA8525C5BE0F88E27C2B3C337E522DDC170C1764D615 1 1A021C8EFE70DCC7F81DD8E8CDC74F3D64E63E886C73B3A8B9849696E99FF3 1 2505CB0CFAAE75ACCAF60CB5A9F7E7A8250918155886E7FFF9A32D7B5A0500 1 095E45DDF417D05FB10933FFC63D474548B7FFFF7888802F07FFFFFF7D07A8 1 00000000000000000000000000000000000000000000000000000000000000").unwrap()
768        };
769        let deserialized: TestPointG2Structure = serde_json::from_str(&serde_json::to_string(&structure).unwrap()).unwrap();
770
771        assert_eq!(structure, deserialized);
772    }
773
774    #[test]
775    fn deserialize_works_for_big_sum() {
776        let mut big = ECP2::from_hex("1 7A574E39839EBC8E7F8D567865D5D9AAC54952659F0E393BE35C7FC3BE93CDA6 1 AFB9BF4A3B655BFFDC89C14720101773569FDD36A67440AEB7C2FFB861B74025 1 1F25D2A75390350C9C77DE886B503D5EA2CC3685037460F9CF93601BFA88028E 1 306E80C709AAA293B8D2AAABF04838C8AB96BFB3F8E0C4A89940D227A8BF8B01 1 6867E792BBE850A8716C97F7140D95FD6DB76C5DB0F4876E800B18E2CB0226B3 1 427CB9FC452B316239ABCA9C0078E5F36B4E9FC777B6D91587BB7DA64C1C1E94".to_string());
777        let mut big_2 = big.clone();
778        big.add(&mut big_2);
779        let deserialized = ECP2::from_hex(big.to_hex());
780        assert_eq!(deserialized, big);
781    }
782
783    #[test]
784    fn serialize_deserialize_works_for_pair() {
785        let point_g1 = PointG1 {
786            point: PointG1::from_string("1 01FC3950C5B03061739A4621E205643FDCC1BFE2AC0F2996F46944F7AC340B 1 1056E3F5EE2EA7F7E340764B7BE8A38AAFE66C25573880810726812069BB11 1 095E45DDF417D05FB10933FFC63D474548B7FFFF7888802F07FFFFFF7D07A8").unwrap().point
787        };
788        let point_g2 = PointG2 {
789            point: PointG2::from_string("1 16027A65C15E16E00BFCAD948F216B5CFBE07B98876D8889A5DEE03DE7C57B 1 0EC9DBC2286A9485A0DA8525C5BE0F88E27C2B3C337E522DDC170C1764D615 1 1A021C8EFE70DCC7F81DD8E8CDC74F3D64E63E886C73B3A8B9849696E99FF3 1 2505CB0CFAAE75ACCAF60CB5A9F7E7A8250918155886E7FFF9A32D7B5A0500 1 095E45DDF417D05FB10933FFC63D474548B7FFFF7888802F07FFFFFF7D07A8 1 00000000000000000000000000000000000000000000000000000000000000").unwrap().point
790        };
791        let pair = TestPairStructure {
792            field: Pair::pair(&point_g1, &point_g2).unwrap()
793        };
794        let deserialized: TestPairStructure = serde_json::from_str(&serde_json::to_string(&pair).unwrap()).unwrap();
795
796        assert_eq!(pair, deserialized);
797    }
798}