From ff5e25942abc7bd17f51d092ba3793e956a0cfe3 Mon Sep 17 00:00:00 2001 From: GZTime Date: Thu, 9 Jan 2025 01:27:04 +0800 Subject: [PATCH] feat: recheck result --- src/main.rs | 90 +++++++++++++++++++--------------- src/utils/hash_pattern.rs | 25 +++++++++- src/utils/vanity_secret_key.rs | 24 +++++++-- 3 files changed, 94 insertions(+), 45 deletions(-) diff --git a/src/main.rs b/src/main.rs index 54e7b4f..032069d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -62,13 +62,15 @@ fn main() -> anyhow::Result<()> { } } + let pattern = match &ARGS.pattern { + Some(pattern) => Some(HashPattern::from_str(pattern)?), + None => None, + }; + let (filter, estimate) = match &ARGS.filter { Some(filter) => (filter.clone(), None), - None => match &ARGS.pattern { - Some(pattern) => { - let hash_pattern = HashPattern::from_str(pattern)?; - (hash_pattern.filter, Some(hash_pattern.possibliity)) - } + None => match &pattern { + Some(p) => (p.filter.clone(), Some(p.possibliity)), None => bail!("No filter or pattern given"), }, }; @@ -89,7 +91,7 @@ fn main() -> anyhow::Result<()> { let (tx_hashdata, rx_hashdata) = channel::>(); let (tx_result, rx_result) = channel::>(); - let mut hashed: usize = 0; + let mut hashed = 0; let mut start = Instant::now(); let pro_que = ProQue::builder() @@ -126,48 +128,55 @@ fn main() -> anyhow::Result<()> { debug!("Receive result from OpenCL thread"); let vanity_timestamp = rx_result.recv()?; - hashed += dimension * iteration; + hashed += bench_size; let elapsed = start.elapsed().as_secs_f64(); bar.inc(bench_size); if let Some(vanity_timestamp) = vanity_timestamp { vanity_key.edit_timestamp(vanity_timestamp, &mut rng); - vanity_key.log_state(); - match estimate { - Some(estimate) => info!( - "Hashed: {} ({:.02}x) Time: {:.02}s Speed: {} hash/s", - format_number(hashed as f64), - (hashed as f64) / estimate, - elapsed, - format_number((hashed as f64) / elapsed), - ), - None => info!( - "Hashed: {} Time: {:.02}s Speed: {} hash/s", - format_number(hashed as f64), - elapsed, - format_number((hashed as f64) / elapsed), - ), + if match &pattern { + Some(pattern) => vanity_key.check_pattern(pattern), + None => true, + } { + vanity_key.log_state(); + + match estimate { + Some(estimate) => info!( + "Hashed: {} ({:.02}x) Time: {:.02}s Speed: {} hash/s", + format_number(hashed as f64), + (hashed as f64) / estimate, + elapsed, + format_number((hashed as f64) / elapsed), + ), + None => info!( + "Hashed: {} Time: {:.02}s Speed: {} hash/s", + format_number(hashed as f64), + elapsed, + format_number((hashed as f64) / elapsed), + ), + } + + if let Some(ref output_dir) = ARGS.output { + fs::write( + Path::new(output_dir).join(format!( + "{}-sec.asc", + hex::encode_upper(vanity_key.secret_key.fingerprint().as_bytes()) + )), + vanity_key.to_armored_string()?, + ) + .unwrap(); + } + + if ARGS.oneshot { + break; + } + + hashed = 0; + bar.reset(); + start = Instant::now(); } - - if let Some(ref output_dir) = ARGS.output { - fs::write( - Path::new(output_dir).join(format!( - "{}-sec.asc", - hex::encode_upper(vanity_key.secret_key.fingerprint().as_bytes()) - )), - vanity_key.to_armored_string()?, - ) - .unwrap(); - } - - if ARGS.oneshot { - break; - } - - hashed = 0; - start = Instant::now(); } if let Some(timeout) = ARGS.timeout { @@ -215,6 +224,7 @@ fn opencl_thread( } buffer_result.read(&mut vec).enq().unwrap(); + tx_result .send(match vec[0] { 0 => None, diff --git a/src/utils/hash_pattern.rs b/src/utils/hash_pattern.rs index d92a627..fe6cc31 100644 --- a/src/utils/hash_pattern.rs +++ b/src/utils/hash_pattern.rs @@ -4,18 +4,40 @@ use anyhow::bail; #[derive(Debug, Clone)] pub struct HashPattern { + pub pattern: String, pub filter: String, pub possibliity: f64, } +impl HashPattern { + pub fn is_match(&self, hash: &[u8]) -> bool { + if hash.len() != 20 { + return false; + } + + let hash_str = hex::encode_upper(hash); + + let mut matched = true; + for (i, c) in self.pattern.chars().enumerate() { + if c.is_ascii_hexdigit() && c != hash_str.chars().nth(i).unwrap() { + matched = false; + break; + } + } + + matched + } +} + impl FromStr for HashPattern { type Err = anyhow::Error; fn from_str(s: &str) -> Result { - let pattern = match s.trim().replace(" ", "").to_ascii_uppercase() { + let pattern = match s.trim().replace(' ', "").to_ascii_uppercase() { x if x.len() <= 40 => "*".repeat(40 - x.len()) + &x, _ => bail!("Invalid pattern: {}", s), }; + let mut parts: Vec = vec![]; // Handle fixed 0-9A-F @@ -85,6 +107,7 @@ impl FromStr for HashPattern { }; Ok(HashPattern { + pattern, filter, possibliity: (16f64).powi((fixed_pos_count + wildcard_pos_count) as i32), }) diff --git a/src/utils/vanity_secret_key.rs b/src/utils/vanity_secret_key.rs index deeca36..8ca83f7 100644 --- a/src/utils/vanity_secret_key.rs +++ b/src/utils/vanity_secret_key.rs @@ -1,3 +1,4 @@ +use anyhow::Result; use byteorder::{BigEndian, ByteOrder}; use log::{debug, info}; use pgp::{ @@ -13,7 +14,7 @@ use smallvec::smallvec; use crate::ARGS; -use super::CipherSuite; +use super::{CipherSuite, HashPattern}; /// Get the data used to calculate the fingerprint of a private key fn build_secret_key_hashdata(secret_key: impl SecretKeyTrait) -> Vec { @@ -222,9 +223,24 @@ impl VanitySecretKey { } } - pub fn to_armored_string(&self) -> Result { - self.secret_key - .to_armored_string(pgp::ArmorOptions::default()) + pub fn to_armored_string(&self) -> Result { + Ok(self + .secret_key + .to_armored_string(pgp::ArmorOptions::default())?) + } + + pub fn check_pattern(&self, pattern: &HashPattern) -> bool { + if pattern.is_match(self.secret_key.fingerprint().as_bytes()) { + return true; + } + + for subkey in &self.secret_key.secret_subkeys { + if pattern.is_match(subkey.fingerprint().as_bytes()) { + return true; + } + } + + false } pub fn log_state(&self) {