mini_sign/
keypair.rs

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