Running Experiments with RSA
Michaela Molina (michaela.molina@sjsu.edu)
Purpose:
In this file we show our use of RSA. This system may be broken by a quantum computer in the future. We use this system in our experiments comparing pre-quantum systems with post-quantum systems.
Code:
main.rs
use rsa::{PublicKey, RsaPrivateKey, RsaPublicKey, PaddingScheme};
mod text;
use rand::Rng;
use std::mem;
use std::time::Instant;
use std::time::Duration;
fn main() {
let bits = 2048;
let private_key = RsaPrivateKey::new(&mut rng, bits).expect("failed to generate a key");
let public_key = RsaPublicKey::from(&private_key);
let mut data = (&text::text()[0..500 as usize]).to_string(); // data is a string
// Encrypt
let mut chars_per_block:usize = 250;
let mut blocks = divide_into_blocks(data.clone(), chars_per_block); // blocks is a Vec of Strings
let mut iv = iv(chars_per_block);
let mut prev_ciphertext = &iv[..];
let mut copy = Vec::new();
let mut ciphertext = Vec::new();
for block in &blocks {
let mut data = block.as_bytes();
let mut data = xor_vec_of_u8(&data.to_vec(), &prev_ciphertext.to_vec()); // Vec<u8> operations
let mut data = &data[..];
let padding = PaddingScheme::new_pkcs1v15_encrypt();
let mut enc_data = public_key.encrypt(&mut rng, padding, &data[..]).expect("failed to encrypt");
copy = enc_data.clone();
prev_ciphertext = ©[..];
ciphertext.push(enc_data.to_vec());
}
// Decrypt
let mut prev_ciphertext = iv;
let mut plaintext = Vec::new();
for block in ciphertext {
let block_copy = block.clone();
let enc_data = &block[..];
let padding = PaddingScheme::new_pkcs1v15_encrypt();
let dec_data = private_key.decrypt(padding, &enc_data).expect("failed to decrypt");
let mut plaintext_block = xor_vec_of_u8(&dec_data.to_vec(), &prev_ciphertext);
plaintext.push(plaintext_block);
prev_ciphertext = block_copy.clone();
}
let mut vec_of_strings:Vec<String> = Vec::new();
let mut final_string = String::from("");
for block in plaintext {
let st = std::str::from_utf8(&block[..]).unwrap();
st.to_string();
final_string.push_str(st);
}
final_string = final_string.trim_end().to_string();
println!("final string = '{}'", final_string);
}
fn iv(len:usize) -> Vec<u8> {
let mut iv = Vec::new();
for i in 0..len {
iv.push(rand::thread_rng().gen_range(0..2_u64.pow(8 as u32)) as u8);
}
iv
}
fn divide_into_blocks(s:String, len:usize) -> Vec<String> {
let mut blocks = Vec::new();
let mut block = String::from("");
for c in s.chars() {
block.push_str(&c.to_string());
if block.len() == len {
blocks.push(block.clone());
block = String::from("");
}
}
if block.len() > 0 {
while block.len() < 10 {
block.push_str(&' '.to_string());
}
blocks.push(block.clone());
}
blocks
}
fn xor_vec_of_u8(a:&Vec<u8>, b:&Vec<u8>) -> Vec<u8> {
let mut c = Vec::new();
let mut i = 0;
while i < a.len() && i < b.len() {
c.push(a[i] ^ b[i]);
i += 1;
}
c
}
Cargo.toml
[package]
name = "rsa"
version = "0.1.0"
edition = "2021"
[dependencies]
rand = "0.8.5"
rsa = "0.6.1"
|