-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #43 from stakwork/feat/chacha20poly1305
Feat/chacha20poly1305
- Loading branch information
Showing
20 changed files
with
460 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,4 +5,5 @@ Cargo.lock | |
.DS_Store | ||
sphinx-key/Cargo.lock | ||
notes.md | ||
test-flash | ||
test-flash | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
[package] | ||
name = "sphinx-key-crypter" | ||
version = "0.1.0" | ||
authors = ["Evan Feenstra <[email protected]>"] | ||
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" } | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
use anyhow::anyhow; | ||
use lightning::util::chacha20poly1305rfc::ChaCha20Poly1305RFC; | ||
|
||
pub const MSG_LEN: usize = 32; | ||
pub const KEY_LEN: usize = 32; | ||
pub const NONCE_END_LEN: usize = 8; | ||
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]> { | ||
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, KEY_LEN, MSG_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(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use secp256k1::ecdh::SharedSecret; | ||
use secp256k1::{SecretKey, PublicKey}; | ||
use anyhow::Result; | ||
|
||
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[..])?; | ||
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(()) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
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 secp256k1::rand::{rngs::OsRng, thread_rng, RngCore}; | ||
use secp256k1::Secp256k1; | ||
|
||
#[test] | ||
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(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#!/bin/bash | ||
|
||
n=32 | ||
|
||
hexdump -vn "$n" -e ' /1 "%02x"' /dev/urandom ; echo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Oops, something went wrong.