use std::{ fs::OpenOptions, io::Write, pin::Pin, thread::{spawn, JoinHandle}, time::Duration, }; mod cpu; pub type Key = [u8; 32]; struct ProgressCounter(pub *mut u64); unsafe impl Send for ProgressCounter {} unsafe impl Sync for ProgressCounter {} impl ProgressCounter { fn incr(&mut self, n: u64) { unsafe { *self.0 += n; } } } fn work(mut progress: ProgressCounter) -> JoinHandle<()> { spawn(move || { let mut rng = { use rand::SeedableRng; rand_xoshiro::Xoshiro256StarStar::from_rng(rand::thread_rng()).unwrap() }; const ITERS: u64 = 256; loop { for _ in 0..ITERS { let key = cpu::generate_privkey(&mut rng); let pub_key = cpu::get_pubkey(&key); // b64(pub_key).starts_with("char") && b64(pub_key)[4] in ["+", "/"] if pub_key[0] == 0x72 && pub_key[1] == 0x16 && pub_key[2] == 0xab && pub_key[3] >= 0xf8 { let key_str = base64::encode(key); let pub_key_str = base64::encode(pub_key); println!("{} -> {}", key_str, pub_key_str); { let mut file = OpenOptions::new() .create(true) .append(true) .open("keys.log") .unwrap(); let _ = writeln!(file, "{} -> {}", key_str, pub_key_str); } } } progress.incr(ITERS); } }) } const NUM_THREADS: usize = 24; struct Progress(Pin>); impl Progress { fn new() -> Self { Progress(Box::pin([0; NUM_THREADS])) } unsafe fn the_pointer(&mut self) -> *mut u64 { self.0.as_mut_ptr() } fn total(&self) -> u64 { self.0.iter().sum() } } fn main() { let mut progress = Progress::new(); let _handles: Vec<_> = (0..NUM_THREADS) .map(|id| { let ptr = unsafe { progress.the_pointer().add(id) }; let progress = ProgressCounter(ptr); work(progress) }) .collect(); let mut last_total_progress = 0; let mut sleep_secs = 1.0; loop { let total_progress = progress.total(); let delta = total_progress - last_total_progress; last_total_progress = total_progress; println!("Guesses/sec ≈ {:.0}", delta as f64 / sleep_secs); std::thread::sleep(Duration::from_secs_f64(sleep_secs)); sleep_secs *= 1.05; } }