diff --git a/src/algo/feistel0.rs b/src/algo/feistel0.rs index 7901704..2a33ab5 100644 --- a/src/algo/feistel0.rs +++ b/src/algo/feistel0.rs @@ -10,13 +10,13 @@ const SBOX: [u8; 0x10] = [0x4, 3, 9, 0xa, 0xb, 2, 0xe, 1, 0xd, 0xc, 8, 6, 7, 5, 0, 0xf]; -fn swap_bits(n: u8, p1: u8, p2: u8) -> u8 { - let bit1 = (n >> p1) & 1; - let bit2 = (n >> p2) & 1; - let mut x = (bit1 ^ bit2); - x = (x << p1) | (x << p2); - - n ^ x +#[test] +/// test inner against the given values +fn test_inner() { + assert!(inner(0x1234, 0x0000) == 0x29a8); + assert!(inner(0x1234, 0x2345) == 0x0aed); + assert!(inner(0xabcd, 0xbeef) == 0x089a); + assert!(inner(0x9876, 0xfedc) == 0x93c5); } pub fn inner(input: u16, key: u16) -> u16 { @@ -24,11 +24,12 @@ pub fn inner(input: u16, key: u16) -> u16 { let mut blocks: [u8; 4] = [ ((input & 0xf000) >> 12).to_be_bytes()[1], ((input & 0x0f00) >> 08).to_be_bytes()[1], - ((input & 0x000f) >> 00).to_be_bytes()[1], ((input & 0x00f0) >> 04).to_be_bytes()[1], + ((input & 0x000f) >> 00).to_be_bytes()[1], ]; - dbg!(&blocks); + println!("{:04b} {:04b} {:04b} {:04b}", blocks[0], blocks[1], blocks[2], blocks[3]); + println!("{:x}{:x}{:x}{:x}", blocks[0], blocks[1], blocks[2], blocks[3]); // each block must not be more than 0xf for block in blocks { @@ -41,17 +42,43 @@ pub fn inner(input: u16, key: u16) -> u16 { blocks[1] = SBOX[blocks[1] as usize]; blocks[2] = SBOX[blocks[2] as usize]; - dbg!(&blocks); + println!("{:04b} {:04b} {:04b} {:04b}", blocks[0], blocks[1], blocks[2], blocks[3]); + println!("{:x}{:x}{:x}{:x}", blocks[0], blocks[1], blocks[2], blocks[3]); // swap position and endianess for outer blocks - let tmp = blocks[0]; - blocks[0] = u8::swap_bytes(blocks[3]); - blocks[3] = u8::swap_bytes(tmp); + let mut b0 = 0; + let mut b3 = 0; + b0 |= (blocks[0] & 0b1000) >> 3; + b0 |= (blocks[0] & 0b0100) >> 1; + b0 |= (blocks[0] & 0b0010) << 1; + b0 |= (blocks[0] & 0b0001) << 3; + b3 |= (blocks[3] & 0b1000) >> 3; + b3 |= (blocks[3] & 0b0100) >> 1; + b3 |= (blocks[3] & 0b0010) << 1; + b3 |= (blocks[3] & 0b0001) << 3; - dbg!(&blocks); + blocks[0] = b3; + blocks[3] = b0; println!("{:04b} {:04b} {:04b} {:04b}", blocks[0], blocks[1], blocks[2], blocks[3]); println!("{:x}{:x}{:x}{:x}", blocks[0], blocks[1], blocks[2], blocks[3]); - panic!("Not implemented"); + for block in blocks { + if block > 0xf { + panic!("Block is more than 0xf: {block}"); + } + } + + let mut result: u16 = 0; + result |= (blocks[0] as u16) << 12; + result |= (blocks[1] as u16) << 08; + result |= (blocks[2] as u16) << 04; + result |= (blocks[3] as u16) << 00; + + return result ^ key +} + +pub fn sbox(index: u8) -> u8 { + assert!(index < 0xf); + return SBOX[index as usize]; } diff --git a/src/main.rs b/src/main.rs index da52e0b..4437897 100644 --- a/src/main.rs +++ b/src/main.rs @@ -111,8 +111,10 @@ struct XorArgs { #[derive(Subcommand, Clone, Debug, PartialEq, Eq)] enum AlgoActions { - #[command(name="feistel-i")] - Feistel0Inner(Feistel0InnerArgs) + #[command(name="feistel0-i")] + Feistel0Inner(Feistel0InnerArgs), + #[command(name="feistel0-sbox")] + Feistel0SBOX(Feistel0SBOXArgs) } #[derive(Args, Clone, Debug, PartialEq, Eq)] @@ -123,6 +125,12 @@ struct Feistel0InnerArgs { key: u16, } +#[derive(Args, Clone, Debug, PartialEq, Eq)] +struct Feistel0SBOXArgs { + #[clap(value_parser=maybe_hex::)] + index: u8, +} + /*************************************************************************************************/ /// main function of plexcryptool. /// @@ -183,7 +191,16 @@ pub fn main() { println!("{}", result) } else { - println!("result is {}", result) + println!("result is {} ({:04x})", result, result) + } + } + AlgoActions::Feistel0SBOX(alg_fsb_args) => { + let result: u8 = algo::feistel0::sbox(alg_fsb_args.index); + if args.machine { + println!("{}", result) + } + else { + println!("result is {} ({:x})", result, result) } } }