Implement challenge 33 Diffie-Hellman
This commit is contained in:
parent
ddafb43934
commit
9e568ac97c
@ -8,3 +8,4 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
openssl = ">= 0.10.38"
|
openssl = ">= 0.10.38"
|
||||||
rand = ">= 0.8.5"
|
rand = ">= 0.8.5"
|
||||||
|
num-bigint = { version = ">= 0.4", features = ["rand"] }
|
||||||
|
8
data/33.txt
Normal file
8
data/33.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
ffffffffffffffffc90fdaa22168c234c4c6628b80dc1cd129024
|
||||||
|
e088a67cc74020bbea63b139b22514a08798e3404ddef9519b3cd
|
||||||
|
3a431b302b0a6df25f14374fe1356d6d51c245e485b576625e7ec
|
||||||
|
6f44c42e9a637ed6b0bff5cb6f406b7edee386bfb5a899fa5ae9f
|
||||||
|
24117c4b1fe649286651ece45b3dc2007cb8a163bf0598da48361
|
||||||
|
c55d39a69163fa8fd24cf5f83655d23dca3ad961c62f356208552
|
||||||
|
bb9ed529077096966d670c354e4abc9804f1746c08ca237327fff
|
||||||
|
fffffffffffff
|
17
src/bytes.rs
17
src/bytes.rs
@ -1,15 +1,10 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
#[derive(PartialEq, PartialOrd, Debug)]
|
#[derive(PartialEq, Eq, PartialOrd, Debug)]
|
||||||
pub struct Bytes(pub Vec<u8>);
|
pub struct Bytes(pub Vec<u8>);
|
||||||
|
|
||||||
impl Bytes {
|
impl Bytes {
|
||||||
pub fn empty() -> Bytes {
|
|
||||||
Bytes(vec![])
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_utf8(s: &str) -> Bytes {
|
pub fn from_utf8(s: &str) -> Bytes {
|
||||||
Bytes(s.as_bytes().to_vec())
|
Bytes(s.as_bytes().to_vec())
|
||||||
}
|
}
|
||||||
@ -62,16 +57,6 @@ impl Bytes {
|
|||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_ascii(&self) -> bool {
|
|
||||||
let Bytes(v) = self;
|
|
||||||
for &c in v.iter() {
|
|
||||||
if !(32..=127).contains(&c) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ascii_score(&self) -> u32 {
|
pub fn ascii_score(&self) -> u32 {
|
||||||
let Bytes(v) = self;
|
let Bytes(v) = self;
|
||||||
let mut r = 0;
|
let mut r = 0;
|
||||||
|
@ -14,6 +14,7 @@ mod md4;
|
|||||||
mod mt19937;
|
mod mt19937;
|
||||||
mod mtcipher;
|
mod mtcipher;
|
||||||
mod parser;
|
mod parser;
|
||||||
|
mod rsa;
|
||||||
mod set1;
|
mod set1;
|
||||||
mod set2;
|
mod set2;
|
||||||
mod set3;
|
mod set3;
|
||||||
@ -59,4 +60,5 @@ fn main() {
|
|||||||
set4::challenge32();
|
set4::challenge32();
|
||||||
}
|
}
|
||||||
set5::challenge33();
|
set5::challenge33();
|
||||||
|
set5::challenge34();
|
||||||
}
|
}
|
||||||
|
12
src/rsa.rs
Normal file
12
src/rsa.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
pub fn expmod(base: u32, exp: u32, m: u32) -> u32 {
|
||||||
|
if exp == 0 {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp % 2 == 0 {
|
||||||
|
let s = expmod(base, exp / 2, m);
|
||||||
|
(s * s) % m
|
||||||
|
} else {
|
||||||
|
(expmod(base, exp - 1, m) * base) % m
|
||||||
|
}
|
||||||
|
}
|
@ -186,7 +186,7 @@ mod challenge19 {
|
|||||||
|
|
||||||
for i in 0..ciphers_len {
|
for i in 0..ciphers_len {
|
||||||
for j in i..ciphers_len {
|
for j in i..ciphers_len {
|
||||||
if target_bytes[i] == None || target_bytes[j] == None {
|
if target_bytes[i].is_none() || target_bytes[j].is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let xored = target_bytes[i].unwrap() ^ target_bytes[j].unwrap();
|
let xored = target_bytes[i].unwrap() ^ target_bytes[j].unwrap();
|
||||||
|
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() {
|
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");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user