Skip to content

Instantly share code, notes, and snippets.

@MAGANER
Last active March 26, 2021 19:15
Show Gist options
  • Save MAGANER/918193ac5c9e5b60e9f63b52154d7239 to your computer and use it in GitHub Desktop.
Save MAGANER/918193ac5c9e5b60e9f63b52154d7239 to your computer and use it in GitHub Desktop.
RSA example in RUST
use rand::prelude::*;
use modinverse::modinverse;
fn is_prime(n: u32) -> bool
{
//checks is number prime
let limit = (n as f64).sqrt() as u32;
for i in 2..=limit {
if n % i == 0 {
return false;
}
}
true
}
fn generate_prime_numbers(max:u32) -> Vec<u32>
{
//it generates big prime numbers, required with RSA
let mut numbers = Vec::new();
for n in 2..max+1
{
if is_prime(n)
{
numbers.push(n);
}
}
numbers
}
fn get_random_prime_numbers(numbers:&Vec<u32>) -> (u32,u32)
{
//get two random prime numbers
let mut rng = thread_rng();
let q = rng.gen_range(0..numbers.len());
let p = rng.gen_range(0..numbers.len());
(numbers[q as usize],numbers[p as usize])
}
pub fn get_modulus(numbers:(u32,u32)) -> u32
{
numbers.0*numbers.1
}
fn compute_euler_fn(p:u32,q:u32) -> u32
{
(p-1)*(q-1)
}
fn gcd(_a:u32,_b:u32) -> u32
{
//Euclidean algorithm
let mut a = _a;
let mut b = _b;
while a != 0 && b != 0
{
if a > b
{
a = a % b;
} else {
b = b % a;
}
}
a + b
}
fn get_open_exponent(random_pair:(u32,u32),numbers:&Vec<u32>) -> u32
{
let euler_fn_val = compute_euler_fn(random_pair.0,random_pair.1);
let mut _numbers:Vec<u32> = Vec::new();
let mut prime = 0;
let mut counter = 0;
while prime < euler_fn_val && counter < numbers.len()
{
prime = numbers[counter as usize];
if gcd(prime,euler_fn_val) == 1
{
_numbers.push(prime);
}
counter += 1;
}
let pos_to_get = thread_rng().gen_range(0.._numbers.len());
_numbers[pos_to_get]
}
fn get_secret_key(exponent:u32,random_pair:(u32,u32)) -> Result<u32,String>
{
let euler_fn_val = compute_euler_fn(random_pair.0,random_pair.1);
match modinverse(exponent as i32,euler_fn_val as i32)
{
Some(val) => Ok(val.abs() as u32),
None => Err("can not get secret key!".to_string())
}
}
fn main()
{
let prime_numbers = generate_prime_numbers(100);
let random_pair = get_random_prime_numbers(&prime_numbers);
let n = get_modulus(random_pair);
let e = get_open_exponent(random_pair,&prime_numbers);
let d = match get_secret_key(e,random_pair)
{
Ok(val) => val,
Err(eval)=> {
println!("{}",eval);
0
}
};
println!("{} and {} is open key",n,e);
println!("secret key :{}",d);
//example: how to encode single character
let a = 'h' as u32;
let power = power_big_int(a.to_bigint().unwrap(),e);
let code = power%n.to_bigint().unwrap();
println!("encoded number is {}",code);
}
use num_bigint::*;
fn power_big_int(a:BigInt,pow:u32) -> BigInt
{
let mut number = a;
for _ in 0..pow
{
number = number.clone()*&number;
}
number
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment