From c70f265ceda560a64b3854de43bad6ec553c2751 Mon Sep 17 00:00:00 2001 From: Evan Feenstra Date: Wed, 29 Jun 2022 16:28:38 -0700 Subject: [PATCH 1/6] crypter module using chacha20poly1305 for symmetric cipher --- Cargo.toml | 1 + crypter/Cargo.toml | 14 ++++++++++++++ crypter/src/lib.rs | 39 +++++++++++++++++++++++++++++++++++++++ sphinx-key/Cargo.toml | 2 ++ 4 files changed, 56 insertions(+) create mode 100644 crypter/Cargo.toml create mode 100644 crypter/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 97cce6e..4213dcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ exclude = [ "sphinx-key", + "crypter" ] [patch.crates-io] diff --git a/crypter/Cargo.toml b/crypter/Cargo.toml new file mode 100644 index 0000000..2d2b463 --- /dev/null +++ b/crypter/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "sphinx-key-crypter" +version = "0.1.0" +authors = ["Evan Feenstra "] +edition = "2018" + +[dependencies.lightning] +version = "0.0.108" +default-features = false +features = ["std", "grind_signatures"] + +[patch.crates-io] +lightning = { git = "https://github.com/Evanfeenstra/rust-lightning", branch = "v0.0.108-branch" } + diff --git a/crypter/src/lib.rs b/crypter/src/lib.rs new file mode 100644 index 0000000..1de86e6 --- /dev/null +++ b/crypter/src/lib.rs @@ -0,0 +1,39 @@ +use lightning::util::chacha20poly1305rfc::ChaCha20Poly1305RFC; + +pub fn test_chacha20poly1305() { + + let key = [0; 32]; + // 32 bytes key + // 12 byte nonce + let n: u64 = 123456; + let mut nonce = [0; 12]; + println!("chacha1"); + nonce[4..].copy_from_slice(&n.to_le_bytes()[..]); + println!("chacha2"); + let mut chacha = ChaCha20Poly1305RFC::new(&key, &nonce, &[0; 0]); + println!("chacha3"); + let mut tag = [0; 16]; + let plaintext = b"plaintext"; + let mut res = [0; 50]; + chacha.encrypt(plaintext, &mut res[0..plaintext.len()], &mut tag); + println!("chacha4 {:?}", res); + println!("tag {:?}", tag); + + let mut chacha2 = ChaCha20Poly1305RFC::new(&key, &nonce, &[0; 0]); + let mut dec = [0; 9]; + let ok = chacha2.decrypt(&res[0..9], &mut dec, &tag); + + println!("ok {}", ok); + println!("dec {:?}", dec); + println!("decrypted: {}", String::from_utf8_lossy(&dec[..])); +} + +#[cfg(test)] +mod tests { + use crate::test_chacha20poly1305; + + #[test] + fn find_solution_1_btc() { + test_chacha20poly1305(); + } +} \ No newline at end of file diff --git a/sphinx-key/Cargo.toml b/sphinx-key/Cargo.toml index 5d266b2..8c1f798 100644 --- a/sphinx-key/Cargo.toml +++ b/sphinx-key/Cargo.toml @@ -21,6 +21,7 @@ pingpong = [] [dependencies] esp-idf-sys = { version = "0.31.5", features = ["binstart"] } sphinx-key-signer = { path = "../signer", optional = true } +sphinx-key-crypter = { path = "../crypter" } embedded-svc = { version = "0.21.2" } esp-idf-svc = "0.41" esp-idf-hal = "0.37" @@ -36,6 +37,7 @@ serde_json = { version = "1.0.81", default-features = false } # updates the "rand" create to use esp RNG getrandom = { version = "0.2", git = "https://github.com/esp-rs-compat/getrandom.git" } secp256k1 = { git = "https://github.com/Evanfeenstra/rust-secp256k1", branch = "v0.22.0-new-rand" } +lightning = { git = "https://github.com/Evanfeenstra/rust-lightning", branch = "v0.0.108-branch" } [build-dependencies] embuild = "0.29" From cb95ab609a545a9877db6a26a440373d02bbdb01 Mon Sep 17 00:00:00 2001 From: Evan Feenstra Date: Fri, 1 Jul 2022 09:36:20 -0700 Subject: [PATCH 2/6] ecdh and chachapoly tests --- crypter/Cargo.toml | 9 ++++++ crypter/src/chacha.rs | 56 +++++++++++++++++++++++++++++++++++++ crypter/src/ecdh.rs | 47 +++++++++++++++++++++++++++++++ crypter/src/lib.rs | 65 ++++++++++++++++++++++--------------------- 4 files changed, 146 insertions(+), 31 deletions(-) create mode 100644 crypter/src/chacha.rs create mode 100644 crypter/src/ecdh.rs diff --git a/crypter/Cargo.toml b/crypter/Cargo.toml index 2d2b463..e21c893 100644 --- a/crypter/Cargo.toml +++ b/crypter/Cargo.toml @@ -4,11 +4,20 @@ version = "0.1.0" authors = ["Evan Feenstra "] edition = "2018" +[dependencies] +rand = "0.8" +anyhow = {version = "1", features = ["backtrace"]} +log = "0.4" +base64 = { version = "0.13.0" } +secp256k1 = { version = "0.22.0", features = ["std", "rand-std"] } + [dependencies.lightning] version = "0.0.108" default-features = false features = ["std", "grind_signatures"] [patch.crates-io] +getrandom = { version = "0.2", git = "https://github.com/esp-rs-compat/getrandom.git" } +secp256k1 = { git = "https://github.com/Evanfeenstra/rust-secp256k1", branch = "v0.22.0-new-rand" } lightning = { git = "https://github.com/Evanfeenstra/rust-lightning", branch = "v0.0.108-branch" } diff --git a/crypter/src/chacha.rs b/crypter/src/chacha.rs new file mode 100644 index 0000000..d0f0798 --- /dev/null +++ b/crypter/src/chacha.rs @@ -0,0 +1,56 @@ +use lightning::util::chacha20poly1305rfc::ChaCha20Poly1305RFC; +use anyhow::anyhow; + +pub const MSG_LEN: usize = 32; +pub const KEY_LEN: usize = 32; +pub const NONCE_END_LEN: usize = 8; +const TAG_LEN: usize = 16; +const CIPHER_LEN: usize = MSG_LEN + NONCE_END_LEN + TAG_LEN; + +pub fn encrypt(plaintext: [u8; MSG_LEN], key: [u8; KEY_LEN], nonce_end: [u8; NONCE_END_LEN]) -> anyhow::Result<[u8; CIPHER_LEN]> { + let mut nonce = [0; 4 + NONCE_END_LEN]; + nonce[4..].copy_from_slice(&nonce_end); + let mut chacha = ChaCha20Poly1305RFC::new(&key, &nonce, &[0; 0]); + let mut res = [0; MSG_LEN]; + let mut tag = [0; TAG_LEN]; + chacha.encrypt(&plaintext[..], &mut res[0..plaintext.len()], &mut tag); + let mut ret = [0; CIPHER_LEN]; + ret[..MSG_LEN].copy_from_slice(&res); + ret[MSG_LEN..MSG_LEN + NONCE_END_LEN].copy_from_slice(&nonce_end); + ret[MSG_LEN + NONCE_END_LEN..].copy_from_slice(&tag); + Ok(ret) +} + +pub fn decrypt(ciphertext: [u8; CIPHER_LEN], key: [u8; KEY_LEN]) -> anyhow::Result<[u8; MSG_LEN]> { + let mut nonce = [0; 4 + NONCE_END_LEN]; + nonce[4..].copy_from_slice(&ciphertext[MSG_LEN..MSG_LEN + NONCE_END_LEN]); + let mut tag = [0; TAG_LEN]; + tag.copy_from_slice(&ciphertext[MSG_LEN + NONCE_END_LEN..]); + let mut chacha2 = ChaCha20Poly1305RFC::new(&key, &nonce, &[0; 0]); + let mut dec = [0; MSG_LEN]; + let ok = chacha2.decrypt(&ciphertext[..MSG_LEN], &mut dec, &tag); + if ok { + Ok(dec) + } else { + Err(anyhow!("failed chacha authentication")) + } +} + +#[cfg(test)] +mod tests { + use crate::chacha::{decrypt, encrypt, MSG_LEN, KEY_LEN, NONCE_END_LEN}; + use rand::{rngs::OsRng, RngCore}; + + #[test] + fn test_chacha() -> anyhow::Result<()> { + let key = [9; KEY_LEN]; + let plaintext = [1; MSG_LEN]; + let mut nonce_end = [0; NONCE_END_LEN]; + OsRng.fill_bytes(&mut nonce_end); + let cipher = encrypt(plaintext, key, nonce_end)?; + let plain = decrypt(cipher, key)?; + assert_eq!(plaintext, plain); + Ok(()) + } + +} \ No newline at end of file diff --git a/crypter/src/ecdh.rs b/crypter/src/ecdh.rs new file mode 100644 index 0000000..8d998c1 --- /dev/null +++ b/crypter/src/ecdh.rs @@ -0,0 +1,47 @@ +use secp256k1::ecdh::SharedSecret; +use secp256k1::{SecretKey, PublicKey}; +use anyhow::Result; + +const PUBLIC_KEY_LEN: usize = 33; +const PRIVATE_KEY_LEN: usize = 32; +const SECRET_LEN: usize = 32; + +pub fn derive_shared_secret_from_slice(their_public_key: [u8; PUBLIC_KEY_LEN], my_private_key: [u8; PRIVATE_KEY_LEN]) -> Result<[u8; SECRET_LEN]> { + let public_key = PublicKey::from_slice(&their_public_key[..])?; + let private_key = SecretKey::from_slice(&my_private_key[..])?; + Ok(derive_shared_secret(&public_key, &private_key).secret_bytes()) +} + +pub fn derive_shared_secret(their_public_key: &PublicKey, my_private_key: &SecretKey) -> SharedSecret { + SharedSecret::new(their_public_key, my_private_key) +} + +#[cfg(test)] +mod tests { + use crate::ecdh::{derive_shared_secret, derive_shared_secret_from_slice}; + use rand::thread_rng; + use secp256k1::Secp256k1; + + #[test] + fn test_ecdh() -> anyhow::Result<()> { + let s = Secp256k1::new(); + let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); + let (sk2, pk2) = s.generate_keypair(&mut thread_rng()); + let sec1 = derive_shared_secret(&pk2, &sk1); + let sec2 = derive_shared_secret(&pk1, &sk2); + assert_eq!(sec1, sec2); + Ok(()) + } + + #[test] + fn test_ecdh_from_slice() -> anyhow::Result<()> { + let s = Secp256k1::new(); + let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); + let (sk2, pk2) = s.generate_keypair(&mut thread_rng()); + let sec1 = derive_shared_secret_from_slice(pk2.serialize(), sk1.secret_bytes())?; + let sec2 = derive_shared_secret_from_slice(pk1.serialize(), sk2.secret_bytes())?; + assert_eq!(sec1, sec2); + Ok(()) + } + +} \ No newline at end of file diff --git a/crypter/src/lib.rs b/crypter/src/lib.rs index 1de86e6..5e2ca49 100644 --- a/crypter/src/lib.rs +++ b/crypter/src/lib.rs @@ -1,39 +1,42 @@ -use lightning::util::chacha20poly1305rfc::ChaCha20Poly1305RFC; +pub mod chacha; +pub mod ecdh; -pub fn test_chacha20poly1305() { - - let key = [0; 32]; - // 32 bytes key - // 12 byte nonce - let n: u64 = 123456; - let mut nonce = [0; 12]; - println!("chacha1"); - nonce[4..].copy_from_slice(&n.to_le_bytes()[..]); - println!("chacha2"); - let mut chacha = ChaCha20Poly1305RFC::new(&key, &nonce, &[0; 0]); - println!("chacha3"); - let mut tag = [0; 16]; - let plaintext = b"plaintext"; - let mut res = [0; 50]; - chacha.encrypt(plaintext, &mut res[0..plaintext.len()], &mut tag); - println!("chacha4 {:?}", res); - println!("tag {:?}", tag); - - let mut chacha2 = ChaCha20Poly1305RFC::new(&key, &nonce, &[0; 0]); - let mut dec = [0; 9]; - let ok = chacha2.decrypt(&res[0..9], &mut dec, &tag); - - println!("ok {}", ok); - println!("dec {:?}", dec); - println!("decrypted: {}", String::from_utf8_lossy(&dec[..])); -} #[cfg(test)] mod tests { - use crate::test_chacha20poly1305; + use crate::chacha::{decrypt, encrypt, MSG_LEN, NONCE_END_LEN}; + use crate::ecdh::derive_shared_secret_from_slice; + use rand::{rngs::OsRng, RngCore, thread_rng}; + use secp256k1::Secp256k1; #[test] - fn find_solution_1_btc() { - test_chacha20poly1305(); + fn test_crypter() -> anyhow::Result<()> { + // two keypairs + let s = Secp256k1::new(); + let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); + let (sk2, pk2) = s.generate_keypair(&mut thread_rng()); + + // derive shared secrets + let sec1 = derive_shared_secret_from_slice( + pk2.serialize(), sk1.secret_bytes() + )?; + let sec2 = derive_shared_secret_from_slice( + pk1.serialize(), sk2.secret_bytes() + )?; + assert_eq!(sec1, sec2); + + // encrypt plaintext with sec1 + let plaintext = [1; MSG_LEN]; + let mut nonce_end = [0; NONCE_END_LEN]; + OsRng.fill_bytes(&mut nonce_end); + let cipher = encrypt(plaintext, sec1, nonce_end)?; + + // decrypt with sec2 + let plain = decrypt(cipher, sec2)?; + assert_eq!(plaintext, plain); + + println!("PLAINTEXT MATCHES!"); + Ok(()) } + } \ No newline at end of file From c8e6e834e9ac213152a26a5aa3e1280db4aa202a Mon Sep 17 00:00:00 2001 From: Evan Feenstra Date: Fri, 1 Jul 2022 10:39:14 -0700 Subject: [PATCH 3/6] config bin to test seed encryption to device --- .gitignore | 3 +- Cargo.toml | 1 + crypter/src/ecdh.rs | 6 ++-- crypter/src/lib.rs | 14 +++----- tester/Cargo.toml | 12 +++++++ tester/src/config.rs | 86 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 109 insertions(+), 13 deletions(-) create mode 100644 tester/src/config.rs diff --git a/.gitignore b/.gitignore index ca2e8d2..fbad06e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ Cargo.lock .DS_Store sphinx-key/Cargo.lock notes.md -test-flash \ No newline at end of file +test-flash +.env \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 4213dcc..6108ea6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,3 +17,4 @@ exclude = [ # updates the "rand" create to use esp RNG getrandom = { version = "0.2", git = "https://github.com/esp-rs-compat/getrandom.git" } secp256k1 = { git = "https://github.com/Evanfeenstra/rust-secp256k1", branch = "v0.22.0-new-rand" } +lightning = { git = "https://github.com/Evanfeenstra/rust-lightning", branch = "v0.0.108-branch" } diff --git a/crypter/src/ecdh.rs b/crypter/src/ecdh.rs index 8d998c1..cc55641 100644 --- a/crypter/src/ecdh.rs +++ b/crypter/src/ecdh.rs @@ -2,9 +2,9 @@ use secp256k1::ecdh::SharedSecret; use secp256k1::{SecretKey, PublicKey}; use anyhow::Result; -const PUBLIC_KEY_LEN: usize = 33; -const PRIVATE_KEY_LEN: usize = 32; -const SECRET_LEN: usize = 32; +pub const PUBLIC_KEY_LEN: usize = 33; +pub const PRIVATE_KEY_LEN: usize = 32; +pub const SECRET_LEN: usize = 32; pub fn derive_shared_secret_from_slice(their_public_key: [u8; PUBLIC_KEY_LEN], my_private_key: [u8; PRIVATE_KEY_LEN]) -> Result<[u8; SECRET_LEN]> { let public_key = PublicKey::from_slice(&their_public_key[..])?; diff --git a/crypter/src/lib.rs b/crypter/src/lib.rs index 5e2ca49..222b5ad 100644 --- a/crypter/src/lib.rs +++ b/crypter/src/lib.rs @@ -1,12 +1,13 @@ pub mod chacha; pub mod ecdh; +pub use secp256k1; #[cfg(test)] mod tests { use crate::chacha::{decrypt, encrypt, MSG_LEN, NONCE_END_LEN}; use crate::ecdh::derive_shared_secret_from_slice; - use rand::{rngs::OsRng, RngCore, thread_rng}; + use rand::{rngs::OsRng, thread_rng, RngCore}; use secp256k1::Secp256k1; #[test] @@ -17,12 +18,8 @@ mod tests { let (sk2, pk2) = s.generate_keypair(&mut thread_rng()); // derive shared secrets - let sec1 = derive_shared_secret_from_slice( - pk2.serialize(), sk1.secret_bytes() - )?; - let sec2 = derive_shared_secret_from_slice( - pk1.serialize(), sk2.secret_bytes() - )?; + let sec1 = derive_shared_secret_from_slice(pk2.serialize(), sk1.secret_bytes())?; + let sec2 = derive_shared_secret_from_slice(pk1.serialize(), sk2.secret_bytes())?; assert_eq!(sec1, sec2); // encrypt plaintext with sec1 @@ -38,5 +35,4 @@ mod tests { println!("PLAINTEXT MATCHES!"); Ok(()) } - -} \ No newline at end of file +} diff --git a/tester/Cargo.toml b/tester/Cargo.toml index 7b767e0..03b36c0 100644 --- a/tester/Cargo.toml +++ b/tester/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] sphinx-key-signer = { path = "../signer" } sphinx-key-parser = { path = "../parser" } +sphinx-key-crypter = { path = "../crypter" } vls-protocol = { git = "https://gitlab.com/Evanfeenstra/validating-lightning-signer", branch = "partial-std" } vls-protocol-signer = { git = "https://gitlab.com/Evanfeenstra/validating-lightning-signer", branch = "partial-std", default-features = false, features = ["std", "secp-lowmemory"] } # vls-protocol = { path = "../../../evanf/validating-lightning-signer/vls-protocol" } @@ -20,3 +21,14 @@ clap = "3.2.6" clap_derive = "3.2.6" fern = { version = "0.6", features = ["colored"] } chrono = "0.4" +rand = "0.8" +reqwest = { version = "0.11.11", features = ["json"] } +hex = "0.4.3" +serde = { version = "1.0.101", features = ["derive"] } +serde_json = "1.0" +urlencoding = "2.1.0" +dotenv = "0.15.0" + +[[bin]] +name = "config" +path = "src/config.rs" diff --git a/tester/src/config.rs b/tester/src/config.rs new file mode 100644 index 0000000..61bb0c6 --- /dev/null +++ b/tester/src/config.rs @@ -0,0 +1,86 @@ +use rand::{rngs::OsRng, thread_rng, RngCore}; +use serde::{Deserialize, Serialize}; +use sphinx_key_crypter::chacha::{encrypt, MSG_LEN, NONCE_END_LEN}; +use sphinx_key_crypter::ecdh::{derive_shared_secret_from_slice, PUBLIC_KEY_LEN}; +use sphinx_key_crypter::secp256k1::Secp256k1; +use std::convert::TryInto; +use std::time::Duration; +use dotenv::dotenv; +use std::env; + +const URL: &str = "http://192.168.71.1/"; + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct EcdhBody { + pub pubkey: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ConfigBody { + pub seed: String, + pub ssid: String, + pub pass: String, + pub broker: String, +} +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct ConfigResponse { + pub success: bool, +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + dotenv().ok(); + + let ssid: String = env::var("SSID").expect("no ssid"); + let pass: String = env::var("PASS").expect("no pass"); + let broker: String = env::var("BROKER").expect("no broker"); + + let s = Secp256k1::new(); + let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); + + let client = reqwest::Client::builder() + .timeout(Duration::from_secs(10)) + .build() + .expect("couldnt build reqwest client"); + + let body = EcdhBody { + pubkey: hex::encode(pk1.serialize()), + }; + let res = client + .post(format!("{}{}", URL, "ecdh")) + .json(&body) + .header("Content-Type", "application/json") + .send() + .await?; + let their_ecdh: EcdhBody = res.json().await?; + let their_pk = hex::decode(their_ecdh.pubkey)?; + + let their_pk_bytes: [u8; PUBLIC_KEY_LEN] = their_pk[..PUBLIC_KEY_LEN].try_into()?; + let shared_secret = derive_shared_secret_from_slice(their_pk_bytes, sk1.secret_bytes())?; + + let plaintext = [1; MSG_LEN]; + let mut nonce_end = [0; NONCE_END_LEN]; + OsRng.fill_bytes(&mut nonce_end); + let cipher = encrypt(plaintext, shared_secret, nonce_end)?; + + let cipher_seed = hex::encode(cipher); + let config = ConfigBody { + seed: cipher_seed, + ssid, pass, broker, + }; + + let conf_string = serde_json::to_string(&config)?; + let conf_encoded = urlencoding::encode(&conf_string).to_owned(); + + let res2 = client + .post(format!("{}{}{}", URL, "/config?config=", conf_encoded)) + .send() + .await?; + let conf_res: ConfigResponse = res2.json().await?; + + if conf_res.success { + println!("SUCCESS!") + } + + Ok(()) +} From 5bb4a990d24486addf88113dd3f18d0f90b4ba57 Mon Sep 17 00:00:00 2001 From: Evan Feenstra Date: Fri, 1 Jul 2022 13:19:11 -0700 Subject: [PATCH 4/6] encrypted seed to hardware, configDTO, tested config bin that takes params from .env --- README.md | 27 +++++++++++++++++++ crypter/src/chacha.rs | 19 +++++++------ crypter/src/lib.rs | 2 +- sphinx-key/Cargo.toml | 1 + sphinx-key/newseed.sh | 5 ++++ sphinx-key/run.sh | 7 +++++ sphinx-key/src/conn/http.rs | 50 ++++++++++++++++++++++++++++------- sphinx-key/src/core/config.rs | 34 +++++++++++++----------- tester/src/config.rs | 16 +++++------ 9 files changed, 120 insertions(+), 41 deletions(-) create mode 100755 sphinx-key/newseed.sh create mode 100755 sphinx-key/run.sh diff --git a/README.md b/README.md index 5c89d79..8f7f049 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,25 @@ ls /dev/cu.* espmonitor /dev/tty.usbserial-1420 ``` +### configure the hardware + +make a seed: `./sphinx-key/newseed.sh` + +make a `.env` file like: + +``` +SSID=my_ssid +PASS=my_wifi_password +BROKER=my_ip:1883 +SEED=my_seed +``` + +connect to the `sphinxkey` network on your computer + +`cargo run --bin config` + +This will encrypt your seed and send to the hardware, along with your home wifi information and broker address + # dependencies `cd sphinx-key` @@ -98,3 +117,11 @@ esptool.py --chip esp32c3 elf2image target/riscv32imc-esp-espidf/release/sphinx- esptool.py --chip esp32c3 -p /dev/tty.usbserial-1420 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x10000 target/riscv32imc-esp-espidf/release/sphinx-key.bin espmonitor /dev/tty.usbserial-1420 + +### config + +./sphinx-key/rando.sh + +make your .env + +cargo run --bin config \ No newline at end of file diff --git a/crypter/src/chacha.rs b/crypter/src/chacha.rs index d0f0798..fd03189 100644 --- a/crypter/src/chacha.rs +++ b/crypter/src/chacha.rs @@ -1,13 +1,17 @@ -use lightning::util::chacha20poly1305rfc::ChaCha20Poly1305RFC; use anyhow::anyhow; +use lightning::util::chacha20poly1305rfc::ChaCha20Poly1305RFC; -pub const MSG_LEN: usize = 32; +pub const MSG_LEN: usize = 32; pub const KEY_LEN: usize = 32; pub const NONCE_END_LEN: usize = 8; -const TAG_LEN: usize = 16; -const CIPHER_LEN: usize = MSG_LEN + NONCE_END_LEN + TAG_LEN; +pub const TAG_LEN: usize = 16; +pub const CIPHER_LEN: usize = MSG_LEN + NONCE_END_LEN + TAG_LEN; -pub fn encrypt(plaintext: [u8; MSG_LEN], key: [u8; KEY_LEN], nonce_end: [u8; NONCE_END_LEN]) -> anyhow::Result<[u8; CIPHER_LEN]> { +pub fn encrypt( + plaintext: [u8; MSG_LEN], + key: [u8; KEY_LEN], + nonce_end: [u8; NONCE_END_LEN], +) -> anyhow::Result<[u8; CIPHER_LEN]> { let mut nonce = [0; 4 + NONCE_END_LEN]; nonce[4..].copy_from_slice(&nonce_end); let mut chacha = ChaCha20Poly1305RFC::new(&key, &nonce, &[0; 0]); @@ -38,7 +42,7 @@ pub fn decrypt(ciphertext: [u8; CIPHER_LEN], key: [u8; KEY_LEN]) -> anyhow::Resu #[cfg(test)] mod tests { - use crate::chacha::{decrypt, encrypt, MSG_LEN, KEY_LEN, NONCE_END_LEN}; + use crate::chacha::{decrypt, encrypt, KEY_LEN, MSG_LEN, NONCE_END_LEN}; use rand::{rngs::OsRng, RngCore}; #[test] @@ -52,5 +56,4 @@ mod tests { assert_eq!(plaintext, plain); Ok(()) } - -} \ No newline at end of file +} diff --git a/crypter/src/lib.rs b/crypter/src/lib.rs index 222b5ad..e81c883 100644 --- a/crypter/src/lib.rs +++ b/crypter/src/lib.rs @@ -7,7 +7,7 @@ pub use secp256k1; mod tests { use crate::chacha::{decrypt, encrypt, MSG_LEN, NONCE_END_LEN}; use crate::ecdh::derive_shared_secret_from_slice; - use rand::{rngs::OsRng, thread_rng, RngCore}; + use secp256k1::rand::{rngs::OsRng, thread_rng, RngCore}; use secp256k1::Secp256k1; #[test] diff --git a/sphinx-key/Cargo.toml b/sphinx-key/Cargo.toml index 8c1f798..8dc89c1 100644 --- a/sphinx-key/Cargo.toml +++ b/sphinx-key/Cargo.toml @@ -32,6 +32,7 @@ url = "2" serde_urlencoded = "0.7.1" serde = { version = "1.0.137", default-features = false } serde_json = { version = "1.0.81", default-features = false } +hex = "0.4.3" [patch.crates-io] # updates the "rand" create to use esp RNG diff --git a/sphinx-key/newseed.sh b/sphinx-key/newseed.sh new file mode 100755 index 0000000..4a41e14 --- /dev/null +++ b/sphinx-key/newseed.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +n=32 + +hexdump -vn "$n" -e ' /1 "%02x"' /dev/urandom ; echo \ No newline at end of file diff --git a/sphinx-key/run.sh b/sphinx-key/run.sh new file mode 100755 index 0000000..d447cd8 --- /dev/null +++ b/sphinx-key/run.sh @@ -0,0 +1,7 @@ +cargo +nightly build --release + +esptool.py --chip esp32c3 elf2image target/riscv32imc-esp-espidf/release/sphinx-key + +esptool.py --chip esp32c3 -p /dev/tty.usbserial-1420 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x10000 target/riscv32imc-esp-espidf/release/sphinx-key.bin + +espmonitor /dev/tty.usbserial-1420 \ No newline at end of file diff --git a/sphinx-key/src/conn/http.rs b/sphinx-key/src/conn/http.rs index f21cc1c..3b92762 100644 --- a/sphinx-key/src/conn/http.rs +++ b/sphinx-key/src/conn/http.rs @@ -1,32 +1,64 @@ use crate::conn::html; -use crate::core::config::Config; +use crate::core::config::{Config, ConfigDTO}; +use serde::Deserialize; +use std::convert::TryInto; +use std::sync::{Arc, Condvar, Mutex}; + +use embedded_svc::httpd::registry::Registry; use embedded_svc::httpd::*; use esp_idf_svc::httpd as idf; -use std::sync::{Condvar, Mutex, Arc}; -use embedded_svc::httpd::registry::Registry; -use serde::Deserialize; + +use sphinx_key_crypter::chacha::{decrypt, CIPHER_LEN}; +use sphinx_key_crypter::ecdh::{derive_shared_secret_from_slice, PUBLIC_KEY_LEN}; +use sphinx_key_crypter::secp256k1::rand::thread_rng; +use sphinx_key_crypter::secp256k1::Secp256k1; +#[derive(Clone, Debug, Deserialize)] +pub struct Ecdh { + pub pubkey: String, +} #[derive(Clone, Debug, Deserialize)] pub struct Params { - pub config: String + pub config: String, } #[allow(unused_variables)] pub fn config_server(mutex: Arc<(Mutex>, Condvar)>) -> Result { + let s = Secp256k1::new(); + let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); + let pk_hex = hex::encode(pk1.serialize()); let server = idf::ServerRegistry::new() .at("/") .get(|_| Ok(html::HTML.into()))? + .at("/ecdh") + .get(move |_| Ok(format!("{{\"pubkey\":\"{}\"}}", pk_hex).to_owned().into()))? .at("/config") .post(move |request| { - let bod = &request.query_string() + let bod = &request + .query_string() .ok_or(anyhow::anyhow!("failed to parse query string"))?; println!("bod {:?}", bod); let params = serde_urlencoded::from_str::(bod)?; - let conf = serde_json::from_str::(¶ms.config)?; - + let dto = serde_json::from_str::(¶ms.config)?; + + let their_pk = hex::decode(dto.pubkey)?; + let their_pk_bytes: [u8; PUBLIC_KEY_LEN] = their_pk[..PUBLIC_KEY_LEN].try_into()?; + let shared_secret = + derive_shared_secret_from_slice(their_pk_bytes, sk1.secret_bytes())?; + // decrypt seed + let cipher_seed = hex::decode(dto.seed)?; + let cipher: [u8; CIPHER_LEN] = cipher_seed[..CIPHER_LEN].try_into()?; + let seed = decrypt(cipher, shared_secret)?; + + let conf = Config { + broker: dto.broker, + ssid: dto.ssid, + pass: dto.pass, + seed: seed, + }; let mut wait = mutex.0.lock().unwrap(); *wait = Some(conf); mutex.1.notify_one(); @@ -34,4 +66,4 @@ pub fn config_server(mutex: Arc<(Mutex>, Condvar)>) -> Result, config: &Config) -> Result> { - let wifi = conn::wifi::start_client( - default_nvs, - config - )?; +pub fn start_wifi_client(default_nvs: Arc, config: &Config) -> Result> { + let wifi = conn::wifi::start_client(default_nvs, config)?; println!("CLIENT CONNECTED!!!!!! {:?}", wifi.get_status()); Ok(wifi) } -pub fn start_config_server_and_wait(default_nvs: Arc) -> Result<(Box, Config)> { - +pub fn start_config_server_and_wait( + default_nvs: Arc, +) -> Result<(Box, Config)> { let mutex = Arc::new((Mutex::new(None), Condvar::new())); #[allow(clippy::redundant_clone)] #[allow(unused_mut)] - let mut wifi = conn::wifi::start_access_point( - default_nvs.clone(), - )?; + let mut wifi = conn::wifi::start_access_point(default_nvs.clone())?; let httpd = conn::http::config_server(mutex.clone()); - let mut wait = mutex.0.lock().unwrap(); let config: &Config = loop { @@ -67,4 +71,4 @@ pub fn start_config_server_and_wait(default_nvs: Arc) -> Result<( // thread::sleep(Duration::from_secs(1)); println!("===> config! {:?}", config); Ok((wifi, config.clone())) -} \ No newline at end of file +} diff --git a/tester/src/config.rs b/tester/src/config.rs index 61bb0c6..19984bb 100644 --- a/tester/src/config.rs +++ b/tester/src/config.rs @@ -21,6 +21,7 @@ pub struct ConfigBody { pub ssid: String, pub pass: String, pub broker: String, + pub pubkey: String, // for ecdh } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct ConfigResponse { @@ -34,6 +35,9 @@ async fn main() -> anyhow::Result<()> { let ssid: String = env::var("SSID").expect("no ssid"); let pass: String = env::var("PASS").expect("no pass"); let broker: String = env::var("BROKER").expect("no broker"); + let seed_string: String = env::var("SEED").expect("no seed"); + let seed: [u8; MSG_LEN] = hex::decode(seed_string)?[..MSG_LEN].try_into()?; + println!("seed {:?}", seed); let s = Secp256k1::new(); let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); @@ -43,12 +47,8 @@ async fn main() -> anyhow::Result<()> { .build() .expect("couldnt build reqwest client"); - let body = EcdhBody { - pubkey: hex::encode(pk1.serialize()), - }; let res = client - .post(format!("{}{}", URL, "ecdh")) - .json(&body) + .get(format!("{}{}", URL, "ecdh")) .header("Content-Type", "application/json") .send() .await?; @@ -58,22 +58,22 @@ async fn main() -> anyhow::Result<()> { let their_pk_bytes: [u8; PUBLIC_KEY_LEN] = their_pk[..PUBLIC_KEY_LEN].try_into()?; let shared_secret = derive_shared_secret_from_slice(their_pk_bytes, sk1.secret_bytes())?; - let plaintext = [1; MSG_LEN]; let mut nonce_end = [0; NONCE_END_LEN]; OsRng.fill_bytes(&mut nonce_end); - let cipher = encrypt(plaintext, shared_secret, nonce_end)?; + let cipher = encrypt(seed, shared_secret, nonce_end)?; let cipher_seed = hex::encode(cipher); let config = ConfigBody { seed: cipher_seed, ssid, pass, broker, + pubkey: hex::encode(pk1.serialize()), }; let conf_string = serde_json::to_string(&config)?; let conf_encoded = urlencoding::encode(&conf_string).to_owned(); let res2 = client - .post(format!("{}{}{}", URL, "/config?config=", conf_encoded)) + .post(format!("{}{}{}", URL, "config?config=", conf_encoded)) .send() .await?; let conf_res: ConfigResponse = res2.json().await?; From c0d2a813afcfd5780df5bc437975936d44df0c32 Mon Sep 17 00:00:00 2001 From: Evan Feenstra Date: Fri, 1 Jul 2022 17:11:23 -0700 Subject: [PATCH 5/6] add network to config bin and NVS storage --- README.md | 1 + sphinx-key/src/conn/http.rs | 1 + sphinx-key/src/core/config.rs | 2 ++ sphinx-key/src/main.rs | 54 ++++++++++++++++------------------- tester/src/config.rs | 9 ++++-- 5 files changed, 36 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 8f7f049..8b6d851 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ SSID=my_ssid PASS=my_wifi_password BROKER=my_ip:1883 SEED=my_seed +NETWORK=regtest ``` connect to the `sphinxkey` network on your computer diff --git a/sphinx-key/src/conn/http.rs b/sphinx-key/src/conn/http.rs index 3b92762..4f60ea0 100644 --- a/sphinx-key/src/conn/http.rs +++ b/sphinx-key/src/conn/http.rs @@ -57,6 +57,7 @@ pub fn config_server(mutex: Arc<(Mutex>, Condvar)>) -> Result = option_env!("NETWORK"); - fn main() -> Result<()> { - // Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once, // or else some patches to the runtime implemented by esp-idf-sys might not link properly. esp_idf_sys::link_patches(); - let network: Network = if let Some(n) = NETWORK { - match n { - "bitcoin" => Network::Bitcoin, - "mainnet" => Network::Bitcoin, - "testnet" => Network::Testnet, - "signet" => Network::Signet, - "regtest" => Network::Regtest, - _ => Network::Regtest, - } - } else { - Network::Regtest - }; - esp_idf_svc::log::EspLogger::initialize_default(); thread::sleep(Duration::from_secs(1)); - log::info!("Network set to {:?}", network); let peripherals = Peripherals::take().unwrap(); let pins = peripherals.pins; @@ -63,10 +46,14 @@ fn main() -> Result<()> { sd_card(peripherals.spi2); let default_nvs = Arc::new(EspDefaultNvs::new()?); - let mut store = EspNvsStorage::new_default(default_nvs.clone(), "sphinx", true).expect("no storage"); + let mut store = + EspNvsStorage::new_default(default_nvs.clone(), "sphinx", true).expect("no storage"); let existing: Option = store.get("config").expect("failed"); if let Some(exist) = existing { - println!("=============> START CLIENT NOW <============== {:?}", exist); + println!( + "=============> START CLIENT NOW <============== {:?}", + exist + ); // store.remove("config").expect("couldnt remove config"); led_tx.send(Status::ConnectingToWifi).unwrap(); let _wifi = start_wifi_client(default_nvs.clone(), &exist)?; @@ -77,17 +64,26 @@ fn main() -> Result<()> { // _conn needs to stay in scope or its dropped let (mqtt, connection) = conn::mqtt::make_client(&exist.broker, CLIENT_ID)?; let mqtt_client = conn::mqtt::start_listening(mqtt, connection, tx)?; - // this blocks forever... the "main thread" log::info!(">>>>>>>>>>> blocking forever..."); let do_log = true; + let network = match exist.network.as_str() { + "bitcoin" => Network::Bitcoin, + "mainnet" => Network::Bitcoin, + "testnet" => Network::Testnet, + "signet" => Network::Signet, + "regtest" => Network::Regtest, + _ => Network::Regtest, + }; + log::info!("Network set to {:?}", network); make_event_loop(mqtt_client, rx, network, do_log, led_tx)?; - } else { led_tx.send(Status::WifiAccessPoint).unwrap(); println!("=============> START SERVER NOW AND WAIT <=============="); if let Ok((wifi, config)) = start_config_server_and_wait(default_nvs.clone()) { - store.put("config", &config).expect("could not store config"); + store + .put("config", &config) + .expect("could not store config"); println!("CONFIG SAVED"); drop(wifi); thread::sleep(Duration::from_secs(1)); diff --git a/tester/src/config.rs b/tester/src/config.rs index 19984bb..7665d9f 100644 --- a/tester/src/config.rs +++ b/tester/src/config.rs @@ -22,6 +22,7 @@ pub struct ConfigBody { pub pass: String, pub broker: String, pub pubkey: String, // for ecdh + pub network: String, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct ConfigResponse { @@ -37,7 +38,11 @@ async fn main() -> anyhow::Result<()> { let broker: String = env::var("BROKER").expect("no broker"); let seed_string: String = env::var("SEED").expect("no seed"); let seed: [u8; MSG_LEN] = hex::decode(seed_string)?[..MSG_LEN].try_into()?; - println!("seed {:?}", seed); + let network: String = env::var("NETWORK").unwrap_or("regtest".to_string()); + if !(network == "bitcoin" || network == "mainnet" || network == "testnet" || network == "signet" || network == "regtest") { + panic!("invalid network string"); + } + println!("network {:?}", network); let s = Secp256k1::new(); let (sk1, pk1) = s.generate_keypair(&mut thread_rng()); @@ -65,7 +70,7 @@ async fn main() -> anyhow::Result<()> { let cipher_seed = hex::encode(cipher); let config = ConfigBody { seed: cipher_seed, - ssid, pass, broker, + ssid, pass, broker, network, pubkey: hex::encode(pk1.serialize()), }; From 0c9b9471af6b4cdd087699bb15566145db2405d7 Mon Sep 17 00:00:00 2001 From: Evan Feenstra Date: Tue, 5 Jul 2022 11:03:14 -0700 Subject: [PATCH 6/6] Hsmd2 init msg constructed on hardware itself, broker does not wait for init reply to being --- README.md | 4 ++- broker/src/main.rs | 21 ------------- signer/src/lib.rs | 3 +- sphinx-key/src/core/events.rs | 55 ++++++++++++++++++----------------- sphinx-key/src/core/init.rs | 20 +++++++++++++ sphinx-key/src/core/mod.rs | 1 + sphinx-key/src/main.rs | 4 +-- 7 files changed, 57 insertions(+), 51 deletions(-) create mode 100644 sphinx-key/src/core/init.rs diff --git a/README.md b/README.md index 8b6d851..5afdec5 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,9 @@ Find the path to your `riscv32-esp-elf-gcc` binary within the `.embuild` dir: ### flash release -`espflash target/riscv32imc-esp-espidf/release/sphinx-key --monitor` +`esptool.py --chip esp32c3 elf2image target/riscv32imc-esp-espidf/release/sphinx-key` + +`esptool.py --chip esp32c3 -p /dev/tty.usbserial-1420 -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 4MB 0x10000 target/riscv32imc-esp-espidf/release/sphinx-key.bin` ### monitor diff --git a/broker/src/main.rs b/broker/src/main.rs index 4830fff..57cba59 100644 --- a/broker/src/main.rs +++ b/broker/src/main.rs @@ -9,7 +9,6 @@ mod util; use crate::chain_tracker::MqttSignerPort; use crate::mqtt::start_broker; use crate::unix_fd::SignerLoop; -use bitcoin::Network; use clap::{arg, App, AppSettings, Arg}; use std::env; use std::sync::Arc; @@ -54,26 +53,9 @@ fn main() -> anyhow::Result<()> { .arg(arg!(--"log-io" "ignored dev flag")) .arg(arg!(--version "show a dummy version")) .arg(arg!(--test "run a test against the embedded device")) - .arg( - Arg::new("network") - .help("bitcoin network") - .long("network") - .value_parser(["regtest", "signet", "testnet", "mainnet", "bitcoin"]) - .default_value("regtest"), - ); let matches = app.get_matches(); - let network_string: &String = matches.get_one("network").expect("expected a network"); - let network: Network = match network_string.as_str() { - "bitcoin" => Network::Bitcoin, - "mainnet" => Network::Bitcoin, - "testnet" => Network::Testnet, - "signet" => Network::Signet, - "regtest" => Network::Regtest, - _ => Network::Regtest, - }; - if matches.is_present("version") { // Pretend to be the right version, given to us by an env var let version = @@ -82,7 +64,6 @@ fn main() -> anyhow::Result<()> { return Ok(()); } - log::info!("NETWORK: {}", network.to_string()); if matches.is_present("test") { run_test::run_test(); return Ok(()); @@ -98,8 +79,6 @@ fn main() -> anyhow::Result<()> { log::info!("=> connection status: {}", status); assert_eq!(status, true, "expected connected = true"); // runtime.block_on(async { - init::blocking_connect(tx.clone(), network); - log::info!("=====> sent seed!"); if let Ok(btc_url) = env::var("BITCOIND_RPC_URL") { let signer_port = MqttSignerPort::new(tx.clone()); diff --git a/signer/src/lib.rs b/signer/src/lib.rs index 69d11e7..e949908 100644 --- a/signer/src/lib.rs +++ b/signer/src/lib.rs @@ -1,14 +1,15 @@ use lightning_signer::persist::{DummyPersister, Persist}; // use lightning_signer::Arc; -use sphinx_key_parser::MsgDriver; use std::sync::Arc; use vls_protocol::model::PubKey; use vls_protocol::msgs::{self, read_serial_request_header, write_serial_response_header, Message}; use vls_protocol::serde_bolt::WireString; use vls_protocol_signer::handler::{Handler, RootHandler}; + pub use vls_protocol_signer::lightning_signer; pub use vls_protocol_signer::lightning_signer::bitcoin::Network; pub use vls_protocol_signer::vls_protocol; +pub use sphinx_key_parser::MsgDriver; pub struct InitResponse { pub root_handler: RootHandler, diff --git a/sphinx-key/src/core/events.rs b/sphinx-key/src/core/events.rs index aa8ce09..b19d668 100644 --- a/sphinx-key/src/core/events.rs +++ b/sphinx-key/src/core/events.rs @@ -1,4 +1,6 @@ use crate::conn::mqtt::{QOS, RETURN_TOPIC, TOPIC}; +use crate::core::init::make_init_msg; + use sphinx_key_signer::vls_protocol::model::PubKey; use sphinx_key_signer::{self, InitResponse}; use sphinx_key_signer::lightning_signer::bitcoin::Network; @@ -36,35 +38,35 @@ pub fn make_event_loop( rx: mpsc::Receiver, network: Network, do_log: bool, - led_tx: mpsc::Sender + led_tx: mpsc::Sender, + seed: [u8; 32] ) -> Result<()> { - // initialize the RootHandler - let root_handler = loop { - if let Ok(event) = rx.recv() { - match event { - Event::Connected => { - log::info!("SUBSCRIBE to {}", TOPIC); - mqtt.subscribe(TOPIC, QOS) - .expect("could not MQTT subscribe"); - led_tx.send(Status::Connected).unwrap(); - } - Event::Message(ref msg_bytes) => { - let InitResponse { - root_handler, - init_reply, - } = sphinx_key_signer::init(msg_bytes.clone(), network).expect("failed to init signer"); - mqtt.publish(RETURN_TOPIC, QOS, false, init_reply) - .expect("could not publish init response"); - break root_handler; - } - Event::Disconnected => { - led_tx.send(Status::ConnectingToMqtt).unwrap(); - log::info!("GOT an early Event::Disconnected msg!"); - } + while let Ok(event) = rx.recv() { + match event { + Event::Connected => { + log::info!("SUBSCRIBE to {}", TOPIC); + mqtt.subscribe(TOPIC, QOS) + .expect("could not MQTT subscribe"); + led_tx.send(Status::Connected).unwrap(); + break; + } + Event::Message(ref _msg_bytes) => { + panic!("should not be a message before connection"); + } + Event::Disconnected => { + led_tx.send(Status::ConnectingToMqtt).unwrap(); + log::info!("GOT an early Event::Disconnected msg!"); } } - }; + } + // initialize the RootHandler + let init_msg = make_init_msg(network, seed).expect("failed to make init msg"); + let InitResponse { + root_handler, + init_reply: _, + } = sphinx_key_signer::init(init_msg, network).expect("failed to init signer"); + // signing loop let dummy_peer = PubKey([0; 33]); while let Ok(event) = rx.recv() { @@ -105,7 +107,8 @@ pub fn make_event_loop( rx: mpsc::Receiver, _network: Network, do_log: bool, - led_tx: mpsc::Sender + led_tx: mpsc::Sender, + _seed: [u8; 32] ) -> Result<()> { log::info!("About to subscribe to the mpsc channel"); while let Ok(event) = rx.recv() { diff --git a/sphinx-key/src/core/init.rs b/sphinx-key/src/core/init.rs new file mode 100644 index 0000000..b13cd7d --- /dev/null +++ b/sphinx-key/src/core/init.rs @@ -0,0 +1,20 @@ +use sphinx_key_signer::MsgDriver; +use sphinx_key_signer::vls_protocol::model::Secret; +use sphinx_key_signer::vls_protocol::{msgs, serde_bolt::WireString}; +use sphinx_key_signer::lightning_signer::bitcoin::Network; + +pub fn make_init_msg(network: Network, seed: [u8; 32]) -> anyhow::Result> { + let allowlist = Vec::new(); + log::info!("allowlist {:?} seed {:?}", allowlist, seed); + let init = msgs::HsmdInit2 { + derivation_style: 0, + network_name: WireString(network.to_string().as_bytes().to_vec()), + dev_seed: Some(Secret(seed)), + dev_allowlist: allowlist, + }; + let sequence = 0; + let mut md = MsgDriver::new_empty(); + msgs::write_serial_request_header(&mut md, sequence, 0)?; + msgs::write(&mut md, init)?; + Ok(md.bytes()) +} diff --git a/sphinx-key/src/core/mod.rs b/sphinx-key/src/core/mod.rs index dafb93a..d0d98e1 100644 --- a/sphinx-key/src/core/mod.rs +++ b/sphinx-key/src/core/mod.rs @@ -1,2 +1,3 @@ pub mod events; pub mod config; +pub mod init; \ No newline at end of file diff --git a/sphinx-key/src/main.rs b/sphinx-key/src/main.rs index 1dfe7c4..5429f2a 100644 --- a/sphinx-key/src/main.rs +++ b/sphinx-key/src/main.rs @@ -65,7 +65,6 @@ fn main() -> Result<()> { let (mqtt, connection) = conn::mqtt::make_client(&exist.broker, CLIENT_ID)?; let mqtt_client = conn::mqtt::start_listening(mqtt, connection, tx)?; // this blocks forever... the "main thread" - log::info!(">>>>>>>>>>> blocking forever..."); let do_log = true; let network = match exist.network.as_str() { "bitcoin" => Network::Bitcoin, @@ -76,7 +75,8 @@ fn main() -> Result<()> { _ => Network::Regtest, }; log::info!("Network set to {:?}", network); - make_event_loop(mqtt_client, rx, network, do_log, led_tx)?; + log::info!(">>>>>>>>>>> blocking forever..."); + make_event_loop(mqtt_client, rx, network, do_log, led_tx, exist.seed)?; } else { led_tx.send(Status::WifiAccessPoint).unwrap(); println!("=============> START SERVER NOW AND WAIT <==============");