sp1_lib/
bn254.rs

1use crate::{
2    syscall_bn254_add, syscall_bn254_double,
3    utils::{AffinePoint, WeierstrassAffinePoint, WeierstrassPoint},
4};
5
6/// The number of limbs in [Bn254AffinePoint].
7pub const N: usize = 16;
8
9/// A point on the Bn254 curve.
10#[derive(Copy, Clone)]
11#[repr(align(4))]
12pub struct Bn254Point(pub WeierstrassPoint<N>);
13
14impl WeierstrassAffinePoint<N> for Bn254Point {
15    fn infinity() -> Self {
16        Self(WeierstrassPoint::Infinity)
17    }
18
19    fn is_infinity(&self) -> bool {
20        matches!(self.0, WeierstrassPoint::Infinity)
21    }
22}
23
24impl AffinePoint<N> for Bn254Point {
25    const GENERATOR: [u32; N] = [1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0];
26
27    #[allow(deprecated)]
28    /// The generator has been taken from py_pairing python library by the Ethereum Foundation:
29    ///
30    /// https://github.com/ethereum/py_pairing/blob/5f609da/py_ecc/bn128/bn128_field_elements.py
31    const GENERATOR_T: Self = Self(WeierstrassPoint::Affine(Self::GENERATOR));
32
33    fn new(limbs: [u32; N]) -> Self {
34        Self(WeierstrassPoint::Affine(limbs))
35    }
36
37    fn identity() -> Self {
38        Self::infinity()
39    }
40
41    fn is_identity(&self) -> bool {
42        self.is_infinity()
43    }
44
45    fn limbs_ref(&self) -> &[u32; N] {
46        match &self.0 {
47            WeierstrassPoint::Infinity => panic!("Infinity point has no limbs"),
48            WeierstrassPoint::Affine(limbs) => limbs,
49        }
50    }
51
52    fn limbs_mut(&mut self) -> &mut [u32; N] {
53        match &mut self.0 {
54            WeierstrassPoint::Infinity => panic!("Infinity point has no limbs"),
55            WeierstrassPoint::Affine(limbs) => limbs,
56        }
57    }
58
59    fn add_assign(&mut self, other: &Self) {
60        let a = self.limbs_mut();
61        let b = other.limbs_ref();
62        unsafe {
63            syscall_bn254_add(a, b);
64        }
65    }
66
67    fn complete_add_assign(&mut self, other: &Self) {
68        self.weierstrass_add_assign(other);
69    }
70
71    fn double(&mut self) {
72        let a = self.limbs_mut();
73        unsafe {
74            syscall_bn254_double(a);
75        }
76    }
77}