Skip to main content

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}