Files
simple-rust-tests/__crypto/btc-address/src/main.rs
2020-10-17 12:05:51 +08:00

89 lines
2.5 KiB
Rust

use std::{ thread, sync::{ Arc, Mutex } };
use rand::rngs::OsRng;
use secp256k1::{ Secp256k1, key::PublicKey };
use sha2::Sha256;
use ripemd160::Ripemd160;
use digest::{ Input, FixedOutput };
const PREFIX: &[&str] = &["1Hatter"];
fn main() {
println!("Prefix: {:?}", PREFIX);
let num_of_vcpus = num_cpus::get();
let num_of_phycpus = num_cpus::get_physical();
println!("You have {} vCPUs, from {} phyCPUs", num_of_vcpus, num_of_phycpus);
let stop_flag = Arc::new(Mutex::new(false));
let mut handles = vec![];
for ind in 0..num_of_phycpus {
println!("- Running task {} of {}", ind, num_of_phycpus);
let the_stop_flag = Arc::clone(&stop_flag);
let child = thread::spawn(move || {
run_one_task(ind, the_stop_flag);
});
handles.push(child);
}
while let Some(h) = handles.pop() {
h.join().unwrap();
}
println!("Finished!");
}
fn run_one_task(ind: usize, the_stop_flag: Arc<Mutex<bool>>) {
let secp = Secp256k1::new();
let mut rng = OsRng::new().expect("OsRng");
for i in 0..10_000_000 {
let (secret_key, public_key) = secp.generate_keypair(&mut rng);
let s = make_btc_address(&public_key);
if i % 1_000 == 0 {
if *the_stop_flag.lock().unwrap() {
return;
}
if i > 0 && i % 100_000 == 0 {
println!("> {} - {}", ind, i);
}
}
if PREFIX.iter().any(|p| s.starts_with(p)) {
println!("{}", s);
println!("{}", secret_key);
*the_stop_flag.lock().unwrap() = true;
break;
}
}
}
fn make_btc_address(public_key: &PublicKey) -> String {
let public_key_bytes = public_key.serialize_uncompressed().to_vec();
let riphemd160_sha256_pub_key = calc_ripemd160(&calc_sha256(&public_key_bytes));
let mut btc_addr = Vec::<u8>::with_capacity(25);
btc_addr.push(0x00 as u8);
btc_addr.extend_from_slice(&riphemd160_sha256_pub_key);
let checksum = &calc_sha256(&calc_sha256(&btc_addr))[0..4];
btc_addr.extend_from_slice(checksum);
bs58::encode(&btc_addr).into_string()
}
#[inline]
fn calc_sha256(i: &[u8]) -> Vec<u8> {
calc_hash(Sha256::default(), i)
}
#[inline]
fn calc_ripemd160(i: &[u8]) -> Vec<u8> {
calc_hash(Ripemd160::default(), i)
}
#[inline]
fn calc_hash<T>(mut hasher: T, i: &[u8]) -> Vec<u8> where T: Input + FixedOutput {
hasher.input(&i);
hasher.fixed_result().to_vec()
}