Implement challenge 33 Diffie-Hellman

This commit is contained in:
2022-08-31 19:30:34 -04:00
parent ddafb43934
commit 9e568ac97c
7 changed files with 91 additions and 19 deletions

View File

@@ -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");
}