1use scrypt::password_hash::rand_core::{self, RngCore};
2
3use crate::{errors::Result, PublicKeyBox, SecretKeyBox};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct KeyPairBox<'p, 's> {
9 pub public_key_box: PublicKeyBox<'p>,
11 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 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}