add elliptic curves, diffie hellman and 'messaging'
This commit is contained in:
parent
7960658ef9
commit
11f22a44be
4 changed files with 148 additions and 29 deletions
109
src/keygen.rs
Normal file
109
src/keygen.rs
Normal file
|
@ -0,0 +1,109 @@
|
|||
use core::str;
|
||||
|
||||
use crate::utils::*;
|
||||
|
||||
struct EllipticCurve {
|
||||
a: i128,
|
||||
b: i128,
|
||||
r#mod: i128,
|
||||
}
|
||||
impl EllipticCurve {
|
||||
pub fn new(a: i128, b: i128, r#mod: i128) -> Self {
|
||||
EllipticCurve {
|
||||
a: a,
|
||||
b: b,
|
||||
r#mod: r#mod,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn y(&self, x: i128) -> i128 {
|
||||
(x.pow(3) + self.b * x + self.a) % self.r#mod
|
||||
}
|
||||
pub fn random(&self) -> (i128, i128) {
|
||||
let mut start = rand::random::<i128>() % self.r#mod;
|
||||
let i_count = rand::random::<i8>();
|
||||
|
||||
for _ in 0..i_count {
|
||||
start = self.y(start);
|
||||
}
|
||||
|
||||
(start, self.y(start))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Person {
|
||||
pub name: String,
|
||||
private_key: Option<u32>,
|
||||
pub public_key: Option<u32>,
|
||||
pub shared_key: Option<u32>,
|
||||
}
|
||||
impl Person {
|
||||
pub fn new(name: &str) -> Self {
|
||||
Person {
|
||||
name: name.to_string(),
|
||||
private_key: None,
|
||||
public_key: None,
|
||||
shared_key: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gen_keys(&mut self, start: u32, r#mod: u32) {
|
||||
let private = rand::random::<u32>();
|
||||
self.private_key = Some(private.into());
|
||||
let public = mod_pow(start, private.into(), r#mod);
|
||||
self.public_key = Some(public);
|
||||
eprintln!(
|
||||
"{}: private: {} -> public: {}",
|
||||
self.name,
|
||||
self.private_key.unwrap(),
|
||||
self.public_key.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
pub fn gen_shared(&mut self, public: u32, r#mod: u32) {
|
||||
self.shared_key = Some(mod_pow(public, self.private_key.unwrap(), r#mod))
|
||||
}
|
||||
|
||||
pub fn diffie_hellman(p1: &mut Self, p2: &mut Self) {
|
||||
let r = rand::random::<u32>();
|
||||
let mut m: u32 = 4;
|
||||
while m < r || !is_prime(m) {
|
||||
m = rand::random::<u32>();
|
||||
}
|
||||
p1.gen_keys(r.into(), m.into());
|
||||
p2.gen_keys(r.into(), m.into());
|
||||
p1.gen_shared(p2.public_key.unwrap(), m.into());
|
||||
p2.gen_shared(p1.public_key.unwrap(), m.into());
|
||||
assert_eq!(p1.shared_key, p2.shared_key);
|
||||
}
|
||||
|
||||
fn xor_cipher(msg: &[u8], key: u32) -> Vec<u8> {
|
||||
let key_bytes = key.to_le_bytes();
|
||||
let key_len = key_bytes.len();
|
||||
|
||||
msg.iter()
|
||||
.enumerate()
|
||||
.map(|(i, &byte)| byte ^ key_bytes[i % key_len])
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn send(&self, msg_raw: &[u8], target: &Self) {
|
||||
let encrypted_raw = Self::xor_cipher(msg_raw, self.shared_key.unwrap());
|
||||
let encrypted = str::from_utf8(&encrypted_raw).unwrap_or("not displayable");
|
||||
let msg = str::from_utf8(&msg_raw).unwrap_or("not displayable");
|
||||
eprintln!(
|
||||
"[{}] Sending message '{}' ({}) to {}",
|
||||
self.name, msg, encrypted, target.name
|
||||
);
|
||||
target.recv(&encrypted_raw, self);
|
||||
}
|
||||
fn recv(&self, msg_raw: &[u8], source: &Self) {
|
||||
let decrypted_raw = Self::xor_cipher(msg_raw, self.shared_key.unwrap());
|
||||
let decrypted = str::from_utf8(&decrypted_raw).unwrap_or("not displayable");
|
||||
let msg = str::from_utf8(&msg_raw).unwrap_or("not displayable");
|
||||
eprintln!(
|
||||
"[{}] Received message '{}' ({}) from {}",
|
||||
self.name, decrypted, msg, source.name
|
||||
);
|
||||
}
|
||||
}
|
10
src/main.rs
10
src/main.rs
|
@ -1,6 +1,15 @@
|
|||
use keygen::Person;
|
||||
|
||||
mod keygen;
|
||||
mod pollard_rho;
|
||||
mod utils;
|
||||
|
||||
fn main() {
|
||||
let mut alice = Person::new("alice");
|
||||
let mut bob = Person::new("bob");
|
||||
Person::diffie_hellman(&mut alice, &mut bob);
|
||||
alice.send(b"Hello World", &bob);
|
||||
/*
|
||||
let mut n = 0;
|
||||
while n % 2 == 0 {
|
||||
n = rand::random::<u16>();
|
||||
|
@ -10,4 +19,5 @@ fn main() {
|
|||
"Generated random number {}, got prime divisor {}",
|
||||
n, n_primediv
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::utils::{is_prime, mod_pow};
|
||||
use gcd::Gcd;
|
||||
|
||||
/**
|
||||
|
@ -40,32 +41,3 @@ pub fn pollard_rho(n: u32) -> u32 {
|
|||
|
||||
div
|
||||
}
|
||||
|
||||
/**
|
||||
* Discrete/Modular exponentiation
|
||||
*
|
||||
* Highly memory efficient because the full result is never stored, but shortened by defined modulo instead.
|
||||
* We can use that because the prime divisor required for our algorithm is guarenteed to be smaller
|
||||
* than n.
|
||||
*
|
||||
* Counterpart function to the discrete logarithm.
|
||||
*/
|
||||
fn mod_pow(base: u32, exp: u32, r#mod: u32) -> u32 {
|
||||
let mut result = 1;
|
||||
for _ in 0..exp - 1 {
|
||||
result = (result * base) % r#mod;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
/**
|
||||
* very primitive prime checker
|
||||
*/
|
||||
fn is_prime(n: u32) -> bool {
|
||||
for i in (3..=(n as f32).sqrt() as u32).step_by(2) {
|
||||
if n % i == 0 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
|
28
src/utils.rs
Normal file
28
src/utils.rs
Normal file
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Discrete/Modular exponentiation
|
||||
*
|
||||
* Highly memory efficient because the full result is never stored, but shortened by defined modulo instead.
|
||||
* We can use that because the prime divisor required for our algorithm is guarenteed to be smaller
|
||||
* than n.
|
||||
*
|
||||
* Counterpart function to the discrete logarithm.
|
||||
*/
|
||||
pub fn mod_pow(base: u32, exp: u32, r#mod: u32) -> u32 {
|
||||
let mut result: u64 = 1;
|
||||
for _ in 0..exp - 1 {
|
||||
result = (result * u64::from(base)) % u64::from(r#mod);
|
||||
}
|
||||
u32::try_from(result).unwrap()
|
||||
}
|
||||
|
||||
/**
|
||||
* very primitive prime checker
|
||||
*/
|
||||
pub fn is_prime(n: u32) -> bool {
|
||||
for i in (3..=(n as f32).sqrt() as u32).step_by(2) {
|
||||
if n % i == 0 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
Loading…
Add table
Reference in a new issue