Skip to content

Commit

Permalink
adding my code to tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
AnarchistHoneybun committed Jun 27, 2024
1 parent bd40099 commit 581b119
Show file tree
Hide file tree
Showing 13 changed files with 1,326 additions and 0 deletions.
6 changes: 6 additions & 0 deletions kupyna512/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[package]
name = "kupyna512"
version = "0.1.0"
edition = "2021"

[dependencies]
101 changes: 101 additions & 0 deletions kupyna512/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#[cfg(test)]
mod tests;
mod sub_units;

const STATE_SIZE: usize = 1024;
const HASH_SIZE: usize = 512;

const MAX_MESSAGE_LENGTH: usize = 18446744073709551615;

fn pad_message(message: &[u8], msg_len_bits: usize, state_size: usize) -> Vec<u8> {
let round_msg_len = message.len() * 8;
let d =
((-((round_msg_len + 97) as isize) % (state_size as isize)) + state_size as isize) as usize;

// Calculate the length of padding to be added
let pad_len = d / 8;

// We set the padded message size upfront to reduce allocations
let padded_len = (msg_len_bits + 7) / 8 + pad_len + 13;
let mut padded_message = vec![0x00; padded_len];

// Copy n bits from the input message
let full_bytes = msg_len_bits / 8;
let remaining_bits = msg_len_bits % 8;

padded_message[..full_bytes].copy_from_slice(&message[..full_bytes]);

if remaining_bits > 0 {
let last_byte = message[full_bytes];
padded_message[full_bytes] = last_byte & ((1 << remaining_bits) - 1);
}

// Set the n+1'th bit to high
padded_message[msg_len_bits / 8] |= 1 << (7 - (msg_len_bits % 8));

// Convert the length to a byte array and copy it into the padded message
let n_bytes = (msg_len_bits as u128).to_le_bytes(); // message length in little-endian
padded_message[padded_len - 12..].copy_from_slice(&n_bytes[0..12]);

padded_message
}

fn divide_into_blocks(padded_message: &[u8], state_size: usize) -> Vec<&[u8]> {
padded_message.chunks(state_size / 8).collect()
}

fn truncate(block: &[u8], n: usize) -> Vec<u8> {
let bytes_to_keep = n / 8;
let start_index = if block.len() > bytes_to_keep {
block.len() - bytes_to_keep
} else {
0
};
block[start_index..].to_vec()
}

pub fn hash(message: Vec<u8>, length: Option<usize>) -> Result<Vec<u8>, &'static str> {
let mut message = message;
let message_length: usize;
if let Some(len) = length {
if len > MAX_MESSAGE_LENGTH {
return Err("Message is too long");
}
if len > message.len() * 8 {
return Err("Message length is less than the provided length");
}

let mut trimmed_message = message[..(len/8)].to_vec();

if len % 8 != 0 {
let extra_byte = message[len/8];
let extra_bits = len % 8;
let mask = 0xFF << (8 - extra_bits);
trimmed_message.push(extra_byte & mask);
}

message = trimmed_message;
message_length = len;

} else {
if message.len() * 8 > MAX_MESSAGE_LENGTH {
return Err("Message is too long");
}
message_length = message.len() * 8;
}

let padded_message = pad_message(&message, message_length, STATE_SIZE);

let blocks = divide_into_blocks(&padded_message, STATE_SIZE);

let mut init_vector: Vec<u8> = vec![0; STATE_SIZE/8];
init_vector[0] = 0x80; // set the first bit of this init vector to high


let fin_vector = sub_units::plant(blocks, &init_vector);

let hash = truncate(&fin_vector, HASH_SIZE);

Ok(hash)
}

10 changes: 10 additions & 0 deletions kupyna512/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use kupyna512;

fn main() {
let message = b"Hello, World!".to_vec();
let _message_length = 0;

let hash_code = kupyna512::hash(message, None).unwrap();

println!("{:02X?}", hash_code);
}
43 changes: 43 additions & 0 deletions kupyna512/src/sub_units/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
mod t_xor_plus;

use t_xor_plus::{t_xor_l, t_plus_l};

const ROUNDS: usize = 14;

fn xor_bytes(a: &[u8], b: &[u8]) -> Vec<u8> {
a.iter().zip(b.iter()).map(|(x, y)| x ^ y).collect()
}

fn silo(message_block: &[u8], prev_vector: &[u8]) -> Vec<u8> {

let m_xor_p = xor_bytes(message_block, prev_vector);

let t_xor_mp = t_xor_l(&m_xor_p, ROUNDS);

let t_plus_m = t_plus_l(&message_block, ROUNDS);

let return_vector = xor_bytes(&(xor_bytes(&t_xor_mp, &t_plus_m)), prev_vector);

return_vector

}

pub(crate) fn plant(message_blocks: Vec<&[u8]>, init_vector: &[u8]) -> Vec<u8> {

let mut last_vector = init_vector.to_vec();

for block in message_blocks {
last_vector = silo(block, &last_vector);
}

let last_vector = finalize(&last_vector);

last_vector
}

