A high-performance parallel password cracking system that demonstrates the effectiveness of parallel computing using OpenMP. This project implements and compares sequential and parallel brute-force attacks on DES-encrypted passwords.
GitHub Repository: https://github.com/lapemaya/Parallel-Password-Decryption
- Overview
- Features
- Architecture
- Algorithms
- Performance Optimizations
- Requirements
- Installation
- Usage
- Benchmarking
- Results
- Project Structure
- Technical Details
- License
For a detailed technical analysis including:
- In-depth discussion of optimization strategies
- Comprehensive performance analysis with statistical metrics
Please refer to Parallel Password Decryption Report.pdf which contains the full academic report of this work.
This project implements a brute-force password cracking system that targets 8-character date-formatted passwords (DDMMYYYY) encrypted using the DES algorithm with crypt(). The implementation includes:
- Sequential version: Single-threaded baseline implementation
- Parallel version: OpenMP-based multi-threaded implementation with cancellation points
- Parallel NOWAIT version: Optimized parallel version without implicit barriers
- Maximum speedup: 12.04Γ with 25 threads (NOWAIT variant)
- Peak throughput: ~4.42 million passwords per second
- Optimal efficiency: 90-100% at 2-4 threads
- Overthreading analysis: Performance characterization up to 32 threads, demonstrating degradation beyond physical core counts
The project demonstrates significant performance improvements through parallelization while also revealing the limits of overthreading when thread counts exceed available hardware resources.
- Brute-force attack on DES-encrypted passwords
- Random password generation for testing (500 iterations)
- Real-time progress tracking with visual progress bars
- Performance metrics: execution time, passwords/second, speedup, efficiency
- Correctness verification: validates found passwords against targets
- OpenMP parallelization with dynamic thread configuration
- Loop cancellation: early termination when password is found
- Thread-safe operations: atomic flags and critical sections
- Reentrant cryptography: uses
crypt_r()for thread safety - Two parallel strategies:
- Standard version with implicit synchronization
- NOWAIT version for reduced barrier overhead
- Comprehensive benchmarking suite (bash script)
- Automated testing across multiple thread counts (1, 2, 4, 8, 16, 20)
- Visualization tools (Python scripts for plotting)
- Metrics tracked:
- Execution time
- Speedup vs sequential baseline
- Parallel efficiency
- Scalability
- Throughput (passwords/second)
- Format: 8-character date strings (DDMMYYYY)
- Day range: 00-31 (32 values)
- Month range: 00-12 (13 values)
- Year range: 0000-2025 (2026 values)
- Total combinations: 32 Γ 13 Γ 2026 = 842,816 per iteration
- Test iterations: 500 random passwords per benchmark run
βββββββββββββββββββββββββββββββββββββββββββ
β Master Thread β
β - Generates random target password β
β - Initializes search space β
βββββββββββββββββ¬ββββββββββββββββββββββββββ
β
βββββββββΌββββββββ
β Fork Threads β
βββββββββ¬ββββββββ
β
βββββββββββββ΄ββββββββββββ
β Parallel Search β
β - collapse(3) loops β
β - static scheduling β
β - cancellation point β
βββββββββββββ¬ββββββββββββ
β
βββββββββΌββββββββ
β Join Threads β
βββββββββββββββββ
for each random target password:
for day in 0..31:
for month in 0..12:
for year in 0..2025:
generate candidate password
hash = crypt(candidate, salt)
if hash matches target:
found = true
break all loops#pragma omp parallel
{
for each random target password:
#pragma omp for collapse(3) schedule(static)
for day in 0..31:
for month in 0..12:
for year in 0..2025:
#pragma omp cancellation point for
if found_flag:
#pragma omp cancel for
generate candidate password
hash = crypt_r(candidate, salt, &thread_data)
if hash matches target:
#pragma omp critical
{
found = candidate
found_flag = true
}
}-
Standard Parallel Version:
- Uses
#pragma omp cancel forwhich requires waiting for all threads - Implicit barrier at the end of parallel for
- Safer but slightly slower
- Uses
-
NOWAIT Version:
- Uses
if (found_flag) continuewithout formal cancellation - No implicit barriers with
nowaitclause - Faster but requires careful synchronization
- Uses
- Optimization: Construct 8-character candidate passwords using arithmetic on integers (
'0' + digit) instead of high-level string formatting - Effect: Lower CPU time per candidate, reduced heap activity, less allocator-related jitter
- Optimization: Each thread uses separate
crypt_datastruct with reentrantcrypt_r()instead of non-reentrantcrypt() - Effect: Removes shared-state contention, avoids sequentialization, improves parallel scalability
- Optimization: Check two representative bytes (positions 3 and 4) before performing full
strcmp()on DES hash - Effect: Most candidates fail the cheap check, reducing expensive string comparisons and saving CPU cycles
- Optimization:
std::atomic<bool>with relaxed loads for frequent checks and release store when setting flag - Effect: Fast early exit with minimal synchronization cost, balances correctness with low-overhead polling
- Optimization: Cancellation points and
#pragma omp cancel forallow threads to stop iterating when match found - Effect: Faster termination when password found (note: cannot combine with
nowaitclause)
- Optimization:
collapse(3)directive withschedule(static)for deterministic, low-overhead partitioning - Effect: Reduced runtime scheduling overhead, good cache locality for contiguous iteration chunks
- Optimization: OpenMP
reduction(+:total_passwords_tested)avoids atomic increments on hot path - Effect: Lower contention on global counter while maintaining accurate aggregated metrics
- Optimization: Avoid dynamic allocations inside hot loop (no temporary
std::stringper candidate) - Effect: Prevents allocator contention, reduces cache pollution, lower latency per candidate
-O3 # Maximum optimization
-march=native # CPU-specific instructions
-ffast-math # Aggressive math optimizations
-DNDEBUG # Remove debug assertions- OS: Linux (tested on Ubuntu-based systems)
- CPU: Multi-core processor (tested on Intel Core i9-13900H with 14 cores, 20 threads via Hyper-Threading)
- RAM: Minimum 2GB
- Compiler: GCC 9.0+ or Clang 10.0+ with OpenMP 4.0+ support
- CMake 3.12 or higher
- OpenMP (typically included with GCC)
- Python 3.6+ (for visualization)
- matplotlib
- pandas
- numpy
libcrypt(DES encryption, standard on Linux)- Standard C++ libraries (C++11)
git clone https://github.com/lapemaya/Parallel-Password-Decryption
cd Password-Decryptionpip3 install matplotlib pandas numpymkdir -p cmake-build-debug
cd cmake-build-debug
cmake -DCMAKE_BUILD_TYPE=Release ..
make
cd ..ls cmake-build-debug/
# Should show: Password8Sequenziale, Password8ParallelRandomPassword,
# Password8ParallelRandomPasswordNOWAIT./cmake-build-debug/Password8Sequenziale- Runs single-threaded baseline
- No parameters needed
- Outputs execution time and throughput
./cmake-build-debug/Password8ParallelRandomPassword- Prompts for number of threads
- Displays available cores
- Validates thread count
./cmake-build-debug/Password8ParallelRandomPassword 8- Directly specifies 8 threads
- Useful for scripting and benchmarking
./cmake-build-debug/Password8ParallelRandomPasswordNOWAIT 8- Optimized version without implicit barriers
- Same interface as standard parallel version
Enable OpenMP cancellation (required for parallel versions):
export OMP_CANCELLATION=trueControl thread affinity:
export OMP_PROC_BIND=true
export OMP_PLACES=coresThe project includes a comprehensive benchmarking system:
./benchmark.shThis script:
- Runs sequential version to establish baseline
- Tests parallel versions with 1, 2, 4, 8, 16, 20 threads
- Tests NOWAIT version with additional 25 and 32 threads (overthreading analysis)
- Collects execution time, speedup, efficiency metrics
- Saves results to
benchmark_results/benchmark_TIMESTAMP.csv
python3 plot_benchmark.py benchmark_results/benchmark_TIMESTAMP.csvGenerates individual plots:
*_execution_time.png: Execution time vs threads*_speedup.png: Speedup vs threads (with ideal reference)*_efficiency.png: Parallel efficiency percentage*_scalability.png: Strong scaling analysis*_throughput.png: Passwords cracked per second*_combined.png: Summary dashboard with all metrics*_summary_table.png: Performance statistics table
Edit benchmark.sh to customize:
THREAD_COUNTS=(1 2 4 8 16 20) # Thread counts to test
NUM_RUNS=3 # Repetitions per test (for averaging)| Threads | Sequential (s) | Parallel (s) | NOWAIT (s) |
|---|---|---|---|
| 1 | 571.04 | 590.55 | 591.77 |
| 2 | --- | 283.27 | 301.39 |
| 4 | --- | 161.25 | 158.35 |
| 8 | --- | 97.44 | 101.75 |
| 16 | --- | 64.41 | 67.00 |
| 20 | --- | 54.28 | 55.57 |
| 25 | --- | --- | 47.43 |
| 32 | --- | --- | 50.07 |
| Threads | Parallel | NOWAIT | Ideal |
|---|---|---|---|
| 1 | 0.97Γ | 0.96Γ | 1.00Γ |
| 2 | 2.01Γ | 1.89Γ | 2.00Γ |
| 4 | 3.54Γ | 3.60Γ | 4.00Γ |
| 8 | 5.86Γ | 5.61Γ | 8.00Γ |
| 16 | 8.86Γ | 8.52Γ | 16.00Γ |
| 20 | 10.52Γ | 10.27Γ | 20.00Γ |
| 25 | --- | 12.04Γ | 25.00Γ |
| 32 | --- | 11.40Γ | 32.00Γ |
| Threads | Parallel Eff | NOWAIT Eff | Quality |
|---|---|---|---|
| 1 | 96.7% | 96.5% | Excellent |
| 2 | 100.5% | 94.5% | Excellent |
| 4 | 88.5% | 90.0% | Very Good |
| 8 | 73.3% | 70.1% | Good |
| 16 | 55.4% | 53.3% | Moderate |
| 20 | 52.6% | 51.4% | Moderate |
| 25 | --- | 48.2% | Fair |
| 32 | --- | 35.6% | Poor |
| Threads | Sequential | Parallel | NOWAIT |
|---|---|---|---|
| 1 | 737,972 | 374,606 | 374,518 |
| 2 | --- | 746,267 | 745,892 |
| 4 | --- | 1,390,429 | 1,388,791 |
| 8 | --- | 2,173,329 | 2,182,808 |
| 16 | --- | 3,351,151 | 3,350,576 |
| 20 | --- | 3,895,931 | 3,841,099 |
| 25 | --- | --- | 4,423,183 |
| 32 | --- | --- | 4,512,225 |
Throughput measured in passwords per second
- Near-linear speedup up to 2 threads (~100% efficiency)
- Good scaling up to 8 threads with 70-73% efficiency
- Peak performance at 25 threads: Maximum speedup of 12.04Γ and throughput of 4.42M passwords/sec
- Overthreading penalty: Performance degrades at 32 threads despite exceeding hardware thread capacity (20 logical threads)
- NOWAIT advantage: 1-5% improvement over standard parallel version by eliminating implicit barriers
- Efficiency decline: From 90-100% at 2-4 threads to 35.6% at 32 threads
Why 25 threads improve performance:
- Workload balancing compensates for irregular early-termination behavior
- I/O and memory latency hiding keeps computational units busy
- Hyper-Threading headroom allows slight oversubscription
Why 32 threads degrade performance:
- Context switching overhead (32 threads on 20 hardware threads)
- Cache thrashing with more threads competing for L1/L2/L3 cache
- Memory bandwidth saturation
- Synchronization contention on atomic operations
- TLB pressure with more concurrent address spaces
Optimal thread count: 20-25 threads represent the sweet spot for this workload on this hardware, balancing parallelism with hardware constraints.
Password-Decryption/
βββ README.md # This file
βββ CMakeLists.txt # Build configuration
βββ benchmark.sh # Automated benchmarking
βββ plot_benchmark.py # Visualization generator
β
βββ Password8Sequenziale.cpp # Sequential implementation
βββ Password8ParallelRandomPassword.cpp # Parallel with cancellation
βββ Password8ParallelRandomPasswordNOWAIT.cpp # Parallel NOWAIT version
β
βββ parallel_password_report.tex # Technical report (LaTeX)
β
βββ cmake-build-debug/ # Build artifacts
β βββ Password8Sequenziale # Sequential binary
β βββ Password8ParallelRandomPassword # Parallel binary
β βββ Password8ParallelRandomPasswordNOWAIT # Parallel NOWAIT binary
β
βββ benchmark_results/ # Benchmark outputs
β βββ benchmark_*.csv # Raw data
β βββ benchmark_*_[plot_type].png # Visualizations
β
- Algorithm: Data Encryption Standard (DES)
- Function:
crypt()/crypt_r()(POSIX standard) - Salt: Fixed 2-character salt "AB"
- Output: 13-character hash string
#pragma omp parallel: Create parallel region#pragma omp for collapse(3): Parallelize 3 nested loops#pragma omp critical: Protect shared data updates#pragma omp cancellation point for: Check for cancellation#pragma omp cancel for: Request loop cancellationreduction(+:var): Parallel sum accumulationschedule(static): Static work distribution
- Thread-local storage: Each thread has independent
crypt_datastructure - Atomic operations: Lock-free synchronization for found flag
- Critical sections: Minimal locking for result storage
-
Amdahl's Law: Sequential portions limit parallelization
- Random password generation (sequential)
- Progress reporting (sequential)
- Result verification (sequential)
-
Early Termination & Load Imbalance:
- Password found at random iteration in search space
- Some threads find password early in their chunks
- Other threads waste work on their assigned portions
- Static scheduling cannot rebalance work dynamically
- Load imbalance increases with more threads
-
Synchronization Overhead:
- Atomic flag checks at every iteration
- Critical section contention when password found
- Thread creation/destruction costs
- Memory ordering operations
-
Hardware Limitations:
- Memory bandwidth bottleneck (crypt_r() is memory-intensive)
- Cache contention (thread-local crypt_data structures compete for cache)
- Cache coherence traffic between cores
- NUMA effects on multi-socket systems
- TLB pressure with many concurrent threads
-
Overthreading Effects (beyond 20-25 threads):
- Excessive context switching
- Cache thrashing
- Resource contention
- Diminishing returns on parallelism
This project demonstrates:
- Parallel algorithm design: Converting sequential to parallel code with OpenMP
- Thread synchronization: Atomic operations, critical sections, memory ordering
- Performance analysis: Speedup, efficiency, scalability metrics and visualization
- Optimization techniques: Early termination, cache optimization, reentrant functions
- Benchmarking methodology: Systematic performance evaluation across thread counts
- OpenMP programming: Practical use of parallel constructs (collapse, reduction, cancellation, nowait)
- Hardware constraints: Understanding overthreading, Hyper-Threading, and resource contention
- Trade-offs: Balancing synchronization overhead vs. early termination benefits
Contributions are welcome! Areas for improvement:
- GPU acceleration (CUDA implementation)
- Distributed computing (MPI version)
- Alternative hash algorithms (SHA, bcrypt)
- Rainbow table generation
- Dictionary attack implementation
This project is for educational purposes only. Use responsibly and ethically.
Lapo Chiostrini
University of Florence - Parallel Computing Course
Email: lapo.chiostrini1@edu.unifi.it
- OpenMP community for parallel computing standards
- Python matplotlib/pandas for visualization tools
- POSIX crypt library for encryption functions
Note: This software is intended for educational purposes and ethical security research only. Do not use for unauthorized access to systems or data.