Skip to content

Commit

Permalink
feat: add support for secp256k1 elliptic curve
Browse files Browse the repository at this point in the history
Expand the elliptic curve implementation to support the secp256k1 curve,
which is widely used in cryptocurrencies like Bitcoin. This includes:

- Adding the secp256k1 curve parameters (a = 0, b = 7) and prime field.
- Implementing the base point (G) and order of the curve.
- Providing unit tests to verify that the base point lies on the curve
  and that multiplying the base point by the curve's order results in
  the point at infinity.

These changes improve the versatility of the library by allowing users
to perform cryptographic operations on the secp256k1 curve.
  • Loading branch information
pycckuu committed Sep 30, 2024
1 parent 9c46d3a commit b6edce1
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 5 deletions.
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This project implements Elliptic Curve Cryptography (ECC) operations in Rust. It

## Features

- Elliptic curve representation and operations
- Elliptic curve representation and operations (in Weierstrass form: y^2 = x^3 + ax + b)
- Point arithmetic on elliptic curves (addition, doubling, scalar multiplication)
- Finite field arithmetic
- Comprehensive test suite for all implemented operations
Expand All @@ -19,7 +19,7 @@ This is the main entry point of the library. It re-exports the public items from

### src/ec.rs

Contains the `EllipticCurve` struct and its implementation, which represents an elliptic curve and provides methods for curve operations.
Contains the `EllipticCurve` struct and its implementation, which represents an elliptic curve in Weierstrass form (y^2 = x^3 + ax + b) and provides methods for curve operations.

### src/point.rs

Expand All @@ -29,12 +29,29 @@ Defines the `Point` struct, representing a point on an elliptic curve, including

Implements the `FiniteField` struct with finite field arithmetic operations such as addition, multiplication, and inversion.

### src/curves/mod.rs and src/curves/bjj.rs
### src/curves/mod.rs and src/curves/secp256k1.rs

These files contain implementations of specific elliptic curves, including the Baby Jubjub (BJJ) curve.
These files contain implementations of specific elliptic curves

Each module contains its own tests, ensuring the correctness of the implemented operations.

### Supported Curves

This implementation currently supports the following elliptic curve:

#### secp256k1

The secp256k1 curve is widely used in cryptocurrencies, most notably Bitcoin. It is defined by the following parameters:

- **Equation**: y² = x³ + 7 (over a finite field)
- **Prime field**: p = 2²⁵⁶ - 2³² - 2⁹ - 2⁸ - 2⁷ - 2⁶ - 2⁴ - 1
- **Base point (G) coordinates**:
- x = 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 (hex)
- y = 483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 (hex)
- **Order (n)**: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 (hex)

The implementation of the secp256k1 curve can be found in: `src/curves/secp256k1.rs`

## Usage

To use this library in your Rust project, add it as a dependency in your `Cargo.toml` file:
Expand All @@ -52,7 +69,7 @@ use ecc_rust::{EllipticCurve, Point, FiniteField};
use num_bigint::BigUint;

fn main() {
// Create a new elliptic curve y^2 = x^3 + 2x + 2 over F_17
// Create a new elliptic curve in Weierstrass form: y^2 = x^3 + 2x + 2 over F_17
let curve = EllipticCurve::new(
BigUint::from(2u32),
BigUint::from(2u32),
Expand Down
1 change: 1 addition & 0 deletions src/curves/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod secp256k1;
43 changes: 43 additions & 0 deletions src/curves/secp256k1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use num_bigint::BigUint;
use crate::ec::EllipticCurve;
use crate::point::Point;

/// Returns the base point (generator) for the secp256k1 curve
pub fn base_point() -> Point {
let x = BigUint::parse_bytes(b"79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16).unwrap();
let y = BigUint::parse_bytes(b"483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16).unwrap();
Point::Coordinates(x, y)
}

/// Returns the secp256k1 curve parameters
pub fn secp256k1() -> EllipticCurve {
let p = BigUint::parse_bytes(b"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16).unwrap();
let a = BigUint::from(0u32);
let b = BigUint::from(7u32);

EllipticCurve { a, b, p }
}

/// Returns the order of the secp256k1 curve
pub fn curve_order() -> BigUint {
BigUint::parse_bytes(b"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16).unwrap()
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_secp256k1_params() {
let curve = secp256k1();
let g = base_point();
let n = curve_order();

// Verify that the base point is on the curve
assert!(curve.is_on_curve(&g), "Base point is not on the curve");

// Verify that n * G = O (point at infinity)
let result = curve.mul(&g, &n);
assert_eq!(result, Point::Identity, "n * G did not result in the point at infinity");
}
}

0 comments on commit b6edce1

Please sign in to comment.