Skip to content

Commit

Permalink
Implement compression function
Browse files Browse the repository at this point in the history
  • Loading branch information
iwiwsb committed Oct 22, 2023
1 parent 5b27f9f commit c2070aa
Showing 1 changed file with 139 additions and 47 deletions.
186 changes: 139 additions & 47 deletions md6/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl MD6 {
Some(Self { rounds, ..self })
}

fn control_word(
pub fn control_word(
&self,
is_final_compression: bool,
num_of_padding_data_bits: u16,
Expand All @@ -72,7 +72,33 @@ impl MD6 {
}
}

fn compression(&self, node_id: u64, control_word: ControlWord, data: [u64; 64]) -> [u64; 16] {
pub fn compression(
&self,
node_id: u64,
control_word: ControlWord,
data: [u64; 64],
) -> [u64; 16] {
let mut input = [0u64; 89];
input[0..=14].copy_from_slice(&Self::VECTOR_Q);
input[15..=22].copy_from_slice(
self.key
.chunks(8)
.map(|bytes: &[u8]| -> u64 {
u64::from_be_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6],
bytes[7],
])
})
.collect::<Vec<u64>>()
.as_slice(),
);
input[23] = node_id;
input[24] = control_word.into();
input[25..].copy_from_slice(&data);
self.compression_internal(input)
}

fn compression_internal(&self, input: [u64; 89]) -> [u64; 16] {
const T0: usize = 17;
const T1: usize = 18;
const T2: usize = 21;
Expand All @@ -82,9 +108,6 @@ impl MD6 {
const R_I_N: [u64; 16] = [10, 5, 13, 10, 11, 12, 2, 7, 14, 15, 7, 13, 11, 7, 6, 12];
const L_I_N: [u64; 16] = [11, 24, 9, 16, 15, 9, 27, 15, 6, 2, 29, 8, 15, 5, 31, 9];

const S0: u64 = 0x0123_4567_89AB_CDEF;
const S1: u64 = 0x7311_C281_2425_CFA0;

const S: [u64; 168] = [
0x0123456789abcdef,
0x0347cace1376567e,
Expand Down Expand Up @@ -256,23 +279,6 @@ impl MD6 {
0x2859265840d89322,
];

let mut input = [0u64; 89];
input[0..=14].copy_from_slice(&Self::VECTOR_Q);
input[15..=22].copy_from_slice(
self.key
.chunks(8)
.map(|bytes: &[u8]| -> u64 {
u64::from_be_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6],
bytes[7],
])
})
.collect::<Vec<u64>>()
.as_slice(),
);
input[23] = node_id;
input[24] = control_word.into();
input[25..].copy_from_slice(&data);
let input_len = input.len();
let steps = self.rounds as usize * 16;
let mut output_vec = Vec::new();
Expand All @@ -282,7 +288,6 @@ impl MD6 {
x += (input[i - T1] ^ input[i - T2]) + (input[i - T3] ^ input[i - T4]);
x += x >> R_I_N[i - input_len];
output_vec[i - input_len] = x + (x << L_I_N[i - input_len]);
dbg!(output_vec[i - input_len]);
}
let mut result = [0u64; 16];
result.copy_from_slice(&output_vec[steps + input_len - 16..steps + input_len - 1]);
Expand All @@ -297,10 +302,6 @@ impl MD6 {
default_r
}
}

fn next_round_const(curr_round_const: u64) -> u64 {
curr_round_const.rotate_left(1) ^ (curr_round_const | 0x7311_C281_2425_CFA0)
}
}

impl KeySizeUser for MD6 {
Expand Down Expand Up @@ -343,24 +344,44 @@ impl Update for MD6 {
}
}

