1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
//! Elliptic curve cryptography (ECC) primitives.
//!
//! The elliptic curve is a plane curve over a finite field which consists of
//! the points satisfying the following equation: <sup>[[1][curve]]</sup>
//!
//! y^2 = x^3 + ax + b
//!
//! [curve]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography#Theory
use winapi::shared::bcrypt::*;
/// Represents a named elliptic curve.
pub trait Curve {
/// Returns a type-erased [`NamedCurve`] enum (in contrast to a concrete
/// unit structs, e.g. [`NistP256`]).
///
/// [`NamedCurve`]: enum.NamedCurve.html
/// [`NistP256`]: struct.NistP256.html
fn as_curve(&self) -> NamedCurve;
/// Size of the field in bits that the curve is defined over.
///
/// NOTE: These are **NOT** bits of security.
fn key_bits(&self) -> u32;
}
/// NIST-P256 (a.k.a `secp256r1` or `prime256v1`).
///
/// Provides 128-bits of security and is defined over a field size of 256.
pub struct NistP256;
impl Curve for NistP256 {
fn as_curve(&self) -> NamedCurve {
NamedCurve::NistP256
}
fn key_bits(&self) -> u32 {
256
}
}
/// NIST-P384 (a.k.a `secp384r1` or `prime384v1`).
///
/// Provides 192-bits of security and is defined over a field size of 256.
pub struct NistP384;
impl Curve for NistP384 {
fn as_curve(&self) -> NamedCurve {
NamedCurve::NistP384
}
fn key_bits(&self) -> u32 {
384
}
}
/// NIST-521 (a.k.a `secp521r1` or `prime521v1`).
///
/// Provides 256-bits of security and is defined over a field size of 521.
pub struct NistP521;
impl Curve for NistP521 {
fn as_curve(&self) -> NamedCurve {
NamedCurve::NistP521
}
fn key_bits(&self) -> u32 {
521
}
}
/// Elliptic curve offering 128 bits of security and designed for use with the
/// elliptic curve Diffie–Hellman (ECDH) key agreement scheme.
pub struct Curve25519;
impl Curve for Curve25519 {
fn as_curve(&self) -> NamedCurve {
NamedCurve::Curve25519
}
fn key_bits(&self) -> u32 {
255
}
}
/// Type-erased named curve enumeration. For concrete types, see unit structs
/// defined in this module.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum NamedCurve {
/// NIST P-256. See [`NistP256`](struct.NistP256.html).
NistP256,
/// NIST P-384. See [`NistP384`](struct.NistP384.html).
NistP384,
/// NIST P-521. See [`NistP521`](struct.NistP521.html).
NistP521,
/// See [`Curve25519`](struct.Curve25519.html).
Curve25519,
// TODO: Implement more
}
impl NamedCurve {
pub fn to_str(self) -> &'static str {
match self {
Self::NistP256 => BCRYPT_ECC_CURVE_NISTP256,
Self::NistP384 => BCRYPT_ECC_CURVE_NISTP384,
Self::NistP521 => BCRYPT_ECC_CURVE_NISTP521,
Self::Curve25519 => BCRYPT_ECC_CURVE_25519,
}
}
pub fn key_bits(self) -> u32 {
match self {
Self::NistP256 => NistP256.key_bits(),
Self::NistP384 => NistP384.key_bits(),
Self::NistP521 => NistP521.key_bits(),
Self::Curve25519 => Curve25519.key_bits(),
}
}
}