openvm_ecc_guest/
k256.rs
1extern crate alloc;
2
3use core::ops::{Add, Neg};
4
5use hex_literal::hex;
6#[cfg(not(target_os = "zkvm"))]
7use lazy_static::lazy_static;
8#[cfg(not(target_os = "zkvm"))]
9use num_bigint::BigUint;
10use openvm_algebra_guest::{Field, IntMod};
11use openvm_algebra_moduli_macros::moduli_declare;
12use openvm_ecc_sw_macros::sw_declare;
13
14use super::group::{CyclicGroup, Group};
15use crate::weierstrass::{CachedMulTable, IntrinsicCurve};
16
17#[cfg(not(target_os = "zkvm"))]
18lazy_static! {
19 pub static ref SECP256K1_MODULUS: BigUint = BigUint::from_bytes_be(&hex!(
21 "FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F"
22 ));
23 pub static ref SECP256K1_ORDER: BigUint = BigUint::from_bytes_be(&hex!(
24 "FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141"
25 ));
26}
27
28pub const SECP256K1_NUM_LIMBS: usize = 32;
29pub const SECP256K1_LIMB_BITS: usize = 8;
30pub const SECP256K1_BLOCK_SIZE: usize = 32;
31const CURVE_B: Secp256k1Coord = Secp256k1Coord::from_const_bytes(seven_le());
32const fn seven_le() -> [u8; 32] {
33 let mut buf = [0u8; 32];
34 buf[0] = 7;
35 buf
36}
37
38moduli_declare! {
39 Secp256k1Coord { modulus = "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F" },
40 Secp256k1Scalar { modulus = "0xFFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141" },
41}
42
43sw_declare! {
44 Secp256k1Point { mod_type = Secp256k1Coord, b = CURVE_B },
45}
46
47impl Field for Secp256k1Coord {
48 const ZERO: Self = <Self as IntMod>::ZERO;
49 const ONE: Self = <Self as IntMod>::ONE;
50
51 type SelfRef<'a> = &'a Self;
52
53 fn double_assign(&mut self) {
54 IntMod::double_assign(self);
55 }
56
57 fn square_assign(&mut self) {
58 IntMod::square_assign(self);
59 }
60}
61
62impl CyclicGroup for Secp256k1Point {
63 const GENERATOR: Self = Secp256k1Point {
65 x: Secp256k1Coord::from_const_bytes(hex!(
67 "9817F8165B81F259D928CE2DDBFC9B02070B87CE9562A055ACBBDCF97E66BE79"
68 )),
69 y: Secp256k1Coord::from_const_bytes(hex!(
70 "B8D410FB8FD0479C195485A648B417FDA808110EFCFBA45D65C4A32677DA3A48"
71 )),
72 };
73 const NEG_GENERATOR: Self = Secp256k1Point {
74 x: Secp256k1Coord::from_const_bytes(hex!(
75 "9817F8165B81F259D928CE2DDBFC9B02070B87CE9562A055ACBBDCF97E66BE79"
76 )),
77 y: Secp256k1Coord::from_const_bytes(hex!(
78 "7727EF046F2FB863E6AB7A59B74BE80257F7EEF103045BA29A3B5CD98825C5B7"
79 )),
80 };
81}
82
83impl IntrinsicCurve for k256::Secp256k1 {
84 type Scalar = Secp256k1Scalar;
85 type Point = Secp256k1Point;
86
87 fn msm(coeffs: &[Self::Scalar], bases: &[Self::Point]) -> Self::Point
88 where
89 for<'a> &'a Self::Point: Add<&'a Self::Point, Output = Self::Point>,
90 {
91 if coeffs.len() < 25 {
93 let table = CachedMulTable::<Self>::new_with_prime_order(bases, 4);
94 table.windowed_mul(coeffs)
95 } else {
96 crate::msm(coeffs, bases)
97 }
98 }
99}