ts_crypto/
eddsa.rs

1//! Edwards keys
2
3use const_oid::ObjectIdentifier;
4use der::{Decode, asn1::OctetString};
5use pkcs8::PrivateKeyInfoRef;
6use signature::{SignatureEncoding, Signer};
7
8pub use const_oid::db::rfc8410::{ID_ED_448, ID_ED_25519};
9pub use ed448_goldilocks::{SigningKey as Ed448SigningKey, VerifyingKey as Ed448VerifyingKey};
10pub use ed25519_dalek::{SigningKey as Ed25519SigningKey, VerifyingKey as Ed25519VerifyingKey};
11
12/// A verifying key using `EdDSA`.
13pub trait VerifyingKey {
14    /// Returns if this key verifies the message to match the signature.
15    fn verifies(&self, signature: &[u8], message: &[u8]) -> bool;
16
17    /// Get this key's raw public key representation.
18    fn raw_public_key(&self) -> Vec<u8>;
19
20    /// Create a verifying key from a raw public key.
21    fn from_raw_public_key(bytes: &[u8]) -> Option<Self>
22    where
23        Self: Sized;
24
25    /// Get the object identifier of the curve.
26    fn curve_oid(&self) -> ObjectIdentifier;
27
28    /// Create a new key from a subject public key info der.
29    fn from_spki_der(der: &[u8]) -> Option<Self>
30    where
31        Self: Sized;
32}
33
34/// A singing key using `EdDSA`
35pub trait SigningKey {
36    /// Sign the message using this key.
37    fn sign(&self, message: &[u8]) -> Vec<u8>;
38
39    /// Create a new key from a PKCS8 DER.
40    fn from_pkcs8_der(der: &[u8]) -> Option<Self>
41    where
42        Self: Sized;
43
44    /// Create a verifying key from this key.
45    fn verifying_key(&self) -> Box<dyn VerifyingKey>;
46}
47
48impl VerifyingKey for Ed25519VerifyingKey {
49    fn verifies(&self, signature: &[u8], message: &[u8]) -> bool {
50        let Ok(signature) = ed25519_dalek::Signature::from_slice(signature) else {
51            return false;
52        };
53        self.verify_strict(message, &signature).is_ok()
54    }
55
56    fn raw_public_key(&self) -> Vec<u8> {
57        self.as_bytes().to_vec()
58    }
59
60    fn from_raw_public_key(bytes: &[u8]) -> Option<Self>
61    where
62        Self: Sized,
63    {
64        let key = Self::from_bytes(bytes.try_into().ok()?).ok()?;
65        if key.is_weak() {
66            return None;
67        }
68        Some(key)
69    }
70
71    fn from_spki_der(der: &[u8]) -> Option<Self>
72    where
73        Self: Sized,
74    {
75        <Self as pkcs8::DecodePublicKey>::from_public_key_der(der).ok()
76    }
77
78    fn curve_oid(&self) -> ObjectIdentifier {
79        ID_ED_25519
80    }
81}
82
83impl VerifyingKey for Ed448VerifyingKey {
84    fn verifies(&self, signature: &[u8], message: &[u8]) -> bool {
85        let Ok(signature) = ed448_goldilocks::Signature::from_slice(signature) else {
86            return false;
87        };
88        self.verify_raw(&signature, message).is_ok()
89    }
90
91    fn raw_public_key(&self) -> Vec<u8> {
92        self.as_bytes().to_vec()
93    }
94
95    fn from_raw_public_key(bytes: &[u8]) -> Option<Self>
96    where
97        Self: Sized,
98    {
99        let key = Self::from_bytes(bytes.try_into().ok()?).ok()?;
100        Some(key)
101    }
102
103    fn from_spki_der(der: &[u8]) -> Option<Self>
104    where
105        Self: Sized,
106    {
107        <Self as pkcs8::DecodePublicKey>::from_public_key_der(der).ok()
108    }
109
110    fn curve_oid(&self) -> ObjectIdentifier {
111        ID_ED_448
112    }
113}
114
115impl SigningKey for Ed25519SigningKey {
116    fn sign(&self, message: &[u8]) -> Vec<u8> {
117        <Self as Signer<ed25519::Signature>>::sign(self, message).to_vec()
118    }
119
120    fn from_pkcs8_der(der: &[u8]) -> Option<Self>
121    where
122        Self: Sized,
123    {
124        let pkcs = PrivateKeyInfoRef::from_der(der).ok()?;
125        let octet_string = OctetString::from_der(pkcs.private_key.as_bytes()).ok()?;
126        let key = ed25519_dalek::SecretKey::try_from(octet_string.as_bytes()).ok()?;
127        Some(Self::from(key))
128    }
129
130    fn verifying_key(&self) -> Box<dyn VerifyingKey> {
131        Box::new(self.verifying_key())
132    }
133}
134
135impl SigningKey for Ed448SigningKey {
136    fn sign(&self, message: &[u8]) -> Vec<u8> {
137        <Self as Signer<ed448::Signature>>::sign(self, message).to_vec()
138    }
139
140    fn from_pkcs8_der(der: &[u8]) -> Option<Self>
141    where
142        Self: Sized,
143    {
144        let pkcs = PrivateKeyInfoRef::from_der(der).ok()?;
145        let octet_string = OctetString::from_der(pkcs.private_key.as_bytes()).ok()?;
146        let key = ed448_goldilocks::SecretKey::try_from(octet_string.as_bytes()).ok()?;
147        Some(Self::from(key))
148    }
149
150    fn verifying_key(&self) -> Box<dyn VerifyingKey> {
151        Box::new(self.verifying_key())
152    }
153}