Skip to main content

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 = 8;
8
9/// An affine point on the Secp256k1 curve.
10#[derive(Copy, Clone, Debug)]
11#[repr(align(8))]
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: [u64; N] = [
26        17627433388654248598,
27        8575836109218198432,
28        17923454489921339634,
29        7716867327612699207,
30        14678990851816772085,
31        3156516839386865358,
32        10297457778147434006,
33        5756518291402817435,
34    ];
35
36    #[allow(deprecated)]
37    const GENERATOR_T: Self = Self(WeierstrassPoint::Affine(Self::GENERATOR));
38
39    fn new(limbs: [u64; N]) -> Self {
40        Self(WeierstrassPoint::Affine(limbs))
41    }
42
43    fn identity() -> Self {
44        Self::infinity()
45    }
46
47    fn is_identity(&self) -> bool {
48        self.is_infinity()
49    }
50
51    fn limbs_ref(&self) -> &[u64; N] {
52        match &self.0 {
53            WeierstrassPoint::Infinity => panic!("Infinity point has no limbs"),
54            WeierstrassPoint::Affine(limbs) => limbs,
55        }
56    }
57
58    fn limbs_mut(&mut self) -> &mut [u64; N] {
59        match &mut self.0 {
60            WeierstrassPoint::Infinity => panic!("Infinity point has no limbs"),
61            WeierstrassPoint::Affine(limbs) => limbs,
62        }
63    }
64
65    fn add_assign(&mut self, other: &Self) {
66        let a = self.limbs_mut();
67        let b = other.limbs_ref();
68        unsafe {
69            syscall_secp256r1_add(a, b);
70        }
71    }
72
73    fn complete_add_assign(&mut self, other: &Self) {
74        self.weierstrass_add_assign(other);
75    }
76
77    fn double(&mut self) {
78        match &mut self.0 {
79            WeierstrassPoint::Infinity => (),
80            WeierstrassPoint::Affine(limbs) => unsafe {
81                syscall_secp256r1_double(limbs);
82            },
83        }
84    }
85}