diff --git a/Cargo.toml b/Cargo.toml index 7594476..4baef2e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "xxxdh" license = "MIT" -version = "0.4.0" +version = "0.5.0" edition = "2021" authors = ["Oleksandr Yermakov "] categories = ["cryptography"] @@ -12,11 +12,9 @@ description = "Pure Rust X3DH key exchange protocol implementation" [dependencies] aes-gcm = {version = "0.9.4", optional = true } -curve25519-dalek-ng = { version = "4.1.1", optional = true } -hkdf = "0.12.0" +cryptimitives = "0.5.0" +cryptraits = "0.2.0" rand_core = "0.6.3" -schnorrkel = { version = "0.10.2", optional = true } -sha2 = "0.10.0" thiserror = "1.0.30" zeroize = "1.4.3" @@ -25,4 +23,4 @@ default = ["x25519-ristretto", "hkdf-sha256", "aead-aes-gcm"] aead-aes-gcm = ["aes-gcm"] hkdf-sha256 = [] hkdf-sha512 = [] -x25519-ristretto = ["curve25519-dalek-ng", "schnorrkel"] \ No newline at end of file +x25519-ristretto = [] \ No newline at end of file diff --git a/README.md b/README.md index f51d2c5..47184d2 100644 --- a/README.md +++ b/README.md @@ -9,41 +9,44 @@ Implementation is close to the [Signal Spec](https://signal.org/docs/specificati ## Usage ```rust +//! Basic example. + +use cryptimitives::{aead, kdf::sha256, key::x25519_ristretto}; +use cryptraits::{convert::ToVec, key::KeyPair, signature::Sign}; use rand_core::OsRng; use xxxdh::{ - aes_gcm, inmem, sha256, x25519_ristretto, IdentityKeyStorage, OnetimeKeyStorage, PreKeyStorage, - Protocol, Sign, SignatureStorage, ToVec, + inmem, IdentityKeyStorage, OnetimeKeyStorage, PreKeyStorage, Protocol, SignatureStorage, }; fn main() { // Instantiate Alice protocol. - let alice_identity = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); - let alice_prekey = x25519_ristretto::PreKeyPair::generate_with(OsRng); + let alice_identity = x25519_ristretto::KeyPair::generate_with(OsRng); + let alice_prekey = x25519_ristretto::KeyPair::generate_with(OsRng); let alice_signature = alice_identity.sign(&alice_prekey.to_public().to_vec()); let mut alice_protocol = Protocol::< - x25519_ristretto::IdentitySecretKey, + x25519_ristretto::SecretKey, x25519_ristretto::EphemeralSecretKey, x25519_ristretto::Signature, inmem::Storage<_, _>, sha256::Kdf, - aes_gcm::Aead, + aead::aes_gcm::Aes256Gcm, >::new(alice_identity, alice_prekey, alice_signature, None); // Instantiate Bob protocol. - let onetime_keypair = x25519_ristretto::OnetimeKeyPair::generate_with(OsRng); + let onetime_keypair = x25519_ristretto::KeyPair::generate_with(OsRng); - let bob_identity = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); - let bob_prekey = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); + let bob_identity = x25519_ristretto::KeyPair::generate_with(OsRng); + let bob_prekey = x25519_ristretto::KeyPair::generate_with(OsRng); let bob_signature = bob_identity.sign(&bob_prekey.to_public().to_vec()); let mut bob_protocol = Protocol::< - x25519_ristretto::IdentitySecretKey, + x25519_ristretto::SecretKey, x25519_ristretto::EphemeralSecretKey, x25519_ristretto::Signature, inmem::Storage<_, _>, sha256::Kdf, - aes_gcm::Aead, + aead::aes_gcm::Aes256Gcm, >::new( bob_identity, bob_prekey, @@ -82,4 +85,5 @@ fn main() { println!("Alice shared secret: {:?}", alice_sk); println!("Bob shared secret: {:?}", bob_sk); } + ``` diff --git a/examples/basic.rs b/examples/basic.rs index ac651bf..7fdbb1a 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,40 +1,41 @@ //! Basic example. +use cryptimitives::{aead, kdf::sha256, key::x25519_ristretto}; +use cryptraits::{convert::ToVec, key::KeyPair, signature::Sign}; use rand_core::OsRng; use xxxdh::{ - aes_gcm, inmem, sha256, x25519_ristretto, IdentityKeyStorage, OnetimeKeyStorage, PreKeyStorage, - Protocol, Sign, SignatureStorage, ToVec, + inmem, IdentityKeyStorage, OnetimeKeyStorage, PreKeyStorage, Protocol, SignatureStorage, }; fn main() { // Instantiate Alice protocol. - let alice_identity = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); - let alice_prekey = x25519_ristretto::PreKeyPair::generate_with(OsRng); + let alice_identity = x25519_ristretto::KeyPair::generate_with(OsRng); + let alice_prekey = x25519_ristretto::KeyPair::generate_with(OsRng); let alice_signature = alice_identity.sign(&alice_prekey.to_public().to_vec()); let mut alice_protocol = Protocol::< - x25519_ristretto::IdentitySecretKey, + x25519_ristretto::SecretKey, x25519_ristretto::EphemeralSecretKey, x25519_ristretto::Signature, inmem::Storage<_, _>, sha256::Kdf, - aes_gcm::Aead, + aead::aes_gcm::Aes256Gcm, >::new(alice_identity, alice_prekey, alice_signature, None); // Instantiate Bob protocol. - let onetime_keypair = x25519_ristretto::OnetimeKeyPair::generate_with(OsRng); + let onetime_keypair = x25519_ristretto::KeyPair::generate_with(OsRng); - let bob_identity = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); - let bob_prekey = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); + let bob_identity = x25519_ristretto::KeyPair::generate_with(OsRng); + let bob_prekey = x25519_ristretto::KeyPair::generate_with(OsRng); let bob_signature = bob_identity.sign(&bob_prekey.to_public().to_vec()); let mut bob_protocol = Protocol::< - x25519_ristretto::IdentitySecretKey, + x25519_ristretto::SecretKey, x25519_ristretto::EphemeralSecretKey, x25519_ristretto::Signature, inmem::Storage<_, _>, sha256::Kdf, - aes_gcm::Aead, + aead::aes_gcm::Aes256Gcm, >::new( bob_identity, bob_prekey, diff --git a/src/aead/aes_gcm.rs b/src/aead/aes_gcm.rs deleted file mode 100644 index a8cbee8..0000000 --- a/src/aead/aes_gcm.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! AES-GCM AEAD algorytm implementation. - -use aes_gcm::{aead::Aead as _, Key, NewAead, Nonce}; - -use crate::errors::{AeadError, AeadResult}; - -pub struct Aead(::aes_gcm::Aes256Gcm); - -impl super::Aead for Aead { - const NONCE_LEN: usize = 12; - - fn new(key: &[u8]) -> Self { - let key = Key::from_slice(key); - Self(::aes_gcm::Aes256Gcm::new(key)) - } - - fn encrypt(&self, nonce: &[u8], data: &[u8]) -> AeadResult> { - let nonce = Nonce::from_slice(nonce); - self.0.encrypt(nonce, data).or(Err(AeadError)) - } - - fn decrypt(&self, nonce: &[u8], data: &[u8]) -> AeadResult> { - let nonce = Nonce::from_slice(nonce); - self.0.decrypt(nonce, data).or(Err(AeadError)) - } -} diff --git a/src/aead/mod.rs b/src/aead/mod.rs deleted file mode 100644 index e9a24e6..0000000 --- a/src/aead/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! AEAD cipher. -#[cfg(feature = "aes-gcm")] -pub mod aes_gcm; - -use crate::errors::AeadResult; - -pub trait Aead { - const NONCE_LEN: usize; - - fn new(key: &[u8]) -> Self; - fn encrypt(&self, nonce: &[u8], data: &[u8]) -> AeadResult>; - fn decrypt(&self, nonce: &[u8], data: &[u8]) -> AeadResult>; -} diff --git a/src/errors.rs b/src/errors.rs index f5995d7..c955750 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,29 +1,8 @@ //! Crate custom errors. +use cryptimitives::errors::{AeadError, KdfError, KeyPairError, SignatureError}; use thiserror::Error; -/// Errors which may occur while processing keypairs. -/// -/// This error may arise due to: -/// -/// * Being given bytes with a length different to what was expected. -#[derive(Debug, Error)] -pub enum KeypairError { - #[error("being given bytes with a length different to what was expected")] - BytesLengthError, - - #[error("underlying error: {0}")] - UnderlyingError(String), -} - -/// Errors which may occur while processing signatures. -#[derive(Debug, Error, PartialEq)] -pub enum SignatureError { - /// A signature verification equation failed. - #[error("signature verification equation failed")] - EquationFalse, -} - /// X3DH protocol errors. #[derive(Debug, Error)] pub enum XxxDhError { @@ -36,38 +15,26 @@ pub enum XxxDhError { UnknownPrekey, /// Error occurred in the underlying KDF function. - #[error(transparent)] - KdfError(#[from] KdfError), + #[error("{0:?}")] + KdfError(KdfError), /// Error occurred in the underlying keypair. - #[error(transparent)] - KeypairError(#[from] KeypairError), + #[error("{0:?}")] + KeypairError(KeyPairError), /// Error occurred in the underlying AEAD cipher. - #[error(transparent)] - AeadError(#[from] AeadError), + #[error("{0:?}")] + AeadError(AeadError), /// Error occured in the underlying signature. - #[error(transparent)] - SignatureError(#[from] SignatureError), + #[error("{0:?}")] + SignatureError(SignatureError), /// Storge related errors. #[error(transparent)] StorageError(#[from] StorageError), } -/// Error which may occur while deriving keys. -#[derive(Debug, Error)] -pub enum KdfError { - #[error("invalid length")] - InvalidLength, -} - -/// AEAD algorithm error. -#[derive(Debug, Error)] -#[error("AEAD error")] -pub struct AeadError; - /// Storage related errors #[allow(dead_code)] #[derive(Debug, Error)] @@ -77,20 +44,26 @@ pub enum StorageError { UnknownError, } -/// `Result` specialized to this crate for convenience. Used for keypair related results. -pub type KeyResult = Result; +impl From for XxxDhError { + fn from(e: KdfError) -> Self { + Self::KdfError(e) + } +} + +impl From for XxxDhError { + fn from(e: AeadError) -> Self { + Self::AeadError(e) + } +} -/// `Result` specialized to this crate for convenience. Used for signture related results. -pub type SignatureResult = Result; +impl From for XxxDhError { + fn from(e: SignatureError) -> Self { + Self::SignatureError(e) + } +} /// `Result` specialized to this crate for convenience. Used for protocol related results. pub type XxxDhResult = Result; -/// `Result` specialized to this crate for convenience. Used for kdf related results. -pub type KdfResult = Result; - -/// `Result` specialized to this crate for convenience. Used for AEAD related results. -pub type AeadResult = Result; - /// `Result` specialized to this crate for convenience. Used for storage related results. pub type StorageResult = Result; diff --git a/src/kdf/mod.rs b/src/kdf/mod.rs deleted file mode 100644 index f221621..0000000 --- a/src/kdf/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::errors::KdfResult; - -/// X3DH KDF trait. -pub trait Kdf { - fn new(salt: Option<&[u8]>, data: &[u8]) -> Self; - fn expand(&self, info: &[u8], okm: &mut [u8]) -> KdfResult<()>; -} - -#[cfg(feature = "hkdf-sha256")] -pub mod sha256; - -#[cfg(feature = "hkdf-sha512")] -pub mod sha512; diff --git a/src/kdf/sha256.rs b/src/kdf/sha256.rs deleted file mode 100644 index d615dd6..0000000 --- a/src/kdf/sha256.rs +++ /dev/null @@ -1,16 +0,0 @@ -use hkdf::Hkdf; -use sha2::Sha256; - -use crate::errors::{KdfError, KdfResult}; - -pub struct Kdf(Hkdf); - -impl super::Kdf for Kdf { - fn new(salt: Option<&[u8]>, data: &[u8]) -> Self { - Self(Hkdf::::new(salt, data)) - } - - fn expand(&self, info: &[u8], okm: &mut [u8]) -> KdfResult<()> { - self.0.expand(info, okm).or(Err(KdfError::InvalidLength)) - } -} diff --git a/src/kdf/sha512.rs b/src/kdf/sha512.rs deleted file mode 100644 index 9feb50d..0000000 --- a/src/kdf/sha512.rs +++ /dev/null @@ -1,16 +0,0 @@ -use hkdf::Hkdf; -use sha2::Sha512; - -use crate::errors::{KdfError, KdfResult}; - -pub struct Kdf(Hkdf); - -impl super::Kdf for Kdf { - fn new(salt: Option<&[u8]>, data: &[u8]) -> Self { - Self(Hkdf::::new(salt, data)) - } - - fn expand(&self, info: &[u8], okm: &mut [u8]) -> KdfResult<()> { - self.0.expand(info, okm).or(Err(KdfError::InvalidLength)) - } -} diff --git a/src/key_exchange.rs b/src/key_exchange.rs deleted file mode 100644 index 35992b5..0000000 --- a/src/key_exchange.rs +++ /dev/null @@ -1,10 +0,0 @@ -//! Key exchange traits. - -use crate::keys::{PublicKey, SharedSecretKey}; - -pub trait DiffieHellman { - type SS: SharedSecretKey; - type PK: PublicKey; - - fn diffie_hellman(&self, peer_public: &Self::PK) -> Self::SS; -} diff --git a/src/keys/mod.rs b/src/keys/mod.rs deleted file mode 100644 index a2f834f..0000000 --- a/src/keys/mod.rs +++ /dev/null @@ -1,315 +0,0 @@ -use std::fmt::Debug; - -use rand_core::{CryptoRng, OsRng, RngCore}; -use zeroize::Zeroize; - -use crate::{ - errors::{KeyResult, KeypairError}, - signature::{Sign, Verify}, - traits::{FromBytes, ToVec}, - DiffieHellman, -}; - -#[cfg(feature = "x25519-ristretto")] -pub mod x25519_ristretto; - -/// A public key for use in X3DH protocol. -pub trait PublicKey: Debug + Copy + PartialEq {} - -/// A secret key for use in X3DH protocol. -pub trait SecretKey: Zeroize + Debug { - type PK: PublicKey; - - /// Generate an "unbiased" `SecretKey` directly from a user - /// suplied `csprng` uniformly. - fn generate_with(csprng: R) -> Self - where - Self: Sized; - - /// Derive the `PublicKey` corresponding to this `SecretKey`. - fn to_public(&self) -> Self::PK; -} - -pub trait SharedSecretKey {} - -pub struct KeyPair -where - SK: SecretKey, -{ - secret: SK, - public: SK::PK, -} - -impl KeyPair -where - SK: SecretKey, -{ - pub fn generate_with(csprng: R) -> Self - where - R: CryptoRng + RngCore, - { - let secret: SK = SK::generate_with(csprng); - let public = secret.to_public(); - - KeyPair { secret, public } - } - - /// Get a `PublicKey` of `KeyPair`. - pub fn to_public(&self) -> SK::PK { - self.public - } - - /// Get a `PublicKey` of `KeyPair`. - pub fn to_secret(&self) -> &SK { - &self.secret - } -} - -impl Zeroize for KeyPair -where - SK: SecretKey, -{ - fn zeroize(&mut self) { - self.secret.zeroize(); - } -} - -impl Drop for KeyPair -where - SK: SecretKey, -{ - fn drop(&mut self) { - self.zeroize(); - } -} - -impl FromBytes for KeyPair -where - SK: SecretKey + FromBytes, - SK::PK: FromBytes, -{ - const LEN: usize = SK::LEN + <::PK as FromBytes>::LEN; - - /// Deserialize a `IdentityKeyPair` from bytes. - /// - /// # Inputs - /// - /// * `bytes`: an `&[u8]` consisting of byte representations of - /// first a `SecretKey` and then the corresponding `PublicKey`. - /// - /// # Returns - /// - /// A `Result` whose okay value is a `Keypair` or whose error value - /// is an `KeypairError` describing the error that occurred. - fn from_bytes(bytes: &[u8]) -> KeyResult> { - if bytes.len() != Self::LEN { - return Err(KeypairError::BytesLengthError); - } - - let secret = SK::from_bytes(&bytes[..SK::LEN])?; - let public = SK::PK::from_bytes(&bytes[SK::LEN..])?; - - Ok(KeyPair { secret, public }) - } -} - -impl ToVec for KeyPair -where - SK: SecretKey + ToVec, - SK::PK: ToVec, -{ - const LEN: usize = SK::LEN + ::LEN; - - fn to_vec(&self) -> Vec { - let mut bytes: Vec = Vec::new(); - - bytes.extend(self.secret.to_vec()); - bytes.extend(self.public.to_vec()); - - bytes - } -} - -impl Sign for KeyPair -where - SK: SecretKey + Sign, -{ - type SIG = ::SIG; - - fn sign(&self, data: &[u8]) -> Self::SIG - where - Self: Sized, - { - self.secret.sign(data) - } -} - -impl DiffieHellman for KeyPair -where - SK: SecretKey + Sign + DiffieHellman, -{ - type SS = ::SS; - type PK = ::PK; - - fn diffie_hellman(&self, peer_public: &Self::PK) -> ::SS { - self.secret.diffie_hellman(peer_public) - } -} - -impl Verify for KeyPair -where - SK: SecretKey, - SK::PK: Verify, -{ - type SIG = ::SIG; - - fn verify(&self, data: &[u8], signature: &Self::SIG) -> crate::errors::SignatureResult<()> { - self.public.verify(data, signature) - } -} - -impl Debug for KeyPair -where - SK: SecretKey, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("KeyPair") - .field("secret", &String::from("")) - .field("public", &self.public) - .finish() - } -} - -impl Default for KeyPair -where - SK: SecretKey, -{ - fn default() -> Self { - let secret: SK = SecretKey::generate_with(OsRng); - let public = secret.to_public(); - - Self { secret, public } - } -} - -/// Identity keypair type alias; -pub type IdentityKeyPair = KeyPair; - -/// Prekeypair type alias; -pub type PreKeyPair = KeyPair; - -/// One-time keypair type alias; -pub type OnetimeKeyPair = KeyPair; - -#[cfg(test)] -pub mod tests { - use crate::Signature; - - use super::*; - - #[derive(Debug, PartialEq, Clone, Copy, Eq, Hash)] - pub struct TestPublicKey([u8; 5]); - - impl PublicKey for TestPublicKey {} - - impl FromBytes for TestPublicKey { - const LEN: usize = 5; - - fn from_bytes(bytes: &[u8]) -> KeyResult - where - Self: Sized, - { - let mut key: [u8; ::LEN] = [0; ::LEN]; - - for i in 0..::LEN { - key[i] = bytes[i]; - } - - Ok(Self(key)) - } - } - - impl ToVec for TestPublicKey { - const LEN: usize = 5; - - fn to_vec(&self) -> Vec - where - Self: Sized, - { - Vec::from(self.0) - } - } - - #[derive(Debug, Zeroize)] - #[zeroize(drop)] - pub struct TestSecretKey([u8; 5]); - - impl SecretKey for TestSecretKey { - type PK = TestPublicKey; - - fn generate_with(_csprng: R) -> Self - where - Self: Sized, - { - todo!() - } - - fn to_public(&self) -> Self::PK { - todo!() - } - } - - impl FromBytes for TestSecretKey { - const LEN: usize = 5; - - fn from_bytes(bytes: &[u8]) -> KeyResult - where - Self: Sized, - { - let mut key: [u8; Self::LEN] = [0; Self::LEN]; - - for i in 0..Self::LEN { - key[i] = bytes[i]; - } - - Ok(Self(key)) - } - } - - #[derive(Debug, Clone, Copy, PartialEq)] - pub struct TestSignature([u8; 2]); - - impl Signature for TestSignature {} - - impl ToVec for TestSignature { - const LEN: usize = 2; - - fn to_vec(&self) -> Vec - where - Self: Sized, - { - Vec::from(self.0) - } - } - - impl FromBytes for TestSignature { - const LEN: usize = 2; - - fn from_bytes(bytes: &[u8]) -> KeyResult - where - Self: Sized, - { - let mut signature: [u8; 2] = [0; 2]; - - for i in 0..2 { - signature[i] = bytes[i]; - } - - Ok(Self(signature)) - } - } - - pub type TestIdentityKeyPair = KeyPair; - - pub type TestPreKeyPair = KeyPair; -} diff --git a/src/keys/x25519_ristretto.rs b/src/keys/x25519_ristretto.rs deleted file mode 100644 index c921002..0000000 --- a/src/keys/x25519_ristretto.rs +++ /dev/null @@ -1,360 +0,0 @@ -//! X3DH implemetation using Curve25519 with Ristretto point compression. - -use std::fmt::Debug; - -use curve25519_dalek_ng::{ristretto::RistrettoPoint, scalar::Scalar}; -use zeroize::Zeroize; - -use crate::{ - errors::{KeyResult, KeypairError, SignatureError, SignatureResult}, - key_exchange, keys, - signature::{self, Sign}, - traits::{self, FromBytes, ToVec}, -}; - -#[derive(Zeroize, Debug)] -#[zeroize(drop)] -pub struct IdentitySecretKey(schnorrkel::SecretKey); - -impl From for IdentitySecretKey { - fn from(esk: EphemeralSecretKey) -> Self { - Self::from_bytes(&esk.to_vec()).unwrap() - } -} - -impl keys::SecretKey for IdentitySecretKey { - type PK = IdentityPublicKey; - - fn generate_with(csprng: R) -> Self - where - Self: Sized, - { - Self(schnorrkel::SecretKey::generate_with(csprng)) - } - - fn to_public(&self) -> Self::PK { - IdentityPublicKey(self.0.to_public()) - } -} - -impl traits::FromBytes for IdentitySecretKey { - const LEN: usize = 64; - - fn from_bytes(bytes: &[u8]) -> KeyResult - where - Self: Sized, - { - let secret = schnorrkel::SecretKey::from_bytes(bytes) - .or_else(|e| Err(KeypairError::UnderlyingError(e.to_string())))?; - - Ok(IdentitySecretKey(secret)) - } -} - -impl traits::ToVec for IdentitySecretKey { - const LEN: usize = 64; - - fn to_vec(&self) -> Vec - where - Self: Sized, - { - Vec::from(self.0.to_bytes()) - } -} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct Signature(schnorrkel::Signature); -impl signature::Signature for Signature {} - -impl traits::FromBytes for Signature { - const LEN: usize = 64; - - fn from_bytes(bytes: &[u8]) -> KeyResult - where - Self: Sized, - { - let signature = schnorrkel::Signature::from_bytes(bytes) - .or_else(|e| Err(KeypairError::UnderlyingError(e.to_string())))?; - - Ok(Signature(signature)) - } -} - -impl traits::ToVec for Signature { - const LEN: usize = 64; - - fn to_vec(&self) -> Vec - where - Self: Sized, - { - Vec::from(self.0.to_bytes()) - } -} - -impl<'a> Sign for IdentitySecretKey { - type SIG = Signature; - - fn sign(&self, data: &[u8]) -> Self::SIG - where - Self: Sized, - { - Signature(self.0.sign_simple(b"X3DH", &data, &self.0.to_public())) - } -} - -impl key_exchange::DiffieHellman for IdentitySecretKey { - type SS = SharedSecret; - type PK = IdentityPublicKey; - - fn diffie_hellman(&self, peer_public: &Self::PK) -> Self::SS { - let mut secret_bytes: [u8; 32] = [0; 32]; - - secret_bytes.copy_from_slice(&self.0.to_bytes()[..32]); - - let scalar = Scalar::from_canonical_bytes(secret_bytes).unwrap(); - - SharedSecret(scalar * peer_public.0.as_point()) - } -} - -#[derive(Clone, Copy, PartialEq, Eq, Hash)] -pub struct IdentityPublicKey(schnorrkel::PublicKey); - -impl keys::PublicKey for IdentityPublicKey {} - -impl traits::FromBytes for IdentityPublicKey { - const LEN: usize = 32; - - fn from_bytes(bytes: &[u8]) -> KeyResult - where - Self: Sized, - { - let public = schnorrkel::PublicKey::from_bytes(bytes) - .or_else(|e| Err(KeypairError::UnderlyingError(e.to_string())))?; - - Ok(IdentityPublicKey(public)) - } -} - -impl From for IdentityPublicKey { - fn from(epk: EphemeralPublicKey) -> Self { - Self(epk.0) - } -} - -impl Into for &IdentityPublicKey { - fn into(self) -> EphemeralPublicKey { - EphemeralPublicKey(self.0) - } -} - -impl traits::ToVec for IdentityPublicKey { - const LEN: usize = 32; - - fn to_vec(&self) -> Vec - where - Self: Sized, - { - Vec::from(self.0.to_bytes()) - } -} - -impl signature::Verify for IdentityPublicKey { - type SIG = Signature; - - fn verify(&self, data: &[u8], signature: &Self::SIG) -> SignatureResult<()> { - match self.0.verify_simple(b"X3DH", data, &signature.0) { - Ok(_) => Ok(()), - Err(schnorrkel::SignatureError::EquationFalse) => Err(SignatureError::EquationFalse), - Err(e) => panic!("Unknown error: {:?}", e), - } - } -} - -impl Debug for IdentityPublicKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("PublicKey") - .field( - &self - .0 - .to_bytes() - .iter() - .map(|b| format!("{:02X}", *b)) - .collect::>() - .join(""), - ) - .finish() - } -} - -pub type IdentityKeyPair = keys::KeyPair; -pub type PreKeyPair = keys::KeyPair; -pub type OnetimeKeyPair = keys::KeyPair; - -#[derive(Zeroize, Debug)] -#[zeroize(drop)] -/// A Diffie-Hellman secret key used to derive a shared secret when -/// combined with a public key, that only exists for a short time. -pub struct EphemeralSecretKey(schnorrkel::SecretKey); - -impl keys::SecretKey for EphemeralSecretKey { - type PK = EphemeralPublicKey; - - fn generate_with(csprng: R) -> Self - where - Self: Sized, - { - Self(schnorrkel::SecretKey::generate_with(csprng)) - } - - fn to_public(&self) -> Self::PK { - EphemeralPublicKey(self.0.to_public()) - } -} - -impl key_exchange::DiffieHellman for EphemeralSecretKey { - type SS = SharedSecret; - type PK = EphemeralPublicKey; - - fn diffie_hellman(&self, peer_public: &Self::PK) -> Self::SS { - let mut bytes = [0u8; 32]; - bytes.copy_from_slice(&self.0.to_ed25519_bytes()[..32]); - - SharedSecret(Scalar::from_bits(bytes) * peer_public.0.as_point()) - } -} - -/// The public key derived from an ephemeral secret key. -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct EphemeralPublicKey(schnorrkel::PublicKey); - -impl keys::PublicKey for EphemeralPublicKey {} - -impl From for EphemeralPublicKey { - fn from(ik: IdentityPublicKey) -> Self { - Self(ik.0) - } -} - -impl traits::ToVec for EphemeralPublicKey { - const LEN: usize = 32; - - fn to_vec(&self) -> Vec - where - Self: Sized, - { - Vec::from(self.0.to_bytes()) - } -} - -impl traits::ToVec for EphemeralSecretKey { - const LEN: usize = 32; - - fn to_vec(&self) -> Vec - where - Self: Sized, - { - Vec::from(self.0.to_bytes()) - } -} - -/// A Diffie-Hellman shared secret derived from an `EphemeralSecretKey` -/// and the other party's `PublicKey`. -pub struct SharedSecret(RistrettoPoint); - -impl keys::SharedSecretKey for SharedSecret {} - -impl From for [u8; 32] { - fn from(shared_secret: SharedSecret) -> Self { - shared_secret.0.compress().to_bytes() - } -} - -impl traits::ToVec for SharedSecret { - const LEN: usize = 32; - - fn to_vec(&self) -> Vec - where - Self: Sized, - { - Vec::from(self.0.compress().to_bytes()) - } -} - -#[allow(unused_imports)] -mod tests { - use super::EphemeralSecretKey; - use crate::errors::SignatureError; - use crate::key_exchange::DiffieHellman; - use crate::keys::SecretKey; - use crate::signature::{self, Sign, Verify}; - use crate::traits::{FromBytes, ToVec}; - use crate::x25519_ristretto::IdentityKeyPair; - use rand_core::OsRng; - - #[test] - fn identity_key_construct_from_bytes() { - let bytes = vec![ - 163, 32, 145, 4, 0, 205, 62, 240, 59, 87, 154, 77, 76, 172, 14, 144, 106, 224, 121, - 160, 178, 53, 227, 200, 15, 100, 125, 223, 69, 79, 178, 6, 249, 60, 236, 118, 88, 251, - 237, 212, 121, 28, 158, 94, 173, 159, 109, 18, 119, 32, 95, 39, 151, 112, 222, 230, - 246, 253, 15, 253, 139, 251, 161, 240, 172, 234, 111, 40, 46, 158, 32, 9, 119, 8, 125, - 180, 202, 113, 253, 218, 95, 6, 129, 230, 117, 54, 144, 169, 174, 74, 105, 33, 243, - 176, 206, 32, - ]; - - assert!(IdentityKeyPair::from_bytes(&bytes).is_ok()); - } - - #[test] - fn identity_key_to_vec() { - let bytes = [ - 163, 32, 145, 4, 0, 205, 62, 240, 59, 87, 154, 77, 76, 172, 14, 144, 106, 224, 121, - 160, 178, 53, 227, 200, 15, 100, 125, 223, 69, 79, 178, 6, 249, 60, 236, 118, 88, 251, - 237, 212, 121, 28, 158, 94, 173, 159, 109, 18, 119, 32, 95, 39, 151, 112, 222, 230, - 246, 253, 15, 253, 139, 251, 161, 240, 172, 234, 111, 40, 46, 158, 32, 9, 119, 8, 125, - 180, 202, 113, 253, 218, 95, 6, 129, 230, 117, 54, 144, 169, 174, 74, 105, 33, 243, - 176, 206, 32, - ]; - - assert_eq!( - &IdentityKeyPair::from_bytes(&bytes).unwrap().to_vec(), - &bytes - ); - } - - #[test] - fn identity_key_should_verify_signature() { - const MSG: &[u8] = b"sw0rdfish"; - - let alice_keypair = IdentityKeyPair::default(); - let bob_keypair = IdentityKeyPair::default(); - let alice_public = alice_keypair.to_public(); - - let signature = alice_keypair.sign(MSG); - - assert_eq!( - bob_keypair.verify(MSG, &signature), - Err(SignatureError::EquationFalse) - ); - - assert!(alice_public.verify(MSG, &signature).is_ok()); - } - - #[test] - fn random_dh() { - let alice_secret = EphemeralSecretKey::generate_with(&mut OsRng); - let alice_public = alice_secret.to_public(); - - let bob_secret = EphemeralSecretKey::generate_with(&mut OsRng); - let bob_public = bob_secret.to_public(); - - let alice_shared_secret = alice_secret.diffie_hellman(&bob_public); - let bob_shared_secret = bob_secret.diffie_hellman(&alice_public); - - assert_eq!( - <[u8; 32]>::from(alice_shared_secret), - <[u8; 32]>::from(bob_shared_secret) - ); - } -} diff --git a/src/lib.rs b/src/lib.rs index a3da180..31937f3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,93 +1,81 @@ -mod aead; mod errors; -mod kdf; -mod key_exchange; -mod keys; pub mod protocol; -mod signature; mod storage; -mod traits; -pub use aead::*; -pub use kdf::*; -pub use key_exchange::*; -pub use keys::*; pub use protocol::*; -pub use signature::*; pub use storage::*; -pub use traits::*; -#[cfg(test)] -mod tests { - #[cfg(all( - feature = "x25519-ristretto", - feature = "hkdf-sha512", - feature = "aead-aes-gcm" - ))] - #[test] - fn it_should_exchange_keys_x25519_ristretto_sha512_aes_gcm() { - use rand_core::OsRng; +// #[cfg(test)] +// mod tests { +// #[cfg(all( +// feature = "x25519-ristretto", +// feature = "hkdf-sha512", +// feature = "aead-aes-gcm" +// ))] +// #[test] +// fn it_should_exchange_keys_x25519_ristretto_sha512_aes_gcm() { +// use rand_core::OsRng; - use crate::{ - inmem, sha512, x25519_ristretto, IdentityKeyStorage, OnetimeKeyStorage, PreKeyStorage, - Protocol, Sign, SignatureStorage, ToVec, - }; +// use crate::{ +// inmem, sha512, x25519_ristretto, IdentityKeyStorage, OnetimeKeyStorage, PreKeyStorage, +// Protocol, Sign, SignatureStorage, ToVec, +// }; - let alice_identity = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); - let alice_prekey = x25519_ristretto::PreKeyPair::generate_with(OsRng); - let alice_signature = alice_identity.sign(&alice_prekey.to_public().to_vec()); - let mut alice_protocol = Protocol::< - x25519_ristretto::IdentitySecretKey, - x25519_ristretto::EphemeralSecretKey, - x25519_ristretto::Signature, - inmem::Storage<_, _>, - sha512::Kdf, - crate::aes_gcm::Aead, - >::new(alice_identity, alice_prekey, alice_signature, None); +// let alice_identity = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); +// let alice_prekey = x25519_ristretto::PreKeyPair::generate_with(OsRng); +// let alice_signature = alice_identity.sign(&alice_prekey.to_public().to_vec()); +// let mut alice_protocol = Protocol::< +// x25519_ristretto::IdentitySecretKey, +// x25519_ristretto::EphemeralSecretKey, +// x25519_ristretto::Signature, +// inmem::Storage<_, _>, +// sha512::Kdf, +// crate::aes_gcm::Aead, +// >::new(alice_identity, alice_prekey, alice_signature, None); - let onetime_keypair = x25519_ristretto::OnetimeKeyPair::generate_with(OsRng); +// let onetime_keypair = x25519_ristretto::OnetimeKeyPair::generate_with(OsRng); - let bob_identity = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); - let bob_prekey = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); - let bob_signature = bob_identity.sign(&bob_prekey.to_public().to_vec()); - let mut bob_protocol = Protocol::< - x25519_ristretto::IdentitySecretKey, - x25519_ristretto::EphemeralSecretKey, - x25519_ristretto::Signature, - inmem::Storage<_, _>, - sha512::Kdf, - crate::aes_gcm::Aead, - >::new( - bob_identity, - bob_prekey, - bob_signature, - Some(vec![onetime_keypair]), - ); +// let bob_identity = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); +// let bob_prekey = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); +// let bob_signature = bob_identity.sign(&bob_prekey.to_public().to_vec()); +// let mut bob_protocol = Protocol::< +// x25519_ristretto::IdentitySecretKey, +// x25519_ristretto::EphemeralSecretKey, +// x25519_ristretto::Signature, +// inmem::Storage<_, _>, +// sha512::Kdf, +// crate::aes_gcm::Aead, +// >::new( +// bob_identity, +// bob_prekey, +// bob_signature, +// Some(vec![onetime_keypair]), +// ); - let bob_identity = bob_protocol.storage.get_identity_key_pair().to_public(); - let bob_prekey = bob_protocol.storage.get_prekey_pair().to_public(); - let bob_signature = bob_protocol - .storage - .get_signature(&bob_prekey) - .unwrap() - .unwrap(); - let onetime_key = bob_protocol.storage.provide_ontime_key().unwrap().unwrap(); +// let bob_identity = bob_protocol.storage.get_identity_key_pair().to_public(); +// let bob_prekey = bob_protocol.storage.get_prekey_pair().to_public(); +// let bob_signature = bob_protocol +// .storage +// .get_signature(&bob_prekey) +// .unwrap() +// .unwrap(); +// let onetime_key = bob_protocol.storage.provide_ontime_key().unwrap().unwrap(); - let (alice_identity, alice_ephemeral_key, bob_onetime_key, alice_sk, nonce, ciphertext) = - alice_protocol - .prepare_init_msg(&bob_identity, &bob_prekey, bob_signature, onetime_key) - .unwrap(); +// let (alice_identity, alice_ephemeral_key, bob_onetime_key, alice_sk, nonce, ciphertext) = +// alice_protocol +// .prepare_init_msg(&bob_identity, &bob_prekey, bob_signature, onetime_key) +// .unwrap(); - let bob_sk = bob_protocol - .derive_shared_secret( - &alice_identity, - &alice_ephemeral_key, - &bob_onetime_key, - &nonce, - &ciphertext, - ) - .unwrap(); +// let bob_sk = bob_protocol +// .derive_shared_secret( +// &alice_identity, +// &alice_ephemeral_key, +// &bob_onetime_key, +// &nonce, +// &ciphertext, +// ) +// .unwrap(); - assert_eq!(alice_sk, bob_sk); - } -} +// assert_eq!(alice_sk, bob_sk); +// } +// } diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index 9929402..7a42fb4 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -2,13 +2,20 @@ use std::marker::PhantomData; +use cryptimitives::key::KeyPair; +use cryptraits::{ + aead::Aead, + convert::ToVec, + kdf::Kdf, + key::{KeyPair as _, SecretKey}, + key_exchange::DiffieHellman, + signature::{Signature, Verify}, +}; use rand_core::{OsRng, RngCore}; use crate::{ errors::{XxxDhError, XxxDhResult}, storage::ProtocolStorage, - Aead, DiffieHellman, IdentityKeyPair, Kdf, OnetimeKeyPair, PreKeyPair, SecretKey, Signature, - ToVec, Verify, }; pub const PROTOCOL_INFO: &'static str = "X3DH"; @@ -40,14 +47,17 @@ where SIG: Signature, S: ProtocolStorage::PK, SIG>, KDF: Kdf, - ::SS: ToVec, + ::SSK: ToVec, CIPHER: Aead, + XxxDhError: From<<::PK as Verify>::E> + + From<::E> + + From<::E>, { pub fn new( - identity_keypair: IdentityKeyPair, - prekey_keypair: PreKeyPair, + identity_keypair: KeyPair, + prekey_keypair: KeyPair, prekey_signature: SIG, - onetime_keypairs: Option>>, + onetime_keypairs: Option>>, ) -> Self { let prekey_public = prekey_keypair.to_public(); let mut storage = S::new(identity_keypair, prekey_keypair); @@ -94,7 +104,7 @@ where let sk = self._derive_sk([ ( - self.storage.get_identity_key_pair().to_secret(), + self.storage.get_identity_key_pair().secret(), &receiver_prekey, ), (&ephemeral_key, receiver_identity), @@ -131,8 +141,8 @@ where nonce: &[u8], ciphertext: &[u8], ) -> XxxDhResult> { - let identity_secret = self.storage.get_identity_key_pair().to_secret(); - let prekey_secret = self.storage.get_prekey_pair().to_secret(); + let identity_secret = self.storage.get_identity_key_pair().secret(); + let prekey_secret = self.storage.get_prekey_pair().secret(); let onetime_keypair = self .storage .get_onetime_keypair(receiver_onetime_key) @@ -143,7 +153,7 @@ where (prekey_secret, sender_identity), (&identity_secret, sender_ephemeral_key), (prekey_secret, sender_ephemeral_key), - (onetime_keypair.to_secret(), sender_ephemeral_key), + (onetime_keypair.secret(), sender_ephemeral_key), ])?; let cipher = CIPHER::new(&sk); @@ -165,9 +175,9 @@ where data.extend(sk.diffie_hellman(pk).to_vec()); } - let h = KDF::new(Some(&vec![0_u8; ::SS::LEN]), &data); + let h = KDF::new(Some(&vec![0_u8; ::SSK::LEN]), &data); - let mut sk = vec![0_u8; ::SS::LEN]; + let mut sk = vec![0_u8; ::SSK::LEN]; h.expand(PROTOCOL_INFO.as_bytes(), &mut sk)?; @@ -182,40 +192,41 @@ where feature = "aead-aes-gcm" ))] mod tests { - use crate::{ - sha256::Kdf, - storage::{inmem, IdentityKeyStorage, OnetimeKeyStorage, PreKeyStorage, SignatureStorage}, - x25519_ristretto, Sign, + use cryptimitives::{aead::aes_gcm::Aes256Gcm, kdf::sha256, key::x25519_ristretto}; + use cryptraits::signature::Sign; + + use crate::storage::{ + inmem, IdentityKeyStorage, OnetimeKeyStorage, PreKeyStorage, SignatureStorage, }; use super::*; #[test] fn it_should_exchange_keys() { - let alice_identity = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); - let alice_prekey = x25519_ristretto::PreKeyPair::generate_with(OsRng); + let alice_identity = x25519_ristretto::KeyPair::generate_with(OsRng); + let alice_prekey = x25519_ristretto::KeyPair::generate_with(OsRng); let alice_signature = alice_identity.sign(&alice_prekey.to_public().to_vec()); let mut alice_protocol = Protocol::< - x25519_ristretto::IdentitySecretKey, + x25519_ristretto::SecretKey, x25519_ristretto::EphemeralSecretKey, x25519_ristretto::Signature, inmem::Storage<_, _>, - Kdf, - crate::aes_gcm::Aead, + sha256::Kdf, + Aes256Gcm, >::new(alice_identity, alice_prekey, alice_signature, None); - let onetime_keypair = x25519_ristretto::OnetimeKeyPair::generate_with(OsRng); + let onetime_keypair = x25519_ristretto::KeyPair::generate_with(OsRng); - let bob_identity = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); - let bob_prekey = x25519_ristretto::IdentityKeyPair::generate_with(OsRng); + let bob_identity = x25519_ristretto::KeyPair::generate_with(OsRng); + let bob_prekey = x25519_ristretto::KeyPair::generate_with(OsRng); let bob_signature = bob_identity.sign(&bob_prekey.to_public().to_vec()); let mut bob_protocol = Protocol::< - x25519_ristretto::IdentitySecretKey, + x25519_ristretto::SecretKey, x25519_ristretto::EphemeralSecretKey, x25519_ristretto::Signature, - inmem::Storage<_, _>, - Kdf, - crate::aes_gcm::Aead, + inmem::Storage, + sha256::Kdf, + Aes256Gcm, >::new( bob_identity, bob_prekey, diff --git a/src/signature.rs b/src/signature.rs deleted file mode 100644 index 4600b40..0000000 --- a/src/signature.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! Signature traits. - -use crate::{ - errors::SignatureResult, - traits::{FromBytes, ToVec}, -}; - -pub trait Signature: FromBytes + ToVec + Copy + Clone + PartialEq {} - -/// Sign a message. -pub trait Sign { - type SIG: Signature; - - /// Sign a message. - fn sign(&self, data: &[u8]) -> Self::SIG - where - Self: Sized; -} - -/// Verify a signature -pub trait Verify { - type SIG: Signature; - - /// Verify a signature - fn verify(&self, data: &[u8], signature: &Self::SIG) -> SignatureResult<()>; -} diff --git a/src/storage/inmem.rs b/src/storage/inmem.rs index 5c81cde..f54de6a 100644 --- a/src/storage/inmem.rs +++ b/src/storage/inmem.rs @@ -3,10 +3,14 @@ use core::hash::Hash; use std::collections::{HashMap, HashSet}; -use crate::{ - errors::StorageResult, IdentityKeyPair, OnetimeKeyPair, PreKeyPair, SecretKey, Signature, +use cryptimitives::key::KeyPair; +use cryptraits::{ + key::{KeyPair as _, SecretKey}, + signature::Signature, }; +use crate::errors::StorageResult; + use super::{ IdentityKeyStorage, OnetimeKeyStorage, PreKeyStorage, ProtocolStorage, SignatureStorage, }; @@ -18,15 +22,15 @@ where SK: SecretKey, SIG: Signature, { - identity_key_pair: IdentityKeyPair, + identity_key_pair: KeyPair, known_identities: HashSet, - prekey_pair: PreKeyPair, + prekey_pair: KeyPair, known_prekeys: HashSet, signatures: HashMap, - onetime_keys: HashMap>, + onetime_keys: HashMap>, } impl IdentityKeyStorage for Storage @@ -35,7 +39,7 @@ where SK::PK: Eq + Hash, SIG: Signature, { - fn get_identity_key_pair(&self) -> &IdentityKeyPair { + fn get_identity_key_pair(&self) -> &KeyPair { &self.identity_key_pair } @@ -56,7 +60,7 @@ where SK::PK: Eq + Hash, SIG: Signature, { - fn get_prekey_pair(&self) -> &PreKeyPair { + fn get_prekey_pair(&self) -> &KeyPair { &self.prekey_pair } @@ -94,11 +98,11 @@ where SK::PK: Eq + Hash, SIG: Signature, { - fn get_onetime_keypair(&self, key: &SK::PK) -> StorageResult>> { + fn get_onetime_keypair(&self, key: &SK::PK) -> StorageResult>> { Ok(self.onetime_keys.get(key)) } - fn save_onetime_keypair(&mut self, keypair: OnetimeKeyPair) -> StorageResult<()> { + fn save_onetime_keypair(&mut self, keypair: KeyPair) -> StorageResult<()> { self.onetime_keys.insert(keypair.to_public(), keypair); Ok(()) @@ -125,7 +129,7 @@ where SK::PK: Eq + Hash, SIG: Signature, { - fn new(identity_key_pair: IdentityKeyPair, prekey_pair: PreKeyPair) -> Self { + fn new(identity_key_pair: KeyPair, prekey_pair: KeyPair) -> Self { Self { identity_key_pair, known_identities: HashSet::new(), @@ -139,16 +143,15 @@ where #[cfg(test)] mod tests { - use crate::keys::tests::{ - TestIdentityKeyPair, TestPreKeyPair, TestPublicKey, TestSecretKey, TestSignature, - }; - use crate::traits::FromBytes; + + use cryptimitives::key::util::{TestPublicKey, TestSecretKey, TestSignature}; + use cryptraits::convert::FromBytes; use super::*; - fn get_test_storage() -> Storage { - let identity_keypair = TestIdentityKeyPair::from_bytes(b"teststestp").unwrap(); - let pre_keypair = TestPreKeyPair::from_bytes(b"teststestp").unwrap(); + fn get_test_storage() -> Storage { + let identity_keypair = KeyPair::from_bytes(b"teststestp").unwrap(); + let pre_keypair = KeyPair::from_bytes(b"teststestp").unwrap(); Storage::new(identity_keypair, pre_keypair) } @@ -157,8 +160,8 @@ mod tests { fn it_should_create_protocol_storage() { let public = TestPublicKey::from_bytes(b"testp").unwrap(); - let identity_keypair = TestIdentityKeyPair::from_bytes(b"teststestp").unwrap(); - let pre_keypair = TestPreKeyPair::from_bytes(b"teststestp").unwrap(); + let identity_keypair = KeyPair::from_bytes(b"teststestp").unwrap(); + let pre_keypair = KeyPair::from_bytes(b"teststestp").unwrap(); let storage: Storage = Storage::new(identity_keypair, pre_keypair); @@ -211,7 +214,7 @@ mod tests { #[test] fn it_should_save_onetime_keypair() { let mut storage = get_test_storage(); - let onetime_keypair = TestPreKeyPair::from_bytes(b"teststestp").unwrap(); + let onetime_keypair = KeyPair::from_bytes(b"teststestp").unwrap(); let onetime_public = onetime_keypair.to_public(); assert!(storage.is_onetime_keys_empty().unwrap()); diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 71fc63f..269af9b 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -1,18 +1,21 @@ //! Key storage. pub mod inmem; -use crate::{ - errors::StorageResult, IdentityKeyPair, OnetimeKeyPair, PreKeyPair, PublicKey, SecretKey, - Signature, +use cryptimitives::key::KeyPair; +use cryptraits::{ + key::{PublicKey, SecretKey}, + signature::Signature, }; +use crate::errors::StorageResult; + /// Identity keys storage. pub trait IdentityKeyStorage where SK: SecretKey, { /// Get an identity `IdentityKeyPair`. - fn get_identity_key_pair(&self) -> &IdentityKeyPair; + fn get_identity_key_pair(&self) -> &KeyPair; /// Save a known identity. fn save_identity(&mut self, identity: &SK::PK) -> StorageResult<()>; @@ -27,7 +30,7 @@ where SK: SecretKey, { /// Get a prekey `PreKeyPair`. - fn get_prekey_pair(&self) -> &PreKeyPair; + fn get_prekey_pair(&self) -> &KeyPair; /// Save a known identity. fn save_prekey(&mut self, key: &SK::PK) -> StorageResult<()>; @@ -55,10 +58,10 @@ where SK: SecretKey, { /// Get a `OnetimeKeyPair`. - fn get_onetime_keypair(&self, key: &SK::PK) -> StorageResult>>; + fn get_onetime_keypair(&self, key: &SK::PK) -> StorageResult>>; /// Save a `OnetimeKeyPair`. - fn save_onetime_keypair(&mut self, keypair: OnetimeKeyPair) -> StorageResult<()>; + fn save_onetime_keypair(&mut self, keypair: KeyPair) -> StorageResult<()>; /// Forget a `OnetimeKeyPair`. fn forget_onetime_keypair(&mut self, key: &SK::PK) -> StorageResult<()>; @@ -77,5 +80,5 @@ where PK: PublicKey, S: Signature, { - fn new(identity_keypair: IdentityKeyPair, prekey_keypair: PreKeyPair) -> Self; + fn new(identity_keypair: KeyPair, prekey_keypair: KeyPair) -> Self; } diff --git a/src/traits.rs b/src/traits.rs deleted file mode 100644 index bd3c737..0000000 --- a/src/traits.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Generic utility traits. - -use crate::errors::KeyResult; - -pub trait FromBytes { - const LEN: usize; - - /// Construct a key from a slice of bytes. - fn from_bytes(bytes: &[u8]) -> KeyResult - where - Self: Sized; -} - -pub trait ToVec { - const LEN: usize; - - /// Convert a key into a vec of bytes. - fn to_vec(&self) -> Vec - where - Self: Sized; -}