diff --git a/Cargo.lock b/Cargo.lock index ef6e8c8..b2893d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,6 +66,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "byteorder" version = "1.5.0" @@ -78,6 +84,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + [[package]] name = "colog" version = "1.3.0" @@ -128,6 +143,12 @@ dependencies = [ "log", ] +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "getrandom" version = "0.2.15" @@ -175,6 +196,31 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", + "rand 0.5.6", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -183,7 +229,16 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", - "rand", + "rand 0.8.5", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", ] [[package]] @@ -195,6 +250,40 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-primes" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f25459a616100b36b5af31d8b05abbee29a5f29f83ddf95e78cb2268ab300a" +dependencies = [ + "log", + "num", + "num-bigint 0.2.6", + "num-traits", + "rand 0.5.6", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -231,6 +320,19 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "winapi", +] + [[package]] name = "rand" version = "0.8.5" @@ -239,7 +341,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -249,9 +351,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.6.4" @@ -296,9 +413,10 @@ version = "0.1.0" dependencies = [ "colog", "log", - "num-bigint", + "num-bigint 0.4.6", + "num-primes", "num-traits", - "rand", + "rand 0.8.5", ] [[package]] @@ -330,6 +448,28 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 0e8e6e0..37de6a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,5 @@ colog = "1.3.0" log = "0.4.22" num-bigint = { version = "0.4.6", features = ["rand"] } num-traits = "0.2.19" -rand = "0.8.5" +num-primes = "0.3" +rand = "0.8" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 1d74bad..f7be191 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,9 @@ use colog; use log::info; -use num_bigint::{BigInt, BigUint, RandBigInt, ToBigInt}; +use num_bigint::{BigInt, BigUint, ToBigInt}; +use num_primes::Generator; use num_traits::cast::ToPrimitive; use num_traits::{One, Zero}; -use rand::thread_rng; use std::io; pub struct RSA { @@ -13,22 +13,35 @@ pub struct RSA { } impl RSA { - pub fn new(_key_size: usize) -> Self { - let mut _rng = thread_rng(); + pub fn new(key_size: usize) -> Self { + // Generate two random primes of key_size/2 bits each + let p = Generator::new_prime(key_size / 2); + let q = Generator::new_prime(key_size / 2); - let p = _rng.gen_biguint(1024); - let q = _rng.gen_biguint(1024); - let n = &p * &q; + // Convert num-primes::BigUint to num-bigint::BigUint + let p_bigint = num_bigint::BigUint::parse_bytes(p.to_string().as_bytes(), 10).unwrap(); + let q_bigint = num_bigint::BigUint::parse_bytes(q.to_string().as_bytes(), 10).unwrap(); - let phi = (&p - BigUint::one()) * (&q - BigUint::one()); - let e = _rng.gen_biguint(1024); - let d = mod_inverse(&e, &phi).unwrap(); + let n = &p_bigint * &q_bigint; + + let phi = + (&p_bigint - num_bigint::BigUint::one()) * (&q_bigint - num_bigint::BigUint::one()); + + let e = num_bigint::BigUint::from(65537u32); + + // Calculate private key + let d = mod_inverse(&e, &phi) + .expect("Failed to compute modular inverse - e and phi must be coprime"); + + info!("Generated RSA key pair of {} bits", key_size); + info!("Public key (n,e): ({}, {})", n, e); RSA { n, e, d } } pub fn encrypt(&self, message: &str) -> Vec { message + .trim() // Remove newline .bytes() .map(|b| { let m = BigUint::from(b as u32); @@ -45,7 +58,7 @@ impl RSA { .iter() .map(|c| { let m = c.modpow(&self.d, &self.n); - m.to_u8().unwrap() + m.to_u8().expect("Decrypted value too large for u8") }) .collect(); @@ -84,7 +97,6 @@ fn main() { info!("RSA Encryption/Decryption"); info!("Enter a message to encrypt:"); - let rsa = RSA::new(1024); // Small key size for testing let mut message: String = "".to_string(); match io::stdin().read_line(&mut message) { Ok(n) => match n { @@ -94,6 +106,8 @@ fn main() { Err(error) => println!("error: {error}"), } + let rsa = RSA::new(1024); + info!("Original: {}", message); let encrypted = rsa.encrypt(&message);