1
0
Fork 0
mirror of https://github.com/TransparentLC/opencl_vanity_gpg.git synced 2025-10-20 23:34:08 +00:00

Compare commits

..

No commits in common. "5fd3a100d6adf2e20cd2fc8f9e95b5b7eaf6951c" and "7c43505f54c2c31004f0565b69e2fa71097c1aab" have entirely different histories.

5 changed files with 43 additions and 164 deletions

View file

@ -28,63 +28,35 @@ $ opencl_vanity_gpg -h
Usage: opencl_vanity_gpg [OPTIONS] Usage: opencl_vanity_gpg [OPTIONS]
Options: Options:
-c, --cipher-suite <CIPHER_SUITE> -c, --cipher-suite <CIPHER_SUITE> Cipher suite of the vanity key
Cipher suite of the vanity key ed25519, ecdsa-****, rsa**** => Primary key
ed25519, ecdsa-****, rsa**** => Primary key cv25519, ecdh-**** => Subkey
cv25519, ecdh-**** => Subkey Use gpg CLI for further editing of the key. [default: ed25519] [possible values: ed25519, cv25519, rsa2048, rsa3072, rsa4096, ecdh-p256, ecdh-p384, ecdh-p521, ecdsa-p256, ecdsa-p384, ecdsa-p521]
Use gpg CLI for further editing of the key. [default: ed25519] [possible values: ed25519, cv25519, rsa2048, rsa3072, rsa4096, ecdh-p256, ecdh-p384, ecdh-p521, ecdsa-p256, ecdsa-p384, ecdsa-p521] -u, --user-id <USER_ID> OpenPGP compatible user ID [default: "Dummy <dummy@example.com>"]
-u, --user-id <USER_ID> -p, --pattern <PATTERN> A pattern less than 40 chars for matching fingerprints
OpenPGP compatible user ID [default: "Dummy <dummy@example.com>"] > Format:
-p, --pattern <PATTERN> * 0-9A-F are fixed, G-Z are wildcards
A pattern less than 40 chars for matching fingerprints * Other chars will be ignored
> Format: * Case insensitive
* 0-9A-F are fixed, G-Z are wildcards > Example:
* Other chars will be ignored * 11XXXX** may output a fingerprint ends with 11222234 or 11AAAABF
* Case insensitive * 11XXYYZZ may output a fingerprint ends with 11223344 or 11AABBCC
> Example: -f, --filter <FILTER> OpenCL kernel function for uint h[5] for matching fingerprints
* 11XXXX** may output a fingerprint ends with 11222234 or 11AAAABF Ignore the pattern and no estimate is given if this has been set
* 11XXYYZZ may output a fingerprint ends with 11223344 or 11AABBCC > Example:
-f, --filter <FILTER> * (h[4] & 0xFFFF) == 0x1234 outputs a fingerprint ends with 1234
OpenCL kernel function for uint h[5] for matching fingerprints * (h[0] & 0xFFFF0000) == 0xABCD0000 outputs a fingerprint starts with ABCD
Ignore the pattern and no estimate is given if this has been set -o, --output <OUTPUT> The dir where the vanity keys are saved
> Example: -d, --device <DEVICE> Device ID to use
* (h[4] & 0xFFFF) == 0x1234 outputs a fingerprint ends with 1234 -t, --thread <THREAD> Adjust it to maximum your device's usage
* (h[0] & 0xFFFF0000) == 0xABCD0000 outputs a fingerprint starts with ABCD -i, --iteration <ITERATION> Adjust it to maximum your device's usage [default: 512]
-o, --output <OUTPUT> --timeout <TIMEOUT> Exit after a specified time in seconds
The dir where the vanity keys are saved --oneshot Exit after getting a vanity key
-d, --device <DEVICE> --no-progress Don't print progress
Device ID to use --no-secret-key-logging Don't print armored secret key
-t, --thread <THREAD> --list-device Show available OpenCL devices then exit
Adjust it to maximum your device's usage -h, --help Print help
-i, --iteration <ITERATION> -V, --version Print version
Adjust it to maximum your device's usage [default: 512]
--timeout <TIMEOUT>
Exit after a specified time in seconds
--oneshot
Exit after getting a vanity key
--no-progress
Don't print progress
--no-secret-key-logging
Don't print armored secret key
--list-device
Show available OpenCL devices then exit
--future-timestamp
Generate keys with future timestamps instead of past timestamps
When true: search from start_timestamp forward in time (start_timestamp + 0 to max_time_range)
When false: search from start_timestamp backward in time (start_timestamp - max_time_range to start_timestamp - 0)
--start-timestamp <START_TIMESTAMP>
Custom timestamp to start searching from (Unix timestamp)
This is the base time point from which the search begins
If not specified, uses current time as the starting point
Example: 1640995200 (Jan 1, 2022 00:00:00 UTC)
--max-time-range <MAX_TIME_RANGE>
Maximum time range to search in seconds (default: 86400000 = 1000 days)
future_timestamp=true: search from start_timestamp to (start_timestamp + max_time_range)
future_timestamp=false: search from (start_timestamp - max_time_range) to start_timestamp [default: 86400000]
-h, --help
Print help
-V, --version
Print version
$ opencl_vanity_gpg -p 11XXYYZZ --oneshot $ opencl_vanity_gpg -p 11XXYYZZ --oneshot
[2025-01-08T19:00:25Z INFO opencl_vanity_gpg] Using device: Apple M1 Pro [2025-01-08T19:00:25Z INFO opencl_vanity_gpg] Using device: Apple M1 Pro

