1use anyhow::Result;
21use colored::*;
22
23use crate::asym::{dh, rsa};
24use crate::block::{aes, des};
25use crate::classical::{caesar, playfair, rail_fence, vigenere};
26use crate::cli::{
27 Commands, EncryptionAlgorithm, ExchangeProtocol, HashAlgorithm, KeygenAlgorithm,
28 SigningAlgorithm,
29};
30use crate::hash::{md5, sha1, sha256};
31use crate::stream::rc4;
32use crate::{cli, interactive};
33
34pub fn dispatch_command(args: cli::Args) -> Result<()> {
36 match args.command {
37 Commands::Encrypt { algorithm } => {
38 let algo_name = cli::get_algorithm_name(&algorithm);
39 println!(
40 "{} {}",
41 "π Encrypting with".green(),
42 algo_name.yellow().bold()
43 );
44 handle_encryption(algorithm)?;
45 }
46 Commands::Decrypt { algorithm } => {
47 let algo_name = cli::get_algorithm_name(&algorithm);
48 println!(
49 "{} {}",
50 "π Decrypting with".blue(),
51 algo_name.yellow().bold()
52 );
53 handle_decryption(algorithm)?;
54 }
55 Commands::Hash { algorithm } => {
56 let algo_name = cli::get_hash_algorithm_name(&algorithm);
57 println!(
58 "{} {}",
59 "π’ Hashing with".magenta(),
60 algo_name.yellow().bold()
61 );
62 handle_hashing(algorithm)?;
63 }
64 Commands::Exchange { protocol } => {
65 let protocol_name = cli::get_keyexchange_protocol_name(&protocol);
66 println!(
67 "{} {}",
68 "π Key Exchange with".purple(),
69 protocol_name.yellow().bold()
70 );
71 handle_key_exchange(protocol)?;
72 }
73 Commands::Keygen { algorithm } => {
74 let algo_name = cli::get_keygen_algorithm_name(&algorithm);
75 println!(
76 "{} {}",
77 "π Generating key for".cyan(),
78 algo_name.yellow().bold()
79 );
80 handle_keygen(algorithm)?;
81 }
82 Commands::Sign { algorithm } => {
83 let algo_name = cli::get_signing_algorithm_name(&algorithm);
84 println!("βοΈ Signing with {algo_name} algorithm...");
85
86 if algorithm.rsa {
87 handle_sign(algorithm)?;
88 }
89 }
90 Commands::Verify { algorithm } => {
91 let algo_name = cli::get_signing_algorithm_name(&algorithm);
92 println!("π Verifying {algo_name} signature...");
93
94 if algorithm.rsa {
95 handle_verify(algorithm)?;
96 }
97 }
98 }
99
100 Ok(())
101}
102
103fn handle_encryption(algorithm: EncryptionAlgorithm) -> Result<()> {
136 let input = interactive::prompt_for_input("Enter text to encrypt")?;
137
138 let result = match true {
139 _ if algorithm.caesar => {
140 let shift = interactive::prompt_for_number("Enter shift value (1-25)", 1, 25)?;
141 let encrypted = caesar::encrypt(&input, shift as u8)?;
142 format!("Encrypted text: {encrypted}")
143 }
144 _ if algorithm.vigenere => {
145 let keyword = interactive::prompt_for_input("Enter keyword")?;
146 let encrypted = vigenere::encrypt(&input, &keyword)?;
147 format!("Encrypted text: {encrypted}")
148 }
149 _ if algorithm.playfair => {
150 let keyword = interactive::prompt_for_input("Enter keyword for matrix")?;
151 let encrypted = playfair::encrypt(&input, &keyword)?;
152 format!("Encrypted text: {encrypted}")
153 }
154 _ if algorithm.railfence => {
155 let rails = interactive::prompt_for_number("Enter number of rails (2-10)", 2, 10)?;
156 let encrypted = rail_fence::encrypt(&input, rails as usize)?;
157 format!("Encrypted text: {encrypted}")
158 }
159 _ if algorithm.rc4 => {
160 let key = interactive::prompt_for_password("Enter encryption key")?;
161 let encoding =
162 interactive::prompt_for_choices("Select output encoding", &["base64", "hex"])?;
163 let encrypted = rc4::encrypt(&input, &key, &encoding)?;
164 format!("Encrypted text ({encoding}): {encrypted}")
165 }
166 _ if algorithm.aes => {
167 let password = interactive::prompt_for_password("Enter password")?;
168 let key_size =
169 interactive::prompt_for_choices("Select AES key size", &["128", "192", "256"])?;
170 let mode = interactive::prompt_for_choices("Select encryption mode", &["ECB", "CBC"])?;
171 let encoding =
172 interactive::prompt_for_choices("Select output encoding", &["base64", "hex"])?;
173 let encrypted = aes::encrypt(&input, &password, &key_size, &mode, &encoding)?;
174 format!("Encrypted text (AES-{key_size}, {mode}, {encoding}): {encrypted}")
175 }
176 _ if algorithm.des => {
177 let key = interactive::prompt_for_input("Enter key (exactly 8 characters)")?;
178 if key.len() != 8 {
179 return Err(anyhow::anyhow!("DES key must be exactly 8 characters long"));
180 }
181 let mode = interactive::prompt_for_choices("Select encryption mode", &["ECB", "CBC"])?;
182 let encoding =
183 interactive::prompt_for_choices("Select output encoding", &["base64", "hex"])?;
184 let encrypted = des::encrypt(&input, &key, &mode, &encoding)?;
185 format!("Encrypted text (DES, {mode}, {encoding}): {encrypted}")
186 }
187 _ if algorithm.rsa => {
188 let key_size =
189 interactive::prompt_for_choices("Select RSA key size", &["512", "1024", "2048"])?;
190 let encoding =
191 interactive::prompt_for_choices("Select output encoding", &["base64", "hex"])?;
192 let privkey_format = interactive::prompt_for_choices(
193 "Select private key output format",
194 &["n:d", "PEM"],
195 )?;
196 let (encrypted, private_key) =
197 rsa::encrypt(&input, &key_size, &encoding, &privkey_format)?;
198
199 println!("\nπ RSA Encryption Complete!");
200 println!("π€ Encrypted data: {encrypted}");
201 println!("π Private key (SAVE THIS!): {private_key}");
202 println!("β οΈ Keep your private key secure - you'll need it for decryption!");
203
204 format!("RSA-{key_size} encryption successful. Encrypted data and private key provided above.")
205 }
206 _ => return Err(anyhow::anyhow!("Unknown algorithm")),
207 };
208
209 println!("\n{} {}", "Result:".cyan().bold(), result.white());
210 Ok(())
211}
212
213fn handle_decryption(algorithm: EncryptionAlgorithm) -> Result<()> {
244 let input = interactive::prompt_for_input("Enter text to decrypt")?;
245
246 let result = match true {
247 _ if algorithm.caesar => {
248 let shift = interactive::prompt_for_number("Enter shift value (1-25)", 1, 25)?;
249 let decrypted = caesar::decrypt(&input, shift as u8)?;
250 format!("Decrypted text: {decrypted}")
251 }
252 _ if algorithm.vigenere => {
253 let keyword = interactive::prompt_for_input("Enter keyword")?;
254 let decrypted = vigenere::decrypt(&input, &keyword)?;
255 format!("Decrypted text: {decrypted}")
256 }
257 _ if algorithm.playfair => {
258 let keyword = interactive::prompt_for_input("Enter keyword for matrix")?;
259 let decrypted = playfair::decrypt(&input, &keyword)?;
260 format!("Decrypted text: {decrypted}")
261 }
262 _ if algorithm.railfence => {
263 let rails = interactive::prompt_for_number("Enter number of rails (2-10)", 2, 10)?;
264 let decrypted = rail_fence::decrypt(&input, rails as usize)?;
265 format!("Decrypted text: {decrypted}")
266 }
267 _ if algorithm.rc4 => {
268 let key = interactive::prompt_for_password("Enter decryption key")?;
269 let encoding =
270 interactive::prompt_for_choices("Select input encoding", &["base64", "hex"])?;
271 let decrypted = rc4::decrypt(&input, &key, &encoding)?;
272 format!("Decrypted text: {decrypted}")
273 }
274 _ if algorithm.aes => {
275 let password = interactive::prompt_for_password("Enter password")?;
276 let key_size =
277 interactive::prompt_for_choices("Select AES key size", &["128", "192", "256"])?;
278 let mode = interactive::prompt_for_choices("Select encryption mode", &["ECB", "CBC"])?;
279 let encoding =
280 interactive::prompt_for_choices("Select input encoding", &["base64", "hex"])?;
281 let decrypted = aes::decrypt(&input, &password, &key_size, &mode, &encoding)?;
282 format!("Decrypted text: {decrypted}")
283 }
284 _ if algorithm.des => {
285 let key = interactive::prompt_for_input("Enter key (exactly 8 characters)")?;
286 if key.len() != 8 {
287 return Err(anyhow::anyhow!("DES key must be exactly 8 characters long"));
288 }
289 let mode = interactive::prompt_for_choices("Select encryption mode", &["ECB", "CBC"])?;
290 let encoding =
291 interactive::prompt_for_choices("Select input encoding", &["base64", "hex"])?;
292 let decrypted = des::decrypt(&input, &key, &mode, &encoding)?;
293 format!("Decrypted text: {decrypted}")
294 }
295 _ if algorithm.rsa => {
296 let private_key = interactive::prompt_for_multiline_input(
297 "Enter private key (format: n:d or PEM block, end with empty line)",
298 )?;
299 let encoding =
300 interactive::prompt_for_choices("Select input encoding", &["base64", "hex"])?;
301 let decrypted = rsa::decrypt(&input, &private_key, &encoding)?;
302 format!("Decrypted text: {decrypted}")
303 }
304 _ => return Err(anyhow::anyhow!("Unknown algorithm")),
305 };
306
307 println!("\n{} {}", "Result:".cyan().bold(), result.white());
308 Ok(())
309}
310
311fn handle_hashing(algorithm: HashAlgorithm) -> Result<()> {
340 let input = interactive::prompt_for_input("Enter text to hash")?;
341
342 let result = match true {
343 _ if algorithm.md5 => {
344 let hash_value = md5::hash(&input)?;
345 format!("MD5 hash: {hash_value}")
346 }
347 _ if algorithm.sha1 => {
348 let hash_value = sha1::hash(&input)?;
349 format!("SHA-1 hash: {hash_value}")
350 }
351 _ if algorithm.sha256 => {
352 let hash_value = sha256::hash(&input)?;
353 format!("SHA-256 hash: {hash_value}")
354 }
355 _ => return Err(anyhow::anyhow!("Unknown algorithm")),
356 };
357
358 println!("\n{} {}", "Result:".blue().bold(), result.white());
359 Ok(())
360}
361
362fn handle_key_exchange(protocol: ExchangeProtocol) -> Result<()> {
401 let result = match true {
402 _ if protocol.dh => {
403 let choice = interactive::prompt_for_choices(
404 "Select Diffie-Hellman operation",
405 &[
406 "Interactive Simulation (Alice & Bob)",
407 "Manual Exchange - Start Session",
408 "Manual Exchange - Complete with Other's Key",
409 "Mathematical Concept Demo",
410 ],
411 )?;
412
413 match choice.as_str() {
414 "Interactive Simulation (Alice & Bob)" => dh::key_exchange("interactive")?,
415 "Manual Exchange - Start Session" => {
416 println!("\nπ Starting manual key exchange session...");
417 dh::key_exchange("manual")?
418 }
419 "Manual Exchange - Complete with Other's Key" => {
420 let other_public_key =
421 interactive::prompt_for_input("Enter other party's public key")?
422 .parse::<u64>()
423 .map_err(|_| {
424 anyhow::anyhow!("Invalid public key format. Must be a number.")
425 })?;
426
427 let my_private_key = interactive::prompt_for_input("Enter your private key")?
428 .parse::<u64>()
429 .map_err(|_| {
430 anyhow::anyhow!("Invalid private key format. Must be a number.")
431 })?;
432
433 dh::complete_manual_key_exchange(other_public_key, my_private_key)?
434 }
435 "Mathematical Concept Demo" => dh::key_exchange("demo")?,
436 _ => return Err(anyhow::anyhow!("Invalid choice")),
437 }
438 }
439 _ if protocol.ecdh => "ECDH key exchange is not yet implemented. Coming soon!".to_string(),
440 _ => return Err(anyhow::anyhow!("Unknown key exchange protocol")),
441 };
442
443 println!("\n{} {}", "Result:".cyan().bold(), result.white());
444 Ok(())
445}
446
447fn handle_keygen(algorithm: KeygenAlgorithm) -> Result<()> {
474 if algorithm.rsa {
475 let key_size: String =
476 interactive::prompt_for_choices("Select RSA key size", &["512", "1024", "2048"])?;
477 let format = interactive::prompt_for_key_output_format()?;
478 let key_size_num = key_size
479 .parse::<u32>()
480 .map_err(|_| anyhow::anyhow!("Invalid key size"))?;
481 let (public_key, private_key) = rsa::keygen_and_export(key_size_num, &format)?;
482 println!("\n{} {}", "Public Key:".green().bold(), public_key.white());
483 println!("{} {}", "Private Key:".yellow().bold(), private_key.white());
484 println!("β οΈ Keep your private key secure!");
485 Ok(())
486 } else {
487 Err(anyhow::anyhow!("Unknown key generation algorithm"))
488 }
489}
490
491pub fn handle_sign(algorithm: SigningAlgorithm) -> Result<()> {
493 if algorithm.rsa {
494 println!("π RSA Digital Signature");
495 println!("========================");
496
497 let data = interactive::prompt_for_input("Enter message to sign")?;
498 let private_key =
499 interactive::prompt_for_multiline_input("Enter private key (n:d format or PEM)")?;
500 let encoding = interactive::prompt_for_encoding("Select output encoding")?;
501
502 match rsa::sign(&data, &private_key, &encoding) {
503 Ok(signature) => {
504 println!("\nβ
Digital signature created successfully!");
505 println!("π Original message: {data}");
506 println!(
507 "π Digital signature ({}): {}",
508 encoding.to_uppercase(),
509 signature
510 );
511 println!("\nπ‘ Save this signature to verify the message authenticity later.");
512 }
513 Err(e) => {
514 eprintln!("β Signing failed: {e}");
515 return Err(e);
516 }
517 }
518
519 Ok(())
520 } else {
521 Err(anyhow::anyhow!("Unknown signing algorithm"))
522 }
523}
524
525pub fn handle_verify(algorithm: SigningAlgorithm) -> Result<()> {
527 if algorithm.rsa {
528 println!("π RSA Signature Verification");
529 println!("=============================");
530
531 let data = interactive::prompt_for_input("Enter original message")?;
532 let signature = interactive::prompt_for_input("Enter signature to verify")?;
533 let public_key =
534 interactive::prompt_for_multiline_input("Enter public key (n:e format or PEM)")?;
535 let encoding = interactive::prompt_for_encoding("Select signature encoding")?;
536
537 match rsa::verify(&data, &signature, &public_key, &encoding) {
538 Ok(is_valid) => {
539 println!("\nπ Signature verification result:");
540 println!("π Original message: {data}");
541 println!("π Signature: {}...", &signature[..signature.len().min(20)]);
542
543 if is_valid {
544 println!("β
VALID: The signature is authentic!");
545 println!("π The message integrity is verified and the signature is genuine.");
546 } else {
547 println!("β INVALID: The signature verification failed!");
548 println!(
549 "β οΈ The message may have been tampered with or the signature is forged."
550 );
551 }
552 }
553 Err(e) => {
554 eprintln!("β Verification failed: {e}");
555 return Err(e);
556 }
557 }
558
559 Ok(())
560 } else {
561 Err(anyhow::anyhow!("Unknown verification algorithm"))
562 }
563}