Skip to main content

multiversx_bls/
g1.rs

1use crate::constants::MCLBN_FP_UNIT_SIZE;
2use crate::g2::G2;
3use crate::init::{INIT, init_library};
4use crate::{BlsError, bls_api::*};
5
6/// signature type
7#[derive(Default, Debug, Clone, Copy, Eq)]
8#[repr(C)]
9pub struct G1 {
10    pub x: [u64; MCLBN_FP_UNIT_SIZE],
11    pub y: [u64; MCLBN_FP_UNIT_SIZE],
12    pub z: [u64; MCLBN_FP_UNIT_SIZE],
13}
14
15impl PartialEq for G1 {
16    /// return true if `self` is equal to `rhs`
17    fn eq(&self, rhs: &Self) -> bool {
18        INIT.call_once(init_library);
19        unsafe { blsSignatureIsEqual(self, rhs) == 1 }
20    }
21}
22
23impl G1 {
24    /// return true if `self` is valid signature of `msg` for `public_key`
25    pub fn verify(&self, public_key: G2, msg: &[u8]) -> bool {
26        INIT.call_once(init_library);
27        unsafe { blsVerify(self, &public_key, msg.as_ptr(), msg.len()) == 1 }
28    }
29
30    /// return true if `self` is a valid signature of `msg` for `public keys`
31    /// * `public_keys` - array of public key
32    /// * `msg` - message
33    pub fn fast_aggregate_verify(&self, public_keys: &[G2], msg: &[u8]) -> bool {
34        INIT.call_once(init_library);
35        if public_keys.is_empty() {
36            return false;
37        }
38
39        unsafe {
40            blsFastAggregateVerify(
41                self,
42                public_keys.as_ptr(),
43                public_keys.len(),
44                msg.as_ptr(),
45                msg.len(),
46            ) == 1
47        }
48    }
49
50    /// add a signature to `self`
51    pub fn add_assign(&mut self, signature: G1) {
52        INIT.call_once(init_library);
53        unsafe {
54            blsSignatureAdd(self, &signature);
55        }
56    }
57
58    /// return true if `self` has the valid order
59    pub fn is_valid_order(&self) -> bool {
60        INIT.call_once(init_library);
61        unsafe { blsSignatureIsValidOrder(self) == 1 }
62    }
63
64    /// set the aggregated signature of `sigs`
65    /// * `sigs` - signatures to be aggregated
66    pub fn aggregate(&mut self, sigs: &[G1]) {
67        INIT.call_once(init_library);
68        if sigs.is_empty() {
69            return;
70        }
71
72        unsafe {
73            blsAggregateSignature(self, sigs.as_ptr(), sigs.len());
74        }
75    }
76
77    /// Checks if the `G1` element is the point at infinity (zero element).
78    ///
79    /// This function determines whether the `G1` element represented by `self`
80    /// is the zero element, which is the identity element in the group.
81    ///
82    /// # Returns
83    /// `true` if the `G1` element is the zero element, otherwise `false`.
84    pub fn is_zero(&self) -> bool {
85        unsafe { mclBnG1_isZero(self) == 1 }
86    }
87
88    /// Checks if the `G1` element is valid.
89    ///
90    /// This function determines whether the `G1` element represented by `self`
91    /// is valid according to the cryptographic library's requirements.
92    ///
93    /// # Returns
94    /// `true` if the `G1` element is valid, otherwise `false`.
95    pub fn is_valid(&self) -> bool {
96        unsafe { mclBnG1_isValid(self) == 1 }
97    }
98
99    /// verify the correctness whenever signature setter is used
100    /// * `verify` - enable if true (default off)
101    pub fn verify_signature_order(verify: bool) {
102        unsafe { blsSignatureVerifyOrder(verify as i32) }
103    }
104
105    /// return true if `buf` is deserialized successfully
106    /// * `buf` - serialized data by `serialize`
107    pub fn deserialize(&mut self, buf: &[u8]) -> bool {
108        INIT.call_once(init_library);
109        let n = unsafe { blsSignatureDeserialize(self, buf.as_ptr(), buf.len()) };
110
111        n > 0 && n == buf.len()
112    }
113
114    /// return deserialized `buf`
115    pub fn from_serialized(buf: &[u8]) -> Result<Self, BlsError> {
116        let mut v = Self::default();
117        if v.deserialize(buf) {
118            return Ok(v);
119        }
120
121        Err(crate::BlsError::InvalidData)
122    }
123
124    /// return serialized byte array
125    pub fn serialize(&self) -> Result<Vec<u8>, BlsError> {
126        INIT.call_once(init_library);
127
128        let size = unsafe { mclBn_getFpByteSize() };
129        let mut buf = vec![0u8; size];
130
131        let n = unsafe { blsSignatureSerialize(buf.as_mut_ptr(), size, self) };
132        if n == 0 {
133            return Err(BlsError::SerializeError);
134        }
135
136        buf.truncate(n);
137
138        Ok(buf)
139    }
140}