|
|
@ -1,9 +1,8 @@ |
|
|
|
// Angefangen: 13:30
|
|
|
|
// bis: 16:20
|
|
|
|
//
|
|
|
|
// ca 5h
|
|
|
|
|
|
|
|
use clap::Parser; |
|
|
|
use clap_num::maybe_hex; |
|
|
|
use modinverse::modinverse; |
|
|
|
|
|
|
|
#[derive(Parser)] |
|
|
|
struct Cli { |
|
|
@ -55,7 +54,6 @@ fn derive_keys(mut k: u128) -> Vec<Keys> { |
|
|
|
subkeys.push(((k >> 96) & 0xFFFF) as u16); |
|
|
|
subkeys.push(((k >> 112) & 0xFFFF) as u16); |
|
|
|
k = k.rotate_left(25);
|
|
|
|
println!("key after shift {k}"); |
|
|
|
} |
|
|
|
let mut i = 0; |
|
|
|
while keys.len() < 8 { |
|
|
@ -71,8 +69,8 @@ fn derive_keys(mut k: u128) -> Vec<Keys> { |
|
|
|
} |
|
|
|
|
|
|
|
fn add(a: u16, b: u16) -> u16 { |
|
|
|
let (a, b, m) = (a as u32, b as u32, 0x10000 as u32); |
|
|
|
((a * b) % m) as u16 |
|
|
|
let (a, b, m) = (a as i32, b as i32, 0x10000 as i32); |
|
|
|
((a + b) % m) as u16 |
|
|
|
} |
|
|
|
|
|
|
|
fn mul(a: u16, b: u16) -> u16 { |
|
|
@ -90,26 +88,101 @@ fn mul(a: u16, b: u16) -> u16 { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fn idea_round() -> Vr { |
|
|
|
Vr::split(80)
|
|
|
|
fn idea_round(ks: &Keys, xs: Vr) -> Vr { |
|
|
|
let u1 = mul(ks.z1, xs.v1); |
|
|
|
let u2 = mul(ks.z2, xs.v2); |
|
|
|
let u3 = add(ks.z3, xs.v3); |
|
|
|
let u4 = add(ks.z4, xs.v4); |
|
|
|
let u13 = u1 ^ u3; |
|
|
|
let u24 = u2 ^ u4; |
|
|
|
let u5 = mul(ks.z5, u13); |
|
|
|
let c1 = mul(ks.z6, add(u24, u5)); |
|
|
|
let c2 = add(u5, c1); |
|
|
|
Vr { v1: c1 ^ u3, v2: c2 ^ u4, v3: c1 ^ u1, v4: c2 ^ u2 }
|
|
|
|
} |
|
|
|
|
|
|
|
fn idea_finish(ks: &Keys, xs: Vr) -> Vr { |
|
|
|
let u1 = mul(ks.z1, xs.v1); |
|
|
|
let u2 = mul(ks.z2, xs.v2); |
|
|
|
let u3 = add(ks.z3, xs.v3); |
|
|
|
let u4 = add(ks.z4, xs.v4); |
|
|
|
Vr { v1: u1, v2: u2, v3: u3, v4: u4 }
|
|
|
|
} |
|
|
|
|
|
|
|
fn invert_keys(ks: &Keys, z5: u16, z6: u16) -> Keys { |
|
|
|
let mut z1 = ks.z1 as i32; |
|
|
|
let mut z2 = ks.z2 as i32; |
|
|
|
if ks.z1 == 0 { |
|
|
|
z1 = 0x010000 as i32; |
|
|
|
} |
|
|
|
if ks.z2 == 0 { |
|
|
|
z2 = 0x010000 as i32; |
|
|
|
} |
|
|
|
Keys { |
|
|
|
z1: modinverse(z1 as i32, 0x0010001 as i32).expect("Modular inverse of z1 doesn't exist!") as u16, |
|
|
|
z2: modinverse(z2 as i32, 0x0010001 as i32).expect("Modular inverse of z2 doesn't exist!") as u16, |
|
|
|
z3: (0x10000 as u32 - ks.z3 as u32) as u16, |
|
|
|
z4: (0x10000 as u32 - ks.z4 as u32) as u16, |
|
|
|
z5: z5, |
|
|
|
z6: z6 } |
|
|
|
} |
|
|
|
|
|
|
|
fn encrypt(k: u128, m: u64) -> u64 { |
|
|
|
let xr = Vr::split(m); |
|
|
|
assert_eq!(m, xr.expand()); |
|
|
|
let round_keys = derive_keys(k); |
|
|
|
mul(xr.v1, 0).into() |
|
|
|
// Derive keys
|
|
|
|
let kr = derive_keys(k); |
|
|
|
|
|
|
|
let mut bs = xr; |
|
|
|
let mut i = 0; |
|
|
|
while i < 8 { |
|
|
|
println!("Round {i}:"); |
|
|
|
bs = idea_round(&kr[i], bs); |
|
|
|
println!("intermediate result: {:?}\n", bs.expand()); |
|
|
|
i = i+1; |
|
|
|
} |
|
|
|
let ys = idea_finish(&kr[8], bs); |
|
|
|
ys.expand() |
|
|
|
} |
|
|
|
|
|
|
|
fn decrypt(k: u128, m: u64) -> u64 { |
|
|
|
let xr = Vr::split(m); |
|
|
|
assert_eq!(m, xr.expand()); |
|
|
|
// Derive and invert keys
|
|
|
|
let kr = derive_keys(k); |
|
|
|
let mut dr: Vec<Keys> = Vec::new(); |
|
|
|
let mut i = 8; |
|
|
|
while i > 0 { |
|
|
|
let ds = invert_keys(&kr[i], kr[i-1].z5, kr[i-1].z6); |
|
|
|
i = i-1; |
|
|
|
dr.push(ds); |
|
|
|
} |
|
|
|
let ds = invert_keys(&kr[0], 0, 0); |
|
|
|
dr.push(ds); |
|
|
|
|
|
|
|
let mut bs = xr; |
|
|
|
while i < 8 { |
|
|
|
println!("Round {i}:"); |
|
|
|
bs = idea_round(&dr[i], bs); |
|
|
|
println!("intermediate result: {:?}\n", bs.expand()); |
|
|
|
i = i+1; |
|
|
|
} |
|
|
|
let ys = idea_finish(&dr[8], bs); |
|
|
|
ys.expand() |
|
|
|
} |
|
|
|
|
|
|
|
fn main() { |
|
|
|
println!("Welcome to your IDEA encryption tool!"); |
|
|
|
println!("Welcome to your IDEA encryption tool!\n"); |
|
|
|
|
|
|
|
let args = Cli::parse(); |
|
|
|
let key: u128 = args.key; |
|
|
|
let key2: u128 = args.key; |
|
|
|
let message: u64 = args.message; |
|
|
|
|
|
|
|
println!("message: {:?}, key: {:?}", message, key); |
|
|
|
println!("message: {:?}, key: {:?}\n", message, key); |
|
|
|
|
|
|
|
let cipher: u64 = encrypt(key, message); |
|
|
|
println!("ciphertext: {:?}", cipher); |
|
|
|
println!("Ciphertext: {:?}\n", cipher); |
|
|
|
let plain: u64 = decrypt(key2, cipher); |
|
|
|
println!("Computed plaintext: {:?}", plain); |
|
|
|
} |
|
|
|