From 65dbb7ae70c02dcf24e7304c3b62751cbc77974c Mon Sep 17 00:00:00 2001 From: librelois <elois@ifee.fr> Date: Wed, 28 Aug 2019 01:40:01 +0200 Subject: [PATCH] [ref] whole: migrate from cryptoxide to ring --- Cargo.lock | 22 +- lib/core/conf/Cargo.toml | 2 - lib/core/conf/src/keys.rs | 84 ++--- lib/core/conf/src/lib.rs | 48 ++- lib/core/conf/test/v1/keypairs.json | 6 +- lib/core/conf/test/v2/keypairs.json | 6 +- lib/core/module/src/lib.rs | 6 +- lib/crypto/Cargo.toml | 3 +- lib/crypto/src/keys/bin_signable.rs | 39 ++- lib/crypto/src/keys/ed25519.rs | 278 ++++++--------- lib/crypto/src/keys/mod.rs | 324 +++++++++--------- lib/crypto/src/keys/seed.rs | 74 ++++ lib/crypto/src/keys/text_signable.rs | 28 +- lib/crypto/src/lib.rs | 10 +- lib/crypto/src/rand/mod.rs | 43 +++ lib/dubp/block-doc/src/block.rs | 8 +- lib/dubp/block-doc/src/block/v10.rs | 4 +- lib/dubp/common-doc/src/traits.rs | 6 +- lib/dubp/common-doc/src/traits/text.rs | 6 +- .../src/documents/certification/v10.rs | 31 +- .../user-docs/src/documents/identity/v10.rs | 36 +- .../user-docs/src/documents/membership/v10.rs | 36 +- .../user-docs/src/documents/revocation/v10.rs | 35 +- .../user-docs/src/documents/transaction.rs | 36 +- lib/dunp/network-documents/src/lib.rs | 6 +- .../network-documents/src/network_head_v3.rs | 4 +- .../network-documents/src/network_peer.rs | 4 +- lib/modules/ws2p-v1-legacy/Cargo.toml | 2 - .../ws2p-v1-legacy/src/events/received.rs | 2 +- lib/modules/ws2p-v1-legacy/src/heads.rs | 14 +- lib/modules/ws2p-v1-legacy/src/lib.rs | 10 +- .../ws2p-v1-legacy/src/responses/received.rs | 2 +- .../src/ws_connections/handler.rs | 47 ++- .../src/ws_connections/messages.rs | 6 +- .../src/ws_connections/meta_datas.rs | 10 +- .../ws2p-v1-legacy/src/ws_connections/mod.rs | 30 +- lib/modules/ws2p/ws2p-messages/lib.rs | 10 +- .../ws2p/ws2p-messages/v2/api_features.rs | 18 +- lib/modules/ws2p/ws2p-messages/v2/connect.rs | 9 +- lib/modules/ws2p/ws2p-messages/v2/mod.rs | 11 +- .../ws2p/ws2p-messages/v2/secret_flags.rs | 4 +- .../src/controller/meta_datas.rs | 12 +- .../src/controller/on_message/ack_msg.rs | 2 +- .../src/controller/on_message/connect_msg.rs | 4 +- .../ws2p-protocol/src/controller/on_open.rs | 4 +- lib/modules/ws2p/ws2p-protocol/src/lib.rs | 2 +- .../src/controllers/incoming_connections.rs | 2 +- .../src/controllers/outgoing_connections.rs | 2 +- lib/modules/ws2p/ws2p/src/generate_peer.rs | 12 +- lib/modules/ws2p/ws2p/src/services/mod.rs | 2 +- .../ws2p/ws2p/tests/connection_negociation.rs | 16 +- 51 files changed, 747 insertions(+), 671 deletions(-) create mode 100644 lib/crypto/src/keys/seed.rs create mode 100644 lib/crypto/src/rand/mod.rs diff --git a/Cargo.lock b/Cargo.lock index ccb8f7e6..12bb427b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,6 +198,14 @@ dependencies = [ "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "clear_on_drop" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cc 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cloudabi" version = "0.0.3" @@ -290,11 +298,6 @@ dependencies = [ "subtle 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cryptoxide" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "csv" version = "1.1.1" @@ -460,7 +463,8 @@ dependencies = [ "base58 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cryptoxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "durs-common-tools 0.2.0", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -556,7 +560,6 @@ dependencies = [ name = "durs-conf" version = "0.3.0-dev" dependencies = [ - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", "dubp-currency-params 0.2.0", "dubp-user-docs 0.14.0", @@ -565,7 +568,6 @@ dependencies = [ "durs-module 0.3.0-dev", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.7 (registry+https://github.com/rust-lang/crates.io-index)", "rpassword 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", @@ -803,7 +805,6 @@ name = "durs-ws2p-v1-legacy" version = "0.3.0-dev" dependencies = [ "bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "dubp-block-doc 0.1.0", "dubp-common-doc 0.1.0", "dubp-currency-params 0.2.0", @@ -819,7 +820,6 @@ dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.16.7 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2188,6 +2188,7 @@ dependencies = [ "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" "checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +"checksum clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "97276801e127ffb46b66ce23f35cc96bd454fa311294bced4bbace7baa8b1d17" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e" "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3" @@ -2198,7 +2199,6 @@ dependencies = [ "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -"checksum cryptoxide 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b486f0f6730b6972b7831f0faf2dc7c3280aab69bc07357c7a2f24042b945e36" "checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" "checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" diff --git a/lib/core/conf/Cargo.toml b/lib/core/conf/Cargo.toml index f5119122..b2aa864e 100644 --- a/lib/core/conf/Cargo.toml +++ b/lib/core/conf/Cargo.toml @@ -10,7 +10,6 @@ edition = "2018" path = "src/lib.rs" [dependencies] -byteorder = "1.2.7" dirs = "1.0.2" dup-crypto = { path = "../../crypto" } dubp-currency-params = { path = "../../dubp/currency-params" } @@ -19,7 +18,6 @@ durs-module = { path = "../module" } durs-common-tools = { path = "../../tools/common-tools" } failure = "0.1.5" log = "0.4.*" -ring = "0.16.5" rpassword = "1.0.0" serde = "1.0.*" serde_derive = "1.0.*" diff --git a/lib/core/conf/src/keys.rs b/lib/core/conf/src/keys.rs index cdc98fcd..84bb0579 100644 --- a/lib/core/conf/src/keys.rs +++ b/lib/core/conf/src/keys.rs @@ -170,14 +170,12 @@ pub fn key_wizard(mut key_pairs: DuniterKeyPairs) -> Result<DuniterKeyPairs, Wiz mod tests { use super::*; - static BASE58_SEC_INIT: &'static str = - "4iXXx5GgRkZ85BVPwn8vFXvztdXAAa5yB573ErcAnngAgSVEknNqc16xRnCmsuHFAJ3j3XArB4mv8UVpvrG32vLV"; + static BASE58_SEED_INIT: &'static str = "4iXXx5GgRkZ85BVPwn8vFXvztdXAAa5yB573ErcAnngA"; static BASE58_PUB_INIT: &'static str = "otDgSpKvKAPPmE1MUYxc3UQ3RtEnKYz4iGD3BmwKPzM"; //static SALT_INIT: &'static str = "initsalt"; //static PASSWORD_INIT: &'static str = "initpassword"; - static BASE58_SEC_TEST: &'static str = - "4xr2CFHWQtDUQiPCon3FhEAvSpXEoFZHeEPiBzDUtEbt2wnrFS9ZTtAvUyZypbDvw8wmYhHrJgBVo6GidMrpwoQq"; + static BASE58_SEED_TEST: &'static str = "ELjDWGPyCGMuhr7R7H2aip6UJA9qLRepmK77pcD41UqQ"; static BASE58_PUB_TEST: &'static str = "6sewkaNWyEMqkEa2PVRWrDb3hxWtjPdUSB1zXVCqhdWV"; static SALT_TEST: &'static str = "testsalt"; static PASSWORD_TEST: &'static str = "testpassword"; @@ -185,9 +183,9 @@ mod tests { #[test] fn test_modify_member_keys() { let key_pairs = DuniterKeyPairs { - network_keypair: KeyPairEnum::Ed25519(ed25519::KeyPair { - privkey: ed25519::PrivateKey::from_base58(BASE58_SEC_INIT) - .expect("conf : keypairs file : fail to parse network_sec !"), + network_keypair: KeyPairEnum::Ed25519(ed25519::Ed25519KeyPair { + seed: Seed::from_base58(BASE58_SEED_INIT) + .expect("conf : keypairs file : fail to parse network_seed !"), pubkey: ed25519::PublicKey::from_base58(BASE58_PUB_INIT) .expect("conf : keypairs file : fail to parse network_pub !"), }), @@ -203,11 +201,8 @@ mod tests { ) ); assert_eq!( - result_key_pairs.network_keypair.private_key(), - PrivKey::Ed25519( - ed25519::PrivateKey::from_base58(BASE58_SEC_INIT) - .expect("Wrong data in BASE58_SEC_TEST") - ) + result_key_pairs.network_keypair.seed(), + Seed::from_base58(BASE58_SEED_INIT).expect("Wrong data in BASE58_SEED_INIT"), ); // We expect member key to update as intended @@ -219,20 +214,17 @@ mod tests { ) ); assert_eq!( - result_key_pairs.member_keypair.unwrap().private_key(), - PrivKey::Ed25519( - ed25519::PrivateKey::from_base58(BASE58_SEC_TEST) - .expect("Wrong data in BASE58_SEC_TEST") - ) + result_key_pairs.member_keypair.unwrap().seed(), + Seed::from_base58(BASE58_SEED_TEST).expect("Wrong data in BASE58_SEED_TEST"), ); } #[test] fn test_modify_network_keys() { let key_pairs = DuniterKeyPairs { - network_keypair: KeyPairEnum::Ed25519(ed25519::KeyPair { - privkey: ed25519::PrivateKey::from_base58(BASE58_SEC_INIT) - .expect("conf : keypairs file : fail to parse network_sec !"), + network_keypair: KeyPairEnum::Ed25519(ed25519::Ed25519KeyPair { + seed: Seed::from_base58(BASE58_SEED_INIT) + .expect("conf : keypairs file : fail to parse network_seed !"), pubkey: ed25519::PublicKey::from_base58(BASE58_PUB_INIT) .expect("conf : keypairs file : fail to parse network_pub !"), }), @@ -248,11 +240,8 @@ mod tests { ) ); assert_eq!( - result_key_pairs.network_keypair.private_key(), - PrivKey::Ed25519( - ed25519::PrivateKey::from_base58(BASE58_SEC_TEST) - .expect("Wrong data in BASE58_SEC_TEST") - ) + result_key_pairs.network_keypair.seed(), + Seed::from_base58(BASE58_SEED_TEST).expect("Wrong data in BASE58_SEED_TEST") ); // We expect member key not to change assert_eq!(result_key_pairs.member_keypair, None); @@ -261,15 +250,15 @@ mod tests { #[test] fn test_clear_network_keys() { let key_pairs = DuniterKeyPairs { - network_keypair: KeyPairEnum::Ed25519(ed25519::KeyPair { - privkey: ed25519::PrivateKey::from_base58(BASE58_SEC_INIT) - .expect("conf : keypairs file : fail to parse network_sec !"), + network_keypair: KeyPairEnum::Ed25519(ed25519::Ed25519KeyPair { + seed: Seed::from_base58(BASE58_SEED_INIT) + .expect("conf : keypairs file : fail to parse network_seed !"), pubkey: ed25519::PublicKey::from_base58(BASE58_PUB_INIT) .expect("conf : keypairs file : fail to parse network_pub !"), }), - member_keypair: Some(KeyPairEnum::Ed25519(ed25519::KeyPair { - privkey: ed25519::PrivateKey::from_base58(BASE58_SEC_INIT) - .expect("conf : keypairs file : fail to parse network_sec !"), + member_keypair: Some(KeyPairEnum::Ed25519(ed25519::Ed25519KeyPair { + seed: Seed::from_base58(BASE58_SEED_INIT) + .expect("conf : keypairs file : fail to parse network_seed !"), pubkey: ed25519::PublicKey::from_base58(BASE58_PUB_INIT) .expect("conf : keypairs file : fail to parse network_pub !"), })), @@ -284,11 +273,8 @@ mod tests { ) ); assert_ne!( - result_key_pairs.network_keypair.private_key(), - PrivKey::Ed25519( - ed25519::PrivateKey::from_base58(BASE58_SEC_INIT) - .expect("Wrong data in BASE58_SEC_TEST") - ) + result_key_pairs.network_keypair.seed(), + Seed::from_base58(BASE58_SEED_INIT).expect("Wrong data in BASE58_SEED_TEST") ); // We expect member key not to change @@ -300,26 +286,23 @@ mod tests { ) ); assert_eq!( - result_key_pairs.member_keypair.unwrap().private_key(), - PrivKey::Ed25519( - ed25519::PrivateKey::from_base58(BASE58_SEC_INIT) - .expect("Wrong data in BASE58_SEC_TEST") - ) + result_key_pairs.member_keypair.unwrap().seed(), + Seed::from_base58(BASE58_SEED_INIT).expect("Wrong data in BASE58_SEED_TEST") ); } #[test] fn test_clear_member_keys() { let key_pairs = DuniterKeyPairs { - network_keypair: KeyPairEnum::Ed25519(ed25519::KeyPair { - privkey: ed25519::PrivateKey::from_base58(BASE58_SEC_INIT) - .expect("conf : keypairs file : fail to parse network_sec !"), + network_keypair: KeyPairEnum::Ed25519(ed25519::Ed25519KeyPair { + seed: Seed::from_base58(BASE58_SEED_INIT) + .expect("conf : keypairs file : fail to parse network_seed !"), pubkey: ed25519::PublicKey::from_base58(BASE58_PUB_INIT) .expect("conf : keypairs file : fail to parse network_pub !"), }), - member_keypair: Some(KeyPairEnum::Ed25519(ed25519::KeyPair { - privkey: ed25519::PrivateKey::from_base58(BASE58_SEC_INIT) - .expect("conf : keypairs file : fail to parse network_sec !"), + member_keypair: Some(KeyPairEnum::Ed25519(ed25519::Ed25519KeyPair { + seed: Seed::from_base58(BASE58_SEED_INIT) + .expect("conf : keypairs file : fail to parse network_seed !"), pubkey: ed25519::PublicKey::from_base58(BASE58_PUB_INIT) .expect("conf : keypairs file : fail to parse network_pub !"), })), @@ -334,11 +317,8 @@ mod tests { ) ); assert_eq!( - result_key_pairs.network_keypair.private_key(), - PrivKey::Ed25519( - ed25519::PrivateKey::from_base58(BASE58_SEC_INIT) - .expect("Wrong data in BASE58_SEC_TEST") - ) + result_key_pairs.network_keypair.seed(), + Seed::from_base58(BASE58_SEED_INIT).expect("Wrong data in BASE58_SEED_TEST") ); // We expect member key to change diff --git a/lib/core/conf/src/lib.rs b/lib/core/conf/src/lib.rs index 00a42436..03bd0fb0 100644 --- a/lib/core/conf/src/lib.rs +++ b/lib/core/conf/src/lib.rs @@ -36,15 +36,14 @@ pub mod constants; pub mod keys; use crate::constants::MODULES_DATAS_FOLDER; -use byteorder::{BigEndian, ByteOrder}; use dubp_currency_params::CurrencyName; use dup_crypto::keys::*; +use dup_crypto::rand; use durs_common_tools::fatal_error; use durs_module::{ DursConfTrait, DursGlobalConfTrait, ModuleName, RequiredKeys, RequiredKeysContent, }; use failure::Fail; -use ring::rand; use serde::ser::{Serialize, SerializeStruct, Serializer}; use std::collections::HashSet; use std::fs; @@ -370,8 +369,8 @@ impl Serialize for DuniterKeyPairs { where S: Serializer, { - let member_sec = if let Some(member_keypair) = self.member_keypair { - member_keypair.private_key().to_string() + let member_seed = if let Some(member_keypair) = self.member_keypair { + member_keypair.seed().to_string() } else { String::from("") }; @@ -382,14 +381,14 @@ impl Serialize for DuniterKeyPairs { }; let mut state = serializer.serialize_struct("DuniterKeyPairs", 4)?; state.serialize_field( - "network_sec", - &self.network_keypair.private_key().to_string().as_str(), + "network_seed", + &self.network_keypair.seed().to_string().as_str(), )?; state.serialize_field( "network_pub", &self.network_keypair.public_key().to_string().as_str(), )?; - state.serialize_field("member_sec", member_sec.as_str())?; + state.serialize_field("member_seed", member_seed.as_str())?; state.serialize_field("member_pub", member_pub.as_str())?; state.end() } @@ -426,17 +425,14 @@ impl DuniterKeyPairs { // Warning: This function cannot use the macro fatal_error! because the logger is not yet initialized, so it must use panic ! fn generate_random_keypair(algo: KeysAlgo) -> KeyPairEnum { match algo { - KeysAlgo::Ed25519 => KeyPairEnum::Ed25519(ed25519::KeyPair::generate_random()), + KeysAlgo::Ed25519 => KeyPairEnum::Ed25519(ed25519::Ed25519KeyPair::generate_random()), KeysAlgo::Schnorr => panic!("Schnorr algo not yet supported !"), } } +#[inline] fn generate_random_node_id() -> u32 { - if let Ok(random_bytes) = rand::generate::<[u8; 4]>(&rand::SystemRandom::new()) { - BigEndian::read_u32(&random_bytes.expose()) - } else { - fatal_error!("System error: fail to generate random hash !") - } + rand::gen_u32() } /// Return the user datas folder name @@ -552,37 +548,37 @@ pub fn load_conf_at_path( let json_conf: serde_json::Value = serde_json::from_str(&contents).expect("Conf: Fail to parse keypairs file !"); - if let Some(network_sec) = json_conf.get("network_sec") { + if let Some(network_seed) = json_conf.get("network_seed") { if let Some(network_pub) = json_conf.get("network_pub") { - let network_sec = network_sec + let network_seed = network_seed .as_str() .expect("Conf: Fail to parse keypairs file !"); let network_pub = network_pub .as_str() .expect("Conf: Fail to parse keypairs file !"); - let network_keypair = KeyPairEnum::Ed25519(ed25519::KeyPair { - privkey: ed25519::PrivateKey::from_base58(network_sec) - .expect("conf : keypairs file : fail to parse network_sec !"), + let network_keypair = KeyPairEnum::Ed25519(ed25519::Ed25519KeyPair { + seed: Seed::from_base58(network_seed) + .expect("conf : keypairs file : fail to parse network_seed !"), pubkey: ed25519::PublicKey::from_base58(network_pub) .expect("conf : keypairs file : fail to parse network_pub !"), }); - let member_keypair = if let Some(member_sec) = json_conf.get("member_sec") { + let member_keypair = if let Some(member_seed) = json_conf.get("member_seed") + { if let Some(member_pub) = json_conf.get("member_pub") { - let member_sec = member_sec + let member_seed = member_seed .as_str() .expect("Conf: Fail to parse keypairs file !"); let member_pub = member_pub .as_str() .expect("Conf: Fail to parse keypairs file !"); - if member_sec.is_empty() || member_pub.is_empty() { + if member_seed.is_empty() || member_pub.is_empty() { None } else { - Some(KeyPairEnum::Ed25519(ed25519::KeyPair { - privkey: ed25519::PrivateKey::from_base58(member_sec) - .expect( - "conf : keypairs file : fail to parse member_sec !", - ), + Some(KeyPairEnum::Ed25519(ed25519::Ed25519KeyPair { + seed: Seed::from_base58(member_seed).expect( + "conf : keypairs file : fail to parse member_seed !", + ), pubkey: ed25519::PublicKey::from_base58(member_pub).expect( "conf : keypairs file : fail to parse member_pub !", ), diff --git a/lib/core/conf/test/v1/keypairs.json b/lib/core/conf/test/v1/keypairs.json index e52b2647..b9b380f5 100644 --- a/lib/core/conf/test/v1/keypairs.json +++ b/lib/core/conf/test/v1/keypairs.json @@ -1,6 +1,6 @@ { - "network_sec": "RcrnPyfgEaet2VqQvLeBsgKvfaoUqinQnCooP9bFoDr1W1Focos351r4xBee6Hj2RaV6RRV8PxpdMR6hVVhNNDb", - "network_pub": "39SvsGzGZjdCh1wFS1QKdCR1ZB6rTxRbTZRW8sY5fhq7", - "member_sec": "", + "network_seed": "ELjDWGPyCGMuhr7R7H2aip6UJA9qLRepmK77pcD41UqQ", + "network_pub": "6sewkaNWyEMqkEa2PVRWrDb3hxWtjPdUSB1zXVCqhdWV", + "member_seed": "", "member_pub": "" } \ No newline at end of file diff --git a/lib/core/conf/test/v2/keypairs.json b/lib/core/conf/test/v2/keypairs.json index e52b2647..b9b380f5 100644 --- a/lib/core/conf/test/v2/keypairs.json +++ b/lib/core/conf/test/v2/keypairs.json @@ -1,6 +1,6 @@ { - "network_sec": "RcrnPyfgEaet2VqQvLeBsgKvfaoUqinQnCooP9bFoDr1W1Focos351r4xBee6Hj2RaV6RRV8PxpdMR6hVVhNNDb", - "network_pub": "39SvsGzGZjdCh1wFS1QKdCR1ZB6rTxRbTZRW8sY5fhq7", - "member_sec": "", + "network_seed": "ELjDWGPyCGMuhr7R7H2aip6UJA9qLRepmK77pcD41UqQ", + "network_pub": "6sewkaNWyEMqkEa2PVRWrDb3hxWtjPdUSB1zXVCqhdWV", + "member_seed": "", "member_pub": "" } \ No newline at end of file diff --git a/lib/core/module/src/lib.rs b/lib/core/module/src/lib.rs index d0a09fd3..2f6a6824 100644 --- a/lib/core/module/src/lib.rs +++ b/lib/core/module/src/lib.rs @@ -32,7 +32,7 @@ extern crate serde_derive; use dubp_currency_params::CurrencyName; -use dup_crypto::keys::{KeyPair, KeyPairEnum}; +use dup_crypto::keys::{KeyPair, KeyPairEnum, Signator}; use durs_common_tools::fatal_error; use durs_common_tools::traits::merge::Merge; use durs_network_documents::network_endpoint::{ApiPart, EndpointEnum}; @@ -270,11 +270,11 @@ pub enum RequiredKeysContent { /// Contains the member keypair (private key included). MemberKeyPair(Option<KeyPairEnum>), /// Contains the member public key. - MemberPublicKey(Option<<KeyPairEnum as KeyPair>::PublicKey>), + MemberPublicKey(Option<<<KeyPairEnum as KeyPair>::Signator as Signator>::PublicKey>), /// Contains the network keypair (private key included). NetworkKeyPair(KeyPairEnum), /// Contains the network public key. - NetworkPublicKey(<KeyPairEnum as KeyPair>::PublicKey), + NetworkPublicKey(<<KeyPairEnum as KeyPair>::Signator as Signator>::PublicKey), /// Does not contain any keys None(), } diff --git a/lib/crypto/Cargo.toml b/lib/crypto/Cargo.toml index 87782b60..b51bda46 100644 --- a/lib/crypto/Cargo.toml +++ b/lib/crypto/Cargo.toml @@ -15,7 +15,8 @@ path = "src/lib.rs" [dependencies] base58 = "0.1.*" base64 = "0.10.*" -cryptoxide = "0.1.2" +byteorder = "1.2.3" +clear_on_drop = "0.2.3" failure = "0.1.5" ring = "0.16.5" scrypt = { version = "0.2", default-features = false } diff --git a/lib/crypto/src/keys/bin_signable.rs b/lib/crypto/src/keys/bin_signable.rs index 8c985220..b0a89418 100644 --- a/lib/crypto/src/keys/bin_signable.rs +++ b/lib/crypto/src/keys/bin_signable.rs @@ -30,24 +30,21 @@ pub trait BinSignable<'de>: Serialize + Deserialize<'de> { fn get_bin_without_sig(&self) -> Result<Vec<u8>, failure::Error>; /// Add signature to bin datas fn add_sig_to_bin_datas(&self, bin_datas: &mut Vec<u8>); - /// Sign entity with a private key - fn sign(&mut self, priv_key: PrivKey) -> Result<Vec<u8>, SignError> { + /// Sign entity with a signator + fn sign(&mut self, signator: &SignatorEnum) -> Result<Vec<u8>, SignError> { if self.signature().is_some() { return Err(SignError::AlreadySign); } match self.issuer_pubkey() { - PubKey::Ed25519(_) => match priv_key { - PrivKey::Ed25519(priv_key) => { - let mut bin_msg = self - .get_bin_without_sig() - .map_err(|e| SignError::SerdeError(e.to_string()))?; - let sig = Sig::Ed25519(priv_key.sign(&bin_msg)); - self.set_signature(sig); - self.add_sig_to_bin_datas(&mut bin_msg); - Ok(bin_msg) - } - _ => Err(SignError::WrongAlgo), - }, + PubKey::Ed25519(_) => { + let mut bin_msg = self + .get_bin_without_sig() + .map_err(|e| SignError::SerdeError(e.to_string()))?; + let sig = signator.sign(&bin_msg); + self.set_signature(sig); + self.add_sig_to_bin_datas(&mut bin_msg); + Ok(bin_msg) + } _ => Err(SignError::WrongAlgo), } } @@ -119,10 +116,16 @@ mod tests { #[test] fn test_bin_signable() { - let key_pair = ed25519::KeyPairFromSeedGenerator::generate(&[ + let key_pair = ed25519::KeyPairFromSeedGenerator::generate(&Seed::new([ 0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - ]); + ])); + + let signator = SignatorEnum::Ed25519( + key_pair + .generate_signator() + .expect("fail to generate signator !"), + ); let mut bin_signable_datas = BinSignableTestImpl { datas: vec![0, 1, 2, 3], @@ -133,12 +136,12 @@ mod tests { assert_eq!(Err(SigError::NotSig), bin_signable_datas.verify()); let _bin_msg = bin_signable_datas - .sign(PrivKey::Ed25519(key_pair.privkey)) + .sign(&signator) .expect("Fail to sign datas !"); assert_eq!( Err(SignError::AlreadySign), - bin_signable_datas.sign(PrivKey::Ed25519(key_pair.privkey)) + bin_signable_datas.sign(&signator) ); assert_eq!(Ok(()), bin_signable_datas.verify()) diff --git a/lib/crypto/src/keys/ed25519.rs b/lib/crypto/src/keys/ed25519.rs index c767197c..db072b99 100644 --- a/lib/crypto/src/keys/ed25519.rs +++ b/lib/crypto/src/keys/ed25519.rs @@ -19,14 +19,13 @@ //! //! [`KeyPairGenerator`]: struct.KeyPairGenerator.html -use super::{PrivateKey as PrivateKeyMethods, PublicKey as PublicKeyMethods}; +use super::seed::Seed; +use super::PublicKey as PublicKeyMethods; use crate::bases::*; use base58::ToBase58; use base64; -use cryptoxide as crypto; -use durs_common_tools::fatal_error; -use log::error; -use ring::rand; +use clear_on_drop::ClearOnDrop; +use ring::signature::{Ed25519KeyPair as RingKeyPair, KeyPair, UnparsedPublicKey, ED25519}; use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor}; use serde::ser::{Serialize, SerializeTuple, Serializer}; use std::fmt; @@ -181,116 +180,94 @@ impl super::PublicKey for PublicKey { } fn verify(&self, message: &[u8], signature: &Self::Signature) -> Result<(), SigError> { - if crypto::ed25519::verify(message, &self.0, &signature.0) { - Ok(()) - } else { - Err(SigError::InvalidSig) - } - } -} - -/// Store a Ed25519 private key. -/// -/// Can be generated with [`KeyPairGenerator`]. -/// -/// [`KeyPairGenerator`]: struct.KeyPairGenerator.html -#[derive(Copy, Clone)] -pub struct PrivateKey(pub [u8; 64]); - -impl ToBase58 for PrivateKey { - fn to_base58(&self) -> String { - self.0.to_base58() - } -} - -impl Display for PrivateKey { - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "{}", self.to_base58()) - } -} - -impl Debug for PrivateKey { - // PrivateKey { 468Q1XtT... } - fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { - write!(f, "PrivateKey {{ {} }}", self) + Ok(UnparsedPublicKey::new(&ED25519, &self.0) + .verify(message, &signature.0) + .map_err(|_| SigError::InvalidSig)?) } } -impl PartialEq<PrivateKey> for PrivateKey { - fn eq(&self, other: &PrivateKey) -> bool { - // No PartialEq for [u8;64], need to use 2 [u8;32] - self.0[0..32] == other.0[0..32] && self.0[32..64] == other.0[32..64] - } +#[inline] +fn get_ring_ed25519_pubkey(ring_key_pair: &RingKeyPair) -> PublicKey { + let ring_pubkey: <RingKeyPair as KeyPair>::PublicKey = *ring_key_pair.public_key(); + let mut ring_pubkey_bytes: [u8; 32] = [0u8; 32]; + ring_pubkey_bytes.copy_from_slice(ring_pubkey.as_ref()); + PublicKey(ring_pubkey_bytes) } -impl Eq for PrivateKey {} +/// Store a ed25519 cryptographic signator +#[derive(Debug)] +pub struct Signator(RingKeyPair); -impl super::PrivateKey for PrivateKey { +impl super::Signator for Signator { type Signature = Signature; + type PublicKey = PublicKey; - #[inline] - fn from_base58(base58_data: &str) -> Result<Self, BaseConvertionError> { - Ok(PrivateKey(b58::str_base58_to_64bytes(base58_data)?)) + fn public_key(&self) -> Self::PublicKey { + get_ring_ed25519_pubkey(&self.0) } - - /// Sign a message with this private key. fn sign(&self, message: &[u8]) -> Self::Signature { - Signature(crypto::ed25519::signature(message, &self.0)) + let mut sig_bytes = [0u8; 64]; + sig_bytes.copy_from_slice(self.0.sign(message).as_ref()); + Signature(sig_bytes) } } /// Store a ed25519 cryptographic key pair (`PublicKey` + `PrivateKey`) #[derive(Debug, Copy, Clone, Eq)] -pub struct KeyPair { +pub struct Ed25519KeyPair { /// Store a Ed25519 public key. pub pubkey: PublicKey, - /// Store a Ed25519 private key. - pub privkey: PrivateKey, + /// Store a seed of 32 bytes. + pub seed: Seed, } -impl Display for KeyPair { +impl Display for Ed25519KeyPair { fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { write!(f, "({}, hidden)", self.pubkey.to_base58()) } } -impl PartialEq<KeyPair> for KeyPair { - fn eq(&self, other: &KeyPair) -> bool { - self.pubkey.eq(&other.pubkey) && self.privkey.eq(&other.privkey) +impl PartialEq<Ed25519KeyPair> for Ed25519KeyPair { + fn eq(&self, other: &Ed25519KeyPair) -> bool { + self.pubkey.eq(&other.pubkey) && self.seed.eq(&other.seed) } } -impl super::KeyPair for KeyPair { - type Signature = Signature; - type PublicKey = PublicKey; - type PrivateKey = PrivateKey; +impl super::KeyPair for Ed25519KeyPair { + type Signator = Signator; - fn public_key(&self) -> PublicKey { - self.pubkey + fn generate_signator(&self) -> Result<Self::Signator, super::SignError> { + Ok(Signator( + RingKeyPair::from_seed_and_public_key(self.seed.as_ref(), &self.pubkey.0) + .map_err(|_| super::SignError::CorruptedKeyPair)?, + )) } - fn private_key(&self) -> PrivateKey { - self.privkey + fn public_key(&self) -> PublicKey { + self.pubkey } - fn sign(&self, message: &[u8]) -> Signature { - self.private_key().sign(message) + fn seed(&self) -> Seed { + self.seed } - fn verify(&self, message: &[u8], signature: &Self::Signature) -> Result<(), SigError> { + fn verify( + &self, + message: &[u8], + signature: &<Self::Signator as super::Signator>::Signature, + ) -> Result<(), SigError> { self.public_key().verify(message, signature) } } -impl KeyPair { +impl Ed25519KeyPair { /// Generate random keypair pub fn generate_random() -> Self { - let random_seed = - if let Ok(random_bytes) = rand::generate::<[u8; 32]>(&rand::SystemRandom::new()) { - random_bytes.expose() - } else { - fatal_error!("System error: fail to generate random hash !") - }; + // generate random seed + let mut random_seed = Seed::random(); + // For security, clear automatically random_seed when it's droped + let random_seed = ClearOnDrop::new(&mut random_seed); + // Generate and return keypair from seed KeyPairFromSeedGenerator::generate(&random_seed) } } @@ -304,11 +281,13 @@ impl KeyPairFromSeedGenerator { /// /// The [`PublicKey`](struct.PublicKey.html) will be able to verify messaged signed with /// the [`PrivateKey`](struct.PrivateKey.html). - pub fn generate(seed: &[u8; 32]) -> KeyPair { - let (private, public) = crypto::ed25519::keypair(seed); - KeyPair { - pubkey: PublicKey(public), - privkey: PrivateKey(private), + pub fn generate(seed: &Seed) -> Ed25519KeyPair { + let ring_key_pair = RingKeyPair::from_seed_unchecked(seed.as_ref()) + .expect("dev error: fail to generate ed25519 keypair."); + + Ed25519KeyPair { + pubkey: get_ring_ed25519_pubkey(&ring_key_pair), + seed: *seed, } } } @@ -346,106 +325,95 @@ impl KeyPairFromSaltedPasswordGenerator { } /// Create a seed based on a given password and salt. - pub fn generate_seed(&self, password: &[u8], salt: &[u8]) -> [u8; 32] { + pub fn generate_seed(&self, password: &[u8], salt: &[u8]) -> Seed { let mut seed = [0u8; 32]; scrypt::scrypt(salt, password, &self.scrypt_params, &mut seed) .expect("dev error: invalid seed len"); - seed + Seed::new(seed) } /// Create a keypair based on a given password and salt. /// /// The [`PublicKey`](struct.PublicKey.html) will be able to verify messaged signed with /// the [`PrivateKey`](struct.PrivateKey.html). - pub fn generate(&self, password: &[u8], salt: &[u8]) -> KeyPair { - let seed: [u8; 32] = self.generate_seed(password, salt); + pub fn generate(&self, password: &[u8], salt: &[u8]) -> Ed25519KeyPair { + // Generate seed from tuple (password + salt) + let mut seed = self.generate_seed(password, salt); + // For security, clear automatically seed when it's droped + let seed = ClearOnDrop::new(&mut seed); + // Generate keypair from seed KeyPairFromSeedGenerator::generate(&seed) } } #[cfg(test)] mod tests { - use super::KeyPair as ed25519KeyPair; use super::*; - use crate::keys::{KeyPair, Sig, Signature}; + use crate::keys::{KeyPair, Seed, Sig, Signator, Signature}; use base58::FromBase58; use bincode; use std::collections::hash_map::DefaultHasher; #[test] - fn base58_private_key() { - let private58 = - "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9r\ - qnXuW3iAfZACm7"; - let private_key = super::PrivateKey::from_base58(private58).unwrap(); + fn base58_seed() { + let seed58 = "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV"; // Test base58 encoding/decoding (loop for every bytes) - assert_eq!(private_key.to_base58(), private58); - let private_raw = private58.from_base58().unwrap(); - for (key, raw) in private_key.0.iter().zip(private_raw.iter()) { - assert_eq!(key, raw); - } + let seed = Seed::from_base58(seed58).expect("fail to parser seed !"); + assert_eq!(seed.to_base58(), seed58); - // Test privkey display and debug + // Test seed display and debug assert_eq!( - "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7".to_owned(), - format!("{}", private_key) + "DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV".to_owned(), + format!("{}", seed) ); assert_eq!( - "PrivateKey { 468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7 }".to_owned(), - format!("{:?}", private_key) + "Seed { DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV }".to_owned(), + format!("{:?}", seed) ); - // Test privkey equality - let same_private_key = private_key.clone(); - let other_private_key = PrivateKey([ - 0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, - ]); - assert!(private_key.eq(&same_private_key)); - assert!(!private_key.eq(&other_private_key)); + // Test seed equality + let same_seed = seed.clone(); + let other_seed = Seed::default(); + assert!(seed.eq(&same_seed)); + assert!(!seed.eq(&other_seed)); - // Test privkey parsing + // Test seed parsing assert_eq!( - super::PrivateKey::from_base58( - "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iA\ - fZACm7djh", - ).unwrap_err(), - BaseConvertionError::InvalidLength { found: 67, expected: 64 } + Seed::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLVgth",).unwrap_err(), + BaseConvertionError::InvalidLength { + found: 35, + expected: 32 + } ); assert_eq!( - super::PrivateKey::from_base58( - "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9", - ) - .unwrap_err(), + Seed::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd",).unwrap_err(), BaseConvertionError::InvalidLength { - found: 53, - expected: 64 + found: 31, + expected: 32 } ); assert_eq!( - super::PrivateKey::from_base58( - "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9<<", - ) - .unwrap_err(), + Seed::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQd<<").unwrap_err(), BaseConvertionError::InvalidCharacter { character: '<', - offset: 73 + offset: 42 } ); assert_eq!( - super::PrivateKey::from_base58( + Seed::from_base58( "\ - 468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9\ - 468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9\ - 468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5GiERP7ySs3wM8myLccbAAGejgMRC9\ - ", + DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV\ + DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV\ + DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV\ + DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV\ + DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV\ + " ) .unwrap_err(), - BaseConvertionError::InvalidBaseConverterLength, + BaseConvertionError::InvalidBaseConverterLength ); } @@ -594,18 +562,10 @@ mod tests { #[test] fn message_sign_verify() { - let pubkey = - super::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV").unwrap(); - - let prikey = super::PrivateKey::from_base58( - "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt\ - 5GiERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7", - ) - .unwrap(); + let seed = Seed::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV").unwrap(); let expected_signature = super::Signature::from_base64( - "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FG\ - MMmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==", + "9ARKYkEAwp+kQ01rgvWUwJLchVLpZvHg3t/3H32XwWOoG119NiVCtfPSPtR4GDOeOz6Y+29drOLahqhzy+ciBw==", ) .unwrap(); @@ -617,7 +577,11 @@ UniqueID: tic Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 "; - let sig = prikey.sign(message.as_bytes()); + let signator = KeyPairFromSeedGenerator::generate(&seed) + .generate_signator() + .expect("fail to generate signator !"); + let pubkey = signator.public_key(); + let sig = signator.sign(message.as_bytes()); let wrong_sig = Signature([ 0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -656,10 +620,10 @@ Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 // Test key_pair equality let same_key_pair = key_pair2.clone(); - let other_key_pair = KeyPairFromSeedGenerator::generate(&[ + let other_key_pair = KeyPairFromSeedGenerator::generate(&Seed::new([ 0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]); + ])); assert!(key_pair2.eq(&same_key_pair)); assert!(!key_pair2.eq(&other_key_pair)); } @@ -677,24 +641,10 @@ UniqueID: tic Timestamp: 0-E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 "; - let sig = keypair.sign(message.as_bytes()); + let sig = keypair + .generate_signator() + .expect("fail to gen signator") + .sign(message.as_bytes()); assert!(keypair.verify(message.as_bytes(), &sig).is_ok()); } - - #[test] - fn test_exchange_dh() { - let kp1 = ed25519KeyPair::generate_random(); - let kp2 = ed25519KeyPair::generate_random(); - - let secret1 = crypto::ed25519::exchange(&kp1.pubkey.0, &kp2.privkey.0); - let secret2 = crypto::ed25519::exchange(&kp2.pubkey.0, &kp1.privkey.0); - - assert_eq!(secret1, secret2); - - println!("pk1={}", kp1.pubkey); - println!("pk2={}", kp2.pubkey); - println!("shared_secret1={:?}", secret1); - println!("shared_secret2={:?}", secret2); - //panic!(); - } } diff --git a/lib/crypto/src/keys/mod.rs b/lib/crypto/src/keys/mod.rs index e873a720..090d5f00 100644 --- a/lib/crypto/src/keys/mod.rs +++ b/lib/crypto/src/keys/mod.rs @@ -21,7 +21,7 @@ //! # Usage //! //! ``` -//! use dup_crypto::keys::{Signature, PublicKey, PrivateKey, KeyPair}; +//! use dup_crypto::keys::{KeyPair, PublicKey, Signator, Signature}; //! use dup_crypto::keys::ed25519::KeyPairFromSaltedPasswordGenerator; //! //! let generator = KeyPairFromSaltedPasswordGenerator::with_default_parameters(); @@ -31,9 +31,11 @@ //! b"salt" //! ); //! +//! let signator = keypair.generate_signator().expect("keypair corrupted"); +//! //! let message = "Hello, world!"; //! -//! let signature = keypair.sign(&message.as_bytes()); +//! let signature = signator.sign(&message.as_bytes()); //! //! assert!(keypair.pubkey.verify(&message.as_bytes(), &signature).is_ok()); //! ``` @@ -46,6 +48,13 @@ //! `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/` //! with `=` as padding character. +pub mod bin_signable; +pub mod ed25519; +pub mod seed; +pub mod text_signable; + +pub use seed::Seed; + use crate::bases::BaseConvertionError; use base58::ToBase58; use durs_common_tools::fatal_error; @@ -57,10 +66,6 @@ use std::fmt::Formatter; use std::hash::Hash; use std::str::FromStr; -pub mod bin_signable; -pub mod ed25519; -pub mod text_signable; - /// Cryptographic keys algorithms list #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Hash)] pub enum KeysAlgo { @@ -96,6 +101,9 @@ pub enum SigError { /// SignError #[derive(Debug, Eq, Fail, PartialEq)] pub enum SignError { + /// Corrupted key pair + #[fail(display = "Corrupted key pair.")] + CorruptedKeyPair, /// WrongAlgo #[fail(display = "Wrong algo.")] WrongAlgo, @@ -306,107 +314,47 @@ impl PublicKey for PubKey { } } -/// Define the operations that can be performed on a cryptographic private key. -/// -/// A `PrivateKey` can be converted from/to Base58 format. -/// When converted back and forth the value should be the same. -/// -/// A `PrivateKey` is used to sign a message. The corresponding [`PublicKey`] -/// will then be used to verify that signature. -/// -/// [`PublicKey`]: trait.PublicKey.html -pub trait PrivateKey: Clone + Display + Debug + PartialEq + Eq + ToBase58 { - /// Signature type of associated cryptosystem. - type Signature: Signature; - - /// Create a PrivateKey from a Base58 string. - /// - /// The Base58 string should contains only valid Base58 characters - /// and have a correct length. If it's not the case, a [`BaseConvertionError`] - /// is returned with the corresponding variant. - /// - /// [`BaseConvertionError`]: enum.BaseConvertionError.html - fn from_base58(base58_string: &str) -> Result<Self, BaseConvertionError>; - - /// Sign a message with this private key. - fn sign(&self, message: &[u8]) -> Self::Signature; -} - -/// Store a cryptographic private key. -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum PrivKey { - /// Store a ed25519 private key. - Ed25519(ed25519::PrivateKey), - /// Store a Schnorr private key. - Schnorr(), -} - -impl GetKeysAlgo for PrivKey { - fn algo(&self) -> KeysAlgo { - match *self { - PrivKey::Ed25519(_) => KeysAlgo::Ed25519, - PrivKey::Schnorr() => KeysAlgo::Schnorr, - } - } -} +/// Define the operations that can be performed on a cryptographic key pair. +pub trait KeyPair: Clone + Display + Debug + PartialEq + Eq { + /// Signator type of associated cryptosystem. + type Signator: Signator; -impl ToBase58 for PrivKey { - fn to_base58(&self) -> String { - match *self { - PrivKey::Ed25519(ed25519_privkey) => ed25519_privkey.to_base58(), - PrivKey::Schnorr() => fatal_error!("Schnorr algo not yet supported !"), - } - } -} + /// Generate signator. + fn generate_signator(&self) -> Result<Self::Signator, SignError>; -impl Display for PrivKey { - fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { - write!(f, "{}", self.to_base58()) - } -} + /// Get `PublicKey` + fn public_key(&self) -> <Self::Signator as Signator>::PublicKey; -impl PrivateKey for PrivKey { - type Signature = Sig; + /// Get `Seed` + fn seed(&self) -> Seed; - #[cfg_attr(tarpaulin, skip)] - fn from_base58(_base58_string: &str) -> Result<Self, BaseConvertionError> { - unimplemented!() - } - fn sign(&self, message: &[u8]) -> Self::Signature { - match *self { - PrivKey::Ed25519(ed25519_privkey) => Sig::Ed25519(ed25519_privkey.sign(message)), - PrivKey::Schnorr() => fatal_error!("Schnorr algo not yet supported !"), - } - } + /// Verify a signature with public key. + fn verify( + &self, + message: &[u8], + signature: &<Self::Signator as Signator>::Signature, + ) -> Result<(), SigError>; } -/// Define the operations that can be performed on a cryptographic key pair. -pub trait KeyPair: Clone + Display + Debug + PartialEq + Eq { +/// Define the operations that can be performed on a cryptographic signator. +pub trait Signator: Debug { /// Signature type of associated cryptosystem. type Signature: Signature; /// PublicKey type of associated cryptosystem. type PublicKey: PublicKey; - /// PrivateKey type of associated cryptosystem. - type PrivateKey: PrivateKey; /// Get `PublicKey` fn public_key(&self) -> Self::PublicKey; - /// Get `PrivateKey` - fn private_key(&self) -> Self::PrivateKey; - - /// Sign a message with private key. + /// Sign a message with private key encasuled in signator. fn sign(&self, message: &[u8]) -> Self::Signature; - - /// Verify a signature with public key. - fn verify(&self, message: &[u8], signature: &Self::Signature) -> Result<(), SigError>; } /// Store a cryptographic key pair. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum KeyPairEnum { /// Store a ed25519 key pair. - Ed25519(ed25519::KeyPair), + Ed25519(ed25519::Ed25519KeyPair), /// Store a Schnorr key pair. Schnorr(), } @@ -432,21 +380,25 @@ impl Display for KeyPairEnum { } impl KeyPair for KeyPairEnum { - type Signature = Sig; - type PublicKey = PubKey; - type PrivateKey = PrivKey; + type Signator = SignatorEnum; - fn public_key(&self) -> Self::PublicKey { + fn generate_signator(&self) -> Result<Self::Signator, SignError> { + match *self { + KeyPairEnum::Ed25519(ed25519_keypair) => { + Ok(SignatorEnum::Ed25519(ed25519_keypair.generate_signator()?)) + } + KeyPairEnum::Schnorr() => fatal_error!("Schnorr algo not yet supported !"), + } + } + fn public_key(&self) -> <Self::Signator as Signator>::PublicKey { match *self { KeyPairEnum::Ed25519(ed25519_keypair) => PubKey::Ed25519(ed25519_keypair.public_key()), KeyPairEnum::Schnorr() => fatal_error!("Schnorr algo not yet supported !"), } } - fn private_key(&self) -> Self::PrivateKey { + fn seed(&self) -> Seed { match *self { - KeyPairEnum::Ed25519(ed25519_keypair) => { - PrivKey::Ed25519(ed25519_keypair.private_key()) - } + KeyPairEnum::Ed25519(ed25519_keypair) => ed25519_keypair.seed(), KeyPairEnum::Schnorr() => fatal_error!("Schnorr algo not yet supported !"), } } @@ -462,10 +414,36 @@ impl KeyPair for KeyPairEnum { KeyPairEnum::Schnorr() => fatal_error!("Schnorr algo not yet supported !"), } } +} + +/// Store a cryptographic signator. +#[derive(Debug)] +pub enum SignatorEnum { + /// Store a ed25519 signator. + Ed25519(ed25519::Signator), + /// Store a Schnorr signator. + Schnorr(), +} + +impl Signator for SignatorEnum { + type PublicKey = PubKey; + type Signature = Sig; + + fn public_key(&self) -> Self::PublicKey { + match self { + SignatorEnum::Ed25519(ref ed25519_signator) => { + PubKey::Ed25519(ed25519_signator.public_key()) + } + SignatorEnum::Schnorr() => fatal_error!("Schnorr algo not yet supported !"), + } + } + fn sign(&self, message: &[u8]) -> Sig { - match *self { - KeyPairEnum::Ed25519(ed25519_keypair) => Sig::Ed25519(ed25519_keypair.sign(message)), - KeyPairEnum::Schnorr() => fatal_error!("Schnorr algo not yet supported !"), + match self { + SignatorEnum::Ed25519(ref ed25519_signator) => { + Sig::Ed25519(ed25519_signator.sign(message)) + } + SignatorEnum::Schnorr() => fatal_error!("Schnorr algo not yet supported !"), } } } @@ -474,24 +452,14 @@ impl KeyPair for KeyPairEnum { mod tests { use super::*; + use crate::hashs::Hash; + use ring::{agreement, rand}; pub fn valid_key_pair_1() -> KeyPairEnum { - let kp = KeyPairEnum::Ed25519(ed25519::KeyPair { - pubkey: ed25519::PublicKey([ - 59u8, 106, 39, 188, 206, 182, 164, 45, 98, 163, 168, 208, 42, 111, 13, 115, 101, - 50, 21, 119, 29, 226, 67, 166, 58, 192, 72, 161, 139, 89, 218, 41, - ]), - privkey: ed25519::PrivateKey([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 59, 106, 39, 188, 206, 182, 164, 45, 98, 163, 168, 208, 42, 111, 13, - 115, 101, 50, 21, 119, 29, 226, 67, 166, 58, 192, 72, 161, 139, 89, 218, 41, - ]), - }); - println!("kp.pub={:?}", kp.public_key().to_bytes_vector()); - if let PrivKey::Ed25519(ed_pk) = kp.private_key() { - println!("kp.priv={:?}", ed_pk.0.to_vec()); - } - kp + KeyPairEnum::Ed25519(ed25519::KeyPairFromSeedGenerator::generate(&Seed::new([ + 59u8, 106, 39, 188, 206, 182, 164, 45, 98, 163, 168, 208, 42, 111, 13, 115, 101, 50, + 21, 119, 29, 226, 67, 166, 58, 192, 72, 161, 139, 89, 218, 41, + ]))) } #[test] @@ -555,41 +523,31 @@ mod tests { } #[test] - fn privkey() { - let privkey_bytes = [ + fn seed() { + let seed_default = Seed::default(); + let seed_bytes = [ 0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, ]; - let privkey_str_b58 = - "1111111111111111111111111111111111111111111111111111111111111111".to_owned(); - let privkey = PrivKey::Ed25519(ed25519::PrivateKey(privkey_bytes)); - - assert_eq!(privkey_str_b58, format!("{}", privkey)); - - assert_eq!(KeysAlgo::Ed25519, privkey.algo()); - assert_eq!(KeysAlgo::Schnorr, PrivKey::Schnorr().algo()); - - assert_eq!(privkey_str_b58, privkey.to_base58()); + let seed_str_b58 = "11111111111111111111111111111111".to_owned(); + let seed = Seed::new(seed_bytes); + assert_eq!(seed_default, seed); assert_eq!( - Sig::Ed25519(ed25519::Signature::from_base64("JPurBgnHExHND1woow9nB7xVQjKkdHGs1znQbgv0ttboJXueHKd4SOvxuNWmw4w07F4CT//olYMEBw51Cy0SDA==").unwrap()), - privkey.sign(b"message") + seed_default, + Seed::from_base58(&seed_str_b58).expect("Fail to parse seed !") ); + + assert_eq!(seed_str_b58, format!("{}", seed)); + + assert_eq!(seed_str_b58, seed.to_base58()); } - fn false_key_pair_ed25519() -> ed25519::KeyPair { - ed25519::KeyPair { - pubkey: ed25519::PublicKey([ - 0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - ]), - privkey: ed25519::PrivateKey([ - 0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]), - } + fn false_key_pair_ed25519() -> ed25519::Ed25519KeyPair { + ed25519::KeyPairFromSeedGenerator::generate(&Seed::new([ + 0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + ])) } #[test] @@ -600,17 +558,14 @@ mod tests { assert_eq!(KeysAlgo::Ed25519, false_key_pair.algo()); assert_eq!(KeysAlgo::Schnorr, KeyPairEnum::Schnorr().algo()); assert_eq!( - "(11111111111111111111111111111111, hidden)".to_owned(), + "(4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS, hidden)".to_owned(), format!("{}", false_key_pair) ); assert_eq!( PubKey::Ed25519(false_key_pair_ed25519.pubkey), false_key_pair.public_key() ); - assert_eq!( - PrivKey::Ed25519(false_key_pair_ed25519.privkey), - false_key_pair.private_key() - ); + assert_eq!(false_key_pair_ed25519.seed, false_key_pair.seed()); assert_eq!( Err(SigError::InvalidSig), false_key_pair.verify( @@ -627,7 +582,7 @@ mod tests { #[test] #[should_panic( expected = "Try to verify a signature with key pair of a different algorithm !\n\ - Signature=Schnorr\nKeyPair=(11111111111111111111111111111111, hidden)" + Signature=Schnorr\nKeyPair=(4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS, hidden)" )] fn key_pair_verify_wrong_sig_algo() { let false_key_pair_ed25519 = false_key_pair_ed25519(); @@ -694,20 +649,6 @@ mod tests { let _ = pubkey.verify(b"message", &Sig::Schnorr()); } - #[test] - #[should_panic(expected = "Schnorr algo not yet supported !")] - fn privkey_schnorr_base58() { - let privkey = PrivKey::Schnorr(); - privkey.to_base58(); - } - - #[test] - #[should_panic(expected = "Schnorr algo not yet supported !")] - fn privkey_schnorr_sign() { - let privkey = PrivKey::Schnorr(); - privkey.sign(b"message"); - } - #[test] #[should_panic(expected = "Schnorr algo not yet supported !")] fn key_pair_schnorr_display() { @@ -724,9 +665,9 @@ mod tests { #[test] #[should_panic(expected = "Schnorr algo not yet supported !")] - fn key_pair_schnorr_get_privkey() { + fn key_pair_schnorr_get_seed() { let key_pair = KeyPairEnum::Schnorr(); - key_pair.private_key(); + key_pair.seed(); } #[test] @@ -738,8 +679,59 @@ mod tests { #[test] #[should_panic(expected = "Schnorr algo not yet supported !")] - fn key_pair_schnorr_sign() { - let key_pair = KeyPairEnum::Schnorr(); - key_pair.sign(b"message"); + fn signator_schnorr_get_pubkey() { + let signator = SignatorEnum::Schnorr(); + signator.public_key(); + } + + #[test] + #[should_panic(expected = "Schnorr algo not yet supported !")] + fn signator_schnorr_sign() { + let signator = SignatorEnum::Schnorr(); + signator.sign(b"message"); + } + + #[test] + fn test_exchange_dh() -> Result<(), ring::error::Unspecified> { + let rng = rand::SystemRandom::new(); + + let secret_key_1 = agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng)?; + let public_key_1 = secret_key_1.compute_public_key()?; + + let secret_key_2 = agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng)?; + let public_key_2 = secret_key_2.compute_public_key()?; + + let dh1 = agreement::agree_ephemeral( + secret_key_1, + &agreement::UnparsedPublicKey::new(&agreement::X25519, &public_key_2), + ring::error::Unspecified, + |key_material| { + // In a real application, we'd apply a KDF to the key material and the + // public keys (as recommended in RFC 7748) and then derive session + // keys from the result. + Ok(Hash::compute(key_material)) + }, + )?; + + let dh2 = agreement::agree_ephemeral( + secret_key_2, + &agreement::UnparsedPublicKey::new(&agreement::X25519, &public_key_1), + ring::error::Unspecified, + |key_material| { + // In a real application, we'd apply a KDF to the key material and the + // public keys (as recommended in RFC 7748) and then derive session + // keys from the result. + Ok(Hash::compute(key_material)) + }, + )?; + + assert_eq!(dh1, dh2); + + println!("pk1={:?}", public_key_1); + println!("pk2={:?}", public_key_2); + println!("shared_secret1={:?}", dh1); + println!("shared_secret2={:?}", dh2); + //panic!(); + Ok(()) } } diff --git a/lib/crypto/src/keys/seed.rs b/lib/crypto/src/keys/seed.rs new file mode 100644 index 00000000..34facb3b --- /dev/null +++ b/lib/crypto/src/keys/seed.rs @@ -0,0 +1,74 @@ +// Copyright (C) 2017-2019 The AXIOM TEAM Association. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +//! Provide wrappers around cryptographic seed + +use crate::bases::*; +use base58::ToBase58; +use durs_common_tools::fatal_error; +use log::error; +use ring::rand; +use std::fmt::{self, Debug, Display, Formatter}; + +/// Store a 32 bytes seed used to generate keys. +#[derive(Copy, Clone, Default, Deserialize, PartialEq, Eq, Hash, Serialize)] +pub struct Seed([u8; 32]); + +impl AsRef<[u8]> for Seed { + fn as_ref(&self) -> &[u8] { + &self.0 + } +} + +impl ToBase58 for Seed { + fn to_base58(&self) -> String { + self.0.to_base58() + } +} + +impl Display for Seed { + fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { + write!(f, "{}", self.to_base58()) + } +} + +impl Debug for Seed { + // Seed { DNann1L... } + fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> { + write!(f, "Seed {{ {} }}", self) + } +} + +impl Seed { + #[inline] + /// Create new seed + pub fn new(seed_bytes: [u8; 32]) -> Seed { + Seed(seed_bytes) + } + #[inline] + /// Create seed from base58 str + pub fn from_base58(base58_str: &str) -> Result<Self, BaseConvertionError> { + Ok(Seed(b58::str_base58_to_32bytes(base58_str)?)) + } + #[inline] + /// Generate random seed + pub fn random() -> Seed { + if let Ok(random_bytes) = rand::generate::<[u8; 32]>(&rand::SystemRandom::new()) { + Seed(random_bytes.expose()) + } else { + fatal_error!("System error: fail to generate random seed !") + } + } +} diff --git a/lib/crypto/src/keys/text_signable.rs b/lib/crypto/src/keys/text_signable.rs index 34552512..27c0c6c2 100644 --- a/lib/crypto/src/keys/text_signable.rs +++ b/lib/crypto/src/keys/text_signable.rs @@ -28,15 +28,15 @@ pub trait TextSignable: Debug + Clone { /// Change signature fn set_signature(&mut self, _signature: Sig); /// Sign entity - fn sign(&mut self, priv_key: PrivKey) -> Result<String, SignError> { + fn sign(&mut self, signator: &SignatorEnum) -> Result<String, SignError> { if self.signature().is_some() { return Err(SignError::AlreadySign); } match self.issuer_pubkey() { - PubKey::Ed25519(_) => match priv_key { - PrivKey::Ed25519(priv_key) => { + PubKey::Ed25519(_) => match signator { + SignatorEnum::Ed25519(ed25519_signator) => { let text = self.as_signable_text(); - let sig = priv_key.sign(&text.as_bytes()); + let sig = ed25519_signator.sign(&text.as_bytes()); self.set_signature(Sig::Ed25519(sig)); let str_sig = sig.to_base64(); Ok(format!("{}{}", text, str_sig)) @@ -102,6 +102,10 @@ mod tests { fn test_text_signable() { let key_pair = super::super::tests::valid_key_pair_1(); + let signator = key_pair + .generate_signator() + .expect("fail to generate signator"); + let mut text_signable = TextSignableTestImpl { issuer: key_pair.public_key(), text: "toto".to_owned(), @@ -111,22 +115,16 @@ mod tests { assert_eq!(Err(SigError::NotSig), text_signable.verify()); assert_eq!( Err(SignError::WrongAlgo), - text_signable.sign(PrivKey::Schnorr()) + text_signable.sign(&SignatorEnum::Schnorr()) ); text_signable.issuer = PubKey::Schnorr(); - assert_eq!( - Err(SignError::WrongAlgo), - text_signable.sign(key_pair.private_key()) - ); + assert_eq!(Err(SignError::WrongAlgo), text_signable.sign(&signator)); text_signable.issuer = key_pair.public_key(); assert_eq!( - Ok("4zvwRjXUKGfvwnParsHAS3HuSVzV5cA4McphgmoCtajS:totoe53bEIYLX3IK7p0IBm60jAZfrQWxrBpinvzJqGxvD3kAzoe+zp2FGIXuxHMobrImu/Au33sB9k/6yOhtFz/YAw==".to_owned()), - text_signable.sign(key_pair.private_key()) - ); - assert_eq!( - Err(SignError::AlreadySign), - text_signable.sign(key_pair.private_key()) + Ok("VYgskcKKh525MzFRzpCiT5KXCQrnFLTnzMLffbvm9uw:toto+IC1fFkkYo5ox2loc1IMLCtrir1i6oyljfshNXIyXVcz6sJMFqn+6o8Zip4XdTzoBEORkbcnEnqQEr4TgaHpCw==".to_owned()), + text_signable.sign(&signator) ); + assert_eq!(Err(SignError::AlreadySign), text_signable.sign(&signator)); assert_eq!(Ok(()), text_signable.verify()); let old_sig = text_signable.sig.replace(Sig::Schnorr()); assert_eq!(Err(SigError::NotSameAlgo), text_signable.verify()); diff --git a/lib/crypto/src/lib.rs b/lib/crypto/src/lib.rs index fd648c3c..33ac9c5c 100644 --- a/lib/crypto/src/lib.rs +++ b/lib/crypto/src/lib.rs @@ -13,7 +13,7 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. -//! Manage cryptographic operations for the DUP (DUniter Protocol). +//! Manage cryptographic operations. #![deny( clippy::option_unwrap_used, @@ -39,25 +39,27 @@ extern crate log; pub mod bases; pub mod hashs; pub mod keys; +pub mod rand; #[cfg(test)] mod tests { use super::*; + use crate::keys::Seed; use ring::signature::Ed25519KeyPair; use ring::signature::KeyPair; #[test] fn test_ring_gen_keypair() { - let seed = [ + let seed = Seed::new([ 61u8, 245, 136, 162, 155, 50, 205, 43, 116, 15, 45, 84, 138, 54, 114, 214, 71, 213, 11, 251, 135, 182, 202, 131, 48, 91, 166, 226, 40, 255, 251, 172, - ]; + ]); let legacy_key_pair = keys::ed25519::KeyPairFromSeedGenerator::generate(&seed); let ring_key_pair: Ed25519KeyPair = - Ed25519KeyPair::from_seed_and_public_key(&seed, &legacy_key_pair.pubkey.0) + Ed25519KeyPair::from_seed_and_public_key(seed.as_ref(), &legacy_key_pair.pubkey.0) .expect("fail to generate ring key pair !"); let ring_pubkey: <Ed25519KeyPair as KeyPair>::PublicKey = *ring_key_pair.public_key(); diff --git a/lib/crypto/src/rand/mod.rs b/lib/crypto/src/rand/mod.rs new file mode 100644 index 00000000..313cd60f --- /dev/null +++ b/lib/crypto/src/rand/mod.rs @@ -0,0 +1,43 @@ +// Copyright (C) 2017-2019 The AXIOM TEAM Association. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <https://www.gnu.org/licenses/>. + +//! Manage random generation. + +use byteorder::ByteOrder; +use durs_common_tools::fatal_error; +use log::error; +use ring::rand; + +#[inline] +/// Generate random u32 +pub fn gen_u32() -> u32 { + let rng = rand::SystemRandom::new(); + if let Ok(random_bytes) = rand::generate::<[u8; 4]>(&rng) { + byteorder::BigEndian::read_u32(&random_bytes.expose()) + } else { + fatal_error!("System error: fail to generate random boolean !") + } +} + +#[cfg(test)] +mod tests { + + use super::*; + + #[test] + fn test_gen_u32() { + assert_ne!(gen_u32(), gen_u32()) + } +} diff --git a/lib/dubp/block-doc/src/block.rs b/lib/dubp/block-doc/src/block.rs index 4bb62449..0364e451 100644 --- a/lib/dubp/block-doc/src/block.rs +++ b/lib/dubp/block-doc/src/block.rs @@ -21,7 +21,7 @@ use dubp_common_doc::blockstamp::Blockstamp; use dubp_common_doc::traits::{Document, ToStringObject}; use dubp_common_doc::{BlockHash, BlockNumber}; use dup_crypto::hashs::Hash; -use dup_crypto::keys::{PrivKey, PubKey, PublicKey}; +use dup_crypto::keys::{PubKey, PublicKey, SignatorEnum}; pub use v10::{BlockDocumentV10, BlockDocumentV10Stringified}; @@ -88,7 +88,7 @@ pub trait BlockDocumentTrait { /// Verify block hash fn verify_hash(&self) -> Result<(), VerifyBlockHashError>; /// Sign block - fn sign(&mut self, privkey: PrivKey); + fn sign(&mut self, signator: SignatorEnum); } impl BlockDocumentTrait for BlockDocument { @@ -201,9 +201,9 @@ impl BlockDocumentTrait for BlockDocument { } } #[inline] - fn sign(&mut self, privkey: PrivKey) { + fn sign(&mut self, signator: SignatorEnum) { match self { - BlockDocument::V10(block) => block.sign(privkey), + BlockDocument::V10(block) => block.sign(signator), } } } diff --git a/lib/dubp/block-doc/src/block/v10.rs b/lib/dubp/block-doc/src/block/v10.rs index 857d7915..497c9d47 100644 --- a/lib/dubp/block-doc/src/block/v10.rs +++ b/lib/dubp/block-doc/src/block/v10.rs @@ -345,8 +345,8 @@ Transactions:{transactions} i.reduce(); } } - fn sign(&mut self, privkey: PrivKey) { - self.signatures = vec![privkey.sign(self.compute_will_signed_string().as_bytes())]; + fn sign(&mut self, signator: SignatorEnum) { + self.signatures = vec![signator.sign(self.compute_will_signed_string().as_bytes())]; } fn verify_inner_hash(&self) -> Result<(), VerifyBlockHashError> { match self.inner_hash { diff --git a/lib/dubp/common-doc/src/traits.rs b/lib/dubp/common-doc/src/traits.rs index 1a0c46b4..206aab0e 100644 --- a/lib/dubp/common-doc/src/traits.rs +++ b/lib/dubp/common-doc/src/traits.rs @@ -117,8 +117,8 @@ pub trait DocumentBuilder { /// Type of the builded document. type Document: Document; - /// Type of the private keys signing the documents. - type PrivateKey: PrivateKey< + /// Type of the signator signing the documents. + type Signator: Signator< Signature = <<Self::Document as Document>::PublicKey as PublicKey>::Signature, >; @@ -129,7 +129,7 @@ pub trait DocumentBuilder { ) -> Self::Document; /// Build a document and sign it with the private key. - fn build_and_sign(&self, private_keys: Vec<Self::PrivateKey>) -> Self::Document; + fn build_and_sign(&self, signators: Vec<Self::Signator>) -> Self::Document; } /// Trait for a document parser from a `S` source diff --git a/lib/dubp/common-doc/src/traits/text.rs b/lib/dubp/common-doc/src/traits/text.rs index e3c721e1..717e7a88 100644 --- a/lib/dubp/common-doc/src/traits/text.rs +++ b/lib/dubp/common-doc/src/traits/text.rs @@ -117,14 +117,14 @@ pub trait TextDocumentBuilder: DocumentBuilder { /// /// - Text without signatures /// - Signatures - fn build_signed_text(&self, private_keys: Vec<PrivKey>) -> (String, Vec<Sig>) { + fn build_signed_text(&self, signators: Vec<SignatorEnum>) -> (String, Vec<Sig>) { let text = self.generate_text(); let signatures: Vec<_> = { let text_bytes = text.as_bytes(); - private_keys + signators .iter() - .map(|key| key.sign(text_bytes)) + .map(|signator| signator.sign(text_bytes)) .collect() }; diff --git a/lib/dubp/user-docs/src/documents/certification/v10.rs b/lib/dubp/user-docs/src/documents/certification/v10.rs index d125639d..d21a823c 100644 --- a/lib/dubp/user-docs/src/documents/certification/v10.rs +++ b/lib/dubp/user-docs/src/documents/certification/v10.rs @@ -296,13 +296,13 @@ impl<'a> CertificationDocumentV10Builder<'a> { impl<'a> DocumentBuilder for CertificationDocumentV10Builder<'a> { type Document = CertificationDocumentV10; - type PrivateKey = PrivKey; + type Signator = SignatorEnum; fn build_with_signature(&self, signatures: Vec<Sig>) -> CertificationDocumentV10 { self.build_with_text_and_sigs(self.generate_text(), signatures) } - fn build_and_sign(&self, private_keys: Vec<PrivKey>) -> CertificationDocumentV10 { + fn build_and_sign(&self, private_keys: Vec<SignatorEnum>) -> CertificationDocumentV10 { let (text, signatures) = self.build_signed_text(private_keys); self.build_with_text_and_sigs(text, signatures) } @@ -335,21 +335,19 @@ CertTimestamp: {blockstamp} #[cfg(test)] mod tests { use super::*; - use dup_crypto::keys::{PrivateKey, PublicKey, Signature}; + use dup_crypto::keys::{PublicKey, Signature}; #[test] fn generate_real_document() { - let pubkey = PubKey::Ed25519( - ed25519::PublicKey::from_base58("4tNQ7d9pj2Da5wUVoW9mFn7JjuPoowF977au8DdhEjVR") - .unwrap(), + let keypair = ed25519::KeyPairFromSeedGenerator::generate( + &Seed::from_base58("4tNQ7d9pj2Da5wUVoW9mFn7JjuPoowF977au8DdhEjVR").unwrap(), ); - - let prikey = PrivKey::Ed25519(ed25519::PrivateKey::from_base58( - "3XGWuuU1dQ7zaYPzE76ATfY71STzRkbT3t4DE1bSjMhYje81XdJFeXVG9uMPi3oDeRTosT2dmBAFH8VydrAUWXRZ", - ).unwrap()); + let pubkey = PubKey::Ed25519(keypair.public_key()); + let signator = + SignatorEnum::Ed25519(keypair.generate_signator().expect("fail to gen signator")); let sig = Sig::Ed25519(ed25519::Signature::from_base64( - "qfR6zqT1oJbqIsppOi64gC9yTtxb6g6XA9RYpulkq9ehMvqg2VYVigCbR0yVpqKFsnYiQTrnjgFuFRSJCJDfCw==", + "sYbaZp3pP9F/CveT1LPiJXECTBHlNurDXqmBo71N7JX/rvmHw6m/sid9bGdIa8cUq+vDD4DMB/F7r7As1p4rAg==", ).unwrap()); let target = PubKey::Ed25519( @@ -381,13 +379,22 @@ mod tests { blockstamp: &blockstamp, }; + /*println!( + "Signatures = {:?}", + builder + .build_and_sign(vec![SignatorEnum::Ed25519( + keypair.generate_signator().expect("fail to gen signator") + )]) + .signatures() + );*/ + assert!(builder .build_with_signature(vec![sig]) .verify_signatures() .is_ok()); assert!(builder - .build_and_sign(vec![prikey]) + .build_and_sign(vec![signator]) .verify_signatures() .is_ok()); } diff --git a/lib/dubp/user-docs/src/documents/identity/v10.rs b/lib/dubp/user-docs/src/documents/identity/v10.rs index b26c078f..82741e9b 100644 --- a/lib/dubp/user-docs/src/documents/identity/v10.rs +++ b/lib/dubp/user-docs/src/documents/identity/v10.rs @@ -234,13 +234,13 @@ impl<'a> IdentityDocumentV10Builder<'a> { impl<'a> DocumentBuilder for IdentityDocumentV10Builder<'a> { type Document = IdentityDocumentV10; - type PrivateKey = PrivKey; + type Signator = SignatorEnum; fn build_with_signature(&self, signatures: Vec<Sig>) -> IdentityDocumentV10 { self.build_with_text_and_sigs(self.generate_text(), signatures) } - fn build_and_sign(&self, private_keys: Vec<PrivKey>) -> IdentityDocumentV10 { + fn build_and_sign(&self, private_keys: Vec<SignatorEnum>) -> IdentityDocumentV10 { let (text, signatures) = self.build_signed_text(private_keys); self.build_with_text_and_sigs(text, signatures) } @@ -268,27 +268,20 @@ Timestamp: {blockstamp} mod tests { use super::*; use dubp_common_doc::traits::Document; - use dup_crypto::keys::{PrivateKey, PublicKey, Signature}; + use dup_crypto::keys::Signature; #[test] fn generate_real_document() { - let pubkey = PubKey::Ed25519( - ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV") - .unwrap(), - ); - - let prikey = PrivKey::Ed25519( - ed25519::PrivateKey::from_base58( - "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\ - iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7", - ) - .unwrap(), + let keypair = ed25519::KeyPairFromSeedGenerator::generate( + &Seed::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV").unwrap(), ); + let pubkey = PubKey::Ed25519(keypair.public_key()); + let signator = + SignatorEnum::Ed25519(keypair.generate_signator().expect("fail to gen signator")); let sig = Sig::Ed25519( ed25519::Signature::from_base64( - "1eubHHbuNfilHMM0G2bI30iZzebQ2cQ1PC7uPAw08FGM\ - MmQCRerlF/3pc4sAcsnexsxBseA/3lY03KlONqJBAg==", + "mmFepRsiOjILKnCvEvN3IZScLOfg8+e0JPAl5VkiuTLZRGJKgKhPy8nQlCKbeg0jefQm/2HJ78e/Sj+NMqYLCw==", ) .unwrap(), ); @@ -305,12 +298,21 @@ mod tests { issuer: &pubkey, }; + /*println!( + "Signatures = {:?}", + builder + .build_and_sign(vec![SignatorEnum::Ed25519( + keypair.generate_signator().expect("fail to gen signator") + )]) + .signatures() + );*/ + assert!(builder .build_with_signature(vec![sig]) .verify_signatures() .is_ok()); assert!(builder - .build_and_sign(vec![prikey]) + .build_and_sign(vec![signator]) .verify_signatures() .is_ok()); } diff --git a/lib/dubp/user-docs/src/documents/membership/v10.rs b/lib/dubp/user-docs/src/documents/membership/v10.rs index 25ecc0b0..966c9f66 100644 --- a/lib/dubp/user-docs/src/documents/membership/v10.rs +++ b/lib/dubp/user-docs/src/documents/membership/v10.rs @@ -291,13 +291,13 @@ impl<'a> MembershipDocumentV10Builder<'a> { impl<'a> DocumentBuilder for MembershipDocumentV10Builder<'a> { type Document = MembershipDocumentV10; - type PrivateKey = PrivKey; + type Signator = SignatorEnum; fn build_with_signature(&self, signatures: Vec<Sig>) -> MembershipDocumentV10 { self.build_with_text_and_sigs(self.generate_text(), signatures) } - fn build_and_sign(&self, private_keys: Vec<PrivKey>) -> MembershipDocumentV10 { + fn build_and_sign(&self, private_keys: Vec<SignatorEnum>) -> MembershipDocumentV10 { let (text, signatures) = self.build_signed_text(private_keys); self.build_with_text_and_sigs(text, signatures) } @@ -331,27 +331,20 @@ CertTS: {ity_blockstamp} #[cfg(test)] mod tests { use super::*; - use dup_crypto::keys::{PrivateKey, PublicKey, Signature}; + use dup_crypto::keys::Signature; #[test] fn generate_real_document() { - let pubkey = PubKey::Ed25519( - ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV") - .unwrap(), - ); - - let prikey = PrivKey::Ed25519( - ed25519::PrivateKey::from_base58( - "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\ - iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7", - ) - .unwrap(), + let keypair = ed25519::KeyPairFromSeedGenerator::generate( + &Seed::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV").unwrap(), ); + let pubkey = PubKey::Ed25519(keypair.public_key()); + let signator = + SignatorEnum::Ed25519(keypair.generate_signator().expect("fail to gen signator")); let sig = Sig::Ed25519( ed25519::Signature::from_base64( - "s2hUbokkibTAWGEwErw6hyXSWlWFQ2UWs2PWx8d/kkEl\ - AyuuWaQq4Tsonuweh1xn4AC1TVWt4yMR3WrDdkhnAw==", + "cUgoc8AI+Tae/AZmRfTnW+xq3XFtmYoUi2LXlmXr8/7LaXiUccQb8+Ds1nZoBp/8+t031HMwqAUpVIqww2FGCg==", ) .unwrap(), ); @@ -370,12 +363,21 @@ mod tests { identity_blockstamp: &block, }; + /*println!( + "Signatures = {:?}", + builder + .build_and_sign(vec![SignatorEnum::Ed25519( + keypair.generate_signator().expect("fail to gen signator") + )]) + .signatures() + );*/ + assert!(builder .build_with_signature(vec![sig]) .verify_signatures() .is_ok()); assert!(builder - .build_and_sign(vec![prikey]) + .build_and_sign(vec![signator]) .verify_signatures() .is_ok()); } diff --git a/lib/dubp/user-docs/src/documents/revocation/v10.rs b/lib/dubp/user-docs/src/documents/revocation/v10.rs index d58118e8..daf0539e 100644 --- a/lib/dubp/user-docs/src/documents/revocation/v10.rs +++ b/lib/dubp/user-docs/src/documents/revocation/v10.rs @@ -264,13 +264,13 @@ impl<'a> RevocationDocumentV10Builder<'a> { impl<'a> DocumentBuilder for RevocationDocumentV10Builder<'a> { type Document = RevocationDocumentV10; - type PrivateKey = PrivKey; + type Signator = SignatorEnum; fn build_with_signature(&self, signatures: Vec<Sig>) -> RevocationDocumentV10 { self.build_with_text_and_sigs(self.generate_text(), signatures) } - fn build_and_sign(&self, private_keys: Vec<PrivKey>) -> RevocationDocumentV10 { + fn build_and_sign(&self, private_keys: Vec<SignatorEnum>) -> RevocationDocumentV10 { let (text, signatures) = self.build_signed_text(private_keys); self.build_with_text_and_sigs(text, signatures) } @@ -299,25 +299,19 @@ IdtySignature: {idty_sig} #[cfg(test)] mod tests { use super::*; - use dup_crypto::keys::{PrivateKey, PublicKey, Signature}; + use dup_crypto::keys::Signature; #[test] fn generate_real_document() { - let pubkey = PubKey::Ed25519( - ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV") - .unwrap(), - ); - - let prikey = PrivKey::Ed25519( - ed25519::PrivateKey::from_base58( - "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\ - iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7", - ) - .unwrap(), + let keypair = ed25519::KeyPairFromSeedGenerator::generate( + &Seed::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV").unwrap(), ); + let pubkey = PubKey::Ed25519(keypair.public_key()); + let signator = + SignatorEnum::Ed25519(keypair.generate_signator().expect("fail to gen signator")); let sig = Sig::Ed25519(ed25519::Signature::from_base64( - "XXOgI++6qpY9O31ml/FcfbXCE6aixIrgkT5jL7kBle3YOMr+8wrp7Rt+z9hDVjrNfYX2gpeJsuMNfG4T/fzVDQ==", + "gBD2mCr7E/tW8u3wqVK7IWtQB6IKxddg13UMl9ypVsv/VhqhAFTBba9BwoK5t6H9eqF1d+4sCB3WY2eJ/yuUAg==", ).unwrap()); let identity_blockstamp = Blockstamp::from_string( @@ -337,13 +331,22 @@ mod tests { identity_sig: &identity_sig, }; + /*println!( + "Signatures = {:?}", + builder + .build_and_sign(vec![SignatorEnum::Ed25519( + keypair.generate_signator().expect("fail to gen signator") + )]) + .signatures() + );*/ + assert!(builder .build_with_signature(vec![sig]) .verify_signatures() .is_ok()); assert!(builder - .build_and_sign(vec![prikey]) + .build_and_sign(vec![signator]) .verify_signatures() .is_ok()); } diff --git a/lib/dubp/user-docs/src/documents/transaction.rs b/lib/dubp/user-docs/src/documents/transaction.rs index 8a172294..38bf5a7e 100644 --- a/lib/dubp/user-docs/src/documents/transaction.rs +++ b/lib/dubp/user-docs/src/documents/transaction.rs @@ -851,13 +851,13 @@ impl<'a> TransactionDocumentBuilder<'a> { impl<'a> DocumentBuilder for TransactionDocumentBuilder<'a> { type Document = TransactionDocument; - type PrivateKey = PrivKey; + type Signator = SignatorEnum; fn build_with_signature(&self, signatures: Vec<Sig>) -> TransactionDocument { self.build_with_text_and_sigs(self.generate_text(), signatures) } - fn build_and_sign(&self, private_keys: Vec<PrivKey>) -> TransactionDocument { + fn build_and_sign(&self, private_keys: Vec<SignatorEnum>) -> TransactionDocument { let (text, signatures) = self.build_signed_text(private_keys); self.build_with_text_and_sigs(text, signatures) } @@ -951,21 +951,15 @@ mod tests { #[test] fn generate_real_document() { - let pubkey = PubKey::Ed25519( - ed25519::PublicKey::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV") - .unwrap(), - ); - - let prikey = PrivKey::Ed25519( - ed25519::PrivateKey::from_base58( - "468Q1XtTq7h84NorZdWBZFJrGkB18CbmbHr9tkp9snt5G\ - iERP7ySs3wM8myLccbAAGejgMRC9rqnXuW3iAfZACm7", - ) - .unwrap(), + let keypair = ed25519::KeyPairFromSeedGenerator::generate( + &Seed::from_base58("DNann1Lh55eZMEDXeYt59bzHbA3NJR46DeQYCS2qQdLV").unwrap(), ); + let pubkey = PubKey::Ed25519(keypair.public_key()); + let signator = + SignatorEnum::Ed25519(keypair.generate_signator().expect("fail to gen signator")); let sig = Sig::Ed25519(ed25519::Signature::from_base64( - "pRQeKlzCsvPNmYAAkEP5jPPQO1RwrtFMRfCajEfkkrG0UQE0DhoTkxG3Zs2JFmvAFLw67pn1V5NQ08zsSfJkBg==", + "cq86RugQlqAEyS8zFkB9o0PlWPSb+a6D/MEnLe8j+okyFYf/WzI6pFiBkQ9PSOVn5I0dwzVXg7Q4N1apMWeGAg==", ).unwrap()); let block = Blockstamp::from_string( @@ -998,16 +992,20 @@ mod tests { comment: "test", hash: None, }; - println!( - "Signature = {:?}", - builder.build_and_sign(vec![prikey]).signatures() - ); + /*println!( + "Signatures = {:?}", + builder + .build_and_sign(vec![SignatorEnum::Ed25519( + keypair.generate_signator().expect("fail to gen signator") + )]) + .signatures() + );*/ assert!(builder .build_with_signature(vec![sig]) .verify_signatures() .is_ok()); assert!(builder - .build_and_sign(vec![prikey]) + .build_and_sign(vec![signator]) .verify_signatures() .is_ok()); } diff --git a/lib/dunp/network-documents/src/lib.rs b/lib/dunp/network-documents/src/lib.rs index 074deb93..573c1acf 100644 --- a/lib/dunp/network-documents/src/lib.rs +++ b/lib/dunp/network-documents/src/lib.rs @@ -159,11 +159,11 @@ mod tests { use super::network_endpoint::*; use super::*; - pub fn keypair1() -> ed25519::KeyPair { - let seed = [ + pub fn keypair1() -> ed25519::Ed25519KeyPair { + let seed = Seed::new([ 61u8, 245, 136, 162, 155, 50, 205, 43, 116, 15, 45, 84, 138, 54, 114, 214, 71, 213, 11, 251, 135, 182, 202, 131, 48, 91, 166, 226, 40, 255, 251, 172, - ]; + ]); ed25519::KeyPairFromSeedGenerator::generate(&seed) } diff --git a/lib/dunp/network-documents/src/network_head_v3.rs b/lib/dunp/network-documents/src/network_head_v3.rs index 1dc80cc8..1dddb956 100644 --- a/lib/dunp/network-documents/src/network_head_v3.rs +++ b/lib/dunp/network-documents/src/network_head_v3.rs @@ -233,6 +233,8 @@ mod tests { #[test] fn head_v3_sign_and_verify() { let keypair = keypair1(); + let signator = + SignatorEnum::Ed25519(keypair.generate_signator().expect("Fail to gen signator")); let mut head_v3 = NetworkHeadV3 { currency_name: CurrencyName("g1".to_owned()), api_outgoing_conf: 0u8, @@ -251,7 +253,7 @@ mod tests { step: 0, }; // Sign - let sign_result = head_v3.sign(PrivKey::Ed25519(keypair.private_key())); + let sign_result = head_v3.sign(&signator); if let Ok(head_v3_raw) = sign_result { println!("{}", head_v3_raw); assert_eq!( diff --git a/lib/dunp/network-documents/src/network_peer.rs b/lib/dunp/network-documents/src/network_peer.rs index 6b9d63f6..f4fd7dea 100644 --- a/lib/dunp/network-documents/src/network_peer.rs +++ b/lib/dunp/network-documents/src/network_peer.rs @@ -316,6 +316,8 @@ mod tests { #[test] fn peer_card_v11_sign_and_verify() { let keypair1 = keypair1(); + let signator = + SignatorEnum::Ed25519(keypair1.generate_signator().expect("Fail to gen signator")); let mut peer_card_v11 = PeerCardV11 { currency_name: CurrencyName(String::from("g1")), issuer: PubKey::Ed25519(keypair1.public_key()), @@ -326,7 +328,7 @@ mod tests { sig: None, }; // Sign - let sign_result = peer_card_v11.sign(PrivKey::Ed25519(keypair1.private_key())); + let sign_result = peer_card_v11.sign(&signator); if let Ok(peer_card_v11_raw) = sign_result { println!("{}", peer_card_v11_raw); assert_eq!( diff --git a/lib/modules/ws2p-v1-legacy/Cargo.toml b/lib/modules/ws2p-v1-legacy/Cargo.toml index 042c5664..0a54e936 100644 --- a/lib/modules/ws2p-v1-legacy/Cargo.toml +++ b/lib/modules/ws2p-v1-legacy/Cargo.toml @@ -11,7 +11,6 @@ path = "src/lib.rs" [dependencies] bincode = "1.0.1" -byteorder = "1.2.3" dubp-block-doc = { path = "../../dubp/block-doc"} #, version = "0.1.0" } dubp-common-doc = { path = "../../dubp/common-doc"} #, version = "0.1.0" } dubp-currency-params = { path = "../../dubp/currency-params" } @@ -27,7 +26,6 @@ durs-wot = { path = "../../dubp/wot" } failure = "0.1.5" log = "0.4.*" maplit = "1.0.1" -ring = "0.16.5" serde = { version = "1.0.*", features = ["derive"] } serde_json = "1.0.*" structopt= "0.2.*" diff --git a/lib/modules/ws2p-v1-legacy/src/events/received.rs b/lib/modules/ws2p-v1-legacy/src/events/received.rs index 377f1150..4f67ecfa 100644 --- a/lib/modules/ws2p-v1-legacy/src/events/received.rs +++ b/lib/modules/ws2p-v1-legacy/src/events/received.rs @@ -36,7 +36,7 @@ pub fn receive_event( ws2p_module.current_blockstamp ); ws2p_module.my_head = Some(heads::generate_my_head( - &ws2p_module.key_pair, + &ws2p_module.my_signator, ws2p_module.node_id, ws2p_module.soft_name, ws2p_module.soft_version, diff --git a/lib/modules/ws2p-v1-legacy/src/heads.rs b/lib/modules/ws2p-v1-legacy/src/heads.rs index 40b17925..50726fe8 100644 --- a/lib/modules/ws2p-v1-legacy/src/heads.rs +++ b/lib/modules/ws2p-v1-legacy/src/heads.rs @@ -18,7 +18,7 @@ use dubp_common_doc::Blockstamp; use durs_network_documents::network_head_v2::*; pub fn generate_my_head( - network_keypair: &KeyPairEnum, + network_signator: &SignatorEnum, node_id: NodeId, soft_name: &str, soft_version: &str, @@ -28,7 +28,7 @@ pub fn generate_my_head( let message = NetworkHeadMessage::V2(NetworkHeadMessageV2 { api: String::from("WS2POCA"), version: 1, - pubkey: network_keypair.public_key(), + pubkey: network_signator.public_key(), blockstamp: *my_current_blockstamp, node_uuid: node_id, software: String::from(soft_name), @@ -40,7 +40,7 @@ pub fn generate_my_head( let message_v2 = NetworkHeadMessage::V2(NetworkHeadMessageV2 { api: String::from("WS2POCA"), version: 2, - pubkey: network_keypair.public_key(), + pubkey: network_signator.public_key(), blockstamp: *my_current_blockstamp, node_uuid: node_id, software: String::from(soft_name), @@ -51,13 +51,9 @@ pub fn generate_my_head( }); NetworkHead::V2(Box::new(NetworkHeadV2 { message: message.clone(), - sig: network_keypair - .private_key() - .sign(message.to_string().as_bytes()), + sig: network_signator.sign(message.to_string().as_bytes()), message_v2: message_v2.clone(), - sig_v2: network_keypair - .private_key() - .sign(message_v2.to_string().as_bytes()), + sig_v2: network_signator.sign(message_v2.to_string().as_bytes()), step: 0, uid: my_uid, })) diff --git a/lib/modules/ws2p-v1-legacy/src/lib.rs b/lib/modules/ws2p-v1-legacy/src/lib.rs index 382fdb53..2463631b 100644 --- a/lib/modules/ws2p-v1-legacy/src/lib.rs +++ b/lib/modules/ws2p-v1-legacy/src/lib.rs @@ -250,6 +250,7 @@ pub struct WS2Pv1Module { mpsc::Receiver<WS2PThreadSignal>, ), pub my_head: Option<NetworkHead>, + pub my_signator: SignatorEnum, pub next_receiver: usize, pub node_id: NodeId, pub pending_received_requests: HashMap<ModuleReqId, WS2Pv1ReqFullId>, @@ -297,6 +298,11 @@ impl WS2Pv1Module { requests_awaiting_response: HashMap::new(), heads_cache: HashMap::new(), my_head: None, + my_signator: if let Ok(signator) = key_pair.generate_signator() { + signator + } else { + fatal_error!("Your key pair is corrupted, please recreate it !"); + }, uids_cache: HashMap::new(), count_dal_requests: 0, } @@ -322,8 +328,8 @@ impl From<dup_crypto::bases::BaseConvertionError> for WS2PMsgParseErr { pub trait WS2PMessage: Sized { fn parse(v: &serde_json::Value, currency: String) -> Result<Self, WS2PMsgParseErr>; fn to_raw(&self) -> String; - fn sign(&self, key_pair: KeyPairEnum) -> Sig { - key_pair.sign(self.to_raw().as_bytes()) + fn sign(&self, signator: &SignatorEnum) -> Sig { + signator.sign(self.to_raw().as_bytes()) } fn verify(&self) -> bool; //fn parse_and_verify(v: serde_json::Value, currency: String) -> bool; diff --git a/lib/modules/ws2p-v1-legacy/src/responses/received.rs b/lib/modules/ws2p-v1-legacy/src/responses/received.rs index cb3df65e..8c7d3e96 100644 --- a/lib/modules/ws2p-v1-legacy/src/responses/received.rs +++ b/lib/modules/ws2p-v1-legacy/src/responses/received.rs @@ -33,7 +33,7 @@ pub fn receive_response( ws2p_module.current_blockstamp = *current_blockstamp_; if ws2p_module.my_head.is_none() { ws2p_module.my_head = Some(heads::generate_my_head( - &ws2p_module.key_pair, + &ws2p_module.my_signator, ws2p_module.node_id, ws2p_module.soft_name, ws2p_module.soft_version, diff --git a/lib/modules/ws2p-v1-legacy/src/ws_connections/handler.rs b/lib/modules/ws2p-v1-legacy/src/ws_connections/handler.rs index 1c6987be..ff7d51ba 100644 --- a/lib/modules/ws2p-v1-legacy/src/ws_connections/handler.rs +++ b/lib/modules/ws2p-v1-legacy/src/ws_connections/handler.rs @@ -21,6 +21,8 @@ use super::states::WS2PConnectionState; use crate::constants::*; use crate::*; use dup_crypto::keys::*; +use durs_common_tools::fatal_error; +use log::error; use std::sync::mpsc; #[allow(deprecated)] use ws::util::{Timeout, Token}; @@ -38,10 +40,10 @@ pub struct Client { ws: Sender, conductor_sender: mpsc::Sender<WS2PThreadSignal>, currency: String, - key_pair: KeyPairEnum, connect_message: Message, conn_meta_datas: WS2PConnectionMetaDatas, last_mess_time: SystemTime, + signator: SignatorEnum, spam_interval: bool, spam_counter: usize, timeout: Option<Timeout>, @@ -51,7 +53,7 @@ pub fn connect_to_ws2p_endpoint( endpoint: &EndpointV1, conductor_sender: &mpsc::Sender<WS2PThreadSignal>, currency: &str, - key_pair: KeyPairEnum, + keypair: &KeyPairEnum, ) -> ws::Result<()> { // Get endpoint url let ws_url = endpoint.get_url(true, false).expect("Endpoint unreachable"); @@ -67,25 +69,34 @@ pub fn connect_to_ws2p_endpoint( .expect("WS2P: Fail to get ep.node_uuid() !"), ); - // Generate connect message - let connect_message = - generate_connect_message(currency, key_pair, conn_meta_datas.challenge.clone()); - // Log info!("WS2P: Try connection to {} ...", ws_url); // Connect to websocket - ws::connect(ws_url, |ws| Client { - ws, - conductor_sender: conductor_sender.clone(), - currency: String::from(currency), - key_pair, - connect_message: connect_message.clone(), - conn_meta_datas: conn_meta_datas.clone(), - last_mess_time: SystemTime::now(), - spam_interval: false, - spam_counter: 0, - timeout: None, + ws::connect(ws_url, |ws| { + // Generate signator + let signator = if let Ok(signator) = keypair.generate_signator() { + signator + } else { + fatal_error!("Your key pair is corrupted, please recreate it !"); + }; + + // Generate connect message + let connect_message = + generate_connect_message(currency, &signator, conn_meta_datas.challenge.clone()); + + Client { + ws, + conductor_sender: conductor_sender.clone(), + currency: String::from(currency), + connect_message: connect_message.clone(), + conn_meta_datas: conn_meta_datas.clone(), + last_mess_time: SystemTime::now(), + signator, + spam_interval: false, + spam_counter: 0, + timeout: None, + } }) } @@ -157,7 +168,7 @@ impl Handler for Client { from: self.conn_meta_datas.node_full_id(), payload: self.conn_meta_datas.parse_and_check_incoming_message( &self.currency, - self.key_pair, + &self.signator, &json_message, ), })); diff --git a/lib/modules/ws2p-v1-legacy/src/ws_connections/messages.rs b/lib/modules/ws2p-v1-legacy/src/ws_connections/messages.rs index 64167849..37e85c74 100644 --- a/lib/modules/ws2p-v1-legacy/src/ws_connections/messages.rs +++ b/lib/modules/ws2p-v1-legacy/src/ws_connections/messages.rs @@ -58,17 +58,17 @@ pub enum WS2Pv1MsgPayload { pub fn generate_connect_message( currency: &str, - key_pair: KeyPairEnum, + signator: &SignatorEnum, challenge: String, ) -> Message { // Create CONNECT Message let mut connect_message = WS2PConnectMessageV1 { currency: String::from(currency), - pubkey: key_pair.public_key(), + pubkey: signator.public_key(), challenge, signature: None, }; - connect_message.signature = Some(connect_message.sign(key_pair)); + connect_message.signature = Some(connect_message.sign(signator)); Message::text( serde_json::to_string(&connect_message).expect("Fail to serialize CONNECT message !"), ) diff --git a/lib/modules/ws2p-v1-legacy/src/ws_connections/meta_datas.rs b/lib/modules/ws2p-v1-legacy/src/ws_connections/meta_datas.rs index d88eca23..3d8d08dc 100644 --- a/lib/modules/ws2p-v1-legacy/src/ws_connections/meta_datas.rs +++ b/lib/modules/ws2p-v1-legacy/src/ws_connections/meta_datas.rs @@ -61,7 +61,7 @@ impl WS2PConnectionMetaDatas { pub fn parse_and_check_incoming_message( &mut self, currency: &str, - key_pair: KeyPairEnum, + signator: &SignatorEnum, msg: &serde_json::Value, ) -> WS2Pv1MsgPayload { if let Some(s) = msg.get("auth") { @@ -78,11 +78,11 @@ impl WS2PConnectionMetaDatas { self.remote_challenge = message.challenge.clone(); let mut response = WS2PAckMessageV1 { currency: currency.to_string(), - pubkey: key_pair.public_key(), + pubkey: signator.public_key(), challenge: self.remote_challenge.clone(), signature: None, }; - response.signature = Some(response.sign(key_pair)); + response.signature = Some(response.sign(signator)); return WS2Pv1MsgPayload::ValidConnectMessage( unwrap!(serde_json::to_string(&response)), self.state, @@ -111,11 +111,11 @@ impl WS2PConnectionMetaDatas { }; let mut response = WS2POkMessageV1 { currency: currency.to_string(), - pubkey: key_pair.public_key(), + pubkey: signator.public_key(), challenge: self.challenge.to_string(), signature: None, }; - response.signature = Some(response.sign(key_pair)); + response.signature = Some(response.sign(signator)); return WS2Pv1MsgPayload::ValidAckMessage( unwrap!(serde_json::to_string(&response)), self.state, diff --git a/lib/modules/ws2p-v1-legacy/src/ws_connections/mod.rs b/lib/modules/ws2p-v1-legacy/src/ws_connections/mod.rs index 32becf36..3be33dda 100644 --- a/lib/modules/ws2p-v1-legacy/src/ws_connections/mod.rs +++ b/lib/modules/ws2p-v1-legacy/src/ws_connections/mod.rs @@ -24,8 +24,8 @@ pub mod states; use crate::*; use dup_crypto::keys::*; +use dup_crypto::rand; use durs_network_documents::network_endpoint::EndpointV1; -use ring::rand; use states::WS2PConnectionState; use std::cmp::Ordering; use std::collections::HashSet; @@ -140,7 +140,7 @@ pub fn connect_to_without_checking_quotas( &endpoint_copy, &conductor_sender_copy, ¤cy_copy.expect("WS2PError : No currency !").0, - key_pair_copy, + &key_pair_copy, ); }); } @@ -171,23 +171,19 @@ pub fn close_connection( pub fn get_random_connection<S: ::std::hash::BuildHasher>( connections: HashSet<&NodeFullId, S>, ) -> NodeFullId { - let mut loop_count = 0; - let rng = rand::SystemRandom::new(); - loop { - for ws2p_full_id in &connections { - if loop_count > 10 { - return **ws2p_full_id; - } - if let Ok(random_bytes) = rand::generate::<[u8; 4]>(&rng) { - if random_bytes.expose()[0] < 0b1000_0000 { - return **ws2p_full_id; - } - } else { - fatal_error!("System error: fail to generate random boolean !") - } + let random_usize = rand::gen_u32() as usize; + let mut count = random_usize % connections.len(); + let mut last_node_full_id = None; + for node_full_id in &connections { + if count == 0 { + return **node_full_id; + } else { + count -= 1; + last_node_full_id = Some(**node_full_id); + continue; } - loop_count += 1; } + last_node_full_id.expect("ws2p connections set must be not empty !") } pub fn count_established_connections(ws2p_module: &WS2Pv1Module) -> usize { diff --git a/lib/modules/ws2p/ws2p-messages/lib.rs b/lib/modules/ws2p/ws2p-messages/lib.rs index d5306564..8b5d399a 100644 --- a/lib/modules/ws2p/ws2p-messages/lib.rs +++ b/lib/modules/ws2p/ws2p-messages/lib.rs @@ -174,11 +174,11 @@ mod tests { use std::net::Ipv4Addr; use std::str::FromStr; - pub fn keypair1() -> ed25519::KeyPair { - let seed = [ + pub fn keypair1() -> ed25519::Ed25519KeyPair { + let seed = Seed::new([ 228, 125, 124, 120, 57, 212, 246, 250, 139, 246, 62, 26, 56, 241, 175, 123, 151, 209, 5, 106, 2, 148, 43, 101, 118, 160, 233, 7, 112, 222, 0, 169, - ]; + ]); ed25519::KeyPairFromSeedGenerator::generate(&seed) } @@ -223,6 +223,8 @@ mod tests { pub fn test_ws2p_message(payload: WS2Pv2MessagePayload) { let keypair1 = keypair1(); + let signator = + SignatorEnum::Ed25519(keypair1.generate_signator().expect("fail to gen signator")); let mut ws2p_message = WS2PMessage::V2(WS2Pv2Message { currency_name: CurrencyName(String::from("g1")), issuer_node_id: NodeId(0), @@ -232,7 +234,7 @@ mod tests { signature: None, }); - let sign_result = ws2p_message.sign(PrivKey::Ed25519(keypair1.private_key())); + let sign_result = ws2p_message.sign(&signator); if let Ok(bin_msg) = sign_result { // Test binarization assert_eq!( diff --git a/lib/modules/ws2p/ws2p-messages/v2/api_features.rs b/lib/modules/ws2p/ws2p-messages/v2/api_features.rs index 5a704aee..e37ad4d1 100644 --- a/lib/modules/ws2p/ws2p-messages/v2/api_features.rs +++ b/lib/modules/ws2p/ws2p-messages/v2/api_features.rs @@ -13,13 +13,13 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. -#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] /// WS2PFeatures -pub struct WS2PFeatures(pub Vec<u8>); +pub struct WS2PFeatures(pub [u8; 4]); impl WS2PFeatures { /// Return true if all flags are disabled (or if it's really empty). - pub fn is_empty(&self) -> bool { + pub fn is_empty(self) -> bool { for byte in &self.0 { if *byte > 0u8 { return false; @@ -28,23 +28,23 @@ impl WS2PFeatures { true } /// Check flag DEF - pub fn def(&self) -> bool { + pub fn def(self) -> bool { self.0[0] | 0b1111_1110 == 255u8 } /// Check flag LOW - pub fn low(&self) -> bool { + pub fn low(self) -> bool { self.0[0] | 0b1111_1101 == 255u8 } /// Check flag ABF - pub fn abf(&self) -> bool { + pub fn abf(self) -> bool { self.0[0] | 0b1111_1011 == 255u8 } /// Check features compatibility pub fn check_features_compatibility( - &self, - remote_features: &WS2PFeatures, + self, + remote_features: WS2PFeatures, ) -> Result<WS2PFeatures, ()> { - let mut merged_features = self.clone(); + let mut merged_features = self; // Remove features unsuported by remote node if self.def() && !remote_features.def() { merged_features.0[0] &= 0b1111_1110; diff --git a/lib/modules/ws2p/ws2p-messages/v2/connect.rs b/lib/modules/ws2p/ws2p-messages/v2/connect.rs index 4f45a524..b1ac8257 100644 --- a/lib/modules/ws2p/ws2p-messages/v2/connect.rs +++ b/lib/modules/ws2p/ws2p-messages/v2/connect.rs @@ -129,7 +129,7 @@ impl Default for WS2Pv2ConnectMsg { fn default() -> Self { WS2Pv2ConnectMsg { challenge: Hash::random(), - api_features: WS2PFeatures(vec![]), + api_features: WS2PFeatures([0u8; 4]), flags_queries: WS2PConnectFlags(vec![]), peer_card: None, chunkstamp: None, @@ -187,15 +187,16 @@ mod tests { #[test] fn test_ws2p_message_connect() { let keypair1 = keypair1(); + let signator = + SignatorEnum::Ed25519(keypair1.generate_signator().expect("fail to gen signator")); let mut peer = create_peer_card_v11(); - peer.sign(PrivKey::Ed25519(keypair1.private_key())) - .expect("Fail to sign peer card !"); + peer.sign(&signator).expect("Fail to sign peer card !"); let connect_msg = WS2Pv2ConnectMsg { challenge: Hash::from_hex( "000007722B243094269E548F600BD34D73449F7578C05BD370A6D301D20B5F10", ) .unwrap(), - api_features: WS2PFeatures(vec![7u8]), + api_features: WS2PFeatures([7u8, 0, 0, 0]), flags_queries: WS2PConnectFlags(vec![]), peer_card: Some(peer), chunkstamp: Some( diff --git a/lib/modules/ws2p/ws2p-messages/v2/mod.rs b/lib/modules/ws2p/ws2p-messages/v2/mod.rs index fb57861e..9aad9194 100644 --- a/lib/modules/ws2p/ws2p-messages/v2/mod.rs +++ b/lib/modules/ws2p/ws2p-messages/v2/mod.rs @@ -64,18 +64,18 @@ impl WS2Pv2Message { pub fn encapsulate_payload( currency_name: CurrencyName, issuer_node_id: NodeId, - issuer_keypair: KeyPairEnum, + issuer_signator: &SignatorEnum, payload: WS2Pv2MessagePayload, ) -> Result<(WS2PMessage, Vec<u8>), SignError> { let mut msg = WS2PMessage::V2(WS2Pv2Message { currency_name, issuer_node_id, - issuer_pubkey: issuer_keypair.public_key(), + issuer_pubkey: issuer_signator.public_key(), payload, message_hash: None, signature: None, }); - match msg.sign(issuer_keypair.private_key()) { + match msg.sign(issuer_signator) { Ok(bin_msg) => Ok((msg, bin_msg)), Err(e) => Err(e), } @@ -98,9 +98,10 @@ mod tests { #[test] fn test_ws2p_message_peers() { let keypair1 = keypair1(); + let signator = + SignatorEnum::Ed25519(keypair1.generate_signator().expect("fail to gen signator")); let mut peer = create_peer_card_v11(); - peer.sign(PrivKey::Ed25519(keypair1.private_key())) - .expect("Fail to sign peer card !"); + peer.sign(&signator).expect("Fail to sign peer card !"); test_ws2p_message(WS2Pv2MessagePayload::Peers(vec![peer])); } } diff --git a/lib/modules/ws2p/ws2p-messages/v2/secret_flags.rs b/lib/modules/ws2p/ws2p-messages/v2/secret_flags.rs index 514eacfe..78193a97 100644 --- a/lib/modules/ws2p/ws2p-messages/v2/secret_flags.rs +++ b/lib/modules/ws2p/ws2p-messages/v2/secret_flags.rs @@ -71,12 +71,14 @@ mod tests { #[test] fn test_ws2p_message_secret_flags() { let keypair1 = keypair1(); + let signator = + SignatorEnum::Ed25519(keypair1.generate_signator().expect("fail to gen signator")); let challenge = Hash::random(); let msg = WS2Pv2SecretFlagsMsg { secret_flags: WS2Pv2SecretFlags(vec![]), member_proof: Some(MemberProof { pubkey: PubKey::Ed25519(keypair1.public_key()), - sig: Sig::Ed25519(keypair1.private_key().sign(&challenge.0)), + sig: signator.sign(&challenge.0), }), }; test_ws2p_message(WS2Pv2MessagePayload::SecretFlags(msg)); diff --git a/lib/modules/ws2p/ws2p-protocol/src/controller/meta_datas.rs b/lib/modules/ws2p/ws2p-protocol/src/controller/meta_datas.rs index 1ba32077..0164d0a6 100644 --- a/lib/modules/ws2p/ws2p-protocol/src/controller/meta_datas.rs +++ b/lib/modules/ws2p/ws2p-protocol/src/controller/meta_datas.rs @@ -20,13 +20,16 @@ use crate::MySelfWs2pNode; use dubp_common_doc::Blockstamp; use dubp_currency_params::CurrencyName; use dup_crypto::hashs::Hash; +use dup_crypto::keys::{KeyPair, SignatorEnum}; +use durs_common_tools::fatal_error; use durs_network_documents::network_peer::PeerCardV11; use durs_network_documents::NodeFullId; use durs_ws2p_messages::v2::api_features::WS2PFeatures; use durs_ws2p_messages::v2::connect::WS2Pv2ConnectType; +use log::error; use std::time::SystemTime; -#[derive(Debug, Clone)] +#[derive(Debug)] /// WS2p Connection meta datas pub struct WS2PControllerMetaDatas { /// Local challenge @@ -41,6 +44,8 @@ pub struct WS2PControllerMetaDatas { pub creation_time: SystemTime, /// Connection features pub features: Option<WS2PFeatures>, + /// Signator + pub signator: SignatorEnum, /// Timestamp of last received message pub last_mess_time: SystemTime, /// Local node properties @@ -76,6 +81,11 @@ impl WS2PControllerMetaDatas { local_node, remote_connect_type: None, remote_node: None, + signator: if let Ok(signator) = local_node.my_key_pair.generate_signator() { + signator + } else { + fatal_error!("Your keypair is corrupted, please recreate it !"); + }, spam_interval: false, spam_counter: 0, state: WS2PConnectionState::TryToOpenWS, diff --git a/lib/modules/ws2p/ws2p-protocol/src/controller/on_message/ack_msg.rs b/lib/modules/ws2p/ws2p-protocol/src/controller/on_message/ack_msg.rs index b7780e6d..c987782c 100644 --- a/lib/modules/ws2p/ws2p-protocol/src/controller/on_message/ack_msg.rs +++ b/lib/modules/ws2p/ws2p-protocol/src/controller/on_message/ack_msg.rs @@ -81,7 +81,7 @@ fn send_ok_msg<M: ModuleMessage>( if let Ok((_, bin_ok_msg)) = WS2Pv2Message::encapsulate_payload( controller.meta_datas.currency.clone(), controller.meta_datas.local_node.my_node_id, - controller.meta_datas.local_node.my_key_pair, + &controller.meta_datas.signator, WS2Pv2MessagePayload::Ok(ok_msg), ) { // Order the sending of a OK message diff --git a/lib/modules/ws2p/ws2p-protocol/src/controller/on_message/connect_msg.rs b/lib/modules/ws2p/ws2p-protocol/src/controller/on_message/connect_msg.rs index ca48f635..e8f7ec69 100644 --- a/lib/modules/ws2p/ws2p-protocol/src/controller/on_message/connect_msg.rs +++ b/lib/modules/ws2p/ws2p-protocol/src/controller/on_message/connect_msg.rs @@ -83,7 +83,7 @@ pub fn process_ws2p_v2p_connect_msg<M: ModuleMessage>( .meta_datas .local_node .my_features - .check_features_compatibility(&connect_msg.api_features) + .check_features_compatibility(connect_msg.api_features) { Ok(merged_features) => controller.meta_datas.features = Some(merged_features), Err(_) => { @@ -95,7 +95,7 @@ pub fn process_ws2p_v2p_connect_msg<M: ModuleMessage>( if let Ok((_, bin_ack_msg)) = WS2Pv2Message::encapsulate_payload( controller.meta_datas.currency.clone(), controller.meta_datas.local_node.my_node_id, - controller.meta_datas.local_node.my_key_pair, + &controller.meta_datas.signator, WS2Pv2MessagePayload::Ack { challenge: remote_challenge, }, diff --git a/lib/modules/ws2p/ws2p-protocol/src/controller/on_open.rs b/lib/modules/ws2p/ws2p-protocol/src/controller/on_open.rs index aa78bd89..ca8c4d21 100644 --- a/lib/modules/ws2p/ws2p-protocol/src/controller/on_open.rs +++ b/lib/modules/ws2p/ws2p-protocol/src/controller/on_open.rs @@ -39,7 +39,7 @@ pub fn process<M: ModuleMessage>( // Generate connect message let connect_msg = generate_connect_message( controller.meta_datas.connect_type, - controller.meta_datas.local_node.my_features.clone(), + controller.meta_datas.local_node.my_features, controller.meta_datas.challenge, None, ); @@ -48,7 +48,7 @@ pub fn process<M: ModuleMessage>( if let Ok((_ws2p_full_msg, bin_connect_msg)) = WS2Pv2Message::encapsulate_payload( controller.meta_datas.currency.clone(), controller.meta_datas.local_node.my_node_id, - controller.meta_datas.local_node.my_key_pair, + &controller.meta_datas.signator, WS2Pv2MessagePayload::Connect(Box::new(connect_msg)), ) { // Order the sending of a CONNECT message diff --git a/lib/modules/ws2p/ws2p-protocol/src/lib.rs b/lib/modules/ws2p/ws2p-protocol/src/lib.rs index 2f0a9399..2e79c206 100644 --- a/lib/modules/ws2p/ws2p-protocol/src/lib.rs +++ b/lib/modules/ws2p/ws2p-protocol/src/lib.rs @@ -39,7 +39,7 @@ use durs_network_documents::{NodeFullId, NodeId}; use durs_ws2p_messages::v2::api_features::WS2PFeatures; /// Store self WS2P properties -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct MySelfWs2pNode { /// Local node id pub my_node_id: NodeId, diff --git a/lib/modules/ws2p/ws2p/src/controllers/incoming_connections.rs b/lib/modules/ws2p/ws2p/src/controllers/incoming_connections.rs index d3e306d1..041af740 100644 --- a/lib/modules/ws2p/ws2p/src/controllers/incoming_connections.rs +++ b/lib/modules/ws2p/ws2p/src/controllers/incoming_connections.rs @@ -46,7 +46,7 @@ pub fn listen_on_ws2p_v2_endpoint<A: ToSocketAddrs + Debug>( Hash::random(), WS2Pv2ConnectType::Incoming, currency.clone(), - self_node.clone(), + *self_node, ), orchestrator_sender.clone(), ) { diff --git a/lib/modules/ws2p/ws2p/src/controllers/outgoing_connections.rs b/lib/modules/ws2p/ws2p/src/controllers/outgoing_connections.rs index dcabd55e..3c492f07 100644 --- a/lib/modules/ws2p/ws2p/src/controllers/outgoing_connections.rs +++ b/lib/modules/ws2p/ws2p/src/controllers/outgoing_connections.rs @@ -56,7 +56,7 @@ pub fn connect_to_ws2p_v2_endpoint( Hash::random(), WS2Pv2ConnectType::OutgoingServer, currency.clone(), - self_node.clone(), + *self_node, ), orchestrator_sender.clone(), ) { diff --git a/lib/modules/ws2p/ws2p/src/generate_peer.rs b/lib/modules/ws2p/ws2p/src/generate_peer.rs index d013268e..9eef193c 100644 --- a/lib/modules/ws2p/ws2p/src/generate_peer.rs +++ b/lib/modules/ws2p/ws2p/src/generate_peer.rs @@ -19,7 +19,7 @@ use bincode; use dubp_common_doc::BlockNumber; use dubp_currency_params::CurrencyName; use dup_crypto::keys::text_signable::TextSignable; -use dup_crypto::keys::{KeyPair, KeyPairEnum, SignError}; +use dup_crypto::keys::{SignError, Signator, SignatorEnum}; use durs_common_tools::fatal_error; use durs_network_documents::network_endpoint::*; use durs_network_documents::network_peer::*; @@ -27,7 +27,7 @@ use durs_network_documents::*; pub fn _self_peer_update_endpoints( self_peer: PeerCardV11, - issuer_keys: KeyPairEnum, + issuer_signator: &SignatorEnum, created_on: BlockNumber, new_endpoints: Vec<EndpointEnum>, ) -> Result<PeerCardV11, SignError> { @@ -84,14 +84,14 @@ pub fn _self_peer_update_endpoints( ..self_peer }; - new_self_peer.sign(issuer_keys.private_key())?; + new_self_peer.sign(issuer_signator)?; Ok(new_self_peer) } pub fn _generate_self_peer( currency_name: CurrencyName, - issuer_keys: KeyPairEnum, + issuer_signator: &SignatorEnum, node_id: NodeId, created_on: BlockNumber, endpoints: Vec<EndpointEnum>, @@ -120,7 +120,7 @@ pub fn _generate_self_peer( let mut self_peer = PeerCardV11 { currency_name, - issuer: issuer_keys.public_key(), + issuer: issuer_signator.public_key(), node_id, created_on, endpoints: endpoints_bin, @@ -128,7 +128,7 @@ pub fn _generate_self_peer( sig: None, }; - self_peer.sign(issuer_keys.private_key())?; + self_peer.sign(issuer_signator)?; Ok(self_peer) } diff --git a/lib/modules/ws2p/ws2p/src/services/mod.rs b/lib/modules/ws2p/ws2p/src/services/mod.rs index cbd379be..34ac134a 100644 --- a/lib/modules/ws2p/ws2p/src/services/mod.rs +++ b/lib/modules/ws2p/ws2p/src/services/mod.rs @@ -29,7 +29,7 @@ pub enum WsError { } /// Store self WS2P properties -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct MySelfWs2pNode { /// Local node id pub my_node_id: NodeId, diff --git a/lib/modules/ws2p/ws2p/tests/connection_negociation.rs b/lib/modules/ws2p/ws2p/tests/connection_negociation.rs index 71964484..ae944334 100644 --- a/lib/modules/ws2p/ws2p/tests/connection_negociation.rs +++ b/lib/modules/ws2p/ws2p/tests/connection_negociation.rs @@ -39,19 +39,19 @@ pub fn currency() -> CurrencyName { CurrencyName(String::from("g1")) } -pub fn keypair1() -> ed25519::KeyPair { - let seed = [ +pub fn keypair1() -> ed25519::Ed25519KeyPair { + let seed = Seed::new([ 61u8, 245, 136, 162, 155, 50, 205, 43, 116, 15, 45, 84, 138, 54, 114, 214, 71, 213, 11, 251, 135, 182, 202, 131, 48, 91, 166, 226, 40, 255, 251, 172, - ]; + ]); ed25519::KeyPairFromSeedGenerator::generate(&seed) } -pub fn keypair2() -> ed25519::KeyPair { - let seed = [ +pub fn keypair2() -> ed25519::Ed25519KeyPair { + let seed = Seed::new([ 228, 125, 124, 120, 57, 212, 246, 250, 139, 246, 62, 26, 56, 241, 175, 123, 151, 209, 5, 106, 2, 148, 43, 101, 118, 160, 233, 7, 112, 222, 0, 169, - ]; + ]); ed25519::KeyPairFromSeedGenerator::generate(&seed) } @@ -59,7 +59,7 @@ fn server_node() -> MySelfWs2pNode { MySelfWs2pNode { my_node_id: NodeId(0), my_key_pair: KeyPairEnum::Ed25519(keypair1()), - my_features: WS2PFeatures(vec![5u8]), + my_features: WS2PFeatures([5u8, 0, 0, 0]), } } @@ -67,7 +67,7 @@ fn client_node() -> MySelfWs2pNode { MySelfWs2pNode { my_node_id: NodeId(1), my_key_pair: KeyPairEnum::Ed25519(keypair2()), - my_features: WS2PFeatures(vec![5u8]), + my_features: WS2PFeatures([5u8, 0, 0, 0]), } } -- GitLab