cardano_sdk/cardano/crypto/ed25519/
signing_key.rs

1//  This Source Code Form is subject to the terms of the Mozilla Public
2//  License, v. 2.0. If a copy of the MPL was not distributed with this
3//  file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use crate::{Signature, VerificationKey, pallas::ed25519};
6use anyhow::anyhow;
7use rand_core::RngCore;
8use std::str::FromStr;
9
10/// An ed25519 signing key (non-extended).
11#[derive(Debug, Clone)]
12#[repr(transparent)]
13pub struct SigningKey(ed25519::SecretKey);
14
15// ----------------------------------------------------------------------- Using
16
17impl SigningKey {
18    pub const SIZE: usize = ed25519::SecretKey::SIZE;
19
20    /// Generate a new signing key using available system entropy.
21    pub fn new() -> Self {
22        let mut bytes = [0u8; 32];
23        rand_core::OsRng.fill_bytes(&mut bytes);
24        Self::from(bytes)
25    }
26
27    /// Convert the [`SecretKey`] into its compressed byte composition, and leak its bytes into
28    /// memory. Only use for storing the key securely or for testing. Additional precautions are
29    /// needed to ensure that the leaked bytes are properly de-allocated and cleared.
30    ///
31    /// # Safety
32    ///
33    /// This function is not safe because:
34    ///
35    /// * using it removes all the security measure we put in place
36    ///   to protect your private key: opaque [`Debug`] impl, zeroisation on [`Drop`], ...
37    /// * you will need to be careful not to leak the bytes
38    ///
39    /// # Example
40    ///
41    /// ```
42    /// # use cardano_sdk::SigningKey;
43    /// let key: SigningKey = // ...
44    /// # [0; SigningKey::SIZE].into() ;
45    /// let _: [u8; SigningKey::SIZE] = unsafe { SigningKey::leak(key) };
46    #[inline]
47    pub unsafe fn leak(key: Self) -> [u8; 32] {
48        unsafe { ed25519::SecretKey::leak_into_bytes(key.0) }
49    }
50
51    pub fn sign<T>(&self, msg: T) -> Signature
52    where
53        T: AsRef<[u8]>,
54    {
55        Signature::from(self.0.sign(msg))
56    }
57}
58
59impl Default for SigningKey {
60    fn default() -> Self {
61        Self::new()
62    }
63}
64
65// ----------------------------------------------------------- Converting (from)
66
67impl From<[u8; 32]> for SigningKey {
68    fn from(bytes: [u8; 32]) -> Self {
69        Self(ed25519::SecretKey::from(bytes))
70    }
71}
72
73impl TryFrom<Vec<u8>> for SigningKey {
74    type Error = anyhow::Error;
75
76    fn try_from(bytes: Vec<u8>) -> anyhow::Result<Self> {
77        let array = <[u8; 32]>::try_from(bytes).map_err(|_| anyhow!("invalid signing key"))?;
78        Ok(Self::from(array))
79    }
80}
81
82impl FromStr for SigningKey {
83    type Err = anyhow::Error;
84
85    fn from_str(s: &str) -> anyhow::Result<Self> {
86        let bytes =
87            hex::decode(s).map_err(|e| anyhow!(e).context("malformed base16 signing key"))?;
88
89        let array = <[u8; 32]>::try_from(bytes).map_err(|_| anyhow!("invalid signing key"))?;
90
91        Ok(Self::from(array))
92    }
93}
94
95// ------------------------------------------------------------- Converting (to)
96
97impl SigningKey {
98    pub fn to_verification_key(&self) -> VerificationKey {
99        VerificationKey::from(self)
100    }
101}
102
103impl From<&SigningKey> for VerificationKey {
104    fn from(key: &SigningKey) -> Self {
105        VerificationKey::from(key.0.public_key())
106    }
107}