vanity-rage/src/main.rs

81 lines
2.6 KiB
Rust
Raw Normal View History

/*
vanity-rage a vanity key bruteforcer for age
Copyright (C) 2023 silt
This program is free software: you can redistribute it and/or modify it under the terms of the GNU
Affero General Public License as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program.
If not, see <https://www.gnu.org/licenses/>.
*/
2023-09-30 10:53:27 +00:00
use age::{self, secrecy::ExposeSecret};
use chrono::{
prelude::{DateTime, Local},
SecondsFormat,
};
2023-09-30 06:25:12 +00:00
use glob_match::glob_match;
use rayon::prelude::*;
use std::{env, process};
2023-09-30 07:35:15 +00:00
fn genpair() -> (String, String) {
let key_priv = age::x25519::Identity::generate();
let key_pub = key_priv.to_public();
(
key_priv.to_string().expose_secret().to_string(),
key_pub.to_string(),
)
}
fn try_pattern(pattern: String, key_pub: String) -> bool {
glob_match(&pattern, &key_pub.to_string())
}
2023-09-30 06:25:12 +00:00
fn main() {
let args = env::args();
let pattern = if args.len() < 2 {
println!(std::concat!(
"Usage: \n",
" vanity-rage [QUERY]\n",
"\n",
"Queries follow standard glob syntax:\n",
" ? - match any single character\n",
" * - match zero or more characters\n",
" [abc] - match any character within the brackets\n",
" [!abc] - match any character not within the brackets\n",
"\n",
"The provided glob should be able to match the returned key length\n",
));
process::exit(64);
} else {
2023-09-30 10:15:12 +00:00
format!("age1{}", args.last().unwrap().to_ascii_lowercase())
2023-09-30 06:25:12 +00:00
};
2023-09-30 07:35:15 +00:00
let pairs = loop {
2023-09-30 10:50:04 +00:00
let pairs: Vec<(String, String)> = (0..=4096)
2023-09-30 07:35:15 +00:00
.into_par_iter()
.filter_map(|_| {
let keypair = genpair();
if try_pattern(pattern.clone(), keypair.1.clone()) {
Some(keypair)
} else {
None
}
})
.collect();
if pairs.len() > 0 {
break pairs;
}
};
2023-09-30 10:49:09 +00:00
let (key_priv, key_pub) = pairs.first().unwrap();
2023-09-30 10:53:27 +00:00
let timestamp = Into::<DateTime<Local>>::into(std::time::SystemTime::now())
.to_rfc3339_opts(SecondsFormat::Secs, false);
println!("# created: {timestamp}\n# public key: {key_pub}\n{key_priv}");
2023-09-30 06:25:12 +00:00
}