fn finalize(ult_processed_block: &[u8]) -> Vec<u8> {
let t_xor_ult_processed_block = t_xor_l(ult_processed_block, ROUNDS);
let final_state = xor_bytes(ult_processed_block, &t_xor_ult_processed_block);
final_state
}

162 changes: 162 additions & 0 deletions kupyna512/src/sub_units/t_xor_plus/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
#[cfg(test)]
mod tests;

mod tables;

const ROWS: usize = 16;
const COLS: usize = 8; // For 512-bit state, adjust if needed

const BITS_IN_BYTE: u8 = 8;
const REDUCTION_POLYNOMIAL: u16 = 0x011d;

type Matrix = [[u8; COLS]; ROWS];

use tables::{MDS_MATRIX, SBOXES};


pub(crate) fn block_to_matrix(block: &[u8]) -> Matrix {
let mut matrix = [[0u8; COLS]; ROWS];
for i in 0..ROWS {
for j in 0..COLS {
matrix[i][j] = block[i * COLS + j];
}
}
matrix
}

fn matrix_to_block(matrix: Matrix) -> Vec<u8> {
let mut block = vec![0u8; ROWS * COLS];
for i in 0..ROWS {
for j in 0..COLS {
block[i * COLS + j] = matrix[i][j];
}
}
block
}

pub(crate) fn add_constant_xor(mut state: Matrix, round: usize) -> Matrix {
for j in 0..ROWS {
let constant = ((j * 0x10) ^ round) as u8;
state[j][0] ^= constant;
}
state
}

pub(crate) fn add_constant_plus(mut state: Matrix, round: usize) -> Matrix {
let state_ptr = state.as_mut_ptr() as *mut u64;

for j in 0..ROWS {
// dbg!("{}",j);
unsafe {
*state_ptr.add(j) = state_ptr.add(j).read().wrapping_add(
0x00F0F0F0F0F0F0F3u64 ^ (((((ROWS - j - 1) * 0x10) ^ round) as u64) << 56),
);
}
}

state
}

pub(crate) fn s_box_layer(mut state: Matrix) -> Matrix {
for i in 0..COLS {
for j in 0..ROWS {
state[j][i] = SBOXES[i % 4][state[j][i] as usize];
}
}
state
}

pub(crate) fn rotate_rows(mut state: Matrix) -> Matrix {
let mut temp = [0u8; ROWS];
let mut shift: i32 = -1;
for i in 0..COLS {
if (i == COLS - 1) && true {
shift = 11;
} else {
shift += 1;
}
for col in 0..ROWS {
temp[(col + shift as usize) % ROWS] = state[col][i];
}
for col in 0..ROWS {
state[col][i] = temp[col];
}
}
state
}

fn multiply_gf(mut x: u8, mut y: u8) -> u8 {
let mut r = 0u8;

for _ in 0..BITS_IN_BYTE {
if y & 1 == 1 {
r ^= x;
}
let hbit = (x & 0x80) >> 7;
x <<= 1;
if hbit == 1 {
x ^= REDUCTION_POLYNOMIAL as u8;
}
y >>= 1;
}

r
}

pub(crate) fn mix_columns(state: Matrix) -> Matrix {
let mut result = [[0u8; COLS]; ROWS];

for col in 0..ROWS {
for row in (0..COLS).rev() {
let mut product = 0u8;
for b in (0..COLS).rev() {
product ^= multiply_gf(state[col][b], MDS_MATRIX[row][b]);
}
result[col][row] = product;
}
}

result
}

/// Placeholder for the T⊕l transformation.
///
/// # Arguments
///
/// * `block` - A byte slice representing the block to be transformed.
/// * `_rounds` - The number of rounds to perform.
///
/// # Returns
///
/// * A `Vec<u8>` containing the transformed block.
pub fn t_xor_l(block: &[u8], rounds: usize) -> Vec<u8> {
let mut state = block_to_matrix(block);
for nu in 0..rounds {
state = add_constant_xor(state, nu);
state = s_box_layer(state);
state = rotate_rows(state);
state = mix_columns(state);
}
matrix_to_block(state)
}

/// Placeholder for the T+l transformation.
///
/// # Arguments
///
/// * `block` - A byte slice representing the block to be transformed.
/// * `_rounds` - The number of rounds to perform.
///
/// # Returns
///
/// * A `Vec<u8>` containing the transformed block.
pub fn t_plus_l(block: &[u8], rounds: usize) -> Vec<u8> {
let mut state = block_to_matrix(block);
for nu in 0..rounds {
state = add_constant_plus(state, nu);
state = s_box_layer(state);
state = rotate_rows(state);
state = mix_columns(state);
}
matrix_to_block(state)
}
Loading

0 comments on commit 581b119

Please sign in to comment.