From 68bdfa93a4438743f42ce74e88a38fda071a939b Mon Sep 17 00:00:00 2001 From: nazeh Date: Fri, 8 Dec 2023 16:26:12 +0300 Subject: [PATCH] wip: first implementation of deriving encryption key from passphrase --- Cargo.lock | 41 +++++++++++++++++++++++++++++++++++++++++ kytes/Cargo.toml | 1 + kytes/src/crypto.rs | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 81e4ed2..4b693ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,18 +2,58 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "bytes" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + [[package]] name = "getrandom" version = "0.2.11" @@ -29,6 +69,7 @@ dependencies = [ name = "kytes" version = "0.1.0" dependencies = [ + "blake3", "bytes", "rand", "z32", diff --git a/kytes/Cargo.toml b/kytes/Cargo.toml index f411cef..2278ab1 100644 --- a/kytes/Cargo.toml +++ b/kytes/Cargo.toml @@ -8,6 +8,7 @@ license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +blake3 = "1.5.0" bytes = "1.5.0" rand = "0.8.5" z32 = "1.0.2" diff --git a/kytes/src/crypto.rs b/kytes/src/crypto.rs index 4ecdf72..e9deaa3 100644 --- a/kytes/src/crypto.rs +++ b/kytes/src/crypto.rs @@ -1,9 +1,11 @@ use bytes::{BufMut, Bytes, BytesMut}; use rand::Rng; -const SEED_FILE_PREFIX: &str = "kytes encrypted-seed"; +const SEED_FILE_PREFIX: &str = "kytes seed"; const VERSION: u8 = 0; +const PASSPHRASE_HASHING_ITERATIONS: i32 = 100_000; + /// Takes an encrypted seed and format it into a seed file as follows: /// `kytes encrypted-seed v ` pub fn format_encrypted_seed_file(encrypted_seed: &[u8; 32]) -> Bytes { @@ -35,8 +37,22 @@ pub fn generate_seed() -> [u8; 32] { rng.gen() } +pub fn seed_encryption_key(passphrase: &str) -> [u8; 32] { + let mut hash: [u8; 32] = blake3::hash(passphrase.as_bytes()).into(); + + for i in 0..PASSPHRASE_HASHING_ITERATIONS { + hash = blake3::hash(&hash).into(); + } + + hash.to_owned() +} + #[cfg(test)] mod test { + use std::time::Instant; + + use crate::passphrase::generate_4words_passphrase; + use super::*; #[test] @@ -44,10 +60,27 @@ mod test { let seed = generate_seed(); let seed_file = format_encrypted_seed_file(&seed); + dbg!(&seed_file); + assert_eq!(seed_file.len(), 52 + 4 + SEED_FILE_PREFIX.len()); assert!(seed_file.starts_with(SEED_FILE_PREFIX.as_bytes())); assert!(seed_file.starts_with(SEED_FILE_PREFIX.as_bytes())); assert_eq!(encrypted_seed_file_version(&seed_file).unwrap(), 0); assert!(seed_file.ends_with(&z32::encode(&seed).as_bytes())); } + + #[test] + fn hash() { + let passphrase = generate_4words_passphrase(); + + let start = Instant::now(); + + println!("start hashing..."); + + let hash = seed_encryption_key(&passphrase); + + println!("final hash: {:?}", hash); + + println!("{} ms", start.elapsed().as_millis()); + } }