Skip to content

Commit

Permalink
feat!: always run multithreaded (can be single-thread), reducing code…
Browse files Browse the repository at this point in the history
… duplication
  • Loading branch information
skyf0l committed Nov 11, 2024
1 parent ad74525 commit 63b0171
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 98 deletions.
10 changes: 3 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ members = [
"tools/gen_keys",
]

[features]
default = ["parallel"]
parallel = ["tokio", "mpsc", "num_cpus"]

[profile.dev]
opt-level = 1

Expand All @@ -46,9 +42,9 @@ openssl = "0.10"
base-x = "0.2"
display_bytes = "0.2"
ssh-key = { version = "0.6", features = ["encryption"] }
tokio = { version = "1.40", features = ["rt", "rt-multi-thread"], optional = true }
mpsc = { version = "0.2", optional = true }
num_cpus = { version = "1.15", optional = true }
tokio = { version = "1.40", features = ["rt", "rt-multi-thread"] }
mpsc = "0.2"
num_cpus = "1.15"
update-informer = "1.1"
indicatif = "0.17"
itertools = "0.13"
Expand Down
112 changes: 26 additions & 86 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use rug::integer::IsPrime;
use rug::Integer;
use std::cell::RefCell;
#[cfg(feature = "parallel")]
use std::sync::mpsc;
#[cfg(feature = "parallel")]
use std::sync::Arc;

mod attack;
Expand Down Expand Up @@ -66,31 +64,6 @@ pub fn run_attack(
Ok(solution)
}

/// Run all attacks.
///
/// When the `parallel` feature is enabled, this function will run all attacks in parallel using all available CPU cores.
/// Else, it will run all attacks in sequence (single-threaded).
pub fn run_attacks(params: &Parameters) -> Result<Solution, Option<Factors>> {
#[cfg(feature = "parallel")]
return run_parallel_attacks(params, &ATTACKS, num_cpus::get());
#[cfg(not(feature = "parallel"))]
run_sequence_attacks(params, &ATTACKS)
}

/// Run specific attacks.
///
/// When the `parallel` feature is enabled, this function will run all attacks in parallel using all available CPU cores.
/// Else, it will run all attacks in sequence (single-threaded).
pub fn run_specific_attacks(
params: &Parameters,
attacks: &[Arc<dyn Attack + Sync + Send>],
) -> Result<Solution, Option<Factors>> {
#[cfg(feature = "parallel")]
return run_parallel_attacks(params, attacks, num_cpus::get());
#[cfg(not(feature = "parallel"))]
run_sequence_attacks(params, attacks)
}

fn check_n_prime(n: &Option<Integer>) -> bool {
if let Some(n) = &n {
match n.is_probably_prime(100) {
Expand Down Expand Up @@ -133,54 +106,6 @@ fn create_progress_bar(mp: &MultiProgress) -> ProgressBar {
pb
}

/// Run all attacks in sequence, from fastest to slowest (single-threaded)
pub fn run_sequence_attacks(
params: &Parameters,
attacks: &[Arc<dyn Attack + Sync + Send>],
) -> Result<Solution, Option<Factors>> {
if check_n_prime(&params.n) {
return Err(None);
}

let mut partial_factors: Option<Factors> = None;
let (mp, pb_main) = create_multi_progress(attacks.len());
for attack in attacks.iter() {
match if attack.speed() == AttackSpeed::Fast {
// No progress bar for fast attacks
run_attack(attack.clone(), params, None)
} else {
let pb = create_progress_bar(&mp);
run_attack(attack.clone(), params, Some(&pb))
} {
Ok(solution) => return Ok(solution),
Err(Error::PartialFactorization(factor)) => {
if let Some(partial_factors) = &mut partial_factors {
partial_factors.merge(&factor);
} else {
partial_factors = Some(factor);
}

// Try to create a private key from the partial factors
if let Ok(private_key) = PrivateKey::from_factors(
partial_factors.as_ref().unwrap().clone(),
params.e.clone(),
) {
return Ok(Solution::new_pk("Partial factors", private_key));
}
pb_main.set_message(format!(
"({} factors found) ",
partial_factors.as_ref().unwrap().len()
));
}
_ => {}
}
pb_main.inc(1);
}

Err(partial_factors)
}

#[cfg(feature = "parallel")]
async fn _run_parallel_attacks<'a>(
params: Arc<Parameters>,
attacks: &[Arc<dyn Attack + Sync + Send>],
Expand Down Expand Up @@ -220,9 +145,29 @@ async fn _run_parallel_attacks<'a>(
}
}

/// Run all attacks in parallel, from fastest to slowest (multi-threaded)
#[cfg(feature = "parallel")]
pub fn run_parallel_attacks(
/// Run all attacks on all available CPU cores.
pub fn run_attacks(params: &Parameters) -> Result<Solution, Option<Factors>> {
run_specific_attacks_with_threads(params, &ATTACKS, num_cpus::get())
}

/// Run specific attacks on all available CPU cores.
pub fn run_specific_attacks(
params: &Parameters,
attacks: &[Arc<dyn Attack + Sync + Send>],
) -> Result<Solution, Option<Factors>> {
run_specific_attacks_with_threads(params, attacks, num_cpus::get())
}

/// Run all attacks on a given number of threads.
pub fn run_attacks_with_threads(
params: &Parameters,
threads: usize,
) -> Result<Solution, Option<Factors>> {
run_specific_attacks_with_threads(params, &ATTACKS, threads)
}

/// Run specific attacks on a given number of threads.
pub fn run_specific_attacks_with_threads(
params: &Parameters,
attacks: &[Arc<dyn Attack + Sync + Send>],
threads: usize,
Expand All @@ -231,10 +176,6 @@ pub fn run_parallel_attacks(
return Err(None);
}

if threads <= 1 {
return run_sequence_attacks(params, attacks);
}

// User for key build from partial factors
let param_e = params.e.clone();

Expand Down Expand Up @@ -270,10 +211,9 @@ pub fn run_parallel_attacks(
}

// Try to create a private key from the partial factors
if let Ok(private_key) = PrivateKey::from_factors(
partial_factors.as_ref().unwrap().clone(),
param_e.clone(),
) {
if let Ok(private_key) =
PrivateKey::from_factors(partial_factors.as_ref().unwrap().clone(), &param_e)
{
break Some(Solution::new_pk("Partial factors", private_key));
}
pb_main.set_message(format!(
Expand Down
6 changes: 1 addition & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ struct Args {
#[clap(long)]
factors: bool,
/// Number of threads to use. Default: number of CPUs
#[cfg(feature = "parallel")]
#[clap(short, long, default_value_t = num_cpus::get())]
threads: usize,
/// Specify attacks to run. Default: all. (e.g. --attacks ecm,wiener,sparse)
Expand Down Expand Up @@ -301,10 +300,7 @@ fn main() -> Result<(), MainError> {
.collect::<Vec<_>>();

// Run attacks
#[cfg(feature = "parallel")]
let res = rsacracker::run_parallel_attacks(&params, &attacks, args.threads);
#[cfg(not(feature = "parallel"))]
let res = rsacracker::run_sequence_attacks(&params, &attacks);
let res = rsacracker::run_specific_attacks_with_threads(&params, &attacks, args.threads);
let solution = match res {
Ok(solution) => solution,
Err(partial_factors) => {
Expand Down

0 comments on commit 63b0171

Please sign in to comment.