1 // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 // Copyright by contributors to this project.
3 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
4 
5 use mls_rs_core::crypto::CipherSuite;
6 
7 /// Elliptic curve types
8 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
9 #[repr(u8)]
10 #[non_exhaustive]
11 pub enum Curve {
12     /// NIST Curve-P256
13     P256,
14     /// NIST Curve-P384
15     P384,
16     /// NIST Curve-P521
17     P521,
18     /// Elliptic-curve Diffie-Hellman key exchange Curve25519
19     X25519,
20     /// Edwards-curve Digital Signature Algorithm Curve25519
21     Ed25519,
22     /// Elliptic-curve Diffie-Hellman key exchange Curve448
23     X448,
24     /// Edwards-curve Digital Signature Algorithm Curve448
25     Ed448,
26 }
27 
28 impl Curve {
29     /// Returns the amount of bytes of a secret key using this curve
30     #[inline(always)]
secret_key_size(&self) -> usize31     pub fn secret_key_size(&self) -> usize {
32         match self {
33             Curve::P256 => 32,
34             Curve::P384 => 48,
35             Curve::P521 => 66,
36             Curve::X25519 => 32,
37             Curve::Ed25519 => 64,
38             Curve::X448 => 56,
39             Curve::Ed448 => 114,
40         }
41     }
42 
43     #[inline(always)]
public_key_size(&self) -> usize44     pub fn public_key_size(&self) -> usize {
45         match self {
46             Curve::P256 | Curve::P384 | Curve::P521 => 2 * self.secret_key_size() + 1,
47             Curve::X25519 | Curve::Ed25519 | Curve::X448 | Curve::Ed448 => self.secret_key_size(),
48         }
49     }
50 
from_ciphersuite(cipher_suite: CipherSuite, for_sig: bool) -> Option<Self>51     pub fn from_ciphersuite(cipher_suite: CipherSuite, for_sig: bool) -> Option<Self> {
52         match cipher_suite {
53             CipherSuite::P256_AES128 => Some(Curve::P256),
54             CipherSuite::P384_AES256 => Some(Curve::P384),
55             CipherSuite::P521_AES256 => Some(Curve::P521),
56             CipherSuite::CURVE25519_AES128 | CipherSuite::CURVE25519_CHACHA if for_sig => {
57                 Some(Curve::Ed25519)
58             }
59             CipherSuite::CURVE25519_AES128 | CipherSuite::CURVE25519_CHACHA => Some(Curve::X25519),
60             CipherSuite::CURVE448_AES256 | CipherSuite::CURVE448_CHACHA if for_sig => {
61                 Some(Curve::Ed448)
62             }
63             CipherSuite::CURVE448_AES256 | CipherSuite::CURVE448_CHACHA => Some(Curve::X448),
64             _ => None,
65         }
66     }
67 
68     #[inline(always)]
curve_bitmask(&self) -> Option<u8>69     pub fn curve_bitmask(&self) -> Option<u8> {
70         match self {
71             Curve::P256 | Curve::P384 => Some(0xFF),
72             Curve::P521 => Some(0x01),
73             _ => None,
74         }
75     }
76 }
77