Skip to main content

ckb_alt_bn128/
lib.rs

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) // todo: maybe more sensful error handling
41            .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) // todo: maybe more sensful error handling
168            .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        // convert from Montgomery representation
174        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    /// Initalizes new F_q2(a + bi, a is real coeff, b is imaginary)
247    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}