From 1fd272c01003c7d4d880ca4185e09305cc1f14ce Mon Sep 17 00:00:00 2001 From: Maya Herrscher Date: Fri, 19 Jul 2024 21:46:55 +0200 Subject: [PATCH] Working implementation of encrypt and decrypt --- Cargo.lock | 21 +++++++++++- Cargo.toml | 3 +- src/main.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 108 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1946d41..c9214d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,10 +120,11 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "idea" -version = "0.1.0" +version = "0.2.0" dependencies = [ "clap", "clap-num", + "modinverse", ] [[package]] @@ -132,6 +133,24 @@ version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +[[package]] +name = "modinverse" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f62f577f148cc1a9466e7065a22e59466a7d537cceba5e77e57181d0f706633" +dependencies = [ + "num-integer", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" diff --git a/Cargo.toml b/Cargo.toml index 139f5d0..51de580 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,9 @@ [package] name = "idea" -version = "0.2.0" +version = "1.0.0" edition = "2021" [dependencies] clap = { version = "4.0", features = ["derive"] } clap-num = { version = "1.1" } +modinverse = { version = "0.1" } diff --git a/src/main.rs b/src/main.rs index d573ae9..4f36a88 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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 { 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 { } 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 = 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); }