Skip to main content

mini_sign/
keypair.rs

1use getrandom::rand_core::TryRng;
2use zeroize::Zeroize;
3
4use crate::{errors::Result, PublicKeyBox, SecretKeyBox};
5
6/// A `KeyPairBox` represents a minisign key pair.
7///
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct KeyPairBox<'p, 's> {
10    /// The public key box.
11    pub public_key_box: PublicKeyBox<'p>,
12    /// The secret key box.
13    pub secret_key_box: SecretKeyBox<'s>,
14}
15impl std::fmt::Display for KeyPairBox<'_, '_> {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        write!(f, "{}\n{}", self.public_key_box, self.secret_key_box)
18    }
19}
20impl<'p, 's> KeyPairBox<'p, 's> {
21    /// Generate a new key pair.
22    ///
23    /// # Arguments
24    /// * `password` - The password to encrypt the secret key.
25    /// * `pk_comment` - The comment for the public key.
26    /// * `sk_comment` - The comment for the secret key.
27    ///
28    /// # Returns
29    /// A new key pair.
30    ///
31    /// # Errors
32    /// * `ErrorKind::Kdf` - rng error
33    pub fn generate(
34        password: Option<&[u8]>,
35        pk_comment: Option<&'p str>,
36        sk_comment: Option<&'s str>,
37    ) -> Result<Self> {
38        let (pk, sk) = generate_keypair(password, pk_comment, sk_comment)?;
39        Ok(Self {
40            public_key_box: pk,
41            secret_key_box: sk,
42        })
43    }
44}
45fn generate_keypair<'a, 'b>(
46    password: Option<&[u8]>,
47    pk_comment: Option<&'a str>,
48    sk_comment: Option<&'b str>,
49) -> Result<(PublicKeyBox<'a>, SecretKeyBox<'b>)> {
50    let mut rng = getrandom::SysRng;
51    let mut kid = [0u8; 8];
52    rng.try_fill_bytes(&mut kid)?;
53
54    let mut seed = [0u8; 32];
55    rng.try_fill_bytes(&mut seed)?;
56    let sign_key = ed25519_dalek::SigningKey::from_bytes(&seed);
57    seed.zeroize();
58    let verify_key = sign_key.verifying_key();
59
60    let sk = SecretKeyBox::from_signing_key(sign_key, &kid, password, sk_comment)?;
61    let pk = PublicKeyBox::from_verifying_key(verify_key, &kid, pk_comment)?;
62    Ok((pk, sk))
63}