lab4
This commit is contained in:
22
src/main.rs
22
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::<u8>::from_hex(encrypted)?;
|
||||
|
||||
|
||||
92
src/pha.rs
Normal file
92
src/pha.rs
Normal 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)
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user