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 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 pub fn new() -> IndyCryptoResult<PointG1> {
97 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 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 pub fn is_inf(&self) -> IndyCryptoResult<bool> {
120 Ok(self.point.is_infinity())
121 }
122
123 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 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 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 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 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 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 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 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 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 Ok(GroupOrderElement {
382 bn: random_mod_order()?
383 })
384 }
385
386 pub fn new_from_seed(seed: &[u8]) -> IndyCryptoResult<GroupOrderElement> {
387 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 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 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 pub fn sub_mod(&self, r: &GroupOrderElement) -> IndyCryptoResult<GroupOrderElement> {
421 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 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 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 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 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 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 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 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}