amcl_wrapper/
group_elem_g2.rs1use crate::amcl::hmac;
2use crate::constants::{CurveOrder, GroupG2_SIZE, G2_COMP_BYTE_SIZE, HASH_TYPE};
3use crate::errors::{SerzDeserzError, ValueError};
4use crate::field_elem::{FieldElement, FieldElementVector};
5use crate::group_elem::{GroupElement, GroupElementVector};
6use crate::types::{GroupG2, FP, FP2};
7use crate::utils::{hash_msg, hash_to_field};
8use std::iter;
9use std::ops::{Add, AddAssign, Index, IndexMut, Mul, Neg, Sub, SubAssign};
10
11use core::fmt;
12use std::hash::{Hash, Hasher};
13use std::slice::Iter;
14
15use crate::rayon::iter::IntoParallelRefMutIterator;
16use rayon::prelude::*;
17use serde::de::{Deserialize, Deserializer, Error as DError, Visitor};
18use serde::ser::{Error as SError, Serialize, Serializer};
19use zeroize::Zeroize;
20
21#[derive(Clone)]
23pub struct G2 {
24 value: GroupG2,
25}
26
27impl fmt::Debug for G2 {
28 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
29 write!(f, "ECP2: [ {} ]", self.value.tostring())
30 }
31}
32
33impl GroupElement for G2 {
34 fn new() -> Self {
35 Self {
36 value: GroupG2::new(),
37 }
38 }
39
40 fn identity() -> Self {
41 let mut v = GroupG2::new();
42 v.inf();
43 Self { value: v }
44 }
45
46 fn generator() -> Self {
48 GroupG2::generator().into()
49 }
50
51 fn is_identity(&self) -> bool {
52 self.value.is_infinity()
53 }
54
55 fn set_to_identity(&mut self) {
56 self.value.inf()
57 }
58
59 fn from_msg_hash(msg: &[u8]) -> Self {
60 GroupG2::mapit(&hash_msg(msg)).into()
61 }
62
63 impl_group_elem_byte_conversion_methods!(
64 GroupG2,
65 GroupG2_SIZE,
66 G2_COMP_BYTE_SIZE,
67 SerzDeserzError::G2BytesIncorrectSize
68 );
69
70 fn add_assign_(&mut self, b: &Self) {
71 self.value.add(&b.value);
72 }
73
74 fn sub_assign_(&mut self, b: &Self) {
75 self.value.sub(&b.value);
76 }
77
78 fn plus(&self, b: &Self) -> Self {
79 let mut sum = self.value.clone();
80 sum.add(&b.value);
81 sum.into()
82 }
83
84 fn minus(&self, b: &Self) -> Self {
85 let mut diff = self.value.clone();
86 diff.sub(&b.value);
87 diff.into()
88 }
89
90 fn scalar_mul_const_time(&self, a: &FieldElement) -> Self {
91 self.value.mul(&a.to_bignum()).into()
92 }
93
94 fn double(&self) -> Self {
95 let mut d = self.value.clone();
96 d.dbl();
97 d.into()
98 }
99
100 fn double_mut(&mut self) {
101 self.value.dbl();
102 }
103
104 fn to_hex(&self) -> String {
107 self.value.tostring()
108 }
109
110 fn from_hex(mut string: String) -> Result<Self, SerzDeserzError> {
111 if &string == "infinity" {
112 return Ok(Self::new());
113 }
114
115 unbound_bounded_string!(string, '(', ')', SerzDeserzError::CannotParseG2);
117
118 let (x, y) = split_string_to_2_tuple!(string, SerzDeserzError::CannotParseG2);
119
120 let x_fp2 = parse_hex_as_FP2(x)?;
121 let y_fp2 = parse_hex_as_FP2(y)?;
122
123 Ok(Self {
124 value: GroupG2::new_fp2s(&x_fp2, &y_fp2),
125 })
126 }
127
128 fn negation(&self) -> Self {
129 let mut n = self.to_ecp();
130 n.neg();
131 n.into()
132 }
133
134 fn is_extension() -> bool {
135 return true;
136 }
137
138 fn has_correct_order(&self) -> bool {
139 return self.value.mul(&CurveOrder).is_infinity();
140 }
141}
142
143pub fn parse_hex_as_FP2(mut string: String) -> Result<FP2, SerzDeserzError> {
145 unbound_bounded_string!(string, '[', ']', SerzDeserzError::CannotParseFP2);
147
148 let (a, b) = split_string_to_2_tuple!(string, SerzDeserzError::CannotParseFP2);
149
150 let a_big = FieldElement::parse_hex_as_bignum(a)?;
151 let b_big = FieldElement::parse_hex_as_bignum(b)?;
152 Ok(FP2::new_bigs(&a_big, &b_big))
153}
154
155impl_group_elem_traits!(G2, GroupG2);
156
157impl_group_elem_serz!(G2, GroupG2, "G2");
158
159impl_group_elem_conversions!(G2, GroupG2, GroupG2_SIZE, G2_COMP_BYTE_SIZE);
160
161impl_group_elem_ops!(G2);
162
163impl_scalar_mul_ops!(G2);
164
165impl_group_element_lookup_table!(G2, G2LookupTable);
166
167impl_optmz_scalar_mul_ops!(G2, GroupG2, G2LookupTable);
169
170#[derive(Clone, Debug, Serialize, Deserialize)]
171pub struct G2Vector {
172 elems: Vec<G2>,
173}
174
175impl_group_elem_vec_ops!(G2, G2Vector);
176
177impl_group_elem_vec_product_ops!(G2, G2Vector, G2LookupTable);
178
179impl_group_elem_vec_conversions!(G2, G2Vector);
180
181impl G2 {
182 pub fn binary_scalar_mul(&self, h: &Self, a: &FieldElement, b: &FieldElement) -> Self {
186 let group_elems = iter::once(self).chain(iter::once(h));
188 let field_elems = iter::once(a).chain(iter::once(b));
189 G2Vector::multi_scalar_mul_const_time_without_precomputation(group_elems, field_elems)
190 .unwrap()
191 }
192
193 pub fn hash_to_curve(dst: &[u8], msg: &[u8]) -> G2 {
200 let mut u: [FP; 4] = [FP::new(), FP::new(), FP::new(), FP::new()];
202 hash_to_field(hmac::MC_SHA2, HASH_TYPE, dst, msg, &mut u, 4);
203
204 let fp2_1 = FP2::new_fps(&u[0], &u[1]);
206 let fp2_2 = FP2::new_fps(&u[2], &u[3]);
207
208 let mut P = GroupG2::map2point(&fp2_1);
210 let P1 = GroupG2::map2point(&fp2_2);
211 P.add(&P1);
212 P.cfp();
214
215 Self { value: P }
216 }
217}
218
219#[cfg(test)]
220mod test {
221 use super::*;
222
223 #[test]
224 fn test_parse_hex_for_FP2() {
225 }
227
228 #[test]
229 fn test_parse_bad_hex_for_FP2() {
230 }
232}