diff --git a/src/main.rs b/src/main.rs index da943fc..98c777c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use std::fmt::Display; use hex::{FromHex, ToHex}; use inquire::{validator::Validation, CustomType, Select, Text}; +mod pha; mod rsa; mod utils; @@ -61,7 +62,7 @@ fn generate_key() -> anyhow::Result<()> { }) .prompt()?; - let (public_key, private_key) = rsa::keygen(bits); + let (public_key, private_key) = pha::keygen(bits); println!(); println!("Generated key with {} bits", private_key.bits()); @@ -76,11 +77,10 @@ fn generate_key() -> anyhow::Result<()> { } fn calculate_key() -> anyhow::Result<()> { - let p = CustomType::new("Enter prime p").prompt()?; - let q = CustomType::new("Enter prime q").prompt()?; - let e = CustomType::new("Enter public exponent e").prompt()?; + let n = CustomType::new("Enter prime n").prompt()?; + let e = CustomType::new("Enter e").prompt()?; - let (public_key, private_key) = rsa::calculate_key(p, q, e); + let (public_key, private_key) = pha::calculate_key(n, e); println!(); println!("Public key:"); @@ -98,11 +98,19 @@ fn encrypt() -> anyhow::Result<()> { let data = Text::new("Enter data").prompt()?; - let public_key = rsa::PublicKey::new(n, e); + let public_key = pha::PublicKey::new(n, e); let chunk_size = (public_key.bits() / 8) as usize; let safe_chunk_size = chunk_size - 1; let data = data.as_bytes(); + if chunk_size < 2 { + println!( + "This key cannot encrypt byte data! Key size {} bits is less than 16 bits.", + public_key.bits() + ); + return Ok(()); + } + println!(); println!("data (raw) = {:?}", data); @@ -130,7 +138,7 @@ fn decrypt() -> anyhow::Result<()> { let encrypted = Text::new("Enter encrypted data").prompt()?; - let private_key = rsa::PrivateKey::new(n, d); + let private_key = pha::PrivateKey::new(n, d); let chunk_size = (private_key.bits() / 8) as usize; let encrypted = Vec::::from_hex(encrypted)?; diff --git a/src/pha.rs b/src/pha.rs new file mode 100644 index 0000000..836c5b0 --- /dev/null +++ b/src/pha.rs @@ -0,0 +1,92 @@ +#![allow(unused)] + +use std::fmt::{Display, Formatter}; + +use num::BigUint; + +use crate::utils; + +pub struct PublicKey { + n: BigUint, + e: BigUint, +} + +impl PublicKey { + pub fn new(n: BigUint, e: BigUint) -> Self { + Self { n, e } + } + + pub fn encrypt(&self, chunk: &[u8]) -> Vec { + let message = BigUint::from_bytes_le(chunk); + + let encrypted = message.modpow(&self.e, &self.n); + encrypted.to_bytes_le() + } + + pub fn bits(&self) -> u64 { + self.n.bits() + } +} + +impl Display for PublicKey { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "(n = {:?}, e = {:?})", self.n, self.e) + } +} + +pub struct PrivateKey { + n: BigUint, + d: BigUint, +} + +impl PrivateKey { + pub fn new(n: BigUint, d: BigUint) -> Self { + Self { n, d } + } + + pub fn decrypt(&self, chunk: &[u8]) -> Vec { + let encrypted = BigUint::from_bytes_le(chunk); + + let decrypted = encrypted.modpow(&self.d, &self.n); + decrypted.to_bytes_le() + } + + pub fn bits(&self) -> u64 { + self.n.bits() + } +} + +impl Display for PrivateKey { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "(n = {:?}, d = {:?})", self.n, self.d) + } +} + +pub fn gen_n_e(bits: u64) -> (BigUint, BigUint) { + let mut numbers = utils::generate_n_primes(2, bits); + let a1 = numbers.pop().unwrap(); + let a2 = numbers.pop().unwrap(); + + let (n, e) = if a1 < a2 { (a2, a1) } else { (a1, a2) }; + + (n, e) +} + +pub fn keygen(bits: u64) -> (PublicKey, PrivateKey) { + let (mut n, mut e) = gen_n_e(bits); + while n.bits() < bits { + (n, e) = gen_n_e(bits); + } + + calculate_key(n, e) +} + +pub fn calculate_key(n: BigUint, e: BigUint) -> (PublicKey, PrivateKey) { + let one = BigUint::from(1u8); + let d = e.modinv(&(&n - one)).unwrap(); + + let public_key = PublicKey::new(n.clone(), e); + let private_key = PrivateKey::new(n, d); + + (public_key, private_key) +} diff --git a/src/rsa.rs b/src/rsa.rs index 2dc7d11..5869eb7 100644 --- a/src/rsa.rs +++ b/src/rsa.rs @@ -76,7 +76,7 @@ fn gen_n_phi(bits: u64) -> (BigUint, BigUint) { pub fn keygen(bits: u64) -> (PublicKey, PrivateKey) { let (mut n, mut phi) = gen_n_phi(bits); while n.bits() < bits { - (n, phi) = gen_n_phi(bits); + (n, phi) = gen_n_phi(bits); } let n = n;