struct ControlWord {
rounds: u16,
mode: u8,
is_final_compression: bool,
num_of_padding_data_bits: u16,
keylen: u8,
desired_digest_length: u16,
#[derive(Debug, PartialEq)]
pub struct ControlWord {
pub rounds: u16,
pub mode: u8,
pub is_final_compression: bool,
pub num_of_padding_data_bits: u16,
pub keylen: u8,
pub desired_digest_length: u16,
}

impl From<ControlWord> for u64 {
fn from(value: ControlWord) -> Self {
todo!()
(value.rounds as u64) << 48 | (value.mode as u64) << 40 | (value.is_final_compression as u64) << 36 | (value.num_of_padding_data_bits as u64) << 20 | (value.keylen as u64) << 12 | (value.desired_digest_length as u64)
}
}

impl From<u64> for ControlWord {
fn from(_: u64) -> Self {
todo!()
fn from(value: u64) -> Self {
let bytes = value.to_be_bytes();
let _reserved = bytes[0] >> 4;
let rounds = u16::from_be_bytes([bytes[0] & 0b0000_1111, bytes[1]]);
let mode = bytes[2];
let is_final_compression = bytes[3] & 0b1111_0000 != 0;
let num_of_padding_data_bits = u16::from_be_bytes([
(bytes[3] << 4) | (bytes[4] >> 4),
(bytes[4] << 4) | (bytes[5] >> 4),
]);
let keylen = (bytes[5] << 4) | (bytes[6] >> 4);
let desired_digest_length = u16::from_be_bytes([bytes[6] & 0b0000_1111, bytes[7]]);

Self {
rounds,
mode,
is_final_compression,
num_of_padding_data_bits,
keylen,
desired_digest_length,
}
}
}

Expand All @@ -369,27 +390,98 @@ mod tests {
use super::*;

#[test]
fn test_zero_sized_md6() {
assert_eq!(MD6::new(0).is_err(), true)
fn test_control_word_from_u64_1() {
let left = ControlWord {
rounds: 5,
mode: 64,
is_final_compression: true,
num_of_padding_data_bits: 4072,
keylen: 0,
desired_digest_length: 256,
};

let right = ControlWord::from(0x0005_4010_FE80_0100);

assert_eq!(left, right);
}

#[test]
fn test_control_word_from_u64_2() {
let left = ControlWord {
rounds: 5,
mode: 64,
is_final_compression: false,
num_of_padding_data_bits: 0,
keylen: 10,
desired_digest_length: 224
};

let right = ControlWord::from(0x0005_4000_0000_A0E0);

assert_eq!(left, right);
}

#[test]
fn test_1024byte_md6() {
assert_eq!(MD6::new(1024).is_err(), true)
fn test_control_word_from_u64_3() {
let left = ControlWord {
rounds: 104,
mode: 0,
is_final_compression: false,
num_of_padding_data_bits: 0,
keylen: 0,
desired_digest_length: 256,
};

let right = ControlWord::from(0x0068_0000_0000_0100);

assert_eq!(left, right);
}

#[test]
fn test_1byte_md6() {
assert_eq!(MD6::new(1).is_ok(), true)
fn test_control_word_as_u64_1() {
let left = u64::from(ControlWord {
rounds: 5,
mode: 64,
is_final_compression: true,
num_of_padding_data_bits: 4072,
keylen: 0,
desired_digest_length: 256,
});

let right = 0x0005_4010_FE80_0100;

assert_eq!(left, right);
}

#[test]
fn test_64byte_md6() {
assert_eq!(MD6::new(64).is_ok(), true)
fn test_control_word_as_u64_2() {
let left = u64::from(ControlWord {
rounds: 5,
mode: 64,
is_final_compression: false,
num_of_padding_data_bits: 0,
keylen: 10,
desired_digest_length: 224
});

let right = 0x0005_4000_0000_A0E0;

assert_eq!(left, right)
}

#[test]
fn test_512byte_md6() {
assert_eq!(MD6::new(512).is_err(), true)
fn test_control_word_as_u64_3() {
let left = u64::from(ControlWord {
rounds: 104,
mode: 0,
is_final_compression: false,
num_of_padding_data_bits: 0,
keylen: 0,
desired_digest_length: 256,
});

let right = 0x0068_0000_0000_0100;

assert_eq!(left, right);
}
}

0 comments on commit c2070aa

Please sign in to comment.