aboutsummaryrefslogtreecommitdiff
path: root/core/src/key_pair.rs
diff options
context:
space:
mode:
authorhozan23 <hozan23@proton.me>2023-11-28 22:41:33 +0300
committerhozan23 <hozan23@proton.me>2023-11-28 22:41:33 +0300
commit98a1de91a2dae06323558422c239e5a45fc86e7b (patch)
tree38c640248824fcb3b4ca5ba12df47c13ef26ccda /core/src/key_pair.rs
parentca2a5f8bbb6983d9555abd10eaaf86950b794957 (diff)
implement TLS for inbound and outbound connections
Diffstat (limited to 'core/src/key_pair.rs')
-rw-r--r--core/src/key_pair.rs189
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(())
+ }
+}