diff options
| author | hozan23 <hozan23@proton.me> | 2023-11-28 22:41:33 +0300 | 
|---|---|---|
| committer | hozan23 <hozan23@proton.me> | 2023-11-28 22:41:33 +0300 | 
| commit | 98a1de91a2dae06323558422c239e5a45fc86e7b (patch) | |
| tree | 38c640248824fcb3b4ca5ba12df47c13ef26ccda /core/src/key_pair.rs | |
| parent | ca2a5f8bbb6983d9555abd10eaaf86950b794957 (diff) | |
implement TLS for inbound and outbound connections
Diffstat (limited to 'core/src/key_pair.rs')
| -rw-r--r-- | core/src/key_pair.rs | 189 | 
1 files changed, 189 insertions, 0 deletions
| diff --git a/core/src/key_pair.rs b/core/src/key_pair.rs new file mode 100644 index 0000000..4016351 --- /dev/null +++ b/core/src/key_pair.rs @@ -0,0 +1,189 @@ +use ed25519_dalek::{Signer as _, Verifier as _}; +use rand::rngs::OsRng; + +use crate::{error::Error, Result}; + +/// key cryptography type +pub enum KeyPairType { +    Ed25519, +} + +/// A Public key +pub struct PublicKey(PublicKeyInner); + +/// A Secret key +pub struct SecretKey(Vec<u8>); + +impl PublicKey { +    pub fn as_bytes(&self) -> &[u8] { +        self.0.as_bytes() +    } + +    /// Verify a signature on a message with this public key. +    pub fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<()> { +        self.0.verify(msg, signature) +    } +} + +impl PublicKey { +    pub fn from_bytes(kp_type: &KeyPairType, pk: &[u8]) -> Result<Self> { +        Ok(Self(PublicKeyInner::from_bytes(kp_type, pk)?)) +    } +} + +/// A KeyPair. +#[derive(Clone)] +pub struct KeyPair(KeyPairInner); + +impl KeyPair { +    /// Generate a new random keypair. +    pub fn generate(kp_type: &KeyPairType) -> Self { +        Self(KeyPairInner::generate(kp_type)) +    } + +    /// Sign a message using the private key. +    pub fn sign(&self, msg: &[u8]) -> Vec<u8> { +        self.0.sign(msg) +    } + +    /// Get the public key of this keypair. +    pub fn public(&self) -> PublicKey { +        self.0.public() +    } + +    /// Get the secret key of this keypair. +    pub fn secret(&self) -> SecretKey { +        self.0.secret() +    } +} + +/// An extension trait, adding essential methods to all [`KeyPair`] types. +trait KeyPairExt { +    /// Sign a message using the private key. +    fn sign(&self, msg: &[u8]) -> Vec<u8>; + +    /// Get the public key of this keypair. +    fn public(&self) -> PublicKey; + +    /// Get the secret key of this keypair. +    fn secret(&self) -> SecretKey; +} + +#[derive(Clone)] +enum KeyPairInner { +    Ed25519(Ed25519KeyPair), +} + +impl KeyPairInner { +    fn generate(kp_type: &KeyPairType) -> Self { +        match kp_type { +            KeyPairType::Ed25519 => Self::Ed25519(Ed25519KeyPair::generate()), +        } +    } +} + +impl KeyPairExt for KeyPairInner { +    fn sign(&self, msg: &[u8]) -> Vec<u8> { +        match self { +            KeyPairInner::Ed25519(kp) => kp.sign(msg), +        } +    } + +    fn public(&self) -> PublicKey { +        match self { +            KeyPairInner::Ed25519(kp) => kp.public(), +        } +    } + +    fn secret(&self) -> SecretKey { +        match self { +            KeyPairInner::Ed25519(kp) => kp.secret(), +        } +    } +} + +#[derive(Clone)] +struct Ed25519KeyPair(ed25519_dalek::SigningKey); + +impl Ed25519KeyPair { +    fn generate() -> Self { +        Self(ed25519_dalek::SigningKey::generate(&mut OsRng)) +    } +} + +impl KeyPairExt for Ed25519KeyPair { +    fn sign(&self, msg: &[u8]) -> Vec<u8> { +        self.0.sign(msg).to_bytes().to_vec() +    } + +    fn public(&self) -> PublicKey { +        PublicKey(PublicKeyInner::Ed25519(Ed25519PublicKey( +            self.0.verifying_key(), +        ))) +    } + +    fn secret(&self) -> SecretKey { +        SecretKey(self.0.to_bytes().to_vec()) +    } +} + +/// An extension trait, adding essential methods to all [`PublicKey`] types. +trait PublicKeyExt { +    fn as_bytes(&self) -> &[u8]; + +    /// Verify a signature on a message with this public key. +    fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<()>; +} + +enum PublicKeyInner { +    Ed25519(Ed25519PublicKey), +} + +impl PublicKeyInner { +    pub fn from_bytes(kp_type: &KeyPairType, pk: &[u8]) -> Result<Self> { +        match kp_type { +            KeyPairType::Ed25519 => Ok(Self::Ed25519(Ed25519PublicKey::from_bytes(pk)?)), +        } +    } +} + +impl PublicKeyExt for PublicKeyInner { +    fn as_bytes(&self) -> &[u8] { +        match self { +            Self::Ed25519(pk) => pk.as_bytes(), +        } +    } + +    fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<()> { +        match self { +            Self::Ed25519(pk) => pk.verify(msg, signature), +        } +    } +} + +struct Ed25519PublicKey(ed25519_dalek::VerifyingKey); + +impl Ed25519PublicKey { +    pub fn from_bytes(pk: &[u8]) -> Result<Self> { +        let pk_bytes: [u8; 32] = pk +            .try_into() +            .map_err(|_| Error::TryInto("Failed to convert slice to [u8; 32]"))?; + +        Ok(Self(ed25519_dalek::VerifyingKey::from_bytes(&pk_bytes)?)) +    } +} + +impl PublicKeyExt for Ed25519PublicKey { +    fn as_bytes(&self) -> &[u8] { +        self.0.as_bytes() +    } + +    fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<()> { +        let sig_bytes: [u8; 64] = signature +            .try_into() +            .map_err(|_| Error::TryInto("Failed to convert slice to [u8; 64]"))?; +        self.0 +            .verify(msg, &ed25519_dalek::Signature::from_bytes(&sig_bytes))?; +        Ok(()) +    } +} | 
