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 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 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 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 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 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 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 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: >, 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: >) {
672 unsafe {
673 mclBn_finalExp(y, x);
674 }
675}