-
Notifications
You must be signed in to change notification settings - Fork 253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added support for kupyna512 hash #597
Closed
Closed
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
bd40099
changes on repo root
AnarchistHoneybun 581b119
adding my code to tracking
AnarchistHoneybun b4abbae
removing main.rs
AnarchistHoneybun 0be762c
new test to compensate main.rs
AnarchistHoneybun d99728a
standard formatting
AnarchistHoneybun fa5c077
modified to address clippy warnings
AnarchistHoneybun daac639
Merge pull request #1 from AnarchistHoneybun/clippy_rslv
AnarchistHoneybun File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ members = [ | |
"groestl", | ||
"jh", | ||
"k12", | ||
"kupyna512", | ||
"md2", | ||
"md4", | ||
"md5", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[package] | ||
name = "kupyna512" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
mod sub_units; | ||
#[cfg(test)] | ||
mod tests; | ||
|
||
const STATE_SIZE: usize = 1024; | ||
const HASH_SIZE: usize = 512; | ||
|
||
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 > 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 { | ||
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
mod t_xor_plus; | ||
|
||
use t_xor_plus::{t_plus_l, t_xor_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); | ||
|
||
xor_bytes(&(xor_bytes(&t_xor_mp, &t_plus_m)), prev_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); | ||
} | ||
|
||
finalize(&last_vector) | ||
} | ||
|
||
fn finalize(ult_processed_block: &[u8]) -> Vec<u8> { | ||
let t_xor_ult_processed_block = t_xor_l(ult_processed_block, ROUNDS); | ||
xor_bytes(ult_processed_block, &t_xor_ult_processed_block) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
#[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, row) in state.iter_mut().enumerate().take(ROWS) { | ||
let constant = ((j * 0x10) ^ round) as u8; | ||
row[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 row in state.iter_mut() { | ||
row[i] = SBOXES[i % 4][row[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 { | ||
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) | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heap allocation is not necessary here. You can use byte array instead.