1
0
Files
information-security/src/rsa.rs
2024-10-22 14:05:01 +03:00

105 lines
2.2 KiB
Rust

#![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)
}
}
fn gen_n_phi(bits: u64) -> (BigUint, BigUint) {
let mut numbers = utils::generate_n_primes(2, 2 + bits / 2);
let p = numbers.pop().unwrap();
let q = numbers.pop().unwrap();
let n = &p * &q;
let phi = (p - 1u8) * (q - 1u8);
(n, phi)
}
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);
}
let n = n;
let phi = phi;
let e = BigUint::from(65537u32);
let d = e.modinv(&phi).unwrap();
let public_key = PublicKey::new(n.clone(), e);
let private_key = PrivateKey::new(n, d);
(public_key, private_key)
}
pub fn calculate_key(p: BigUint, q: BigUint, e: BigUint) -> (PublicKey, PrivateKey) {
let n = &p * &q;
let phi = (p - 1u8) * (q - 1u8);
let d = e.modinv(&phi).unwrap();
let public_key = PublicKey::new(n.clone(), e);
let private_key = PrivateKey::new(n, d);
(public_key, private_key)
}