diff --git a/README.md b/README.md index ea7da3f..5fe5500 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 @@ -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: @@ -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), diff --git a/src/curves/mod.rs b/src/curves/mod.rs new file mode 100644 index 0000000..b34f37a --- /dev/null +++ b/src/curves/mod.rs @@ -0,0 +1 @@ +pub mod secp256k1; \ No newline at end of file diff --git a/src/curves/secp256k1.rs b/src/curves/secp256k1.rs new file mode 100644 index 0000000..cd8d120 --- /dev/null +++ b/src/curves/secp256k1.rs @@ -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"); + } +} \ No newline at end of file