1#![no_std]
2
3pub mod arith;
4pub mod ethereum;
5mod fields;
6mod groups;
7
8use crate::fields::FieldElement;
9use crate::groups::{G1Params, G2Params, GroupElement, GroupParams};
10use core::ops::{Add, Mul, Neg, Sub};
11
12#[derive(Copy, Clone, Debug, PartialEq, Eq)]
13#[repr(C)]
14pub struct Fr(fields::Fr);
15
16impl Fr {
17 pub fn zero() -> Self {
18 Fr(fields::Fr::zero())
19 }
20 pub fn one() -> Self {
21 Fr(fields::Fr::one())
22 }
23 pub fn pow(&self, exp: Fr) -> Self {
24 Fr(self.0.pow(exp.0))
25 }
26 pub fn from_str(s: &str) -> Option<Self> {
27 fields::Fr::from_str(s).map(|e| Fr(e))
28 }
29 pub fn inverse(&self) -> Option<Self> {
30 self.0.inverse().map(|e| Fr(e))
31 }
32 pub fn is_zero(&self) -> bool {
33 self.0.is_zero()
34 }
35 pub fn interpret(buf: &[u8; 64]) -> Fr {
36 Fr(fields::Fr::interpret(buf))
37 }
38 pub fn from_slice(slice: &[u8]) -> Result<Self, FieldError> {
39 arith::U256::from_slice(slice)
40 .map_err(|_| FieldError::InvalidSliceLength) .map(|x| Fr::new_mul_factor(x))
42 }
43 pub fn to_big_endian(&self, slice: &mut [u8]) -> Result<(), FieldError> {
44 self.0
45 .raw()
46 .to_big_endian(slice)
47 .map_err(|_| FieldError::InvalidSliceLength)
48 }
49 pub fn new(val: arith::U256) -> Option<Self> {
50 fields::Fr::new(val).map(|x| Fr(x))
51 }
52 pub fn new_mul_factor(val: arith::U256) -> Self {
53 Fr(fields::Fr::new_mul_factor(val))
54 }
55 pub fn into_u256(self) -> arith::U256 {
56 (self.0).into()
57 }
58 pub fn set_bit(&mut self, bit: usize, to: bool) {
59 self.0.set_bit(bit, to);
60 }
61}
62
63impl Add<Fr> for Fr {
64 type Output = Fr;
65
66 fn add(self, other: Fr) -> Fr {
67 Fr(self.0 + other.0)
68 }
69}
70
71impl Sub<Fr> for Fr {
72 type Output = Fr;
73
74 fn sub(self, other: Fr) -> Fr {
75 Fr(self.0 - other.0)
76 }
77}
78
79impl Neg for Fr {
80 type Output = Fr;
81
82 fn neg(self) -> Fr {
83 Fr(-self.0)
84 }
85}
86
87impl Mul for Fr {
88 type Output = Fr;
89
90 fn mul(self, other: Fr) -> Fr {
91 Fr(self.0 * other.0)
92 }
93}
94
95impl core::ops::AddAssign for Fr {
96 #[inline]
97 fn add_assign(&mut self, rhs: Self) {
98 *self = *self + rhs;
99 }
100}
101
102impl core::ops::SubAssign for Fr {
103 #[inline]
104 fn sub_assign(&mut self, rhs: Self) {
105 *self = *self - rhs;
106 }
107}
108
109impl core::ops::MulAssign for Fr {
110 #[inline]
111 fn mul_assign(&mut self, rhs: Self) {
112 *self = *self * rhs;
113 }
114}
115
116#[derive(Debug)]
117pub enum FieldError {
118 InvalidSliceLength,
119 InvalidU512Encoding,
120 NotMember,
121}
122
123#[derive(Debug)]
124pub enum CurveError {
125 InvalidEncoding,
126 NotMember,
127 Field(FieldError),
128 ToAffineConversion,
129}
130
131impl From<FieldError> for CurveError {
132 fn from(fe: FieldError) -> Self {
133 CurveError::Field(fe)
134 }
135}
136
137pub use crate::groups::Error as GroupError;
138
139#[derive(Copy, Clone, Debug, PartialEq, Eq)]
140#[repr(C)]
141pub struct Fq(fields::Fq);
142
143impl Fq {
144 pub fn zero() -> Self {
145 Fq(fields::Fq::zero())
146 }
147 pub fn one() -> Self {
148 Fq(fields::Fq::one())
149 }
150 pub fn pow(&self, exp: Fq) -> Self {
151 Fq(self.0.pow(exp.0))
152 }
153 pub fn from_str(s: &str) -> Option<Self> {
154 fields::Fq::from_str(s).map(|e| Fq(e))
155 }
156 pub fn inverse(&self) -> Option<Self> {
157 self.0.inverse().map(|e| Fq(e))
158 }
159 pub fn is_zero(&self) -> bool {
160 self.0.is_zero()
161 }
162 pub fn interpret(buf: &[u8; 64]) -> Fq {
163 Fq(fields::Fq::interpret(buf))
164 }
165 pub fn from_slice(slice: &[u8]) -> Result<Self, FieldError> {
166 arith::U256::from_slice(slice)
167 .map_err(|_| FieldError::InvalidSliceLength) .and_then(|x| fields::Fq::new(x).ok_or(FieldError::NotMember))
169 .map(|x| Fq(x))
170 }
171 pub fn to_big_endian(&self, slice: &mut [u8]) -> Result<(), FieldError> {
172 let mut a: arith::U256 = self.0.into();
173 a.mul(
175 &fields::Fq::one().raw(),
176 &fields::Fq::modulus(),
177 self.0.inv(),
178 );
179 a.to_big_endian(slice)
180 .map_err(|_| FieldError::InvalidSliceLength)
181 }
182 pub fn from_u256(u256: arith::U256) -> Result<Self, FieldError> {
183 Ok(Fq(fields::Fq::new(u256).ok_or(FieldError::NotMember)?))
184 }
185 pub fn into_u256(self) -> arith::U256 {
186 (self.0).into()
187 }
188 pub fn modulus() -> arith::U256 {
189 fields::Fq::modulus()
190 }
191
192 pub fn sqrt(&self) -> Option<Self> {
193 self.0.sqrt().map(Fq)
194 }
195}
196
197impl Add<Fq> for Fq {
198 type Output = Fq;
199
200 fn add(self, other: Fq) -> Fq {
201 Fq(self.0 + other.0)
202 }
203}
204
205impl Sub<Fq> for Fq {
206 type Output = Fq;
207
208 fn sub(self, other: Fq) -> Fq {
209 Fq(self.0 - other.0)
210 }
211}
212
213impl Neg for Fq {
214 type Output = Fq;
215
216 fn neg(self) -> Fq {
217 Fq(-self.0)
218 }
219}
220
221impl Mul for Fq {
222 type Output = Fq;
223
224 fn mul(self, other: Fq) -> Fq {
225 Fq(self.0 * other.0)
226 }
227}
228
229#[derive(Copy, Clone, Debug, PartialEq, Eq)]
230#[repr(C)]
231pub struct Fq2(fields::Fq2);
232
233impl Fq2 {
234 pub fn one() -> Fq2 {
235 Fq2(fields::Fq2::one())
236 }
237
238 pub fn i() -> Fq2 {
239 Fq2(fields::Fq2::i())
240 }
241
242 pub fn zero() -> Fq2 {
243 Fq2(fields::Fq2::zero())
244 }
245
246 pub fn new(a: Fq, b: Fq) -> Fq2 {
248 Fq2(fields::Fq2::new(a.0, b.0))
249 }
250
251 pub fn is_zero(&self) -> bool {
252 self.0.is_zero()
253 }
254
255 pub fn pow(&self, exp: arith::U256) -> Self {
256 Fq2(self.0.pow(exp))
257 }
258
259 pub fn real(&self) -> Fq {
260 Fq(*self.0.real())
261 }
262
263 pub fn imaginary(&self) -> Fq {
264 Fq(*self.0.imaginary())
265 }
266
267 pub fn sqrt(&self) -> Option<Self> {
268 self.0.sqrt().map(Fq2)
269 }
270
271 pub fn from_slice(bytes: &[u8]) -> Result<Self, FieldError> {
272 let u512 = arith::U512::from_slice(bytes).map_err(|_| FieldError::InvalidU512Encoding)?;
273 let (res, c0) = u512.divrem(&Fq::modulus());
274 Ok(Fq2::new(
275 Fq::from_u256(c0).map_err(|_| FieldError::NotMember)?,
276 Fq::from_u256(res.ok_or(FieldError::NotMember)?).map_err(|_| FieldError::NotMember)?,
277 ))
278 }
279}
280
281impl Add<Fq2> for Fq2 {
282 type Output = Self;
283
284 fn add(self, other: Self) -> Self {
285 Fq2(self.0 + other.0)
286 }
287}
288
289impl Sub<Fq2> for Fq2 {
290 type Output = Self;
291
292 fn sub(self, other: Self) -> Self {
293 Fq2(self.0 - other.0)
294 }
295}
296
297impl Neg for Fq2 {
298 type Output = Self;
299
300 fn neg(self) -> Self {
301 Fq2(-self.0)
302 }
303}
304
305impl Mul for Fq2 {
306 type Output = Self;
307
308 fn mul(self, other: Self) -> Self {
309 Fq2(self.0 * other.0)
310 }
311}
312
313pub trait Group:
314 Send
315 + Sync
316 + Copy
317 + Clone
318 + PartialEq
319 + Eq
320 + Sized
321 + Add<Self, Output = Self>
322 + Sub<Self, Output = Self>
323 + Neg<Output = Self>
324 + Mul<Fr, Output = Self>
325{
326 fn zero() -> Self;
327 fn one() -> Self;
328 fn is_zero(&self) -> bool;
329 fn normalize(&mut self);
330}
331
332#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
333#[repr(C)]
334pub struct G1(groups::G1);
335
336impl G1 {
337 pub fn new(x: Fq, y: Fq, z: Fq) -> Self {
338 G1(groups::G1::new(x.0, y.0, z.0))
339 }
340
341 pub fn x(&self) -> Fq {
342 Fq(self.0.x().clone())
343 }
344
345 pub fn set_x(&mut self, x: Fq) {
346 *self.0.x_mut() = x.0
347 }
348
349 pub fn y(&self) -> Fq {
350 Fq(self.0.y().clone())
351 }
352
353 pub fn set_y(&mut self, y: Fq) {
354 *self.0.y_mut() = y.0
355 }
356
357 pub fn z(&self) -> Fq {
358 Fq(self.0.z().clone())
359 }
360
361 pub fn set_z(&mut self, z: Fq) {
362 *self.0.z_mut() = z.0
363 }
364
365 pub fn b() -> Fq {
366 Fq(G1Params::coeff_b())
367 }
368
369 pub fn double(&self) -> Self {
370 G1(self.0.double())
371 }
372
373 pub fn from_compressed(bytes: &[u8]) -> Result<Self, CurveError> {
374 if bytes.len() != 33 {
375 return Err(CurveError::InvalidEncoding);
376 }
377
378 let sign = bytes[0];
379 let fq = Fq::from_slice(&bytes[1..])?;
380 let x = fq;
381 let y_squared = (fq * fq * fq) + Self::b();
382
383 let mut y = y_squared.sqrt().ok_or(CurveError::NotMember)?;
384
385 if sign == 2 && y.into_u256().get_bit(0).expect("bit 0 always exist; qed") {
386 y = y.neg();
387 } else if sign == 3 && !y.into_u256().get_bit(0).expect("bit 0 always exist; qed") {
388 y = y.neg();
389 } else if sign != 3 && sign != 2 {
390 return Err(CurveError::InvalidEncoding);
391 }
392 AffineG1::new(x, y)
393 .map_err(|_| CurveError::NotMember)
394 .map(Into::into)
395 }
396}
397
398impl Group for G1 {
399 fn zero() -> Self {
400 G1(groups::G1::zero())
401 }
402 fn one() -> Self {
403 G1(groups::G1::one())
404 }
405 fn is_zero(&self) -> bool {
406 self.0.is_zero()
407 }
408 fn normalize(&mut self) {
409 let new = match self.0.to_affine() {
410 Some(a) => a,
411 None => return,
412 };
413
414 self.0 = new.to_jacobian();
415 }
416}
417
418impl Add<G1> for G1 {
419 type Output = G1;
420
421 fn add(self, other: G1) -> G1 {
422 G1(self.0 + other.0)
423 }
424}
425
426impl Sub<G1> for G1 {
427 type Output = G1;
428
429 fn sub(self, other: G1) -> G1 {
430 G1(self.0 - other.0)
431 }
432}
433
434impl Neg for G1 {
435 type Output = G1;
436
437 fn neg(self) -> G1 {
438 G1(-self.0)
439 }
440}
441
442impl Mul<Fr> for G1 {
443 type Output = G1;
444
445 fn mul(self, other: Fr) -> G1 {
446 G1(self.0 * other.0)
447 }
448}
449
450#[derive(Copy, Clone, Debug, PartialEq, Eq)]
451#[repr(C)]
452pub struct AffineG1(groups::AffineG1);
453
454impl AffineG1 {
455 pub fn new(x: Fq, y: Fq) -> Result<Self, GroupError> {
456 Ok(AffineG1(groups::AffineG1::new(x.0, y.0)?))
457 }
458
459 pub fn x(&self) -> Fq {
460 Fq(self.0.x().clone())
461 }
462
463 pub fn set_x(&mut self, x: Fq) {
464 *self.0.x_mut() = x.0
465 }
466
467 pub fn y(&self) -> Fq {
468 Fq(self.0.y().clone())
469 }
470
471 pub fn set_y(&mut self, y: Fq) {
472 *self.0.y_mut() = y.0
473 }
474
475 pub fn from_jacobian(g1: G1) -> Option<Self> {
476 g1.0.to_affine().map(|x| AffineG1(x))
477 }
478}
479
480impl From<AffineG1> for G1 {
481 fn from(affine: AffineG1) -> Self {
482 G1(affine.0.to_jacobian())
483 }
484}
485
486#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
487#[repr(C)]
488pub struct G2(groups::G2);
489
490impl G2 {
491 pub fn new(x: Fq2, y: Fq2, z: Fq2) -> Self {
492 G2(groups::G2::new(x.0, y.0, z.0))
493 }
494
495 pub fn x(&self) -> Fq2 {
496 Fq2(self.0.x().clone())
497 }
498
499 pub fn set_x(&mut self, x: Fq2) {
500 *self.0.x_mut() = x.0
501 }
502
503 pub fn y(&self) -> Fq2 {
504 Fq2(self.0.y().clone())
505 }
506
507 pub fn set_y(&mut self, y: Fq2) {
508 *self.0.y_mut() = y.0
509 }
510
511 pub fn z(&self) -> Fq2 {
512 Fq2(self.0.z().clone())
513 }
514
515 pub fn set_z(&mut self, z: Fq2) {
516 *self.0.z_mut() = z.0
517 }
518
519 pub fn b() -> Fq2 {
520 Fq2(G2Params::coeff_b())
521 }
522
523 pub fn from_compressed(bytes: &[u8]) -> Result<Self, CurveError> {
524 if bytes.len() != 65 {
525 return Err(CurveError::InvalidEncoding);
526 }
527
528 let sign = bytes[0];
529 let x = Fq2::from_slice(&bytes[1..])?;
530
531 let y_squared = (x * x * x) + G2::b();
532 let y = y_squared.sqrt().ok_or(CurveError::NotMember)?;
533 let y_neg = -y;
534
535 let y_gt = y.0.to_u512() > y_neg.0.to_u512();
536
537 let e_y = if sign == 10 {
538 if y_gt { y_neg } else { y }
539 } else if sign == 11 {
540 if y_gt { y } else { y_neg }
541 } else {
542 return Err(CurveError::InvalidEncoding);
543 };
544
545 AffineG2::new(x, e_y)
546 .map_err(|_| CurveError::NotMember)
547 .map(Into::into)
548 }
549}
550
551impl Group for G2 {
552 fn zero() -> Self {
553 G2(groups::G2::zero())
554 }
555 fn one() -> Self {
556 G2(groups::G2::one())
557 }
558 fn is_zero(&self) -> bool {
559 self.0.is_zero()
560 }
561 fn normalize(&mut self) {
562 let new = match self.0.to_affine() {
563 Some(a) => a,
564 None => return,
565 };
566
567 self.0 = new.to_jacobian();
568 }
569}
570
571impl Add<G2> for G2 {
572 type Output = G2;
573
574 fn add(self, other: G2) -> G2 {
575 G2(self.0 + other.0)
576 }
577}
578
579impl Sub<G2> for G2 {
580 type Output = G2;
581
582 fn sub(self, other: G2) -> G2 {
583 G2(self.0 - other.0)
584 }
585}
586
587impl Neg for G2 {
588 type Output = G2;
589
590 fn neg(self) -> G2 {
591 G2(-self.0)
592 }
593}
594
595impl Mul<Fr> for G2 {
596 type Output = G2;
597
598 fn mul(self, other: Fr) -> G2 {
599 G2(self.0 * other.0)
600 }
601}
602
603#[derive(Copy, Clone, PartialEq, Eq)]
604#[repr(C)]
605pub struct Gt(fields::Fq12);
606
607impl Gt {
608 pub fn one() -> Self {
609 Gt(fields::Fq12::one())
610 }
611 pub fn pow(&self, exp: Fr) -> Self {
612 Gt(self.0.pow(exp.0))
613 }
614 pub fn inverse(&self) -> Option<Self> {
615 self.0.inverse().map(Gt)
616 }
617 pub fn final_exponentiation(&self) -> Option<Self> {
618 self.0.final_exponentiation().map(Gt)
619 }
620}
621
622impl Mul<Gt> for Gt {
623 type Output = Gt;
624
625 fn mul(self, other: Gt) -> Gt {
626 Gt(self.0 * other.0)
627 }
628}
629
630pub fn pairing(p: G1, q: G2) -> Gt {
631 Gt(groups::pairing(&p.0, &q.0))
632}
633
634pub fn pairing_batch(pairs: &[(G1, G2)]) -> Gt {
635 let mut ps = [groups::G1::default(); 16];
636 let mut qs = [groups::G2::default(); 16];
637 for (i, (p, q)) in pairs.iter().enumerate() {
638 ps[i] = p.0;
639 qs[i] = q.0;
640 }
641 Gt(groups::pairing_batch(
642 &ps[0..pairs.len()],
643 &qs[0..pairs.len()],
644 ))
645}
646
647pub fn miller_loop_batch(pairs: &[(G2, G1)]) -> Result<Gt, CurveError> {
648 let mut ps = [groups::G2Precomp::default(); 16];
649 let mut qs = [groups::AffineG::<groups::G1Params>::default(); 16];
650 for (i, (p, q)) in pairs.iter().enumerate() {
651 ps[i] =
652 p.0.to_affine()
653 .ok_or(CurveError::ToAffineConversion)?
654 .precompute();
655 qs[i] = q.0.to_affine().ok_or(CurveError::ToAffineConversion)?;
656 }
657 Ok(Gt(groups::miller_loop_batch(&ps, &qs)))
658}
659
660#[derive(Copy, Clone, PartialEq, Eq)]
661#[repr(C)]
662pub struct AffineG2(groups::AffineG2);
663
664impl AffineG2 {
665 pub fn new(x: Fq2, y: Fq2) -> Result<Self, GroupError> {
666 Ok(AffineG2(groups::AffineG2::new(x.0, y.0)?))
667 }
668
669 pub fn x(&self) -> Fq2 {
670 Fq2(self.0.x().clone())
671 }
672
673 pub fn set_x(&mut self, x: Fq2) {
674 *self.0.x_mut() = x.0
675 }
676
677 pub fn y(&self) -> Fq2 {
678 Fq2(self.0.y().clone())
679 }
680
681 pub fn set_y(&mut self, y: Fq2) {
682 *self.0.y_mut() = y.0
683 }
684
685 pub fn from_jacobian(g2: G2) -> Option<Self> {
686 g2.0.to_affine().map(|x| AffineG2(x))
687 }
688}
689
690impl From<AffineG2> for G2 {
691 fn from(affine: AffineG2) -> Self {
692 G2(affine.0.to_jacobian())
693 }
694}