feat: finish P-Box permutation implementation

This commit is contained in:
Kristofers Solo 2025-10-02 12:24:50 +03:00
parent e777444583
commit 384c96d36f
Signed by: kristoferssolo
GPG Key ID: 74FF8144483D82C8
2 changed files with 23 additions and 18 deletions

View File

@ -36,7 +36,7 @@ pub const E_BOX: [u8; 48] = [
]; ];
/// P-box permutation (32 bits). /// P-box permutation (32 bits).
pub const PERMUTATION: [u8; 32] = [ pub const P_BOX: [u8; 32] = [
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19,
13, 30, 6, 22, 11, 4, 25, 13, 30, 6, 22, 11, 4, 25,
]; ];

View File

@ -1,6 +1,6 @@
mod constants; mod constants;
use crate::constants::{E_BOX, IP, PC1_TABLE, PC2_TABLE, ROUND_ROTATIONS, S_BOXES}; use crate::constants::{E_BOX, IP, PC1_TABLE, PC2_TABLE, P_BOX, ROUND_ROTATIONS, S_BOXES};
#[derive(Debug)] #[derive(Debug)]
pub struct Des { pub struct Des {
@ -183,7 +183,7 @@ fn s_box_substitution(block: u64) -> u32 {
#[must_use] #[must_use]
fn p_box_permutation(input: u32) -> u32 { fn p_box_permutation(input: u32) -> u32 {
todo!() u32::try_from(permutate(u64::from(input), 32, 32, &P_BOX)).expect("32-bit value")
} }
#[must_use] #[must_use]
@ -201,7 +201,6 @@ fn process_feistel_rounds(initial_block: u64, subkeys: &[u64]) -> (u32, u32) {
(right, left) // left and right should be swapped (right, left) // left and right should be swapped
} }
/// Feistel function: Expand, XOR with subkey, S-box, permute. /// Feistel function: Expand, XOR with subkey, S-box, permute.
/// `R_i` = `L_(i-1)` XOR f(`R_(i-1)`, `K_1`) /// `R_i` = `L_(i-1)` XOR f(`R_(i-1)`, `K_1`)
#[must_use] #[must_use]
@ -455,19 +454,25 @@ mod tests {
assert_eq!(result, output, "Expected {output:08X}, got {result:08X}"); assert_eq!(result, output, "Expected {output:08X}, got {result:08X}");
} }
// #[test] #[rstest]
fn permuation_pbox() { #[case(0x5C82_B597, 0x234A_A9BB)] // Round 1
let input = 0x0; #[case(0xF8D0_3AAE, 0x3CAB_87A3)] // Round 2
let result = p_box_permutation(input); #[case(0x2710_E16F, 0x4D16_6EB0)] // Round 3
#[case(0x21ED_9F3A, 0xBB23_774C)] // Round 4
// P-box should preserve all bits (32 in, 32 out), just reorder #[case(0x50C8_31EB, 0x2813_ADC3)] // Round 5
let bit_count = input.count_ones(); #[case(0x41F3_4C3D, 0x9E45_CD2C)] // Round 6
let result_bit_count = result.count_ones(); #[case(0x1075_40AD, 0x8C05_1C27)] // Round 7
assert_eq!(bit_count, result_bit_count, "P-box changes bit count"); #[case(0x6C18_7CAE, 0x3C0E_86F9)] // Round 8
#[case(0x110C_5777, 0x2236_7C6A)] // Round 9
// Test specific bit mapping: PERMUTATION[0]=16 means bit 15 (0-based) of output = bit 15 of input #[case(0xDA04_5275, 0x62BC_9C22)] // Round 10
let input_bit_15 = (input >> 15) & 1; #[case(0x7305_D101, 0xE104_FA02)] // Round 11
let output_bit_0 = (result >> 31) & 1; // MSB first #[case(0x7B8B_2635, 0xC268_CFEA)] // Round 12
assert_eq!(input_bit_15, output_bit_0, "P-box bit mapping failed"); #[case(0x9AD1_8B4F, 0xDDBB_2922)] // Round 13
#[case(0x6479_9AF1, 0xB731_8E55)] // Round 14
#[case(0xB2E8_8D3C, 0x5B81_276E)] // Round 15
#[case(0xA783_2429, 0xC8C0_4F98)] // Round 16
fn permuation_pbox(#[case] block: u32, #[case] output: u32) {
let result = p_box_permutation(block);
assert_eq!(result, output, "Expected {output:08X}, got {result:08X}");
} }
} }