mcl_rust/
lib.rs

1#![no_std]
2
3extern crate alloc;
4
5use alloc::string::String;
6use alloc::vec::Vec;
7use core::mem::MaybeUninit;
8use core::ops::{Add, AddAssign};
9use core::ops::{Div, DivAssign};
10use core::ops::{Mul, MulAssign};
11use core::ops::{Sub, SubAssign};
12use core::primitive::str;
13
14#[link(name = "mcl", kind = "static")]
15#[link(name = "mclbn384_256", kind = "static")]
16#[cfg_attr(target_arch = "x86_64", link(name = "stdc++"))]
17#[allow(non_snake_case)]
18extern "C" {
19    // global functions
20    fn mclBn_init(curve: i32, compiledTimeVar: i32) -> i32;
21    fn mclBn_getVersion() -> u32;
22    fn mclBn_getFrByteSize() -> u32;
23    fn mclBn_getFpByteSize() -> u32;
24    fn mclBn_getCurveOrder(buf: *mut u8, maxBufSize: usize) -> usize;
25    fn mclBn_getFieldOrder(buf: *mut u8, maxBufSize: usize) -> usize;
26    fn mclBn_pairing(z: *mut GT, x: *const G1, y: *const G2);
27    fn mclBn_millerLoop(z: *mut GT, x: *const G1, y: *const G2);
28    fn mclBn_finalExp(y: *mut GT, x: *const GT);
29
30    // Fr
31    fn mclBnFr_isEqual(x: *const Fr, y: *const Fr) -> i32;
32    fn mclBnFr_isValid(x: *const Fr) -> i32;
33    fn mclBnFr_isZero(x: *const Fr) -> i32;
34    fn mclBnFr_isOne(x: *const Fr) -> i32;
35    fn mclBnFr_isOdd(x: *const Fr) -> i32;
36    fn mclBnFr_isNegative(x: *const Fr) -> i32;
37    fn mclBnFr_cmp(x: *const Fr, y: *const Fr) -> i32;
38
39    fn mclBnFr_setStr(x: *mut Fr, buf: *const u8, bufSize: usize, ioMode: i32) -> i32;
40    fn mclBnFr_getStr(buf: *mut u8, maxBufSize: usize, x: *const Fr, ioMode: i32) -> usize;
41    fn mclBnFr_serialize(buf: *mut u8, maxBufSize: usize, x: *const Fr) -> usize;
42    fn mclBnFr_deserialize(x: *mut Fr, buf: *const u8, bufSize: usize) -> usize;
43
44    fn mclBnFr_setInt32(x: *mut Fr, v: i32);
45    fn mclBnFr_setLittleEndian(x: *mut Fr, buf: *const u8, bufSize: usize) -> i32;
46    fn mclBnFr_setLittleEndianMod(x: *mut Fr, buf: *const u8, bufSize: usize) -> i32;
47    fn mclBnFr_setHashOf(x: *mut Fr, buf: *const u8, bufSize: usize) -> i32;
48    fn mclBnFr_setByCSPRNG(x: *mut Fr);
49
50    fn mclBnFr_add(z: *mut Fr, x: *const Fr, y: *const Fr);
51    fn mclBnFr_sub(z: *mut Fr, x: *const Fr, y: *const Fr);
52    fn mclBnFr_neg(y: *mut Fr, x: *const Fr);
53
54    fn mclBnFr_mul(z: *mut Fr, x: *const Fr, y: *const Fr);
55    fn mclBnFr_div(z: *mut Fr, x: *const Fr, y: *const Fr);
56    fn mclBnFr_inv(y: *mut Fr, x: *const Fr);
57    fn mclBnFr_sqr(y: *mut Fr, x: *const Fr);
58    fn mclBnFr_squareRoot(y: *mut Fr, x: *const Fr) -> i32;
59
60    // Fp
61    fn mclBnFp_isEqual(x: *const Fp, y: *const Fp) -> i32;
62    fn mclBnFp_isValid(x: *const Fp) -> i32;
63    fn mclBnFp_isZero(x: *const Fp) -> i32;
64    fn mclBnFp_isOne(x: *const Fp) -> i32;
65    fn mclBnFp_isOdd(x: *const Fp) -> i32;
66    fn mclBnFp_isNegative(x: *const Fp) -> i32;
67    fn mclBnFp_cmp(x: *const Fp, y: *const Fp) -> i32;
68
69    fn mclBnFp_setStr(x: *mut Fp, buf: *const u8, bufSize: usize, ioMode: i32) -> i32;
70    fn mclBnFp_getStr(buf: *mut u8, maxBufSize: usize, x: *const Fp, ioMode: i32) -> usize;
71    fn mclBnFp_serialize(buf: *mut u8, maxBufSize: usize, x: *const Fp) -> usize;
72    fn mclBnFp_deserialize(x: *mut Fp, buf: *const u8, bufSize: usize) -> usize;
73
74    fn mclBnFp_setInt32(x: *mut Fp, v: i32);
75    fn mclBnFp_setLittleEndian(x: *mut Fp, buf: *const u8, bufSize: usize) -> i32;
76    fn mclBnFp_setLittleEndianMod(x: *mut Fp, buf: *const u8, bufSize: usize) -> i32;
77    fn mclBnFp_setHashOf(x: *mut Fp, buf: *const u8, bufSize: usize) -> i32;
78    fn mclBnFp_setByCSPRNG(x: *mut Fp);
79
80    fn mclBnFp_add(z: *mut Fp, x: *const Fp, y: *const Fp);
81    fn mclBnFp_sub(z: *mut Fp, x: *const Fp, y: *const Fp);
82    fn mclBnFp_neg(y: *mut Fp, x: *const Fp);
83
84    fn mclBnFp_mul(z: *mut Fp, x: *const Fp, y: *const Fp);
85    fn mclBnFp_div(z: *mut Fp, x: *const Fp, y: *const Fp);
86    fn mclBnFp_inv(y: *mut Fp, x: *const Fp);
87    fn mclBnFp_sqr(y: *mut Fp, x: *const Fp);
88    fn mclBnFp_squareRoot(y: *mut Fp, x: *const Fp) -> i32;
89
90    // Fp2
91    fn mclBnFp2_isEqual(x: *const Fp2, y: *const Fp2) -> i32;
92    fn mclBnFp2_isZero(x: *const Fp2) -> i32;
93
94    fn mclBnFp2_serialize(buf: *mut u8, maxBufSize: usize, x: *const Fp2) -> usize;
95    fn mclBnFp2_deserialize(x: *mut Fp2, buf: *const u8, bufSize: usize) -> usize;
96
97    fn mclBnFp2_add(z: *mut Fp2, x: *const Fp2, y: *const Fp2);
98    fn mclBnFp2_sub(z: *mut Fp2, x: *const Fp2, y: *const Fp2);
99    fn mclBnFp2_neg(y: *mut Fp2, x: *const Fp2);
100
101    fn mclBnFp2_mul(z: *mut Fp2, x: *const Fp2, y: *const Fp2);
102    fn mclBnFp2_div(z: *mut Fp2, x: *const Fp2, y: *const Fp2);
103    fn mclBnFp2_inv(y: *mut Fp2, x: *const Fp2);
104    fn mclBnFp2_sqr(y: *mut Fp2, x: *const Fp2);
105    fn mclBnFp2_squareRoot(y: *mut Fp2, x: *const Fp2) -> i32;
106
107    // G1
108    fn mclBnG1_isEqual(x: *const G1, y: *const G1) -> i32;
109    fn mclBnG1_isValid(x: *const G1) -> i32;
110    fn mclBnG1_isZero(x: *const G1) -> i32;
111
112    fn mclBnG1_setStr(x: *mut G1, buf: *const u8, bufSize: usize, ioMode: i32) -> i32;
113    fn mclBnG1_getStr(buf: *mut u8, maxBufSize: usize, x: *const G1, ioMode: i32) -> usize;
114    fn mclBnG1_serialize(buf: *mut u8, maxBufSize: usize, x: *const G1) -> usize;
115    fn mclBnG1_deserialize(x: *mut G1, buf: *const u8, bufSize: usize) -> usize;
116
117    fn mclBnG1_add(z: *mut G1, x: *const G1, y: *const G1);
118    fn mclBnG1_sub(z: *mut G1, x: *const G1, y: *const G1);
119    fn mclBnG1_neg(y: *mut G1, x: *const G1);
120
121    fn mclBnG1_dbl(y: *mut G1, x: *const G1);
122    fn mclBnG1_mul(z: *mut G1, x: *const G1, y: *const Fr);
123    fn mclBnG1_normalize(y: *mut G1, x: *const G1);
124    fn mclBnG1_hashAndMapTo(x: *mut G1, buf: *const u8, bufSize: usize) -> i32;
125    fn mclBnG1_mulVec(z: *mut G1, x: *const G1, y: *const Fr, n: usize);
126
127    // G2
128    fn mclBnG2_isEqual(x: *const G2, y: *const G2) -> i32;
129    fn mclBnG2_isValid(x: *const G2) -> i32;
130    fn mclBnG2_isZero(x: *const G2) -> i32;
131
132    fn mclBnG2_setStr(x: *mut G2, buf: *const u8, bufSize: usize, ioMode: i32) -> i32;
133    fn mclBnG2_getStr(buf: *mut u8, maxBufSize: usize, x: *const G2, ioMode: i32) -> usize;
134    fn mclBnG2_serialize(buf: *mut u8, maxBufSize: usize, x: *const G2) -> usize;
135    fn mclBnG2_deserialize(x: *mut G2, buf: *const u8, bufSize: usize) -> usize;
136
137    fn mclBnG2_add(z: *mut G2, x: *const G2, y: *const G2);
138    fn mclBnG2_sub(z: *mut G2, x: *const G2, y: *const G2);
139    fn mclBnG2_neg(y: *mut G2, x: *const G2);
140
141    fn mclBnG2_dbl(y: *mut G2, x: *const G2);
142    fn mclBnG2_mul(z: *mut G2, x: *const G2, y: *const Fr);
143    fn mclBnG2_normalize(y: *mut G2, x: *const G2);
144    fn mclBnG2_hashAndMapTo(x: *mut G2, buf: *const u8, bufSize: usize) -> i32;
145    fn mclBnG2_mulVec(z: *mut G2, x: *const G2, y: *const Fr, n: usize);
146
147    // GT
148    fn mclBnGT_isEqual(x: *const GT, y: *const GT) -> i32;
149    fn mclBnGT_isZero(x: *const GT) -> i32;
150    fn mclBnGT_isOne(x: *const GT) -> i32;
151
152    fn mclBnGT_setStr(x: *mut GT, buf: *const u8, bufSize: usize, ioMode: i32) -> i32;
153    fn mclBnGT_getStr(buf: *mut u8, maxBufSize: usize, x: *const GT, ioMode: i32) -> usize;
154    fn mclBnGT_serialize(buf: *mut u8, maxBufSize: usize, x: *const GT) -> usize;
155    fn mclBnGT_deserialize(x: *mut GT, buf: *const u8, bufSize: usize) -> usize;
156
157    fn mclBnGT_setInt32(x: *mut GT, v: i32);
158
159    fn mclBnGT_add(z: *mut GT, x: *const GT, y: *const GT);
160    fn mclBnGT_sub(z: *mut GT, x: *const GT, y: *const GT);
161    fn mclBnGT_neg(y: *mut GT, x: *const GT);
162
163    fn mclBnGT_mul(z: *mut GT, x: *const GT, y: *const GT);
164    fn mclBnGT_div(z: *mut GT, x: *const GT, y: *const GT);
165    fn mclBnGT_inv(y: *mut GT, x: *const GT);
166    fn mclBnGT_sqr(y: *mut GT, x: *const GT);
167
168    fn mclBnGT_pow(z: *mut GT, x: *const GT, y: *const Fr);
169}
170
171pub enum CurveType {
172    BN254 = 0,
173    BN381 = 1,
174    SNARK = 4,
175    BLS12_381 = 5,
176    BLS12_377 = 8,
177    #[allow(non_camel_case_types)]
178    BN_P256 = 9,
179}
180
181const MCLBN_FP_UNIT_SIZE: usize = 6;
182const MCLBN_FR_UNIT_SIZE: usize = 4;
183const MCLBN_COMPILED_TIME_VAR: i32 = MCLBN_FR_UNIT_SIZE as i32 * 10 + MCLBN_FP_UNIT_SIZE as i32;
184
185macro_rules! common_impl {
186    ($t:ty, $is_equal_fn:ident, $is_zero_fn:ident) => {
187        impl PartialEq for $t {
188            fn eq(&self, rhs: &Self) -> bool {
189                unsafe { $is_equal_fn(self, rhs) == 1 }
190            }
191        }
192        impl $t {
193            pub fn zero() -> $t {
194                Default::default()
195            }
196            pub unsafe fn uninit() -> $t {
197                let u = MaybeUninit::<$t>::uninit();
198                let v = unsafe { u.assume_init() };
199                v
200            }
201            pub fn clear(&mut self) {
202                *self = <$t>::zero()
203            }
204            pub fn is_zero(&self) -> bool {
205                unsafe { $is_zero_fn(self) == 1 }
206            }
207        }
208    };
209}
210macro_rules! is_valid_impl {
211    ($t:ty, $is_valid_fn:ident) => {
212        impl $t {
213            pub fn is_valid(&self) -> bool {
214                unsafe { $is_valid_fn(self) == 1 }
215            }
216        }
217    };
218}
219
220macro_rules! serialize_impl {
221    ($t:ty, $size:expr, $serialize_fn:ident, $deserialize_fn:ident) => {
222        impl $t {
223            pub fn deserialize(&mut self, buf: &[u8]) -> bool {
224                unsafe { $deserialize_fn(self, buf.as_ptr(), buf.len()) > 0 }
225            }
226            pub fn serialize(&self) -> Vec<u8> {
227                let size = unsafe { $size } as usize;
228                let mut buf: Vec<u8> = Vec::with_capacity(size);
229                let n: usize;
230                unsafe {
231                    n = $serialize_fn(buf.as_mut_ptr(), size, self);
232                }
233                if n == 0 {
234                    panic!("serialize");
235                }
236                unsafe {
237                    buf.set_len(n);
238                }
239                buf
240            }
241        }
242    };
243}
244
245macro_rules! str_impl {
246    ($t:ty, $maxBufSize:expr, $get_str_fn:ident, $set_str_fn:ident) => {
247        impl $t {
248            pub fn from_str(s: &str, base: i32) -> Option<$t> {
249                let mut v = unsafe { <$t>::uninit() };
250                if v.set_str(s, base) {
251                    return Some(v);
252                }
253                None
254            }
255            pub fn set_str(&mut self, s: &str, base: i32) -> bool {
256                unsafe { $set_str_fn(self, s.as_ptr(), s.len(), base) == 0 }
257            }
258            pub fn get_str(&self, io_mode: i32) -> String {
259                let u = MaybeUninit::<[u8; $maxBufSize]>::uninit();
260                let mut buf = unsafe { u.assume_init() };
261                let n: usize;
262                unsafe {
263                    n = $get_str_fn(buf.as_mut_ptr(), buf.len(), self, io_mode);
264                }
265                if n == 0 {
266                    panic!("mclBnFr_getStr");
267                }
268                unsafe { core::str::from_utf8_unchecked(&buf[0..n]).into() }
269            }
270        }
271    };
272}
273
274macro_rules! int_impl {
275    ($t:ty, $set_int_fn:ident, $is_one_fn:ident) => {
276        impl $t {
277            pub fn from_int(x: i32) -> $t {
278                let mut v = unsafe { <$t>::uninit() };
279                v.set_int(x);
280                v
281            }
282            pub fn set_int(&mut self, x: i32) {
283                unsafe {
284                    $set_int_fn(self, x);
285                }
286            }
287            pub fn is_one(&self) -> bool {
288                unsafe { $is_one_fn(self) == 1 }
289            }
290        }
291    };
292}
293
294macro_rules! base_field_impl {
295    ($t:ty,  $set_little_endian_fn:ident, $set_little_endian_mod_fn:ident, $set_hash_of_fn:ident, $set_by_csprng_fn:ident, $is_odd_fn:ident, $is_negative_fn:ident, $cmp_fn:ident, $square_root_fn:ident) => {
296        impl $t {
297            pub fn set_little_endian(&mut self, buf: &[u8]) -> bool {
298                unsafe { $set_little_endian_fn(self, buf.as_ptr(), buf.len()) == 0 }
299            }
300            pub fn set_little_endian_mod(&mut self, buf: &[u8]) -> bool {
301                unsafe { $set_little_endian_mod_fn(self, buf.as_ptr(), buf.len()) == 0 }
302            }
303            pub fn set_hash_of(&mut self, buf: &[u8]) -> bool {
304                unsafe { $set_hash_of_fn(self, buf.as_ptr(), buf.len()) == 0 }
305            }
306            pub fn set_by_csprng(&mut self) {
307                unsafe { $set_by_csprng_fn(self) }
308            }
309            pub fn is_odd(&self) -> bool {
310                unsafe { $is_odd_fn(self) == 1 }
311            }
312            pub fn is_negative(&self) -> bool {
313                unsafe { $is_negative_fn(self) == 1 }
314            }
315            pub fn cmp(&self, rhs: &$t) -> i32 {
316                unsafe { $cmp_fn(self, rhs) }
317            }
318            pub fn square_root(y: &mut $t, x: &$t) -> bool {
319                unsafe { $square_root_fn(y, x) == 0 }
320            }
321        }
322    };
323}
324
325macro_rules! add_op_impl {
326    ($t:ty, $add_fn:ident, $sub_fn:ident, $neg_fn:ident) => {
327        impl $t {
328            pub fn add(z: &mut $t, x: &$t, y: &$t) {
329                unsafe { $add_fn(z, x, y) }
330            }
331            pub fn sub(z: &mut $t, x: &$t, y: &$t) {
332                unsafe { $sub_fn(z, x, y) }
333            }
334            pub fn neg(y: &mut $t, x: &$t) {
335                unsafe { $neg_fn(y, x) }
336            }
337        }
338        impl<'a> Add for &'a $t {
339            type Output = $t;
340            fn add(self, other: &$t) -> $t {
341                let mut v = unsafe { <$t>::uninit() };
342                <$t>::add(&mut v, &self, &other);
343                v
344            }
345        }
346        impl<'a> AddAssign<&'a $t> for $t {
347            fn add_assign(&mut self, other: &$t) {
348                let z: *mut $t = self;
349                unsafe {
350                    $add_fn(z, z as *const $t, other as *const $t);
351                }
352            }
353        }
354        impl<'a> Sub for &'a $t {
355            type Output = $t;
356            fn sub(self, other: &$t) -> $t {
357                let mut v = unsafe { <$t>::uninit() };
358                <$t>::sub(&mut v, &self, &other);
359                v
360            }
361        }
362        impl<'a> SubAssign<&'a $t> for $t {
363            fn sub_assign(&mut self, other: &$t) {
364                let z: *mut $t = self;
365                unsafe {
366                    $sub_fn(z, z as *const $t, other as *const $t);
367                }
368            }
369        }
370    };
371}
372
373macro_rules! field_mul_op_impl {
374    ($t:ty, $mul_fn:ident, $div_fn:ident, $inv_fn:ident, $sqr_fn:ident) => {
375        impl $t {
376            pub fn mul(z: &mut $t, x: &$t, y: &$t) {
377                unsafe { $mul_fn(z, x, y) }
378            }
379            pub fn div(z: &mut $t, x: &$t, y: &$t) {
380                unsafe { $div_fn(z, x, y) }
381            }
382            pub fn inv(y: &mut $t, x: &$t) {
383                unsafe { $inv_fn(y, x) }
384            }
385            pub fn sqr(y: &mut $t, x: &$t) {
386                unsafe { $sqr_fn(y, x) }
387            }
388        }
389        impl<'a> Mul for &'a $t {
390            type Output = $t;
391            fn mul(self, other: &$t) -> $t {
392                let mut v = unsafe { <$t>::uninit() };
393                <$t>::mul(&mut v, &self, &other);
394                v
395            }
396        }
397        impl<'a> MulAssign<&'a $t> for $t {
398            fn mul_assign(&mut self, other: &$t) {
399                let z: *mut $t = self;
400                unsafe {
401                    $mul_fn(z, z as *const $t, other as *const $t);
402                }
403            }
404        }
405        impl<'a> Div for &'a $t {
406            type Output = $t;
407            fn div(self, other: &$t) -> $t {
408                let mut v = unsafe { <$t>::uninit() };
409                <$t>::div(&mut v, &self, &other);
410                v
411            }
412        }
413        impl<'a> DivAssign<&'a $t> for $t {
414            fn div_assign(&mut self, other: &$t) {
415                let z: *mut $t = self;
416                unsafe {
417                    $div_fn(z, z as *const $t, other as *const $t);
418                }
419            }
420        }
421    };
422}
423
424macro_rules! ec_impl {
425    ($t:ty, $dbl_fn:ident, $mul_fn:ident, $normalize_fn:ident, $set_hash_and_map_fn:ident, $mul_vec_fn:ident) => {
426        impl $t {
427            pub fn dbl(y: &mut $t, x: &$t) {
428                unsafe { $dbl_fn(y, x) }
429            }
430            pub fn mul(z: &mut $t, x: &$t, y: &Fr) {
431                unsafe { $mul_fn(z, x, y) }
432            }
433            pub fn normalize(y: &mut $t, x: &$t) {
434                unsafe { $normalize_fn(y, x) }
435            }
436            pub fn set_hash_of(&mut self, buf: &[u8]) -> bool {
437                unsafe { $set_hash_and_map_fn(self, buf.as_ptr(), buf.len()) == 0 }
438            }
439            pub fn mul_vec(z: &mut $t, x: &[$t], y: &[Fr]) {
440                unsafe { $mul_vec_fn(z, x.as_ptr(), y.as_ptr(), x.len()) }
441            }
442        }
443    };
444}
445
446#[derive(Default, Debug, Clone)]
447#[repr(C)]
448pub struct Fp {
449    d: [u64; MCLBN_FP_UNIT_SIZE],
450}
451impl Fp {
452    pub fn get_order() -> String {
453        get_field_order()
454    }
455}
456common_impl![Fp, mclBnFp_isEqual, mclBnFp_isZero];
457is_valid_impl![Fp, mclBnFp_isValid];
458serialize_impl![
459    Fp,
460    mclBn_getFpByteSize(),
461    mclBnFp_serialize,
462    mclBnFp_deserialize
463];
464str_impl![Fp, 128, mclBnFp_getStr, mclBnFp_setStr];
465int_impl![Fp, mclBnFp_setInt32, mclBnFp_isOne];
466base_field_impl![
467    Fp,
468    mclBnFp_setLittleEndian,
469    mclBnFp_setLittleEndianMod,
470    mclBnFp_setHashOf,
471    mclBnFp_setByCSPRNG,
472    mclBnFp_isOdd,
473    mclBnFp_isNegative,
474    mclBnFp_cmp,
475    mclBnFp_squareRoot
476];
477add_op_impl![Fp, mclBnFp_add, mclBnFp_sub, mclBnFp_neg];
478field_mul_op_impl![Fp, mclBnFp_mul, mclBnFp_div, mclBnFp_inv, mclBnFp_sqr];
479
480#[derive(Default, Debug, Clone)]
481#[repr(C)]
482pub struct Fp2 {
483    pub d: [Fp; 2],
484}
485common_impl![Fp2, mclBnFp2_isEqual, mclBnFp2_isZero];
486serialize_impl![
487    Fp2,
488    mclBn_getFpByteSize() * 2,
489    mclBnFp2_serialize,
490    mclBnFp2_deserialize
491];
492add_op_impl![Fp2, mclBnFp2_add, mclBnFp2_sub, mclBnFp2_neg];
493field_mul_op_impl![Fp2, mclBnFp2_mul, mclBnFp2_div, mclBnFp2_inv, mclBnFp2_sqr];
494impl Fp2 {
495    pub fn square_root(y: &mut Fp2, x: &Fp2) -> bool {
496        unsafe { mclBnFp2_squareRoot(y, x) == 0 }
497    }
498}
499
500#[derive(Default, Debug, Clone)]
501#[repr(C)]
502pub struct Fr {
503    d: [u64; MCLBN_FR_UNIT_SIZE],
504}
505impl Fr {
506    pub fn get_order() -> String {
507        get_curve_order()
508    }
509}
510common_impl![Fr, mclBnFr_isEqual, mclBnFr_isZero];
511is_valid_impl![Fr, mclBnFr_isValid];
512serialize_impl![
513    Fr,
514    mclBn_getFrByteSize(),
515    mclBnFr_serialize,
516    mclBnFr_deserialize
517];
518str_impl![Fr, 128, mclBnFr_getStr, mclBnFr_setStr];
519int_impl![Fr, mclBnFr_setInt32, mclBnFr_isOne];
520base_field_impl![
521    Fr,
522    mclBnFr_setLittleEndian,
523    mclBnFr_setLittleEndianMod,
524    mclBnFr_setHashOf,
525    mclBnFr_setByCSPRNG,
526    mclBnFr_isOdd,
527    mclBnFr_isNegative,
528    mclBnFr_cmp,
529    mclBnFr_squareRoot
530];
531add_op_impl![Fr, mclBnFr_add, mclBnFr_sub, mclBnFr_neg];
532field_mul_op_impl![Fr, mclBnFr_mul, mclBnFr_div, mclBnFr_inv, mclBnFr_sqr];
533
534#[derive(Default, Debug, Clone)]
535#[repr(C)]
536pub struct G1 {
537    pub x: Fp,
538    pub y: Fp,
539    pub z: Fp,
540}
541common_impl![G1, mclBnG1_isEqual, mclBnG1_isZero];
542is_valid_impl![G1, mclBnG1_isValid];
543serialize_impl![
544    G1,
545    mclBn_getFpByteSize(),
546    mclBnG1_serialize,
547    mclBnG1_deserialize
548];
549str_impl![G1, 128 * 3, mclBnG1_getStr, mclBnG1_setStr];
550add_op_impl![G1, mclBnG1_add, mclBnG1_sub, mclBnG1_neg];
551ec_impl![
552    G1,
553    mclBnG1_dbl,
554    mclBnG1_mul,
555    mclBnG1_normalize,
556    mclBnG1_hashAndMapTo,
557    mclBnG1_mulVec
558];
559
560#[derive(Default, Debug, Clone)]
561#[repr(C)]
562pub struct G2 {
563    pub x: Fp2,
564    pub y: Fp2,
565    pub z: Fp2,
566}
567common_impl![G2, mclBnG2_isEqual, mclBnG2_isZero];
568is_valid_impl![G2, mclBnG2_isValid];
569serialize_impl![
570    G2,
571    mclBn_getFpByteSize() * 2,
572    mclBnG2_serialize,
573    mclBnG2_deserialize
574];
575str_impl![G2, 128 * 3 * 2, mclBnG2_getStr, mclBnG2_setStr];
576add_op_impl![G2, mclBnG2_add, mclBnG2_sub, mclBnG2_neg];
577ec_impl![
578    G2,
579    mclBnG2_dbl,
580    mclBnG2_mul,
581    mclBnG2_normalize,
582    mclBnG2_hashAndMapTo,
583    mclBnG2_mulVec
584];
585
586#[derive(Default, Debug, Clone)]
587#[repr(C)]
588pub struct GT {
589    d: [Fp; 12],
590}
591common_impl![GT, mclBnGT_isEqual, mclBnGT_isZero];
592serialize_impl![
593    GT,
594    mclBn_getFpByteSize() * 12,
595    mclBnGT_serialize,
596    mclBnGT_deserialize
597];
598str_impl![GT, 128 * 12, mclBnGT_getStr, mclBnGT_setStr];
599int_impl![GT, mclBnGT_setInt32, mclBnGT_isOne];
600add_op_impl![GT, mclBnGT_add, mclBnGT_sub, mclBnGT_neg];
601field_mul_op_impl![GT, mclBnGT_mul, mclBnGT_div, mclBnGT_inv, mclBnGT_sqr];
602impl GT {
603    pub fn pow(z: &mut GT, x: &GT, y: &Fr) {
604        unsafe { mclBnGT_pow(z, x, y) }
605    }
606}
607
608pub fn get_version() -> u32 {
609    unsafe { mclBn_getVersion() }
610}
611
612pub fn init(curve: CurveType) -> bool {
613    unsafe { mclBn_init(curve as i32, MCLBN_COMPILED_TIME_VAR) == 0 }
614}
615
616pub fn get_fr_serialized_size() -> u32 {
617    unsafe { mclBn_getFrByteSize() as u32 }
618}
619
620pub fn get_fp_serialized_size() -> u32 {
621    unsafe { mclBn_getFpByteSize() as u32 }
622}
623
624pub fn get_g1_serialized_size() -> u32 {
625    get_fp_serialized_size()
626}
627
628pub fn get_g2_serialized_size() -> u32 {
629    get_fp_serialized_size() * 2
630}
631
632pub fn get_gt_serialized_size() -> u32 {
633    get_fp_serialized_size() * 12
634}
635
636macro_rules! get_str_impl {
637    ($get_str_fn:ident) => {{
638        let u = MaybeUninit::<[u8; 256]>::uninit();
639        let mut buf = unsafe { u.assume_init() };
640        let n: usize;
641        unsafe {
642            n = $get_str_fn(buf.as_mut_ptr(), buf.len());
643        }
644        if n == 0 {
645            panic!("get_str");
646        }
647        unsafe { core::str::from_utf8_unchecked(&buf[0..n]).into() }
648    }};
649}
650
651pub fn get_field_order() -> String {
652    get_str_impl![mclBn_getFieldOrder]
653}
654
655pub fn get_curve_order() -> String {
656    get_str_impl![mclBn_getCurveOrder]
657}
658
659pub fn pairing(z: &mut GT, x: &G1, y: &G2) {
660    unsafe {
661        mclBn_pairing(z, x, y);
662    }
663}
664
665pub fn miller_loop(z: &mut GT, x: &G1, y: &G2) {
666    unsafe {
667        mclBn_millerLoop(z, x, y);
668    }
669}
670
671pub fn final_exp(y: &mut GT, x: &GT) {
672    unsafe {
673        mclBn_finalExp(y, x);
674    }
675}