sp1_lib/
secp256r1.rs

1use crate::{
2    syscall_secp256r1_add, syscall_secp256r1_double,
3    utils::{AffinePoint, WeierstrassAffinePoint, WeierstrassPoint},
4};
5
6/// The number of limbs in [Secp256r1Point].
7pub const N: usize = 16;
8
9/// An affine point on the Secp256k1 curve.
10#[derive(Copy, Clone, Debug)]
11#[repr(align(4))]
12pub struct Secp256r1Point(pub WeierstrassPoint<N>);
13
14impl WeierstrassAffinePoint<N> for Secp256r1Point {
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 Secp256r1Point {
25    const GENERATOR: [u32; N] = [
26        3633889942, 4104206661, 770388896, 1996717441, 1671708914, 4173129445, 3777774151,
27        1796723186, 935285237, 3417718888, 1798397646, 734933847, 2081398294, 2397563722,
28        4263149467, 1340293858,
29    ];
30
31    #[allow(deprecated)]
32    const GENERATOR_T: Self = Self(WeierstrassPoint::Affine(Self::GENERATOR));
33
34    fn new(limbs: [u32; N]) -> Self {
35        Self(WeierstrassPoint::Affine(limbs))
36    }
37
38    fn identity() -> Self {
39        Self::infinity()
40    }
41
42    fn is_identity(&self) -> bool {
43        self.is_infinity()
44    }
45
46    fn limbs_ref(&self) -> &[u32; N] {
47        match &self.0 {
48            WeierstrassPoint::Infinity => panic!("Infinity point has no limbs"),
49            WeierstrassPoint::Affine(limbs) => limbs,
50        }
51    }
52
53    fn limbs_mut(&mut self) -> &mut [u32; N] {
54        match &mut self.0 {
55            WeierstrassPoint::Infinity => panic!("Infinity point has no limbs"),
56            WeierstrassPoint::Affine(limbs) => limbs,
57        }
58    }
59
60    fn add_assign(&mut self, other: &Self) {
61        let a = self.limbs_mut();
62        let b = other.limbs_ref();
63        unsafe {
64            syscall_secp256r1_add(a, b);
65        }
66    }
67
68    fn complete_add_assign(&mut self, other: &Self) {
69        self.weierstrass_add_assign(other);
70    }
71
72    fn double(&mut self) {
73        match &mut self.0 {
74            WeierstrassPoint::Infinity => (),
75            WeierstrassPoint::Affine(limbs) => unsafe {
76                syscall_secp256r1_double(limbs);
77            },
78        }
79    }
80}