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}