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