sp1_lib/
secp256k1.rs

1use crate::{
2    syscall_secp256k1_add, syscall_secp256k1_double,
3    utils::{AffinePoint, WeierstrassAffinePoint, WeierstrassPoint},
4};
5
6/// The number of limbs in [Secp256k1Point].
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 Secp256k1Point(pub WeierstrassPoint<N>);
13
14impl WeierstrassAffinePoint<N> for Secp256k1Point {
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 Secp256k1Point {
25    /// The values are taken from https://en.bitcoin.it/wiki/Secp256k1.
26    const GENERATOR: [u32; N] = [
27        385357720, 1509065051, 768485593, 43777243, 3464956679, 1436574357, 4191992748, 2042521214,
28        4212184248, 2621952143, 2793755673, 4246189128, 235997352, 1571093500, 648266853,
29        1211816567,
30    ];
31
32    #[allow(deprecated)]
33    const GENERATOR_T: Self = Self(WeierstrassPoint::Affine(Self::GENERATOR));
34
35    fn new(limbs: [u32; N]) -> Self {
36        Self(WeierstrassPoint::Affine(limbs))
37    }
38
39    fn identity() -> Self {
40        Self::infinity()
41    }
42
43    fn is_identity(&self) -> bool {
44        self.is_infinity()
45    }
46
47    fn limbs_ref(&self) -> &[u32; N] {
48        match &self.0 {
49            WeierstrassPoint::Infinity => panic!("Infinity point has no limbs"),
50            WeierstrassPoint::Affine(limbs) => limbs,
51        }
52    }
53
54    fn limbs_mut(&mut self) -> &mut [u32; N] {
55        match &mut self.0 {
56            WeierstrassPoint::Infinity => panic!("Infinity point has no limbs"),
57            WeierstrassPoint::Affine(limbs) => limbs,
58        }
59    }
60
61    fn add_assign(&mut self, other: &Self) {
62        let a = self.limbs_mut();
63        let b = other.limbs_ref();
64        unsafe {
65            syscall_secp256k1_add(a, b);
66        }
67    }
68
69    fn complete_add_assign(&mut self, other: &Self) {
70        self.weierstrass_add_assign(other);
71    }
72
73    fn double(&mut self) {
74        match &mut self.0 {
75            WeierstrassPoint::Infinity => (),
76            WeierstrassPoint::Affine(limbs) => unsafe {
77                syscall_secp256k1_double(limbs);
78            },
79        }
80    }
81}