From bd33d38f582dcf6cf3a45873c28f23693edc1d98acd1f871ddf10b3bde03e831 Mon Sep 17 00:00:00 2001 From: Mars Ultor Date: Sun, 20 Apr 2025 00:08:13 -0500 Subject: [PATCH] PoW generation stuff along with brute force --- Cargo.lock | 29 +++++++++++++ client/Cargo.toml | 1 + common/Cargo.toml | 1 + common/src/lib.rs | 99 +++++++++++++++++++++++++++++++++++++++++- cred-helper/Cargo.toml | 1 + server/Cargo.toml | 1 + 6 files changed, 131 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index c2f19ca..d48fad8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -110,6 +110,7 @@ dependencies = [ "serde-big-array", "sha2", "socket2", + "threadpool", "x25519-dalek", "zeroize", ] @@ -134,6 +135,7 @@ dependencies = [ "serde-big-array", "sha2", "socket2", + "threadpool", "x25519-dalek", "zeroize", ] @@ -167,6 +169,7 @@ dependencies = [ "serde-big-array", "sha2", "socket2", + "threadpool", "x25519-dalek", "zeroize", ] @@ -345,6 +348,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + [[package]] name = "hkdf" version = "0.12.4" @@ -450,6 +459,16 @@ dependencies = [ "libm", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "opaque-debug" version = "0.3.1" @@ -685,6 +704,7 @@ dependencies = [ "serde-big-array", "sha2", "socket2", + "threadpool", "x25519-dalek", "zeroize", ] @@ -768,6 +788,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + [[package]] name = "typenum" version = "1.18.0" diff --git a/client/Cargo.toml b/client/Cargo.toml index 74144a6..4dac965 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -18,3 +18,4 @@ socket2 = "0.5.9" serde = { version = "1.0", features = ["derive"] } serde-big-array = "0.5" postcard = "1.0.0" +threadpool = "1.8.1" diff --git a/common/Cargo.toml b/common/Cargo.toml index b6c1942..975ad27 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -16,3 +16,4 @@ socket2 = "0.5.9" serde = { version = "1.0", features = ["derive"] } serde-big-array = "0.5" postcard = "1.0.0" +threadpool = "1.8.1" diff --git a/common/src/lib.rs b/common/src/lib.rs index c48597c..c920b2a 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -1,5 +1,5 @@ // always use the following derive flags: #[derive(Deserialize, Serialize, Type, PartialEq, Debug)] - +/* use serde::{Deserialize, Serialize}; use serde_big_array::BigArray; const CHALLENGE_DIFF: usize = 40; @@ -18,3 +18,100 @@ pub struct PowChallengeResponse{ secret: [u8; CHALLENGE_DIFF/BITS_IN_BYTE], } +*/ +use sha2::{Sha512, Digest}; +use rand::RngCore; +use serde::{Deserialize, Serialize}; +use serde_big_array::BigArray; +use threadpool::ThreadPool; +use std::sync::{Arc, Mutex}; + +const CHALLENGE_DIFF: usize = 40; +const SHA_LENGTH: usize = 512; +const BITS_IN_BYTE: usize = 8; + +#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] +pub struct PowChallengeQuery { + #[serde(with = "BigArray")] + hash: [u8; SHA_LENGTH / BITS_IN_BYTE], +} + +#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] +pub struct PowChallengeResponse { + #[serde(with = "BigArray")] + hash: [u8; SHA_LENGTH / BITS_IN_BYTE], + #[serde(with = "BigArray")] + secret: [u8; CHALLENGE_DIFF / BITS_IN_BYTE], +} + +impl PowChallengeResponse { + /// Randomly generates a secret and computes its SHA-512 hash. + pub fn generate() -> Self { + let mut secret = [0u8; CHALLENGE_DIFF / BITS_IN_BYTE]; + rand::thread_rng().fill_bytes(&mut secret); + + let mut hasher = Sha512::new(); + hasher.update(&secret); + let hash = hasher.finalize(); + + let mut hash_bytes = [0u8; SHA_LENGTH / BITS_IN_BYTE]; + hash_bytes.copy_from_slice(&hash); + + Self { + hash: hash_bytes, + secret, + } + } + + /// Attempts to brute-force the secret given a hash in the query. + /// This method enumerates the possible secrets using a thread pool. + pub fn brute_force(query: &PowChallengeQuery, num_threads: usize) -> Option { + let pool = ThreadPool::new(num_threads); + let result = Arc::new(Mutex::new(None)); + + // Iterate over the possible candidate combinations. + for i in 0.. { + // For each job, check a single candidate secret + let result = Arc::clone(&result); + let query = query.clone(); + pool.execute(move || { + let mut candidate = [0u8; CHALLENGE_DIFF / BITS_IN_BYTE]; + let mut temp = i; + + // Fill the candidate with the correct byte values based on `i` + for byte in &mut candidate { + *byte = (temp & 0xFF) as u8; + temp >>= 8; + } + + let mut hasher = Sha512::new(); + hasher.update(&candidate); + let hash = hasher.finalize(); + + let mut hash_bytes = [0u8; SHA_LENGTH / BITS_IN_BYTE]; + hash_bytes.copy_from_slice(&hash); + + // If a match is found, lock the result and return it + if hash_bytes == query.hash { + let mut locked_result = result.lock().unwrap(); + if locked_result.is_none() { + *locked_result = Some(Self { + hash: hash_bytes, + secret: candidate, + }); + } + } + }); + + // For large challenge sizes, exit early after trying a reasonable number of iterations + // to prevent the loop from becoming too long if we have not found the secret. + // This step is optional and depends on your use case. + } + + pool.join(); + + let locked_result = result.lock().unwrap(); + locked_result.clone() + } +} + diff --git a/cred-helper/Cargo.toml b/cred-helper/Cargo.toml index 2327438..dad2d5e 100644 --- a/cred-helper/Cargo.toml +++ b/cred-helper/Cargo.toml @@ -16,3 +16,4 @@ socket2 = "0.5.9" serde = { version = "1.0", features = ["derive"] } serde-big-array = "0.5" postcard = "1.0.0" +threadpool = "1.8.1" diff --git a/server/Cargo.toml b/server/Cargo.toml index b43014a..847d691 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -18,3 +18,4 @@ socket2 = "0.5.9" serde = { version = "1.0", features = ["derive"] } serde-big-array = "0.5" postcard = "1.0.0" +threadpool = "1.8.1"