diff --git a/radicle-crypto/src/lib.rs b/radicle-crypto/src/lib.rs index 96f9aa5f..abe51c57 100644 --- a/radicle-crypto/src/lib.rs +++ b/radicle-crypto/src/lib.rs @@ -374,6 +374,23 @@ impl sqlite::Bindable for &PublicKey { } } +pub mod keypair { + use super::*; + use std::env; + + /// Generate a new keypair using OS randomness. + pub fn generate() -> KeyPair { + #[cfg(debug_assertions)] + if env::var("RAD_DEBUG").is_ok() { + // Generate a test keypair that is always the same. + // This is useful for debugging and testing, since the + // public key is known in advance. + return KeyPair::from_seed(Seed::new([0xff; 32])); + } + KeyPair::generate() + } +} + #[cfg(test)] mod tests { use crate::PublicKey; diff --git a/radicle-crypto/src/ssh/keystore.rs b/radicle-crypto/src/ssh/keystore.rs index 49c46472..893587af 100644 --- a/radicle-crypto/src/ssh/keystore.rs +++ b/radicle-crypto/src/ssh/keystore.rs @@ -5,7 +5,7 @@ use std::{fs, io}; use thiserror::Error; use zeroize::Zeroizing; -use crate::{KeyPair, PublicKey, SecretKey, Signature, Signer, SignerError}; +use crate::{keypair, PublicKey, SecretKey, Signature, Signer, SignerError}; /// A secret key passphrase. pub type Passphrase = Zeroizing; @@ -47,7 +47,7 @@ impl Keystore { /// The `comment` is associated with the private key. /// The `passphrase` is used to encrypt the private key. pub fn init(&self, comment: &str, passphrase: &str) -> Result { - let pair = KeyPair::generate(); + let pair = keypair::generate(); let ssh_pair = ssh_key::private::Ed25519Keypair::from_bytes(&pair)?; let ssh_pair = ssh_key::private::KeypairData::Ed25519(ssh_pair); let secret = ssh_key::PrivateKey::new(ssh_pair, comment)?;