plonky2-ecdsa/src/curve/secp256k1.rs
src/curve/secp256k1.rsRaw
1use plonky2::field::secp256k1_base::Secp256K1Base;
2use plonky2::field::secp256k1_scalar::Secp256K1Scalar;
3use plonky2::field::types::Field;
4use serde::{Deserialize, Serialize};
5
6use crate::curve::curve_types::{AffinePoint, Curve};
7
8#[derive(Debug, Copy, Clone, Deserialize, Eq, Hash, PartialEq, Serialize)]
9pub struct Secp256K1;
10
11impl Curve for Secp256K1 {
12 type BaseField = Secp256K1Base;
13 type ScalarField = Secp256K1Scalar;
14
15 const A: Secp256K1Base = Secp256K1Base::ZERO;
16 const B: Secp256K1Base = Secp256K1Base([7, 0, 0, 0]);
17 const GENERATOR_AFFINE: AffinePoint<Self> = AffinePoint {
18 x: SECP256K1_GENERATOR_X,
19 y: SECP256K1_GENERATOR_Y,
20 zero: false,
21 };
22}
23
24// 55066263022277343669578718895168534326250603453777594175500187360389116729240
25const SECP256K1_GENERATOR_X: Secp256K1Base = Secp256K1Base([
26 0x59F2815B16F81798,
27 0x029BFCDB2DCE28D9,
28 0x55A06295CE870B07,
29 0x79BE667EF9DCBBAC,
30]);
31
32/// 32670510020758816978083085130507043184471273380659243275938904335757337482424
33const SECP256K1_GENERATOR_Y: Secp256K1Base = Secp256K1Base([
34 0x9C47D08FFB10D4B8,
35 0xFD17B448A6855419,
36 0x5DA4FBFC0E1108A8,
37 0x483ADA7726A3C465,
38]);
39
40#[cfg(test)]
41mod tests {
42 use num::BigUint;
43 use plonky2::field::secp256k1_scalar::Secp256K1Scalar;
44 use plonky2::field::types::{Field, PrimeField};
45
46 use crate::curve::curve_types::{AffinePoint, Curve, ProjectivePoint};
47 use crate::curve::secp256k1::Secp256K1;
48
49 #[test]
50 fn test_generator() {
51 let g = Secp256K1::GENERATOR_AFFINE;
52 assert!(g.is_valid());
53
54 let neg_g = AffinePoint::<Secp256K1> {
55 x: g.x,
56 y: -g.y,
57 zero: g.zero,
58 };
59 assert!(neg_g.is_valid());
60 }
61
62 #[test]
63 fn test_naive_multiplication() {
64 let g = Secp256K1::GENERATOR_PROJECTIVE;
65 let ten = Secp256K1Scalar::from_canonical_u64(10);
66 let product = mul_naive(ten, g);
67 let sum = g + g + g + g + g + g + g + g + g + g;
68 assert_eq!(product, sum);
69 }
70
71 #[test]
72 fn test_g1_multiplication() {
73 let lhs = Secp256K1Scalar::from_noncanonical_biguint(BigUint::from_slice(&[
74 1111, 2222, 3333, 4444, 5555, 6666, 7777, 8888,
75 ]));
76 assert_eq!(
77 Secp256K1::convert(lhs) * Secp256K1::GENERATOR_PROJECTIVE,
78 mul_naive(lhs, Secp256K1::GENERATOR_PROJECTIVE)
79 );
80 }
81
82 /// A simple, somewhat inefficient implementation of multiplication which is used as a reference
83 /// for correctness.
84 fn mul_naive(
85 lhs: Secp256K1Scalar,
86 rhs: ProjectivePoint<Secp256K1>,
87 ) -> ProjectivePoint<Secp256K1> {
88 let mut g = rhs;
89 let mut sum = ProjectivePoint::ZERO;
90 for limb in lhs.to_canonical_biguint().to_u64_digits().iter() {
91 for j in 0..64 {
92 if (limb >> j & 1u64) != 0u64 {
93 sum = sum + g;
94 }
95 g = g.double();
96 }
97 }
98 sum
99 }
100}