Skip to content

Commit

Permalink
weierstrass: initial crate
Browse files Browse the repository at this point in the history
Implements `AffinePoint` and `ProjectivePoint` generically for both the
`p256` and `p384` crates, with the potential to use it for
`bp256`/`bp384`/`p521`.
  • Loading branch information
tarcieri committed Aug 3, 2022
1 parent b52672c commit c5fc82f
Show file tree
Hide file tree
Showing 32 changed files with 2,524 additions and 2,622 deletions.
71 changes: 71 additions & 0 deletions .github/workflows/weierstrass.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: weierstrass

on:
pull_request:
paths:
- ".github/workflows/weierstrass.yml"
- "weierstrass/**"
- "Cargo.*"
push:
branches: master

defaults:
run:
working-directory: weierstrass

env:
CARGO_INCREMENTAL: 0
RUSTFLAGS: "-Dwarnings"
RUSTDOCFLAGS: "-Dwarnings"

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.57.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
- wasm32-unknown-unknown
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
override: true
profile: minimal
- run: cargo build --target ${{ matrix.target }} --release --no-default-features

test:
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.57.0 # MSRV
- stable
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
override: true
profile: minimal
- run: cargo check --all-features
- run: cargo test --no-default-features
- run: cargo test
- run: cargo test --all-features

doc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: RustCrypto/actions/cargo-cache@master
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
profile: minimal
- run: cargo doc --all-features
13 changes: 11 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ members = [
"k256",
"p256",
"p384",
"p521"
"p521",
"weierstrass"
]

[profile.dev]
Expand Down
5 changes: 3 additions & 2 deletions p256/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "p256"
version = "0.11.1"
version = "0.12.0-pre"
description = """
Pure Rust implementation of the NIST P-256 (a.k.a. secp256r1, prime256v1)
elliptic curve with support for ECDH, ECDSA signing/verification, and general
Expand All @@ -17,7 +17,8 @@ edition = "2021"
rust-version = "1.57"

[dependencies]
elliptic-curve = { version = "0.12.3", default-features = false, features = ["hazmat", "sec1"] }
elliptic-curve = { version = "0.12", default-features = false, features = ["hazmat", "sec1"] }
weierstrass = { version = "0", path = "../weierstrass" }

# optional dependencies
ecdsa-core = { version = "0.14", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
Expand Down
127 changes: 73 additions & 54 deletions p256/src/arithmetic.rs
Original file line number Diff line number Diff line change
@@ -1,63 +1,82 @@
//! Pure Rust implementation of group operations on secp256r1.
pub(crate) mod affine;
pub(crate) mod field;
#[cfg(feature = "hash2curve")]
mod hash2curve;
pub(crate) mod projective;
pub(crate) mod scalar;
pub(crate) mod util;

use affine::AffinePoint;
use field::{FieldElement, MODULUS};
use projective::ProjectivePoint;
use scalar::Scalar;

/// a = -3
const CURVE_EQUATION_A: FieldElement = FieldElement::ZERO
.subtract(&FieldElement::ONE)
.subtract(&FieldElement::ONE)
.subtract(&FieldElement::ONE);

/// b = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B
const CURVE_EQUATION_B: FieldElement = FieldElement([
0xd89c_df62_29c4_bddf,
0xacf0_05cd_7884_3090,
0xe5a2_20ab_f721_2ed6,
0xdc30_061d_0487_4834,
]);

#[cfg(test)]
mod tests {
use super::{CURVE_EQUATION_A, CURVE_EQUATION_B};
use hex_literal::hex;

const CURVE_EQUATION_A_BYTES: &[u8] =
&hex!("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC");

const CURVE_EQUATION_B_BYTES: &[u8] =
&hex!("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B");

#[test]
fn verify_constants() {
assert_eq!(
CURVE_EQUATION_A.to_bytes().as_slice(),
CURVE_EQUATION_A_BYTES
);
assert_eq!(
CURVE_EQUATION_B.to_bytes().as_slice(),
CURVE_EQUATION_B_BYTES
);
}

#[test]
fn generate_secret_key() {
use crate::SecretKey;
use elliptic_curve::rand_core::OsRng;

let key = SecretKey::random(&mut OsRng);

// Sanity check
assert!(!key.to_be_bytes().iter().all(|b| *b == 0))
}
use self::{field::FieldElement, scalar::Scalar};
use crate::NistP256;
use elliptic_curve::{
AffineArithmetic, PrimeCurveArithmetic, ProjectiveArithmetic, ScalarArithmetic,
};
use weierstrass::WeierstrassCurve;

/// Elliptic curve point in affine coordinates.
pub type AffinePoint = weierstrass::AffinePoint<NistP256>;

/// Elliptic curve point in projective coordinates.
pub type ProjectivePoint = weierstrass::ProjectivePoint<NistP256>;

impl WeierstrassCurve for NistP256 {
type FieldElement = FieldElement;

const ZERO: FieldElement = FieldElement::ZERO;
const ONE: FieldElement = FieldElement::ONE;

/// a = -3
const EQUATION_A: FieldElement = FieldElement::ZERO
.sub(&FieldElement::ONE)
.sub(&FieldElement::ONE)
.sub(&FieldElement::ONE);

/// b = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B
const EQUATION_B: FieldElement = FieldElement([
0xd89c_df62_29c4_bddf,
0xacf0_05cd_7884_3090,
0xe5a2_20ab_f721_2ed6,
0xdc30_061d_0487_4834,
]);

/// Base point of P-256.
///
/// Defined in FIPS 186-4 § D.1.2.3:
///
/// ```text
/// Gₓ = 6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296
/// Gᵧ = 4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5
/// ```
const GENERATOR: (FieldElement, FieldElement) = (
FieldElement([
0xf4a1_3945_d898_c296,
0x7703_7d81_2deb_33a0,
0xf8bc_e6e5_63a4_40f2,
0x6b17_d1f2_e12c_4247,
])
.to_montgomery(),
FieldElement([
0xcbb6_4068_37bf_51f5,
0x2bce_3357_6b31_5ece,
0x8ee7_eb4a_7c0f_9e16,
0x4fe3_42e2_fe1a_7f9b,
])
.to_montgomery(),
);
}

impl AffineArithmetic for NistP256 {
type AffinePoint = AffinePoint;
}

impl ProjectiveArithmetic for NistP256 {
type ProjectivePoint = ProjectivePoint;
}

impl PrimeCurveArithmetic for NistP256 {
type CurveGroup = ProjectivePoint;
}

impl ScalarArithmetic for NistP256 {
type Scalar = Scalar;
}
Loading

0 comments on commit c5fc82f

Please sign in to comment.