From c151f94a841b5ccd2b915c479d5570a3c2dd8f9d Mon Sep 17 00:00:00 2001 From: Niko Date: Fri, 5 May 2023 21:41:41 +0300 Subject: [PATCH] dual 25519 keys (montgomery and edwards) --- Cargo.lock | 2 +- ng-app-js/src/lib.rs | 4 +- ngcli/Cargo.toml | 1 - ngcli/src/main.rs | 67 +++++++++++++++++----------------- ngd/src/main.rs | 29 ++++++++++----- p2p-broker/src/server_ws.rs | 16 +++++--- p2p-client-ws/src/remote_ws.rs | 4 +- p2p-net/Cargo.toml | 1 + p2p-net/src/connection.rs | 1 - p2p-net/src/utils.rs | 31 ++++++++++++++++ p2p-repo/src/errors.rs | 4 +- p2p-repo/src/types.rs | 5 ++- p2p-repo/src/utils.rs | 18 +++++++++ 13 files changed, 126 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64a94c3..cce03bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1081,7 +1081,6 @@ dependencies = [ "p2p-stores-lmdb", "rand 0.7.3", "tempfile", - "xactor", ] [[package]] @@ -1228,6 +1227,7 @@ dependencies = [ "async-trait", "blake3", "debug_print", + "ed25519-dalek", "futures", "getrandom 0.2.8", "gloo-timers", diff --git a/ng-app-js/src/lib.rs b/ng-app-js/src/lib.rs index a60f628..2a46179 100644 --- a/ng-app-js/src/lib.rs +++ b/ng-app-js/src/lib.rs @@ -39,8 +39,8 @@ pub async fn start() { async fn inner_task() -> ResultSend<()> { let server_key = PubKey::Ed25519PubKey([ - 22, 140, 190, 111, 82, 151, 27, 133, 83, 121, 71, 36, 209, 53, 53, 114, 52, 254, 218, - 241, 52, 155, 231, 83, 188, 189, 47, 135, 105, 213, 39, 91, + 95, 155, 249, 202, 41, 105, 71, 51, 206, 126, 9, 84, 132, 92, 60, 7, 74, 179, 46, 21, + 21, 242, 171, 27, 249, 79, 76, 176, 168, 43, 83, 2, ]); let keys = p2p_net::utils::gen_keys(); diff --git a/ngcli/Cargo.toml b/ngcli/Cargo.toml index 2c4d6ae..5fd3d71 100644 --- a/ngcli/Cargo.toml +++ b/ngcli/Cargo.toml @@ -16,7 +16,6 @@ p2p-broker = { path = "../p2p-broker" } p2p-stores-lmdb = { path = "../p2p-stores-lmdb" } async-std = { version = "1.12.0", features = ["attributes"] } futures = "0.3.24" -xactor = "0.7.11" tempfile = "3" fastbloom-rs = "0.5.3" rand = "0.7" diff --git a/ngcli/src/main.rs b/ngcli/src/main.rs index 31d43c8..68f3eef 100644 --- a/ngcli/src/main.rs +++ b/ngcli/src/main.rs @@ -21,16 +21,12 @@ use p2p_stores_lmdb::repo_store::LmdbRepoStore; use rand::rngs::OsRng; use std::collections::HashMap; -use p2p_broker::server::*; -use p2p_broker::server_ws::*; -use p2p_net::broker_connection::*; use p2p_net::errors::*; use p2p_net::types::*; + use p2p_repo::types::*; use p2p_repo::utils::{generate_keypair, now_timestamp}; -use p2p_broker::connection_local::*; - fn block_size() -> usize { store_max_value_size() //store_valid_value_size(0) @@ -557,48 +553,38 @@ async fn test( async fn test_local_connection() { debug_println!("===== TESTING LOCAL API ====="); - let root = tempfile::Builder::new() - .prefix("node-daemon") - .tempdir() - .unwrap(); + let root = tempfile::Builder::new().prefix("ngcli").tempdir().unwrap(); let master_key: [u8; 32] = [0; 32]; std::fs::create_dir_all(root.path()).unwrap(); println!("{}", root.path().to_str().unwrap()); let store = LmdbBrokerStore::open(root.path(), master_key); - let mut server = BrokerServer::new(store, ConfigMode::Local).expect("starting broker"); + //let mut server = BrokerServer::new(store, ConfigMode::Local).expect("starting broker"); let (priv_key, pub_key) = generate_keypair(); - let mut cnx = server.local_connection(pub_key); + // let mut cnx = server.local_connection(pub_key); - test(&mut cnx, pub_key, priv_key).await; + // test(&mut cnx, pub_key, priv_key).await; } async fn test_remote_connection(url: &str) { debug_println!("===== TESTING REMOTE API ====="); let (priv_key, pub_key) = generate_keypair(); - let cnx_res = BrokerConnectionWebSocket::open(url, priv_key, pub_key).await; - match cnx_res { - Ok(mut cnx) => { - if let Err(e) = test(&mut cnx, pub_key, priv_key).await { - debug_println!("error: {:?}", e) - } else { - cnx.close().await; - } - } - Err(e) => {} - } + + // open cnx + + // test(&mut cnx, pub_key, priv_key).await; } -#[xactor::main] +#[async_std::main] async fn main() -> std::io::Result<()> { debug_println!("Starting nextgraph CLI..."); - test_local_connection().await; + //test_local_connection().await; - test_remote_connection("ws://127.0.0.1:3012").await; + //test_remote_connection("ws://127.0.0.1:3012").await; Ok(()) } @@ -609,22 +595,37 @@ mod test { use crate::{test_local_connection, test_remote_connection}; #[async_std::test] - pub async fn test_local_cnx() { - xactor::block_on(test_local_connection()); - } + pub async fn test_local_cnx() {} use async_std::task; use p2p_broker::server_ws::*; + use p2p_net::utils::{gen_keys, Sensitive, U8Array}; + use p2p_net::WS_PORT; + use p2p_repo::types::PubKey; #[async_std::test] pub async fn test_remote_cnx() -> Result<(), Box> { - let thr = task::spawn(run_server_accept_one("127.0.0.1:3012")); - + let keys = gen_keys(); + // println!("Public key of node: {:?}", keys.1); + // println!("Private key of node: {:?}", keys.0.as_slice()); + let pubkey = PubKey::Ed25519PubKey(keys.1); + + println!("Public key of node: {:?}", pubkey); + println!("Private key of node: {:?}", keys.0.as_slice()); + + let thr = task::spawn(run_server_accept_one( + "127.0.0.1", + WS_PORT, + keys.0.as_slice(), + pubkey, + )); + + // time for the server to start std::thread::sleep(std::time::Duration::from_secs(2)); - xactor::block_on(test_remote_connection("ws://127.0.0.1:3012")); + test_remote_connection("ws://127.0.0.1:3012"); - xactor::block_on(thr); + thr.await; Ok(()) } diff --git a/ngd/src/main.rs b/ngd/src/main.rs index bc34bc3..3e8637f 100644 --- a/ngd/src/main.rs +++ b/ngd/src/main.rs @@ -8,33 +8,44 @@ // according to those terms. use p2p_broker::server_ws::run_server; -use p2p_net::utils::{gen_keys, Sensitive, U8Array}; +use p2p_net::utils::{gen_keys, Dual25519Keys, Sensitive, U8Array}; use p2p_net::WS_PORT; use p2p_repo::{ types::{PrivKey, PubKey}, - utils::generate_keypair, + utils::{generate_keypair, keypair_from_ed, sign, verify}, }; #[async_std::main] async fn main() -> std::io::Result<()> { println!("Starting NextGraph daemon..."); - // let keys = generate_keypair(); + // let keys = gen_keys(); + // let pub_key = PubKey::Ed25519PubKey(keys.1); + // let (ed_priv_key, ed_pub_key) = generate_keypair(); + + // let duals = Dual25519Keys::generate(); + // let eds = keypair_from_ed(duals.ed25519_priv, duals.ed25519_pub); + // let test_vector: Vec = vec![71, 51, 206, 126, 9, 84, 132]; + // let sig = sign(eds.0, eds.1, &test_vector).unwrap(); + // verify(&test_vector, sig, eds.1).unwrap(); + + // let privkey = duals.x25519_priv; + // let pubkey = PubKey::Ed25519PubKey(duals.x25519_public); + // println!("Public key of node: {:?}", keys.1); // println!("Private key of node: {:?}", keys.0.as_slice()); let pubkey = PubKey::Ed25519PubKey([ - 22, 140, 190, 111, 82, 151, 27, 133, 83, 121, 71, 36, 209, 53, 53, 114, 52, 254, 218, 241, - 52, 155, 231, 83, 188, 189, 47, 135, 105, 213, 39, 91, + 95, 155, 249, 202, 41, 105, 71, 51, 206, 126, 9, 84, 132, 92, 60, 7, 74, 179, 46, 21, 21, + 242, 171, 27, 249, 79, 76, 176, 168, 43, 83, 2, ]); let privkey = Sensitive::<[u8; 32]>::from_slice(&[ - 160, 133, 237, 116, 151, 53, 156, 151, 21, 227, 226, 35, 1, 224, 44, 207, 148, 33, 79, 160, - 115, 173, 154, 118, 251, 146, 34, 204, 40, 190, 155, 112, + 56, 86, 36, 0, 109, 59, 152, 66, 166, 71, 201, 20, 119, 64, 173, 99, 215, 52, 40, 189, 96, + 142, 3, 134, 167, 187, 235, 4, 39, 26, 31, 119, ]); - //let keys = gen_keys(); println!("Public key of node: {:?}", pubkey); println!("Private key of node: {:?}", privkey.as_slice()); - run_server(format!("127.0.0.1:{}", WS_PORT).as_str(), privkey, pubkey).await?; + run_server("127.0.0.1", WS_PORT, privkey, pubkey).await?; Ok(()) } diff --git a/p2p-broker/src/server_ws.rs b/p2p-broker/src/server_ws.rs index 9363676..f7fbb92 100644 --- a/p2p-broker/src/server_ws.rs +++ b/p2p-broker/src/server_ws.rs @@ -54,10 +54,12 @@ pub async fn accept(tcp: TcpStream, peer_priv_key: Sensitive<[u8; 32]>, peer_pub } pub async fn run_server_accept_one( - addrs: &str, + addr: &str, + port: u16, peer_priv_key: Sensitive<[u8; 32]>, peer_pub_key: PubKey, ) -> std::io::Result<()> { + let addrs = format!("{}:{}", addr, port); let root = tempfile::Builder::new().prefix("ngd").tempdir().unwrap(); let master_key: [u8; 32] = [0; 32]; std::fs::create_dir_all(root.path()).unwrap(); @@ -69,8 +71,8 @@ pub async fn run_server_accept_one( // BrokerServer::new(store, ConfigMode::Local).expect("starting broker"); // let server_arc = Arc::new(server); - let socket = TcpListener::bind(addrs).await?; - debug_println!("Listening on {}", addrs); + let socket = TcpListener::bind(addrs.as_str()).await?; + debug_println!("Listening on {}", addrs.as_str()); let mut connections = socket.incoming(); let tcp = connections.next().await.unwrap()?; @@ -81,10 +83,12 @@ pub async fn run_server_accept_one( } use p2p_net::utils::U8Array; pub async fn run_server( - addrs: &str, + addr: &str, + port: u16, peer_priv_key: Sensitive<[u8; 32]>, peer_pub_key: PubKey, ) -> std::io::Result<()> { + let addrs = format!("{}:{}", addr, port); let root = tempfile::Builder::new().prefix("ngd").tempdir().unwrap(); let master_key: [u8; 32] = [0; 32]; std::fs::create_dir_all(root.path()).unwrap(); @@ -96,8 +100,8 @@ pub async fn run_server( // BrokerServer::new(store, ConfigMode::Local).expect("starting broker"); // let server_arc = Arc::new(server); - let socket = TcpListener::bind(addrs).await?; - debug_println!("Listening on {}", addrs); + let socket = TcpListener::bind(addrs.as_str()).await?; + debug_println!("Listening on {}", addrs.as_str()); let mut connections = socket.incoming(); while let Some(tcp) = connections.next().await { diff --git a/p2p-client-ws/src/remote_ws.rs b/p2p-client-ws/src/remote_ws.rs index 6eff679..4671454 100644 --- a/p2p-client-ws/src/remote_ws.rs +++ b/p2p-client-ws/src/remote_ws.rs @@ -270,8 +270,8 @@ mod test { // getrandom::getrandom(&mut random_buf).unwrap(); let server_key = PubKey::Ed25519PubKey([ - 22, 140, 190, 111, 82, 151, 27, 133, 83, 121, 71, 36, 209, 53, 53, 114, 52, 254, 218, - 241, 52, 155, 231, 83, 188, 189, 47, 135, 105, 213, 39, 91, + 95, 155, 249, 202, 41, 105, 71, 51, 206, 126, 9, 84, 132, 92, 60, 7, 74, 179, 46, 21, + 21, 242, 171, 27, 249, 79, 76, 176, 168, 43, 83, 2, ]); let keys = p2p_net::utils::gen_keys(); diff --git a/p2p-net/Cargo.toml b/p2p-net/Cargo.toml index 95f94d3..decd001 100644 --- a/p2p-net/Cargo.toml +++ b/p2p-net/Cargo.toml @@ -24,6 +24,7 @@ unique_id = "0.1.5" once_cell = "1.17.1" noise-protocol = "0.1.4" noise-rust-crypto = "0.5.0" +ed25519-dalek = "1.0.1" [target.'cfg(target_arch = "wasm32")'.dependencies] gloo-timers = "0.2.6" diff --git a/p2p-net/src/connection.rs b/p2p-net/src/connection.rs index 46e3fd5..448cacc 100644 --- a/p2p-net/src/connection.rs +++ b/p2p-net/src/connection.rs @@ -687,7 +687,6 @@ impl ConnectionBase { >( &self, msg: A, - //stream: Option, ) -> Result, ProtocolError> { if self.fsm.is_none() { return Err(ProtocolError::FsmNotReady); diff --git a/p2p-net/src/utils.rs b/p2p-net/src/utils.rs index e2dc2d2..1d3f170 100644 --- a/p2p-net/src/utils.rs +++ b/p2p-net/src/utils.rs @@ -11,6 +11,7 @@ use crate::log; use async_std::task; +use ed25519_dalek::*; use futures::{channel::mpsc, select, Future, FutureExt, SinkExt}; pub use noise_protocol::U8Array; use noise_protocol::DH; @@ -53,3 +54,33 @@ pub fn gen_keys() -> (Sensitive<[u8; 32]>, [u8; 32]) { let publ = noise_rust_crypto::X25519::pubkey(&pri); (pri, publ) } + +pub struct Dual25519Keys { + pub x25519_priv: Sensitive<[u8; 32]>, + pub x25519_public: [u8; 32], + pub ed25519_priv: SecretKey, + pub ed25519_pub: PublicKey, +} + +impl Dual25519Keys { + pub fn generate() -> Self { + let mut x25519_priv = Sensitive::<[u8; 32]>::new(); + getrandom::getrandom(&mut *x25519_priv).expect("getrandom failed"); + + let ed25519_priv = SecretKey::from_bytes(&x25519_priv.as_slice()).unwrap(); + let ed25519_pub: PublicKey = (&ed25519_priv).into(); + + x25519_priv[0] &= 248; + x25519_priv[31] &= 127; + x25519_priv[31] |= 64; + + let x25519_public = noise_rust_crypto::X25519::pubkey(&x25519_priv); + + Self { + x25519_priv, + x25519_public, + ed25519_priv, + ed25519_pub, + } + } +} diff --git a/p2p-repo/src/errors.rs b/p2p-repo/src/errors.rs index b3ece75..935d74e 100644 --- a/p2p-repo/src/errors.rs +++ b/p2p-repo/src/errors.rs @@ -3,7 +3,7 @@ // This code is partly derived from work written by TG x Thoth from P2Pcollab. // Copyright 2022 TG x Thoth // Licensed under the Apache License, Version 2.0 -// +// // or the MIT license , // at your option. All files in the project carrying such // notice may not be copied, modified, or distributed except @@ -11,6 +11,8 @@ //! Errors +#[derive(Debug, Eq, PartialEq, Clone)] +#[repr(u16)] pub enum NgError { InvalidSignature, SerializationError, diff --git a/p2p-repo/src/types.rs b/p2p-repo/src/types.rs index bf28882..b9f5a0e 100644 --- a/p2p-repo/src/types.rs +++ b/p2p-repo/src/types.rs @@ -57,9 +57,12 @@ impl SymKey { } } -/// Curve25519 public key +/// Curve25519 public key Edwards form pub type Ed25519PubKey = [u8; 32]; +/// Curve25519 public key Montgomery form +pub type Mo25519PubKey = [u8; 32]; + /// Curve25519 private key pub type Ed25519PrivKey = [u8; 32]; diff --git a/p2p-repo/src/utils.rs b/p2p-repo/src/utils.rs index 64539c3..dd0d288 100644 --- a/p2p-repo/src/utils.rs +++ b/p2p-repo/src/utils.rs @@ -43,6 +43,24 @@ pub fn generate_null_keypair() -> (PrivKey, PubKey) { (priv_key, pub_key) } +pub fn keypair_from_ed(secret: SecretKey, public: PublicKey) -> (PrivKey, PubKey) { + // println!( + // "private key: ({}) {:?}", + // keypair.secret.as_bytes().len(), + // keypair.secret.as_bytes() + // ); + // println!( + // "public key: ({}) {:?}", + // keypair.public.as_bytes().len(), + // keypair.public.as_bytes() + // ); + let ed_priv_key = secret.to_bytes(); + let ed_pub_key = public.to_bytes(); + let priv_key = PrivKey::Ed25519PrivKey(ed_priv_key); + let pub_key = PubKey::Ed25519PubKey(ed_pub_key); + (priv_key, pub_key) +} + pub fn sign( author_privkey: PrivKey, author_pubkey: PubKey,