From d3199778e4745424a00b9ef1902b320fe0c0d76d Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Thu, 30 Jan 2020 11:55:15 +0000 Subject: [PATCH 1/3] validator: starting removal of keypair generics --- .../src/services/mixmining/health_check_runner.rs | 12 ++++++------ validator/src/validator.rs | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/validator/src/services/mixmining/health_check_runner.rs b/validator/src/services/mixmining/health_check_runner.rs index 42a3821cea..b53162273f 100644 --- a/validator/src/services/mixmining/health_check_runner.rs +++ b/validator/src/services/mixmining/health_check_runner.rs @@ -1,21 +1,21 @@ -use crypto::identity::MixnetIdentityKeyPair; +use crypto::identity::DummyMixIdentityKeyPair; use healthcheck::HealthChecker; use log::*; use std::time::Duration; use topology::NymTopology; -pub struct HealthCheckRunner { +pub struct HealthCheckRunner { directory_server: String, - health_checker: HealthChecker, + health_checker: HealthChecker, interval: f64, } -impl HealthCheckRunner { +impl HealthCheckRunner { pub fn new( directory_server: String, interval: f64, - health_checker: HealthChecker, - ) -> HealthCheckRunner { + health_checker: HealthChecker, + ) -> HealthCheckRunner { HealthCheckRunner { directory_server, health_checker, diff --git a/validator/src/validator.rs b/validator/src/validator.rs index b4a3e2d0e0..6cdc6f6fc3 100644 --- a/validator/src/validator.rs +++ b/validator/src/validator.rs @@ -13,15 +13,15 @@ pub struct Config { } // allow for a generic validator -pub struct Validator { +pub struct Validator { #[allow(dead_code)] - identity_keypair: IDPair, - health_check_runner: health_check_runner::HealthCheckRunner, + identity_keypair: DummyMixIdentityKeyPair, + health_check_runner: health_check_runner::HealthCheckRunner, tendermint_abci: tendermint::Abci, } // but for time being, since it's a dummy one, have it use dummy keys -impl Validator { +impl Validator { pub fn new(config: Config) -> Self { let dummy_keypair = DummyMixIdentityKeyPair::new(); let hc = HealthChecker::new( From 6b879e88e77ffb0137192c99453533c74dfbc3a7 Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Thu, 30 Jan 2020 12:19:23 +0000 Subject: [PATCH 2/3] nym: removing type parameters on keypairs --- common/crypto/src/identity/mod.rs | 125 ++++++------------ common/healthcheck/src/lib.rs | 10 +- common/healthcheck/src/path_check.rs | 6 +- common/healthcheck/src/result.rs | 12 +- common/pemstore/src/pemstore.rs | 12 +- nym-client/src/client/mod.rs | 29 ++-- nym-client/src/client/topology_control.rs | 18 +-- nym-client/src/commands/init.rs | 4 +- nym-client/src/commands/tcpsocket.rs | 4 +- nym-client/src/commands/websocket.rs | 4 +- sfw-provider/src/main.rs | 4 +- .../src/provider/client_handling/mod.rs | 14 +- sfw-provider/src/provider/mix_handling/mod.rs | 6 +- sfw-provider/src/provider/mod.rs | 14 +- sfw-provider/src/provider/presence.rs | 4 +- .../services/mixmining/health_check_runner.rs | 5 +- validator/src/validator.rs | 6 +- 17 files changed, 102 insertions(+), 175 deletions(-) diff --git a/common/crypto/src/identity/mod.rs b/common/crypto/src/identity/mod.rs index 3c920f84dc..a966ec4cb9 100644 --- a/common/crypto/src/identity/mod.rs +++ b/common/crypto/src/identity/mod.rs @@ -6,90 +6,44 @@ use bs58; use curve25519_dalek::scalar::Scalar; use sphinx::route::DestinationAddressBytes; -pub trait MixnetIdentityKeyPair: Clone { - type PublicKeyMaterial: MixnetIdentityPublicKey; - type PrivateKeyMaterial: MixnetIdentityPrivateKey; - - fn new() -> Self; - fn private_key(&self) -> &Self::PrivateKeyMaterial; - fn public_key(&self) -> &Self::PublicKeyMaterial; - fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self; - - // TODO: signing related methods -} - -pub trait MixnetIdentityPublicKey: - Sized - + PemStorable - + Clone - + for<'a> From<&'a ::PrivateKeyMaterial> -{ - // we need to couple public and private keys together - type PrivateKeyMaterial: MixnetIdentityPrivateKey; - - fn derive_address(&self) -> DestinationAddressBytes; - fn to_bytes(&self) -> Vec; - fn from_bytes(b: &[u8]) -> Self; -} - -pub trait MixnetIdentityPrivateKey: Sized + PemStorable + Clone { - // we need to couple public and private keys together - type PublicKeyMaterial: MixnetIdentityPublicKey; - - /// Returns the associated public key - fn public_key(&self) -> Self::PublicKeyMaterial { - self.into() - } - - fn to_bytes(&self) -> Vec; - fn from_bytes(b: &[u8]) -> Self; -} - -// same for validator - // for time being define a dummy identity using x25519 encryption keys (as we've done so far) // and replace it with proper keys, like ed25519 later on #[derive(Clone)] -pub struct DummyMixIdentityKeyPair { - pub private_key: DummyMixIdentityPrivateKey, - pub public_key: DummyMixIdentityPublicKey, +pub struct MixIdentityKeyPair { + pub private_key: MixIdentityPrivateKey, + pub public_key: MixIdentityPublicKey, } -impl MixnetIdentityKeyPair for DummyMixIdentityKeyPair { - type PublicKeyMaterial = DummyMixIdentityPublicKey; - type PrivateKeyMaterial = DummyMixIdentityPrivateKey; - - fn new() -> Self { +impl MixIdentityKeyPair { + pub fn new() -> Self { let keypair = encryption::x25519::KeyPair::new(); - DummyMixIdentityKeyPair { - private_key: DummyMixIdentityPrivateKey(keypair.private_key), - public_key: DummyMixIdentityPublicKey(keypair.public_key), + MixIdentityKeyPair { + private_key: MixIdentityPrivateKey(keypair.private_key), + public_key: MixIdentityPublicKey(keypair.public_key), } } - fn private_key(&self) -> &DummyMixIdentityPrivateKey { + pub fn private_key(&self) -> &MixIdentityPrivateKey { &self.private_key } - fn public_key(&self) -> &DummyMixIdentityPublicKey { + pub fn public_key(&self) -> &MixIdentityPublicKey { &self.public_key } - fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self { - DummyMixIdentityKeyPair { - private_key: DummyMixIdentityPrivateKey::from_bytes(priv_bytes), - public_key: DummyMixIdentityPublicKey::from_bytes(pub_bytes), + pub fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self { + MixIdentityKeyPair { + private_key: MixIdentityPrivateKey::from_bytes(priv_bytes), + public_key: MixIdentityPublicKey::from_bytes(pub_bytes), } } } #[derive(Debug, Clone, Eq, PartialEq)] -pub struct DummyMixIdentityPublicKey(encryption::x25519::PublicKey); +pub struct MixIdentityPublicKey(encryption::x25519::PublicKey); -impl MixnetIdentityPublicKey for DummyMixIdentityPublicKey { - type PrivateKeyMaterial = DummyMixIdentityPrivateKey; - - fn derive_address(&self) -> DestinationAddressBytes { +impl MixIdentityPublicKey { + pub fn derive_address(&self) -> DestinationAddressBytes { let mut temporary_address = [0u8; 32]; let public_key_bytes = self.to_bytes(); temporary_address.copy_from_slice(&public_key_bytes[..]); @@ -97,65 +51,60 @@ impl MixnetIdentityPublicKey for DummyMixIdentityPublicKey { temporary_address } - fn to_bytes(&self) -> Vec { + pub fn to_bytes(&self) -> Vec { self.0.to_bytes() } - fn from_bytes(b: &[u8]) -> Self { + pub fn from_bytes(b: &[u8]) -> Self { Self(encryption::x25519::PublicKey::from_bytes(b)) } + + pub fn to_base58_string(&self) -> String { + bs58::encode(&self.to_bytes()).into_string() + } + + pub fn from_base58_string(val: String) -> Self { + Self::from_bytes(&bs58::decode(&val).into_vec().unwrap()) + } } -impl PemStorable for DummyMixIdentityPublicKey { +impl PemStorable for MixIdentityPublicKey { fn pem_type(&self) -> String { format!("DUMMY KEY BASED ON {}", self.0.pem_type()) } } -impl DummyMixIdentityPublicKey { - pub fn to_base58_string(&self) -> String { - bs58::encode(&self.to_bytes()).into_string() - } - - #[allow(dead_code)] - fn from_base58_string(val: String) -> Self { - Self::from_bytes(&bs58::decode(&val).into_vec().unwrap()) - } -} - // COPY IS DERIVED ONLY TEMPORARILY UNTIL https://github.com/nymtech/nym/issues/47 is fixed #[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub struct DummyMixIdentityPrivateKey(pub encryption::x25519::PrivateKey); +pub struct MixIdentityPrivateKey(pub encryption::x25519::PrivateKey); -impl<'a> From<&'a DummyMixIdentityPrivateKey> for DummyMixIdentityPublicKey { - fn from(pk: &'a DummyMixIdentityPrivateKey) -> Self { +impl<'a> From<&'a MixIdentityPrivateKey> for MixIdentityPublicKey { + fn from(pk: &'a MixIdentityPrivateKey) -> Self { let private_ref = &pk.0; let public: encryption::x25519::PublicKey = private_ref.into(); - DummyMixIdentityPublicKey(public) + MixIdentityPublicKey(public) } } -impl MixnetIdentityPrivateKey for DummyMixIdentityPrivateKey { - type PublicKeyMaterial = DummyMixIdentityPublicKey; - - fn to_bytes(&self) -> Vec { +impl MixIdentityPrivateKey { + pub fn to_bytes(&self) -> Vec { self.0.to_bytes() } - fn from_bytes(b: &[u8]) -> Self { + pub fn from_bytes(b: &[u8]) -> Self { Self(encryption::x25519::PrivateKey::from_bytes(b)) } } // TODO: this will be implemented differently by using the proper trait -impl DummyMixIdentityPrivateKey { +impl MixIdentityPrivateKey { pub fn as_scalar(self) -> Scalar { let encryption_key = self.0; encryption_key.0 } } -impl PemStorable for DummyMixIdentityPrivateKey { +impl PemStorable for MixIdentityPrivateKey { fn pem_type(&self) -> String { format!("DUMMY KEY BASED ON {}", self.0.pem_type()) } diff --git a/common/healthcheck/src/lib.rs b/common/healthcheck/src/lib.rs index 5554b2bb97..fc4be5850e 100644 --- a/common/healthcheck/src/lib.rs +++ b/common/healthcheck/src/lib.rs @@ -1,5 +1,5 @@ use crate::result::HealthCheckResult; -use crypto::identity::MixnetIdentityKeyPair; +use crypto::identity::MixIdentityKeyPair; use log::trace; use std::fmt::{Error, Formatter}; use std::time::Duration; @@ -33,17 +33,17 @@ impl From for HealthCheckerError { } } -pub struct HealthChecker { +pub struct HealthChecker { num_test_packets: usize, resolution_timeout: Duration, - identity_keypair: IDPair, + identity_keypair: MixIdentityKeyPair, } -impl HealthChecker { +impl HealthChecker { pub fn new( resolution_timeout_f64: f64, num_test_packets: usize, - identity_keypair: IDPair, + identity_keypair: MixIdentityKeyPair, ) -> Self { HealthChecker { resolution_timeout: Duration::from_secs_f64(resolution_timeout_f64), diff --git a/common/healthcheck/src/path_check.rs b/common/healthcheck/src/path_check.rs index a345e82d99..074df7da44 100644 --- a/common/healthcheck/src/path_check.rs +++ b/common/healthcheck/src/path_check.rs @@ -1,4 +1,4 @@ -use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPublicKey}; +use crypto::identity::MixIdentityKeyPair; use itertools::Itertools; use log::{debug, error, info, trace, warn}; use mix_client::MixClient; @@ -27,9 +27,9 @@ pub(crate) struct PathChecker { } impl PathChecker { - pub(crate) async fn new( + pub(crate) async fn new( providers: Vec, - identity_keys: &IDPair, + identity_keys: &MixIdentityKeyPair, check_id: [u8; 16], ) -> Self { let mut provider_clients = HashMap::new(); diff --git a/common/healthcheck/src/result.rs b/common/healthcheck/src/result.rs index 2dd199ffde..677114a457 100644 --- a/common/healthcheck/src/result.rs +++ b/common/healthcheck/src/result.rs @@ -1,6 +1,6 @@ use crate::path_check::{PathChecker, PathStatus}; use crate::score::NodeScore; -use crypto::identity::MixnetIdentityKeyPair; +use crypto::identity::MixIdentityKeyPair; use log::{debug, error, info, warn}; use rand_os::rand_core::RngCore; use sphinx::route::NodeAddressBytes; @@ -102,16 +102,12 @@ impl HealthCheckResult { id } - pub async fn calculate( + pub async fn calculate( topology: &T, iterations: usize, resolution_timeout: Duration, - identity_keys: &IDPair, - ) -> Self - where - T: NymTopology, - IDPair: MixnetIdentityKeyPair, - { + identity_keys: &MixIdentityKeyPair, + ) -> Self { // currently healthchecker supports only up to 255 iterations - if we somehow // find we need more, it's relatively easy change assert!(iterations <= 255); diff --git a/common/pemstore/src/pemstore.rs b/common/pemstore/src/pemstore.rs index 84bc8cf60a..a8d7b4b239 100644 --- a/common/pemstore/src/pemstore.rs +++ b/common/pemstore/src/pemstore.rs @@ -1,5 +1,5 @@ use crate::pathfinder::PathFinder; -use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPrivateKey, MixnetIdentityPublicKey}; +use crypto::identity::MixIdentityKeyPair; use crypto::PemStorable; use pem::{encode, parse, Pem}; use std::fs::File; @@ -27,11 +27,12 @@ impl PemStore { } } - pub fn read_identity(&self) -> io::Result { + pub fn read_identity(&self) -> io::Result { let private_pem = self.read_pem_file(self.private_mix_key.clone())?; let public_pem = self.read_pem_file(self.public_mix_key.clone())?; - let key_pair = IDPair::from_bytes(&private_pem.contents, &public_pem.contents); + let key_pair = + MixIdentityKeyPair::from_bytes(&private_pem.contents, &public_pem.contents); if key_pair.private_key().pem_type() != private_pem.tag { return Err(io::Error::new( @@ -59,10 +60,7 @@ impl PemStore { // This should be refactored and made more generic for when we have other kinds of // KeyPairs that we want to persist (e.g. validator keypairs, or keys for // signing vs encryption). However, for the moment, it does the job. - pub fn write_identity( - &self, - key_pair: IDPair, - ) -> io::Result<()> { + pub fn write_identity(&self, key_pair: MixIdentityKeyPair) -> io::Result<()> { std::fs::create_dir_all(self.config_dir.clone())?; let private_key = key_pair.private_key(); diff --git a/nym-client/src/client/mod.rs b/nym-client/src/client/mod.rs index 8bb090b95f..af074e3b4f 100644 --- a/nym-client/src/client/mod.rs +++ b/nym-client/src/client/mod.rs @@ -3,7 +3,7 @@ use crate::client::received_buffer::ReceivedMessagesBuffer; use crate::client::topology_control::TopologyInnerRef; use crate::sockets::tcp; use crate::sockets::ws; -use crypto::identity::{MixnetIdentityKeyPair, MixnetIdentityPublicKey}; +use crypto::identity::MixIdentityKeyPair; use directory_client::presence::Topology; use futures::channel::mpsc; use futures::join; @@ -36,11 +36,8 @@ pub enum SocketType { None, } -pub struct NymClient -where - IDPair: MixnetIdentityKeyPair + Send + Sync, -{ - keypair: IDPair, +pub struct NymClient { + keypair: MixIdentityKeyPair, // to be used by "send" function or socket, etc pub input_tx: mpsc::UnboundedSender, @@ -55,12 +52,9 @@ where #[derive(Debug)] pub struct InputMessage(pub Destination, pub Vec); -impl NymClient -where - IDPair: 'static + MixnetIdentityKeyPair + Send + Sync, -{ +impl NymClient { pub fn new( - keypair: IDPair, + keypair: MixIdentityKeyPair, socket_listening_address: SocketAddr, directory: String, auth_token: Option, @@ -115,15 +109,14 @@ where let self_address = self.keypair.public_key().derive_address(); // generate same type of keys we have as our identity - let healthcheck_keys = IDPair::new(); + let healthcheck_keys = MixIdentityKeyPair::new(); // TODO: when we switch to our graph topology, we need to remember to change 'Topology' type - let topology_controller = - rt.block_on(topology_control::TopologyControl::::new( - self.directory.clone(), - TOPOLOGY_REFRESH_RATE, - healthcheck_keys, - )); + let topology_controller = rt.block_on(topology_control::TopologyControl::::new( + self.directory.clone(), + TOPOLOGY_REFRESH_RATE, + healthcheck_keys, + )); let provider_client_listener_address = rt.block_on(self.get_provider_socket_address(topology_controller.get_inner_ref())); diff --git a/nym-client/src/client/topology_control.rs b/nym-client/src/client/topology_control.rs index 5ec9422782..90c84679cc 100644 --- a/nym-client/src/client/topology_control.rs +++ b/nym-client/src/client/topology_control.rs @@ -1,5 +1,5 @@ use crate::built_info; -use crypto::identity::MixnetIdentityKeyPair; +use crypto::identity::MixIdentityKeyPair; use healthcheck::HealthChecker; use log::{error, info, trace, warn}; use std::sync::Arc; @@ -12,14 +12,10 @@ const NODE_HEALTH_THRESHOLD: f64 = 0.0; // auxiliary type for ease of use pub type TopologyInnerRef = Arc>>; -pub(crate) struct TopologyControl -where - T: NymTopology, - IDPair: MixnetIdentityKeyPair, -{ +pub(crate) struct TopologyControl { directory_server: String, inner: Arc>>, - health_checker: HealthChecker, + health_checker: HealthChecker, refresh_rate: f64, } @@ -29,15 +25,11 @@ enum TopologyError { NoValidPathsError, } -impl TopologyControl -where - T: NymTopology, - IDPair: MixnetIdentityKeyPair, -{ +impl TopologyControl { pub(crate) async fn new( directory_server: String, refresh_rate: f64, - identity_keypair: IDPair, + identity_keypair: MixIdentityKeyPair, ) -> Self { // this is a temporary solution as the healthcheck will eventually be moved to validators let health_checker = healthcheck::HealthChecker::new(5.0, 2, identity_keypair); diff --git a/nym-client/src/commands/init.rs b/nym-client/src/commands/init.rs index bc4403e6b9..1ee2385ded 100644 --- a/nym-client/src/commands/init.rs +++ b/nym-client/src/commands/init.rs @@ -1,6 +1,6 @@ use crate::config::persistance::pathfinder::ClientPathfinder; use clap::ArgMatches; -use crypto::identity::MixnetIdentityKeyPair; +use crypto::identity::MixIdentityKeyPair; use pemstore::pemstore::PemStore; pub fn execute(matches: &ArgMatches) { @@ -10,7 +10,7 @@ pub fn execute(matches: &ArgMatches) { let pathfinder = ClientPathfinder::new(id); println!("Writing keypairs to {:?}...", pathfinder.config_dir); - let mix_keys = crypto::identity::DummyMixIdentityKeyPair::new(); + let mix_keys = MixIdentityKeyPair::new(); let pem_store = PemStore::new(pathfinder); pem_store.write_identity(mix_keys).unwrap(); diff --git a/nym-client/src/commands/tcpsocket.rs b/nym-client/src/commands/tcpsocket.rs index 7a98a91681..5dce285c0b 100644 --- a/nym-client/src/commands/tcpsocket.rs +++ b/nym-client/src/commands/tcpsocket.rs @@ -1,7 +1,7 @@ use crate::client::{NymClient, SocketType}; use crate::config::persistance::pathfinder::ClientPathfinder; use clap::ArgMatches; -use crypto::identity::DummyMixIdentityKeyPair; +use crypto::identity::MixIdentityKeyPair; use pemstore::pemstore::PemStore; use std::net::ToSocketAddrs; @@ -27,7 +27,7 @@ pub fn execute(matches: &ArgMatches) { .expect("Failed to extract the socket address from the iterator"); // TODO: currently we know we are reading the 'DummyMixIdentityKeyPair', but how to properly assert the type? - let keypair: DummyMixIdentityKeyPair = PemStore::new(ClientPathfinder::new(id)) + let keypair: MixIdentityKeyPair = PemStore::new(ClientPathfinder::new(id)) .read_identity() .unwrap(); // TODO: reading auth_token from disk (if exists); diff --git a/nym-client/src/commands/websocket.rs b/nym-client/src/commands/websocket.rs index 3193c1ffde..bcb375761e 100644 --- a/nym-client/src/commands/websocket.rs +++ b/nym-client/src/commands/websocket.rs @@ -1,7 +1,7 @@ use crate::client::{NymClient, SocketType}; use crate::config::persistance::pathfinder::ClientPathfinder; use clap::ArgMatches; -use crypto::identity::DummyMixIdentityKeyPair; +use crypto::identity::MixIdentityKeyPair; use pemstore::pemstore::PemStore; use std::net::ToSocketAddrs; @@ -27,7 +27,7 @@ pub fn execute(matches: &ArgMatches) { .expect("Failed to extract the socket address from the iterator"); // TODO: currently we know we are reading the 'DummyMixIdentityKeyPair', but how to properly assert the type? - let keypair: DummyMixIdentityKeyPair = PemStore::new(ClientPathfinder::new(id)) + let keypair: MixIdentityKeyPair = PemStore::new(ClientPathfinder::new(id)) .read_identity() .unwrap(); diff --git a/sfw-provider/src/main.rs b/sfw-provider/src/main.rs index 6cd945a2c0..ec2dee141e 100644 --- a/sfw-provider/src/main.rs +++ b/sfw-provider/src/main.rs @@ -1,6 +1,6 @@ use crate::provider::ServiceProvider; use clap::{App, Arg, ArgMatches, SubCommand}; -use crypto::identity::MixnetIdentityKeyPair; +use crypto::identity::MixIdentityKeyPair; use log::error; use std::net::ToSocketAddrs; use std::path::PathBuf; @@ -121,7 +121,7 @@ fn new_config(matches: &ArgMatches) -> provider::Config { print_binding_warning(client_host); } - let key_pair = crypto::identity::DummyMixIdentityKeyPair::new(); // TODO: persist this so keypairs don't change every restart + let key_pair = crypto::identity::MixIdentityKeyPair::new(); // TODO: persist this so keypairs don't change every restart let store_dir = PathBuf::from( matches .value_of("storeDir") diff --git a/sfw-provider/src/provider/client_handling/mod.rs b/sfw-provider/src/provider/client_handling/mod.rs index e3b9dcf86e..67a2658ebe 100644 --- a/sfw-provider/src/provider/client_handling/mod.rs +++ b/sfw-provider/src/provider/client_handling/mod.rs @@ -1,6 +1,6 @@ use crate::provider::storage::{ClientStorage, StoreError}; use crate::provider::ClientLedger; -use crypto::identity::{DummyMixIdentityPrivateKey, MixnetIdentityPrivateKey}; +use crypto::identity::MixIdentityPrivateKey; use futures::lock::Mutex as FMutex; use hmac::{Hmac, Mac}; use log::*; @@ -54,14 +54,14 @@ impl From for ClientProcessingError { pub(crate) struct ClientProcessingData { store_dir: PathBuf, registered_clients_ledger: Arc>, - secret_key: DummyMixIdentityPrivateKey, + secret_key: MixIdentityPrivateKey, } impl ClientProcessingData { pub(crate) fn new( store_dir: PathBuf, registered_clients_ledger: Arc>, - secret_key: DummyMixIdentityPrivateKey, + secret_key: MixIdentityPrivateKey, ) -> Self { ClientProcessingData { store_dir, @@ -153,7 +153,7 @@ impl ClientRequestProcessor { std::fs::create_dir_all(full_store_dir) } - fn generate_new_auth_token(data: Vec, key: DummyMixIdentityPrivateKey) -> AuthToken { + fn generate_new_auth_token(data: Vec, key: MixIdentityPrivateKey) -> AuthToken { // also note that `new_varkey` doesn't even have an execution branch returning an error let mut auth_token_raw = HmacSha256::new_varkey(&key.to_bytes()) .expect("HMAC should be able take key of any size"); @@ -249,7 +249,7 @@ mod generating_new_auth_token { fn for_the_same_input_generates_the_same_auth_token() { let data1 = vec![1u8; 55]; let data2 = vec![1u8; 55]; - let key = DummyMixIdentityPrivateKey::from_bytes(&[1u8; 32]); + let key = MixIdentityPrivateKey::from_bytes(&[1u8; 32]); let token1 = ClientRequestProcessor::generate_new_auth_token(data1, key); let token2 = ClientRequestProcessor::generate_new_auth_token(data2, key); assert_eq!(token1, token2); @@ -259,14 +259,14 @@ mod generating_new_auth_token { fn for_different_inputs_generates_different_auth_tokens() { let data1 = vec![1u8; 55]; let data2 = vec![2u8; 55]; - let key = DummyMixIdentityPrivateKey::from_bytes(&[1u8; 32]); + let key = MixIdentityPrivateKey::from_bytes(&[1u8; 32]); let token1 = ClientRequestProcessor::generate_new_auth_token(data1, key); let token2 = ClientRequestProcessor::generate_new_auth_token(data2, key); assert_ne!(token1, token2); let data1 = vec![1u8; 50]; let data2 = vec![2u8; 55]; - let key = DummyMixIdentityPrivateKey::from_bytes(&[1u8; 32]); + let key = MixIdentityPrivateKey::from_bytes(&[1u8; 32]); let token1 = ClientRequestProcessor::generate_new_auth_token(data1, key); let token2 = ClientRequestProcessor::generate_new_auth_token(data2, key); assert_ne!(token1, token2); diff --git a/sfw-provider/src/provider/mix_handling/mod.rs b/sfw-provider/src/provider/mix_handling/mod.rs index 338943efd1..60ceaf700e 100644 --- a/sfw-provider/src/provider/mix_handling/mod.rs +++ b/sfw-provider/src/provider/mix_handling/mod.rs @@ -1,5 +1,5 @@ use crate::provider::storage::StoreData; -use crypto::identity::DummyMixIdentityPrivateKey; +use crypto::identity::MixIdentityPrivateKey; use log::{error, warn}; use sphinx::{ProcessedPacket, SphinxPacket}; use std::path::PathBuf; @@ -37,12 +37,12 @@ impl From for MixProcessingError { // ProcessingData defines all data required to correctly unwrap sphinx packets #[derive(Debug, Clone)] pub(crate) struct MixProcessingData { - secret_key: DummyMixIdentityPrivateKey, + secret_key: MixIdentityPrivateKey, pub(crate) store_dir: PathBuf, } impl MixProcessingData { - pub(crate) fn new(secret_key: DummyMixIdentityPrivateKey, store_dir: PathBuf) -> Self { + pub(crate) fn new(secret_key: MixIdentityPrivateKey, store_dir: PathBuf) -> Self { MixProcessingData { secret_key, store_dir, diff --git a/sfw-provider/src/provider/mod.rs b/sfw-provider/src/provider/mod.rs index 4e16e5a2a2..56085917aa 100644 --- a/sfw-provider/src/provider/mod.rs +++ b/sfw-provider/src/provider/mod.rs @@ -1,7 +1,7 @@ use crate::provider::client_handling::{ClientProcessingData, ClientRequestProcessor}; use crate::provider::mix_handling::{MixPacketProcessor, MixProcessingData}; use crate::provider::storage::ClientStorage; -use crypto::identity::{DummyMixIdentityPrivateKey, DummyMixIdentityPublicKey}; +use crypto::identity::{MixIdentityPrivateKey, MixIdentityPublicKey}; use directory_client::presence::providers::MixProviderClient; use futures::io::Error; use futures::lock::Mutex as FMutex; @@ -29,8 +29,8 @@ pub struct Config { pub client_socket_address: SocketAddr, pub directory_server: String, pub mix_socket_address: SocketAddr, - pub public_key: DummyMixIdentityPublicKey, - pub secret_key: DummyMixIdentityPrivateKey, + pub public_key: MixIdentityPublicKey, + pub secret_key: MixIdentityPrivateKey, pub store_dir: PathBuf, } @@ -102,8 +102,8 @@ pub struct ServiceProvider { directory_server: String, mix_network_address: SocketAddr, client_network_address: SocketAddr, - public_key: DummyMixIdentityPublicKey, - secret_key: DummyMixIdentityPrivateKey, + public_key: MixIdentityPublicKey, + secret_key: MixIdentityPrivateKey, store_dir: PathBuf, registered_clients_ledger: ClientLedger, } @@ -236,7 +236,7 @@ impl ServiceProvider { async fn start_mixnet_listening( address: SocketAddr, - secret_key: DummyMixIdentityPrivateKey, + secret_key: MixIdentityPrivateKey, store_dir: PathBuf, ) -> Result<(), ProviderError> { let mut listener = tokio::net::TcpListener::bind(address).await?; @@ -258,7 +258,7 @@ impl ServiceProvider { address: SocketAddr, store_dir: PathBuf, client_ledger: Arc>, - secret_key: DummyMixIdentityPrivateKey, + secret_key: MixIdentityPrivateKey, ) -> Result<(), ProviderError> { let mut listener = tokio::net::TcpListener::bind(address).await?; let processing_data = diff --git a/sfw-provider/src/provider/presence.rs b/sfw-provider/src/provider/presence.rs index adfcebaddc..77945cb096 100644 --- a/sfw-provider/src/provider/presence.rs +++ b/sfw-provider/src/provider/presence.rs @@ -1,5 +1,5 @@ use crate::provider::ClientLedger; -use crypto::identity::DummyMixIdentityPublicKey; +use crypto::identity::MixIdentityPublicKey; use directory_client::presence::providers::MixProviderPresence; use directory_client::requests::presence_providers_post::PresenceMixProviderPoster; use directory_client::DirectoryClient; @@ -22,7 +22,7 @@ impl Notifier { directory_server_address: String, client_listener: SocketAddr, mixnet_listener: SocketAddr, - pub_key: DummyMixIdentityPublicKey, + pub_key: MixIdentityPublicKey, client_ledger: Arc>, ) -> Notifier { let directory_config = directory_client::Config { diff --git a/validator/src/services/mixmining/health_check_runner.rs b/validator/src/services/mixmining/health_check_runner.rs index b53162273f..1200c6fe4f 100644 --- a/validator/src/services/mixmining/health_check_runner.rs +++ b/validator/src/services/mixmining/health_check_runner.rs @@ -1,4 +1,3 @@ -use crypto::identity::DummyMixIdentityKeyPair; use healthcheck::HealthChecker; use log::*; use std::time::Duration; @@ -6,7 +5,7 @@ use topology::NymTopology; pub struct HealthCheckRunner { directory_server: String, - health_checker: HealthChecker, + health_checker: HealthChecker, interval: f64, } @@ -14,7 +13,7 @@ impl HealthCheckRunner { pub fn new( directory_server: String, interval: f64, - health_checker: HealthChecker, + health_checker: HealthChecker, ) -> HealthCheckRunner { HealthCheckRunner { directory_server, diff --git a/validator/src/validator.rs b/validator/src/validator.rs index 6cdc6f6fc3..f793440bcc 100644 --- a/validator/src/validator.rs +++ b/validator/src/validator.rs @@ -1,6 +1,6 @@ use crate::network::tendermint; use crate::services::mixmining::health_check_runner; -use crypto::identity::{DummyMixIdentityKeyPair, MixnetIdentityKeyPair}; +use crypto::identity::MixIdentityKeyPair; use healthcheck::HealthChecker; use tokio::runtime::Runtime; @@ -15,7 +15,7 @@ pub struct Config { // allow for a generic validator pub struct Validator { #[allow(dead_code)] - identity_keypair: DummyMixIdentityKeyPair, + identity_keypair: MixIdentityKeyPair, health_check_runner: health_check_runner::HealthCheckRunner, tendermint_abci: tendermint::Abci, } @@ -23,7 +23,7 @@ pub struct Validator { // but for time being, since it's a dummy one, have it use dummy keys impl Validator { pub fn new(config: Config) -> Self { - let dummy_keypair = DummyMixIdentityKeyPair::new(); + let dummy_keypair = MixIdentityKeyPair::new(); let hc = HealthChecker::new( config.health_check.resolution_timeout, config.health_check.num_test_packets, From 9797b8da74072b044a3a193b93b1fa3a48403bc1 Mon Sep 17 00:00:00 2001 From: Dave Hrycyszyn Date: Thu, 30 Jan 2020 12:27:00 +0000 Subject: [PATCH 3/3] crypto: simplified keypairs a bit --- common/crypto/src/encryption/mod.rs | 111 ++++++++++++++++++------- common/crypto/src/encryption/x25519.rs | 99 ---------------------- common/crypto/src/identity/mod.rs | 15 ++-- common/pemstore/src/pemstore.rs | 5 +- sfw-provider/src/main.rs | 1 - 5 files changed, 90 insertions(+), 141 deletions(-) delete mode 100644 common/crypto/src/encryption/x25519.rs diff --git a/common/crypto/src/encryption/mod.rs b/common/crypto/src/encryption/mod.rs index b36ddf1af7..4a38cd89ed 100644 --- a/common/crypto/src/encryption/mod.rs +++ b/common/crypto/src/encryption/mod.rs @@ -1,39 +1,92 @@ use crate::PemStorable; +use curve25519_dalek::montgomery::MontgomeryPoint; +use curve25519_dalek::scalar::Scalar; -pub mod x25519; +// TODO: ensure this is a proper name for this considering we are not implementing entire DH here -pub trait MixnetEncryptionKeyPair -where - Priv: MixnetEncryptionPrivateKey, - Pub: MixnetEncryptionPublicKey, -{ - fn new() -> Self; - fn private_key(&self) -> &Priv; - fn public_key(&self) -> &Pub; - fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self; +const CURVE_GENERATOR: MontgomeryPoint = curve25519_dalek::constants::X25519_BASEPOINT; - // TODO: encryption related methods +pub struct KeyPair { + pub(crate) private_key: PrivateKey, + pub(crate) public_key: PublicKey, } -pub trait MixnetEncryptionPublicKey: - Sized + PemStorable + for<'a> From<&'a ::PrivateKeyMaterial> -{ - // we need to couple public and private keys together - type PrivateKeyMaterial: MixnetEncryptionPrivateKey; +impl KeyPair { + pub fn new() -> Self { + let mut rng = rand_os::OsRng::new().unwrap(); + let private_key_value = Scalar::random(&mut rng); + let public_key_value = CURVE_GENERATOR * private_key_value; - fn to_bytes(&self) -> Vec; - fn from_bytes(b: &[u8]) -> Self; -} - -pub trait MixnetEncryptionPrivateKey: Sized + PemStorable { - // we need to couple public and private keys together - type PublicKeyMaterial: MixnetEncryptionPublicKey; - - /// Returns the associated public key - fn public_key(&self) -> Self::PublicKeyMaterial { - self.into() + KeyPair { + private_key: PrivateKey(private_key_value), + public_key: PublicKey(public_key_value), + } } - fn to_bytes(&self) -> Vec; - fn from_bytes(b: &[u8]) -> Self; + pub fn private_key(&self) -> &PrivateKey { + &self.private_key + } + + pub fn public_key(&self) -> &PublicKey { + &self.public_key + } + + pub fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self { + KeyPair { + private_key: PrivateKey::from_bytes(priv_bytes), + public_key: PublicKey::from_bytes(pub_bytes), + } + } +} + +// COPY IS DERIVED ONLY TEMPORARILY UNTIL https://github.com/nymtech/nym/issues/47 is fixed +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +pub struct PrivateKey(pub Scalar); + +impl PrivateKey { + pub fn to_bytes(&self) -> Vec { + self.0.to_bytes().to_vec() + } + + pub fn from_bytes(b: &[u8]) -> Self { + let mut bytes = [0; 32]; + bytes.copy_from_slice(&b[..]); + // due to trait restriction we have no choice but to panic if this fails + let key = Scalar::from_canonical_bytes(bytes).unwrap(); + Self(key) + } +} + +impl PemStorable for PrivateKey { + fn pem_type(&self) -> String { + String::from("X25519 PRIVATE KEY") + } +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct PublicKey(pub MontgomeryPoint); + +impl<'a> From<&'a PrivateKey> for PublicKey { + fn from(pk: &'a PrivateKey) -> Self { + PublicKey(CURVE_GENERATOR * pk.0) + } +} + +impl PublicKey { + pub fn to_bytes(&self) -> Vec { + self.0.to_bytes().to_vec() + } + + pub fn from_bytes(b: &[u8]) -> Self { + let mut bytes = [0; 32]; + bytes.copy_from_slice(&b[..]); + let key = MontgomeryPoint(bytes); + Self(key) + } +} + +impl PemStorable for PublicKey { + fn pem_type(&self) -> String { + String::from("X25519 PUBLIC KEY") + } } diff --git a/common/crypto/src/encryption/x25519.rs b/common/crypto/src/encryption/x25519.rs deleted file mode 100644 index 44d86783da..0000000000 --- a/common/crypto/src/encryption/x25519.rs +++ /dev/null @@ -1,99 +0,0 @@ -use crate::encryption::{ - MixnetEncryptionKeyPair, MixnetEncryptionPrivateKey, MixnetEncryptionPublicKey, -}; -use crate::PemStorable; -use curve25519_dalek::montgomery::MontgomeryPoint; -use curve25519_dalek::scalar::Scalar; - -// TODO: ensure this is a proper name for this considering we are not implementing entire DH here - -const CURVE_GENERATOR: MontgomeryPoint = curve25519_dalek::constants::X25519_BASEPOINT; - -pub struct KeyPair { - pub(crate) private_key: PrivateKey, - pub(crate) public_key: PublicKey, -} - -impl MixnetEncryptionKeyPair for KeyPair { - fn new() -> Self { - let mut rng = rand_os::OsRng::new().unwrap(); - let private_key_value = Scalar::random(&mut rng); - let public_key_value = CURVE_GENERATOR * private_key_value; - - KeyPair { - private_key: PrivateKey(private_key_value), - public_key: PublicKey(public_key_value), - } - } - - fn private_key(&self) -> &PrivateKey { - &self.private_key - } - - fn public_key(&self) -> &PublicKey { - &self.public_key - } - - fn from_bytes(priv_bytes: &[u8], pub_bytes: &[u8]) -> Self { - KeyPair { - private_key: PrivateKey::from_bytes(priv_bytes), - public_key: PublicKey::from_bytes(pub_bytes), - } - } -} - -// COPY IS DERIVED ONLY TEMPORARILY UNTIL https://github.com/nymtech/nym/issues/47 is fixed -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub struct PrivateKey(pub Scalar); - -impl MixnetEncryptionPrivateKey for PrivateKey { - type PublicKeyMaterial = PublicKey; - - fn to_bytes(&self) -> Vec { - self.0.to_bytes().to_vec() - } - - fn from_bytes(b: &[u8]) -> Self { - let mut bytes = [0; 32]; - bytes.copy_from_slice(&b[..]); - // due to trait restriction we have no choice but to panic if this fails - let key = Scalar::from_canonical_bytes(bytes).unwrap(); - Self(key) - } -} - -impl PemStorable for PrivateKey { - fn pem_type(&self) -> String { - String::from("X25519 PRIVATE KEY") - } -} - -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct PublicKey(pub MontgomeryPoint); - -impl<'a> From<&'a PrivateKey> for PublicKey { - fn from(pk: &'a PrivateKey) -> Self { - PublicKey(CURVE_GENERATOR * pk.0) - } -} - -impl MixnetEncryptionPublicKey for PublicKey { - type PrivateKeyMaterial = PrivateKey; - - fn to_bytes(&self) -> Vec { - self.0.to_bytes().to_vec() - } - - fn from_bytes(b: &[u8]) -> Self { - let mut bytes = [0; 32]; - bytes.copy_from_slice(&b[..]); - let key = MontgomeryPoint(bytes); - Self(key) - } -} - -impl PemStorable for PublicKey { - fn pem_type(&self) -> String { - String::from("X25519 PUBLIC KEY") - } -} diff --git a/common/crypto/src/identity/mod.rs b/common/crypto/src/identity/mod.rs index a966ec4cb9..270e25dcfb 100644 --- a/common/crypto/src/identity/mod.rs +++ b/common/crypto/src/identity/mod.rs @@ -1,6 +1,3 @@ -use crate::encryption::{ - MixnetEncryptionKeyPair, MixnetEncryptionPrivateKey, MixnetEncryptionPublicKey, -}; use crate::{encryption, PemStorable}; use bs58; use curve25519_dalek::scalar::Scalar; @@ -16,7 +13,7 @@ pub struct MixIdentityKeyPair { impl MixIdentityKeyPair { pub fn new() -> Self { - let keypair = encryption::x25519::KeyPair::new(); + let keypair = encryption::KeyPair::new(); MixIdentityKeyPair { private_key: MixIdentityPrivateKey(keypair.private_key), public_key: MixIdentityPublicKey(keypair.public_key), @@ -40,7 +37,7 @@ impl MixIdentityKeyPair { } #[derive(Debug, Clone, Eq, PartialEq)] -pub struct MixIdentityPublicKey(encryption::x25519::PublicKey); +pub struct MixIdentityPublicKey(encryption::PublicKey); impl MixIdentityPublicKey { pub fn derive_address(&self) -> DestinationAddressBytes { @@ -56,7 +53,7 @@ impl MixIdentityPublicKey { } pub fn from_bytes(b: &[u8]) -> Self { - Self(encryption::x25519::PublicKey::from_bytes(b)) + Self(encryption::PublicKey::from_bytes(b)) } pub fn to_base58_string(&self) -> String { @@ -76,12 +73,12 @@ impl PemStorable for MixIdentityPublicKey { // COPY IS DERIVED ONLY TEMPORARILY UNTIL https://github.com/nymtech/nym/issues/47 is fixed #[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub struct MixIdentityPrivateKey(pub encryption::x25519::PrivateKey); +pub struct MixIdentityPrivateKey(pub encryption::PrivateKey); impl<'a> From<&'a MixIdentityPrivateKey> for MixIdentityPublicKey { fn from(pk: &'a MixIdentityPrivateKey) -> Self { let private_ref = &pk.0; - let public: encryption::x25519::PublicKey = private_ref.into(); + let public: encryption::PublicKey = private_ref.into(); MixIdentityPublicKey(public) } } @@ -92,7 +89,7 @@ impl MixIdentityPrivateKey { } pub fn from_bytes(b: &[u8]) -> Self { - Self(encryption::x25519::PrivateKey::from_bytes(b)) + Self(encryption::PrivateKey::from_bytes(b)) } } diff --git a/common/pemstore/src/pemstore.rs b/common/pemstore/src/pemstore.rs index a8d7b4b239..0fbc38b71f 100644 --- a/common/pemstore/src/pemstore.rs +++ b/common/pemstore/src/pemstore.rs @@ -8,7 +8,7 @@ use std::io::prelude::*; use std::path::PathBuf; #[allow(dead_code)] -pub fn read_mix_encryption_keypair_from_disk(_id: String) -> crypto::encryption::x25519::KeyPair { +pub fn read_mix_encryption_keypair_from_disk(_id: String) -> crypto::encryption::KeyPair { unimplemented!() } @@ -31,8 +31,7 @@ impl PemStore { let private_pem = self.read_pem_file(self.private_mix_key.clone())?; let public_pem = self.read_pem_file(self.public_mix_key.clone())?; - let key_pair = - MixIdentityKeyPair::from_bytes(&private_pem.contents, &public_pem.contents); + let key_pair = MixIdentityKeyPair::from_bytes(&private_pem.contents, &public_pem.contents); if key_pair.private_key().pem_type() != private_pem.tag { return Err(io::Error::new( diff --git a/sfw-provider/src/main.rs b/sfw-provider/src/main.rs index ec2dee141e..408ec221b6 100644 --- a/sfw-provider/src/main.rs +++ b/sfw-provider/src/main.rs @@ -1,6 +1,5 @@ use crate::provider::ServiceProvider; use clap::{App, Arg, ArgMatches, SubCommand}; -use crypto::identity::MixIdentityKeyPair; use log::error; use std::net::ToSocketAddrs; use std::path::PathBuf;