mirror of
https://github.com/kristoferssolo/cipher-workshop.git
synced 2025-12-20 11:04:38 +00:00
30 lines
1.2 KiB
Rust
30 lines
1.2 KiB
Rust
/// Generic bit permutation for DES specification.
|
|
///
|
|
/// DES uses 1-based positioning where bit 1 is the leftmost (MSB) and bit 64 is the rightmost (LSB).
|
|
/// This function handles this correctly for arbitrary input/output sizes.
|
|
///
|
|
/// # Arguments
|
|
/// - `input` - The input value (treated as a bitfield of `input_bits` size)
|
|
/// - `input_bits` - Number of meaningful bits in the input (1-64)
|
|
/// - `output_bits` - Number of bits in the output (1-64)
|
|
/// - `position_table` - Table of 1-based positions (1 to `input_bits`) where each output bit comes from.
|
|
/// The table should have `output_bits` entries. For each entry i (0-based), `position_table`[i] indicates
|
|
/// which input bit (1-based) should go to the i-th output bit position (from MSB to LSB).
|
|
#[must_use]
|
|
pub fn permutate(
|
|
input: u64,
|
|
input_bit_amount: u64,
|
|
output_bit_amount: u64,
|
|
position_table: &[u8],
|
|
) -> u64 {
|
|
position_table
|
|
.iter()
|
|
.enumerate()
|
|
.fold(0, |acc, (idx, &input_pos_1based)| {
|
|
let input_bit_pos = input_bit_amount - u64::from(input_pos_1based);
|
|
let bit_value = (input >> input_bit_pos) & 1;
|
|
let output_bit_pos = output_bit_amount - 1 - (idx as u64);
|
|
acc | (bit_value << output_bit_pos)
|
|
})
|
|
}
|