Skip to main content

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