diff options
Diffstat (limited to 'openpgp/src/crypto/backend/rust/asymmetric.rs')
-rw-r--r-- | openpgp/src/crypto/backend/rust/asymmetric.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/openpgp/src/crypto/backend/rust/asymmetric.rs b/openpgp/src/crypto/backend/rust/asymmetric.rs index 1a558bfb..13049578 100644 --- a/openpgp/src/crypto/backend/rust/asymmetric.rs +++ b/openpgp/src/crypto/backend/rust/asymmetric.rs @@ -61,6 +61,59 @@ impl Asymmetric for super::Backend { let public = PublicKey::from(public.clone()); Ok((&secret.diffie_hellman(&public).as_bytes()[..]).into()) } + + fn ed25519_generate_key() -> Result<(Protected, [u8; 32])> { + // ed25519_dalek v1.0.1 doesn't reexport OsRng. It + // depends on 0.7. + use rand07::rngs::OsRng as OsRng; + let pair = ed25519_dalek::Keypair::generate(&mut OsRng); + Ok((pair.secret.as_bytes().as_slice().into(), pair.secret.to_bytes())) + } + + fn ed25519_derive_public(secret: &Protected) -> Result<[u8; 32]> { + use ed25519_dalek::{PublicKey, SecretKey}; + + let secret = SecretKey::from_bytes(secret).map_err(|e| { + Error::InvalidKey(e.to_string()) + })?; + let public = PublicKey::from(&secret); + Ok(public.to_bytes()) + } + + fn ed25519_sign(secret: &Protected, public: &[u8; 32], digest: &[u8]) + -> Result<[u8; 64]> { + use ed25519_dalek::{Keypair, Signer}; + use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH}; + + if secret.len() != SECRET_KEY_LENGTH { + return Err(crate::Error::InvalidArgument( + "Bad Ed25519 secret length".into()).into()); + } + + let mut keypair = Protected::from( + vec![0u8; SECRET_KEY_LENGTH + PUBLIC_KEY_LENGTH] + ); + keypair.as_mut()[..SECRET_KEY_LENGTH].copy_from_slice(secret); + keypair.as_mut()[SECRET_KEY_LENGTH..].copy_from_slice(public); + let pair = Keypair::from_bytes(&keypair)?; + unsafe { + memsec::memzero(keypair.as_mut_ptr(), keypair.len()); + } + + Ok(pair.sign(digest).to_bytes().try_into()?) + } + + fn ed25519_verify(public: &[u8; 32], digest: &[u8], signature: &[u8; 64]) + -> Result<bool> { + use ed25519_dalek::{PublicKey, Signature}; + use ed25519_dalek::{Verifier}; + + let public = PublicKey::from_bytes(public).map_err(|e| { + Error::InvalidKey(e.to_string()) + })?; + let signature = Signature::from_bytes(&signature.clone())?; + Ok(public.verify(digest, &signature).is_ok()) + } } fn pkcs1_padding(hash_algo: HashAlgorithm) -> Result<Pkcs1v15Sign> { |