View file

@ -26,7 +26,7 @@ fn main() -> anyhow::Result<()> {
if ARGS.list_device { if ARGS.list_device {
info!("Available OpenCL devices: \n"); info!("Available OpenCL devices: \n");
for (i, device) in device_list.iter().enumerate() { for (i, device) in device_list.iter().enumerate() {
println!("Device #{i} - {device:?}"); println!("Device #{} - {:?}", i, device);
} }
return Ok(()); return Ok(());
} }
@ -51,32 +51,13 @@ fn main() -> anyhow::Result<()> {
}; };
let iteration = ARGS.iteration; let iteration = ARGS.iteration;
info!(
// Determine the starting timestamp "You will get vanity keys created after {}",
let start_timestamp = ARGS chrono::Utc::now()
.start_timestamp .checked_sub_signed(chrono::TimeDelta::seconds((dimension * iteration) as i64))
.unwrap_or_else(|| chrono::Utc::now().timestamp()); .unwrap()
.to_rfc3339_opts(chrono::SecondsFormat::Millis, true),
// Use the user-specified time range instead of dimension * iteration );
let max_search_offset = ARGS.max_time_range as i64;
if ARGS.future_timestamp {
info!(
"Starting search from {} and going forward in time (up to {} seconds)",
chrono::DateTime::from_timestamp(start_timestamp, 0)
.unwrap_or_else(chrono::Utc::now)
.to_rfc3339_opts(chrono::SecondsFormat::Millis, true),
max_search_offset
);
} else {
info!(
"Starting search from {} and going backward in time (up to {} seconds)",
chrono::DateTime::from_timestamp(start_timestamp, 0)
.unwrap_or_else(chrono::Utc::now)
.to_rfc3339_opts(chrono::SecondsFormat::Millis, true),
max_search_offset
);
}
if ARGS.output.is_none() { if ARGS.output.is_none() {
if ARGS.no_secret_key_logging { if ARGS.no_secret_key_logging {
@ -110,31 +91,6 @@ fn main() -> anyhow::Result<()> {
}; };
let mut vanity_key = VanitySecretKey::new(ARGS.cipher_suite, ARGS.user_id.clone(), &mut rng); let mut vanity_key = VanitySecretKey::new(ARGS.cipher_suite, ARGS.user_id.clone(), &mut rng);
// Set the initial timestamp for the key
// Ensure we use the full timestamp value, not truncated
let initial_timestamp = if start_timestamp > u32::MAX as i64 {
// If timestamp is too large for u32, we need to handle this carefully
// For now, use the current approach but ensure we're aware of the limitation
warn!(
"Timestamp {} is too large for u32, may cause unexpected behavior",
start_timestamp
);
start_timestamp as u32
} else {
start_timestamp as u32
};
info!(
"Using base timestamp: {} ({})",
initial_timestamp,
chrono::DateTime::from_timestamp(initial_timestamp as i64, 0)
.unwrap_or_else(chrono::Utc::now)
.to_rfc3339_opts(chrono::SecondsFormat::Millis, true)
);
vanity_key.edit_timestamp(initial_timestamp, &mut rng);
let mut hashdata = manually_prepare_sha1(vanity_key.hashdata()); let mut hashdata = manually_prepare_sha1(vanity_key.hashdata());
let (tx_hashdata, rx_hashdata) = channel::<Vec<u32>>(); let (tx_hashdata, rx_hashdata) = channel::<Vec<u32>>();
@ -150,10 +106,6 @@ fn main() -> anyhow::Result<()> {
&[ &[
format!("#define FILTER(h) ({filter})"), format!("#define FILTER(h) ({filter})"),
format!("#define CHUNK ({})", hashdata.len() / 16), format!("#define CHUNK ({})", hashdata.len() / 16),
format!(
"#define FUTURE_MODE ({})",
if ARGS.future_timestamp { 1 } else { 0 }
),
] ]
.join("\n"), .join("\n"),
), ),
@ -176,11 +128,8 @@ fn main() -> anyhow::Result<()> {
loop { loop {
debug!("Send key to OpenCL thread"); debug!("Send key to OpenCL thread");
tx_hashdata.send(hashdata)?; tx_hashdata.send(hashdata)?;
let mut vanity_key_next = let vanity_key_next =
VanitySecretKey::new(ARGS.cipher_suite, ARGS.user_id.clone(), &mut rng); VanitySecretKey::new(ARGS.cipher_suite, ARGS.user_id.clone(), &mut rng);
// Set the same initial timestamp for consistency
vanity_key_next.edit_timestamp(initial_timestamp, &mut rng);
let hashdata_next = manually_prepare_sha1(vanity_key_next.hashdata()); let hashdata_next = manually_prepare_sha1(vanity_key_next.hashdata());
debug!("Receive result from OpenCL thread"); debug!("Receive result from OpenCL thread");
@ -275,7 +224,6 @@ fn opencl_thread(
.arg(&buffer_hashdata) .arg(&buffer_hashdata)
.arg(&buffer_result) .arg(&buffer_result)
.arg(ARGS.iteration as u64) .arg(ARGS.iteration as u64)
.arg(ARGS.max_time_range as u32)
.build() .build()
.unwrap(); .unwrap();

View file

@ -4,35 +4,15 @@
#ifdef __INJECTS__ #ifdef __INJECTS__
#define CHUNK (0) #define CHUNK (0)
#define FILTER(h) (false) #define FILTER(h) (false)
#define FUTURE_MODE (0)
#endif #endif
__kernel void vanity_sha1(__constant uint *hashdata, __global uint *result, const ulong iter, const uint max_time_range) { __kernel void vanity_sha1(__constant uint *hashdata, __global uint *result, const ulong iter) {
uint data[CHUNK * 16]; uint data[CHUNK * 16];
for (uint i = 0; i < CHUNK * 16; i++) data[i] = hashdata[i]; for (uint i = 0; i < CHUNK * 16; i++) data[i] = hashdata[i];
uint nonce = data[1]; uint nonce = data[1];
uint thread_id = get_global_id(0);
for (uint i = 0; i < iter; i++) { for (uint i = 0; i < iter; i++) {
// Use a simple sequential approach that searches close to base time first data[1] = nonce - get_global_id(0) * iter - i;
// Each thread gets a small sequential offset if (data[1] > nonce) break;
uint offset = thread_id + i * get_global_size(0);
// Wrap around within max_time_range to avoid going too far
offset = offset % max_time_range;
if (FUTURE_MODE) {
// For future mode: increment timestamp within range
data[1] = nonce + offset;
// Check for overflow
if (data[1] < nonce) break;
} else {
// For past mode: decrement timestamp within range
data[1] = nonce - offset;
// Check for underflow
if (data[1] > nonce) break;
}
uint h[] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}; uint h[] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0};

View file

@ -75,25 +75,6 @@ pub struct Args {
/// Show available OpenCL devices then exit /// Show available OpenCL devices then exit
#[arg(long, default_value_t = false)] #[arg(long, default_value_t = false)]
pub list_device: bool, pub list_device: bool,
/// Generate keys with future timestamps instead of past timestamps
/// When true: search from start_timestamp forward in time (start_timestamp + 0 to max_time_range)
/// When false: search from start_timestamp backward in time (start_timestamp - max_time_range to start_timestamp - 0)
#[arg(long, default_value_t = false, verbatim_doc_comment)]
pub future_timestamp: bool,
/// Custom timestamp to start searching from (Unix timestamp)
/// This is the base time point from which the search begins
/// If not specified, uses current time as the starting point
/// Example: 1640995200 (Jan 1, 2022 00:00:00 UTC)
#[arg(long, verbatim_doc_comment)]
pub start_timestamp: Option<i64>,
/// Maximum time range to search in seconds (default: 86400000 = 1000 days)
/// future_timestamp=true: search from start_timestamp to (start_timestamp + max_time_range)
/// future_timestamp=false: search from (start_timestamp - max_time_range) to start_timestamp
#[arg(long, default_value_t = 86400000, verbatim_doc_comment)]
pub max_time_range: u64,
} }
impl Default for Args { impl Default for Args {
@ -112,9 +93,6 @@ impl Default for Args {
no_progress: true, no_progress: true,
no_secret_key_logging: false, no_secret_key_logging: false,
list_device: false, list_device: false,
future_timestamp: false,
start_timestamp: None,
max_time_range: 86400000,
} }
} }
} }

View file

@ -7,9 +7,9 @@ use std::{fmt::Write, mem};
pub use args::*; pub use args::*;
pub use device::DeviceList; pub use device::DeviceList;
pub use pattern::HashPattern;
use indicatif::*; use indicatif::*;
use indicatif_log_bridge::LogWrapper; use indicatif_log_bridge::LogWrapper;
pub use pattern::HashPattern;
pub use vanity_key::VanitySecretKey; pub use vanity_key::VanitySecretKey;
/// Do SHA-1 padding manually /// Do SHA-1 padding manually
@ -98,6 +98,7 @@ pub fn init_progress_bar(estimate: Option<f64>) -> ProgressBar {
bar bar
} }
pub fn format_number(v: impl Into<f64>) -> String { pub fn format_number(v: impl Into<f64>) -> String {
match Into::<f64>::into(v) { match Into::<f64>::into(v) {
v if v >= 1e12f64 => { v if v >= 1e12f64 => {