multiversx_bls/g2.rs
1use crate::constants::MCLBN_FP_UNIT_SIZE;
2use crate::init::{INIT, init_library};
3use crate::{BlsError, bls_api::*};
4
5/// public key type
6#[derive(Default, Debug, Clone, Copy, Eq)]
7#[repr(C)]
8pub struct G2 {
9 pub x: [[u64; MCLBN_FP_UNIT_SIZE]; 2],
10 pub y: [[u64; MCLBN_FP_UNIT_SIZE]; 2],
11 pub z: [[u64; MCLBN_FP_UNIT_SIZE]; 2],
12}
13
14impl PartialEq for G2 {
15 /// return true if `self` is equal to `rhs`
16 fn eq(&self, rhs: &Self) -> bool {
17 INIT.call_once(init_library);
18 unsafe { blsPublicKeyIsEqual(self, rhs) == 1 }
19 }
20}
21
22impl G2 {
23 /// Adds the given `public_key` to `self`.
24 ///
25 /// This function performs an addition operation on the `G2` element represented by `self`
26 /// and the provided `public_key`.
27 ///
28 /// # Arguments
29 /// * `public_key` - A `G2` element to be added to `self`.
30 pub fn add_assign(&mut self, public_key: G2) {
31 INIT.call_once(init_library);
32 unsafe {
33 blsPublicKeyAdd(self, &public_key);
34 }
35 }
36
37 /// Checks if the `G2` element has a valid order.
38 ///
39 /// This function verifies whether the `G2` element represented by `self`
40 /// is of a valid order as per the cryptographic library's requirements.
41 ///
42 /// # Returns
43 /// * `true` if the `G2` element has a valid order.
44 /// * `false` otherwise.
45 pub fn is_valid_order(&self) -> bool {
46 INIT.call_once(init_library);
47 unsafe { blsPublicKeyIsValidOrder(self) == 1 }
48 }
49
50 /// Sets the `G2` element from a string representation.
51 ///
52 /// # Arguments
53 /// * `s` - A string slice containing the `G2` element in base 10.
54 ///
55 /// # Panics
56 /// May panic if initialization fails or the string is invalid.
57 pub fn set_str(&mut self, s: &str) {
58 INIT.call_once(init_library);
59 unsafe { mclBnG2_setStr(self, s.as_ptr(), s.len(), 10) };
60 }
61
62 /// Deserializes a `G2` element from a byte slice.
63 ///
64 /// # Arguments
65 /// * `buf` - A byte slice containing the serialized `G2` element.
66 ///
67 /// # Returns
68 /// `true` if deserialization is successful and the buffer length matches, otherwise `false`.
69 pub fn deserialize_g2(&mut self, buf: &[u8]) -> bool {
70 INIT.call_once(init_library);
71 let n = unsafe { mclBnG2_deserialize(self, buf.as_ptr(), buf.len()) };
72
73 n > 0 && n == buf.len()
74 }
75
76 /// Checks if the `G2` element is the point at infinity (zero element).
77 ///
78 /// This function determines whether the `G2` element represented by `self`
79 /// is the zero element, which is the identity element in the group.
80 ///
81 /// # Returns
82 /// `true` if the `G2` element is the zero element, otherwise `false`.
83 pub fn is_zero(&self) -> bool {
84 unsafe { mclBnG2_isZero(self) == 1 }
85 }
86
87 /// Checks if the `G2` element is valid.
88 ///
89 /// This function determines whether the `G2` element represented by `self`
90 /// is valid according to the cryptographic library's requirements.
91 ///
92 /// # Returns
93 /// `true` if the `G2` element is valid, otherwise `false`.
94 pub fn is_valid(&self) -> bool {
95 unsafe { mclBnG2_isValid(self) == 1 }
96 }
97
98 /// verify the correctness whenever public key setter is used
99 /// * `verify` - enable if true (default off)
100 pub fn verify_public_key_order(verify: bool) {
101 unsafe { blsPublicKeyVerifyOrder(verify as i32) }
102 }
103
104 /// return serialized byte array
105 pub fn serialize(&self) -> Result<Vec<u8>, BlsError> {
106 INIT.call_once(init_library);
107
108 let size = unsafe { mclBn_getFpByteSize() * 2 };
109 let mut buf = vec![0u8; size];
110
111 let n = unsafe { blsPublicKeySerialize(buf.as_mut_ptr(), size, self) };
112 if n == 0 {
113 return Err(BlsError::SerializeError);
114 }
115
116 buf.truncate(n);
117
118 Ok(buf)
119 }
120
121 pub fn deserialize(&mut self, buf: &[u8]) -> bool {
122 INIT.call_once(init_library);
123 let n = unsafe { blsPublicKeyDeserialize(self, buf.as_ptr(), buf.len()) };
124
125 n > 0 && n == buf.len()
126 }
127
128 /// return deserialized `buf`
129 pub fn from_serialized(buf: &[u8]) -> Result<Self, BlsError> {
130 let mut v = Self::default();
131 if v.deserialize(buf) {
132 return Ok(v);
133 }
134
135 Err(crate::BlsError::InvalidData)
136 }
137}