Change to rayon for multithreaded decryption
parent
9db6b28aa7
commit
b26acdb3d3
@ -1,3 +1,2 @@
|
|||||||
pub mod crypt;
|
pub mod crypt;
|
||||||
pub mod hash;
|
pub mod hash;
|
||||||
pub mod threading;
|
|
@ -1,165 +0,0 @@
|
|||||||
use std::thread;
|
|
||||||
use may::sync::mpmc::{Sender, Receiver, channel};
|
|
||||||
use crate::lib::crypt::{decrypt_data};
|
|
||||||
use crate::lib::hash::{sha_checksum, PassKey};
|
|
||||||
use std::thread::JoinHandle;
|
|
||||||
|
|
||||||
type ChannelControls<T> = (Sender<ThreadControlMessage<T>>, Receiver<ThreadControlMessage<T>>);
|
|
||||||
type DecryptData = (Option<Vec<u8>>, Option<PassKey>);
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct ThreadControlMessage<T> {
|
|
||||||
message_type: MessageType,
|
|
||||||
data: Option<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum MessageType {
|
|
||||||
Data,
|
|
||||||
Stop,
|
|
||||||
DataRequest,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ThreadControlMessage<T> {
|
|
||||||
/// Creates a new data message
|
|
||||||
fn new_data(data: T) -> Self {
|
|
||||||
return Self {
|
|
||||||
message_type: MessageType::Data,
|
|
||||||
data: Some(data),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
/// Creates a new stop message
|
|
||||||
fn new_stop() -> Self {
|
|
||||||
return Self {
|
|
||||||
message_type: MessageType::Stop,
|
|
||||||
data: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// Creates a new message for data requests
|
|
||||||
fn new_request() -> Self {
|
|
||||||
return Self {
|
|
||||||
message_type: MessageType::DataRequest,
|
|
||||||
data: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a channel of a specific type
|
|
||||||
pub fn create_channel<T>() -> ChannelControls<T> {
|
|
||||||
let chan = channel::<ThreadControlMessage<T>>();
|
|
||||||
chan
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the number of cpus there are
|
|
||||||
pub fn cpu_count() -> u8 {
|
|
||||||
return num_cpus::get() as u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Decrypts data multithreaded
|
|
||||||
pub fn decrypt_data_threaded(data: Vec<u8>, pw_table: &Vec<PassKey>, data_checksum: Vec<u8>) -> Option<Vec<u8>> {
|
|
||||||
let chan = create_channel::<DecryptData>();
|
|
||||||
let (rx, tx1) = chan;
|
|
||||||
let chan2 = create_channel::<DecryptData>();
|
|
||||||
let (rx2, tx) = chan2;
|
|
||||||
let mut entry_index = 0;
|
|
||||||
let mut threads: Vec<JoinHandle<()>> = vec![];
|
|
||||||
let num_threads = cpu_count();
|
|
||||||
println!("Creating {} threads...", num_threads);
|
|
||||||
for i in 0u8..num_threads {
|
|
||||||
print!("Starting Thread {}\r", i);
|
|
||||||
let rx1 = rx2.clone();
|
|
||||||
let tx1 = tx1.clone();
|
|
||||||
let data_checksum = data_checksum.clone();
|
|
||||||
let data = data.clone();
|
|
||||||
let child = thread::spawn(move || {
|
|
||||||
decrypt_data_coro(&(rx1, tx1), data, data_checksum);
|
|
||||||
});
|
|
||||||
threads.push(child);
|
|
||||||
if let Ok(entry) = next_password(pw_table, entry_index) {
|
|
||||||
rx.send(ThreadControlMessage::new_data((None, Some(entry)))).unwrap();
|
|
||||||
entry_index += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!("Starting main loop...");
|
|
||||||
loop {
|
|
||||||
if entry_index % 100 == 0 {
|
|
||||||
print!("{} out of {} Passwords tested\r", entry_index, pw_table.len());
|
|
||||||
}
|
|
||||||
let message = tx.recv().unwrap();
|
|
||||||
if let Ok(next_entry) = next_password(pw_table, entry_index) {
|
|
||||||
let msg_data: DecryptData = (None, Some(next_entry));
|
|
||||||
match message.message_type {
|
|
||||||
MessageType::DataRequest => {
|
|
||||||
rx.send(ThreadControlMessage::<DecryptData>::new_data(msg_data)).unwrap();
|
|
||||||
},
|
|
||||||
MessageType::Data => {
|
|
||||||
if let Some((result_data, pass_key)) = message.data {
|
|
||||||
if let Some(decrypted_data) = result_data {
|
|
||||||
rx.send(ThreadControlMessage::new_stop()).unwrap();
|
|
||||||
println!();
|
|
||||||
println!("Received data.");
|
|
||||||
if let Some((pw, _key)) = pass_key {
|
|
||||||
println!("Password is: {}", pw);
|
|
||||||
}
|
|
||||||
return Some(decrypted_data);
|
|
||||||
} else {
|
|
||||||
rx.send(ThreadControlMessage::<DecryptData>::new_data(msg_data)).unwrap();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rx.send(ThreadControlMessage::<DecryptData>::new_data(msg_data)).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
entry_index += 1;
|
|
||||||
} else {
|
|
||||||
rx.send(ThreadControlMessage::new_stop()).unwrap();
|
|
||||||
println!();
|
|
||||||
println!("No remaining passwords!");
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the next password or none if none are left
|
|
||||||
fn next_password(pw_table: &Vec<PassKey>, index: usize) -> Result<PassKey, &str> {
|
|
||||||
if index < pw_table.len() {
|
|
||||||
Ok(pw_table[index].clone())
|
|
||||||
} else {
|
|
||||||
Err("No remaining passwords")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Coroutine to decrypt data
|
|
||||||
fn decrypt_data_coro(controls: &ChannelControls<DecryptData>, data: Vec<u8>, check: Vec<u8>) {
|
|
||||||
loop {
|
|
||||||
let (tx, rx) = controls;
|
|
||||||
if let Ok(message) = rx.recv() {
|
|
||||||
match message.message_type {
|
|
||||||
MessageType::Data => {
|
|
||||||
if let Some((_, pass_key)) = message.data {
|
|
||||||
if let Some((_pw, key)) = pass_key.clone() {
|
|
||||||
let decrypted_data = decrypt_data(&data, key.as_slice());
|
|
||||||
let decr_check = sha_checksum(&decrypted_data);
|
|
||||||
if decr_check == check {
|
|
||||||
tx.send(ThreadControlMessage::new_data((Some(decrypted_data), pass_key))).unwrap();
|
|
||||||
} else {
|
|
||||||
if let Err(_e) = tx.send(ThreadControlMessage::new_request()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MessageType::Stop => {
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
tx.send(ThreadControlMessage::new_request()).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue