signatory/ed25519/
sign.rs

1//! Ed25519 keys.
2
3use super::{Signature, VerifyingKey, ALGORITHM_ID, ALGORITHM_OID};
4use crate::{key::store::GeneratePkcs8, Error, Result};
5use alloc::boxed::Box;
6use core::fmt;
7use ed25519_dalek::SECRET_KEY_LENGTH;
8use rand_core::{OsRng, RngCore};
9use signature::Signer;
10use zeroize::Zeroizing;
11
12/// Ed25519 signing key.
13pub struct SigningKey {
14    inner: Box<dyn Ed25519Signer + Send + Sync>,
15}
16
17impl SigningKey {
18    /// Initialize from a provided signer object.
19    ///
20    /// Use [`SigningKey::from_bytes`] to initialize from a raw private key.
21    pub fn new(signer: Box<dyn Ed25519Signer + Send + Sync>) -> Self {
22        Self { inner: signer }
23    }
24
25    /// Initialize from a raw scalar value (big endian).
26    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
27        let signing_key = ed25519_dalek::SigningKey::try_from(bytes).map_err(|_| Error::Parse)?;
28        Ok(Self::new(Box::new(signing_key)))
29    }
30
31    /// Get the verifying key that corresponds to this signing key.
32    pub fn verifying_key(&self) -> VerifyingKey {
33        self.inner.verifying_key()
34    }
35}
36
37// TODO(tarcieri): use upstream decoder from `ed25519` crate.
38// See: https://docs.rs/ed25519/latest/ed25519/pkcs8/struct.KeypairBytes.html
39impl TryFrom<pkcs8::PrivateKeyInfo<'_>> for SigningKey {
40    type Error = pkcs8::Error;
41
42    fn try_from(private_key: pkcs8::PrivateKeyInfo<'_>) -> pkcs8::Result<Self> {
43        private_key.algorithm.assert_algorithm_oid(ALGORITHM_OID)?;
44
45        if private_key.algorithm.parameters.is_some() {
46            return Err(pkcs8::Error::ParametersMalformed);
47        }
48
49        Self::from_bytes(private_key.private_key).map_err(|_| pkcs8::Error::KeyMalformed)
50    }
51}
52
53#[cfg(feature = "std")]
54impl GeneratePkcs8 for SigningKey {
55    /// Randomly generate a new PKCS#8 private key.
56    fn generate_pkcs8() -> pkcs8::SecretDocument {
57        let mut private_key = Zeroizing::new([0u8; SECRET_KEY_LENGTH]);
58        OsRng.fill_bytes(&mut *private_key);
59        pkcs8::SecretDocument::encode_msg(&pkcs8::PrivateKeyInfo::new(ALGORITHM_ID, &*private_key))
60            .expect("DER encoding error")
61    }
62}
63
64impl Signer<Signature> for SigningKey {
65    fn try_sign(&self, msg: &[u8]) -> signature::Result<Signature> {
66        self.inner.try_sign(msg)
67    }
68}
69
70impl TryFrom<&[u8]> for SigningKey {
71    type Error = Error;
72
73    fn try_from(bytes: &[u8]) -> Result<Self> {
74        Self::from_bytes(bytes)
75    }
76}
77
78impl fmt::Debug for SigningKey {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        f.debug_struct("SigningKey")
81            .field("verifying_key", &self.verifying_key())
82            .finish()
83    }
84}
85
86/// Ed25519 signer
87pub trait Ed25519Signer: Signer<Signature> {
88    /// Get the ECDSA verifying key for this signer
89    fn verifying_key(&self) -> VerifyingKey;
90}
91
92impl<T> Ed25519Signer for T
93where
94    T: Signer<Signature>,
95    VerifyingKey: for<'a> From<&'a T>,
96{
97    fn verifying_key(&self) -> VerifyingKey {
98        self.into()
99    }
100}