win_crypto_ng/asymmetric/
ecc.rs

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