summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto/backend/rust/asymmetric.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/crypto/backend/rust/asymmetric.rs')
-rw-r--r--openpgp/src/crypto/backend/rust/asymmetric.rs53
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> {