Implement challenge 33 Diffie-Hellman
This commit is contained in:
66
src/set5.rs
66
src/set5.rs
@@ -1,3 +1,67 @@
|
||||
use crate::rsa;
|
||||
use num_bigint::{BigUint, RandBigInt, ToBigUint};
|
||||
use rand::Rng;
|
||||
use std::fs;
|
||||
|
||||
pub fn challenge33() {
|
||||
println!("[xxxx] Challenge 33: now we talking!");
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
fn simple_diffie_hellman() {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
// Set a variable "p" to 37 and "g" to 5.
|
||||
let p: u32 = 37;
|
||||
let g: u32 = 5;
|
||||
|
||||
// Generate "a", a random number mod 37. Now generate "A", which is "g" raised to the "a"
|
||||
// power mode 37 --- A = (g**a) % p.
|
||||
let a: u32 = rng.gen::<u32>() % p;
|
||||
let A = rsa::expmod(g, a, p);
|
||||
|
||||
// Do the same for "b" and "B".
|
||||
let b: u32 = rng.gen::<u32>() % p;
|
||||
let B = rsa::expmod(g, b, p);
|
||||
|
||||
// "A" and "B" are public keys. Generate a session key with them; set "s" to "B" raised to
|
||||
// the "a" power mod 37 --- s = (B**a) % p.
|
||||
let s = rsa::expmod(B, a, p);
|
||||
|
||||
// Do the same with A**b, check that you come up with the same "s".
|
||||
let s_ = rsa::expmod(A, b, p);
|
||||
|
||||
assert_eq!(s, s_, "crypto is broken");
|
||||
// To turn "s" into a key, you can just hash it to create 128 bits of key material (or
|
||||
// SHA256 it to create a key for encrypting and a key for a MAC).
|
||||
}
|
||||
|
||||
fn serious_diffie_hellman() {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
let s = fs::read_to_string("data/33.txt").expect("run from git root dir");
|
||||
let b: Vec<u8> = s
|
||||
.chars()
|
||||
.filter(|c| *c != '\n')
|
||||
.map(|c| c.to_digit(16).unwrap().try_into().unwrap())
|
||||
.collect();
|
||||
let p = BigUint::from_radix_be(&b, 16).unwrap();
|
||||
let g = 2_u8.to_biguint().unwrap();
|
||||
|
||||
let a = rng.gen_biguint_below(&p);
|
||||
let A = g.modpow(&a, &p);
|
||||
|
||||
let b = rng.gen_biguint_below(&p);
|
||||
let B = g.modpow(&b, &p);
|
||||
|
||||
let s = B.modpow(&a, &p);
|
||||
let s_ = A.modpow(&b, &p);
|
||||
assert_eq!(s, s_, "crypto is broken");
|
||||
}
|
||||
|
||||
simple_diffie_hellman();
|
||||
serious_diffie_hellman();
|
||||
println!("[okay] Challenge 33: implemented Diffie-Hellman");
|
||||
}
|
||||
|
||||
pub fn challenge34() {
|
||||
println!("[xxxx] Challenge 34: tbd");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user