105 lines
2.2 KiB
Rust
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)
|
|
}
|