arnaucube
arnaucube/plonky2-ecdsaPublic Self-hosted repository
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}