1
0
This commit is contained in:
2024-10-22 15:36:43 +03:00
parent 612c13dc90
commit 0196929843
3 changed files with 108 additions and 8 deletions

View File

@@ -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::<u8>::from_hex(encrypted)?;

92
src/pha.rs Normal file
View File

@@ -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<u8> {
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<u8> {
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)
}

View File

@@ -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;