-
-
Save rust-play/95409abba209dae21a181f2e9772bf2a to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use num_bigint::{BigInt, BigUint, Sign}; | |
use num_traits::{One, Zero}; | |
use std::str::FromStr; // For parsing BigUint from strings (e.g., hex) | |
// --- RSA Core Functions --- | |
/// Performs modular exponentiation: base^exp % modulus | |
fn modpow(base: &BigUint, exp: &BigUint, modulus: &BigUint) -> BigUint { | |
// This is the core of RSA. `num-bigint` provides an optimized `modpow` method. | |
base.modpow(exp, modulus) | |
} | |
// --- RSA Key Structure (Hardcoded for simplicity) --- | |
// In a real application, you'd generate these based on large random primes. | |
// Using small primes (p=61, q=53) for a tiny example. | |
// p = 61 | |
// q = 53 | |
// n = p * q = 61 * 53 = 3233 | |
// phi = (p-1)*(q-1) = 60 * 52 = 3120 | |
// e = 17 (a common choice, coprime with 3120) | |
// d = 17^-1 mod 3120 = 413 (modular multiplicative inverse) | |
const N_STR: &str = "3233"; // n = p * q | |
const E_STR: &str = "17"; // e = public exponent | |
const D_STR: &str = "413"; // d = private exponent | |
// --- Main Application Logic --- | |
fn main() -> Result<(), Box<dyn std::error::Error>> { | |
let args: Vec<String> = std::env::args().collect(); | |
#[cfg(not(debug_assertions))] | |
if args.len() < 2 { | |
eprintln!("Usage: {} <encrypt|decrypt> <message_or_ciphertext_decimal>", args[0]); | |
eprintln!(" <message_or_ciphertext_decimal>: The number to encrypt/decrypt, in decimal."); | |
eprintln!("NOTE: This is a minimal, INSECURE RSA implementation for demonstration ONLY."); | |
eprintln!(" It does NOT use padding and should NOT be used for real cryptography."); | |
return Ok(()); | |
} | |
#[cfg(not(debug_assertions))] | |
let command = &args[1]; | |
let command = &"encrypt"; | |
#[cfg(not(debug_assertions))] | |
let input_decimal_str = &args[2]; | |
let input_decimal_str = &"333"; | |
// Parse the pre-defined RSA parameters | |
let n = BigUint::from_str(N_STR).expect("Invalid N constant"); | |
let e = BigUint::from_str(E_STR).expect("Invalid E constant"); | |
let d = BigUint::from_str(D_STR).expect("Invalid D constant"); | |
// Parse the input message/ciphertext | |
let input_num = BigUint::from_str(input_decimal_str) | |
.map_err(|_| "Input must be a valid decimal number")?; | |
match command.as_ref() { | |
"encrypt" => { | |
// Check if message is smaller than n (required for raw RSA) | |
if input_num >= n { | |
eprintln!("Error: Message ({}) must be smaller than the modulus N ({}).", input_num, n); | |
return Err("Message too large for raw RSA".into()); | |
} | |
// C = M^e mod n | |
let ciphertext = modpow(&input_num, &e, &n); | |
println!("Ciphertext (decimal): {}", ciphertext); | |
} | |
"decrypt" => { | |
// M = C^d mod n | |
let decrypted_message = modpow(&input_num, &d, &n); | |
println!("Decrypted Message (decimal): {}", decrypted_message); | |
} | |
_ => { | |
eprintln!("Unknown command: {}", command); | |
eprintln!("Use 'encrypt' or 'decrypt'."); | |
} | |
} | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment