From 63e8b2fa6b5d4d9bf1ba9234bff0be8a255e612e Mon Sep 17 00:00:00 2001 From: hozan23 Date: Wed, 29 Nov 2023 11:44:53 +0300 Subject: core: Move `key_pair` to the `crypto` module and make it a Cargo feature. --- core/Cargo.toml | 7 +- core/src/crypto/key_pair.rs | 142 +++++++++++++++++++++++++++++++++ core/src/crypto/mod.rs | 3 + core/src/error.rs | 1 + core/src/key_pair.rs | 189 -------------------------------------------- core/src/lib.rs | 5 +- 6 files changed, 155 insertions(+), 192 deletions(-) create mode 100644 core/src/crypto/key_pair.rs create mode 100644 core/src/crypto/mod.rs delete mode 100644 core/src/key_pair.rs (limited to 'core') diff --git a/core/Cargo.toml b/core/Cargo.toml index 5a99e2d..3c8cb9c 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -16,7 +16,12 @@ rand = "0.8.5" thiserror = "1.0.47" dirs = "5.0.1" async-task = "4.5.0" -ed25519-dalek = { version = "2.1.0", features = ["rand_core"]} +ed25519-dalek = { version = "2.1.0", features = ["rand_core"], optional = true} + + +[features] +default = [] +crypto = ["dep:ed25519-dalek"] diff --git a/core/src/crypto/key_pair.rs b/core/src/crypto/key_pair.rs new file mode 100644 index 0000000..899cb6a --- /dev/null +++ b/core/src/crypto/key_pair.rs @@ -0,0 +1,142 @@ +use ed25519_dalek::{Signer as _, Verifier as _}; +use rand::rngs::OsRng; + +use crate::{error::Error, Result}; + +/// key cryptography type +pub enum KeyPairType { + Ed25519, +} + +/// A Secret key +pub struct SecretKey(Vec); + +#[derive(Clone)] +pub enum KeyPair { + Ed25519(Ed25519KeyPair), +} + +impl KeyPair { + /// Generate a new random keypair. + pub fn generate(kp_type: &KeyPairType) -> Self { + match kp_type { + KeyPairType::Ed25519 => Self::Ed25519(Ed25519KeyPair::generate()), + } + } + + /// Sign a message using the private key. + pub fn sign(&self, msg: &[u8]) -> Vec { + match self { + KeyPair::Ed25519(kp) => kp.sign(msg), + } + } + + /// Get the public key of this keypair. + pub fn public(&self) -> PublicKey { + match self { + KeyPair::Ed25519(kp) => kp.public(), + } + } + + /// Get the secret key of this keypair. + pub fn secret(&self) -> SecretKey { + match self { + KeyPair::Ed25519(kp) => kp.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; + + /// Get the public key of this keypair. + fn public(&self) -> PublicKey; + + /// Get the secret key of this keypair. + fn secret(&self) -> SecretKey; +} + +#[derive(Clone)] +pub 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 { + self.0.sign(msg).to_bytes().to_vec() + } + + fn public(&self) -> PublicKey { + PublicKey::Ed25519(Ed25519PublicKey(self.0.verifying_key())) + } + + fn secret(&self) -> SecretKey { + SecretKey(self.0.to_bytes().to_vec()) + } +} + +pub enum PublicKey { + Ed25519(Ed25519PublicKey), +} + +impl PublicKey { + pub fn from_bytes(kp_type: &KeyPairType, pk: &[u8]) -> Result { + match kp_type { + KeyPairType::Ed25519 => Ok(Self::Ed25519(Ed25519PublicKey::from_bytes(pk)?)), + } + } + + pub fn as_bytes(&self) -> &[u8] { + match self { + Self::Ed25519(pk) => pk.as_bytes(), + } + } + + /// Verify a signature on a message with this public key. + pub fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<()> { + match self { + Self::Ed25519(pk) => pk.verify(msg, signature), + } + } +} + +/// 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<()>; +} + +pub struct Ed25519PublicKey(ed25519_dalek::VerifyingKey); + +impl Ed25519PublicKey { + pub fn from_bytes(pk: &[u8]) -> Result { + 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(()) + } +} diff --git a/core/src/crypto/mod.rs b/core/src/crypto/mod.rs new file mode 100644 index 0000000..7d56e69 --- /dev/null +++ b/core/src/crypto/mod.rs @@ -0,0 +1,3 @@ +mod key_pair; + +pub use key_pair::{KeyPair, KeyPairType, PublicKey, SecretKey}; diff --git a/core/src/error.rs b/core/src/error.rs index 7c547c4..cc60696 100644 --- a/core/src/error.rs +++ b/core/src/error.rs @@ -16,6 +16,7 @@ pub enum Error { #[error("Path Not Found Error: {0}")] PathNotFound(&'static str), + #[cfg(feature = "crypto")] #[error(transparent)] Ed25519(#[from] ed25519_dalek::ed25519::Error), diff --git a/core/src/key_pair.rs b/core/src/key_pair.rs deleted file mode 100644 index 4016351..0000000 --- a/core/src/key_pair.rs +++ /dev/null @@ -1,189 +0,0 @@ -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); - -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 { - 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 { - 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; - - /// 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 { - 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 { - 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 { - 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 { - 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(()) - } -} diff --git a/core/src/lib.rs b/core/src/lib.rs index 276ed89..a4ea432 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -14,8 +14,9 @@ pub mod event; /// A simple publish-subscribe system [`Read More`](./pubsub/struct.Publisher.html) pub mod pubsub; -/// A cryptographic key pair -pub mod key_pair; +#[cfg(feature = "crypto")] +/// Collects common cryptographic tools +pub mod crypto; use smol::Executor as SmolEx; use std::sync::Arc; -- cgit v1.2.3