1use getrandom::rand_core::TryRng;
2use zeroize::Zeroize;
3
4use crate::{errors::Result, PublicKeyBox, SecretKeyBox};
5
6#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct KeyPairBox<'p, 's> {
10 pub public_key_box: PublicKeyBox<'p>,
12 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 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}