|
1 |
| -use crate::utils::{add_constant_plus, add_constant_xor, apply_s_box, mix_columns, xor_bytes}; |
| 1 | +use crate::utils::{ |
| 2 | + add_constant_plus, add_constant_xor, apply_s_box, mix_columns, read_u64s_be, xor, |
| 3 | +}; |
| 4 | +use core::array; |
2 | 5 |
|
3 | 6 | pub(crate) const COLS: usize = 16;
|
4 | 7 | const ROUNDS: u64 = 14;
|
5 | 8 |
|
6 |
| -type Matrix = [[u8; 8]; 16]; |
7 |
| - |
8 | 9 | pub(crate) fn compress(prev_vector: &mut [u64; COLS], message_block: &[u8; 128]) {
|
9 |
| - let mut prev_vector_u8 = [0u8; 128]; |
10 |
| - for (src, dst) in prev_vector.iter().zip(prev_vector_u8.chunks_exact_mut(8)) { |
11 |
| - dst.copy_from_slice(&src.to_be_bytes()); |
12 |
| - } |
13 |
| - |
14 |
| - let m_xor_p = xor_bytes(*message_block, prev_vector_u8); |
15 |
| - |
| 10 | + // Convert message block from u8 to u64 (column-major order as per paper) |
| 11 | + let message_u64 = read_u64s_be::<128, COLS>(message_block); |
| 12 | + let m_xor_p = xor(*prev_vector, message_u64); |
16 | 13 | let t_xor_mp = t_xor_l(m_xor_p);
|
17 |
| - |
18 |
| - let t_plus_m = t_plus_l(*message_block); |
19 |
| - |
20 |
| - prev_vector_u8 = xor_bytes(xor_bytes(t_xor_mp, t_plus_m), prev_vector_u8); |
21 |
| - |
22 |
| - for (dst, src) in prev_vector.iter_mut().zip(prev_vector_u8.chunks_exact(8)) { |
23 |
| - *dst = u64::from_be_bytes(src.try_into().unwrap()); |
24 |
| - } |
| 14 | + let t_plus_m = t_plus_l(message_u64); |
| 15 | + *prev_vector = xor(xor(t_xor_mp, t_plus_m), *prev_vector); |
25 | 16 | }
|
26 | 17 |
|
27 |
| -pub(crate) fn t_plus_l(block: [u8; 128]) -> [u8; 128] { |
28 |
| - let mut state = block_to_matrix(block); |
| 18 | +fn t_plus_l(state: [u64; COLS]) -> [u64; COLS] { |
| 19 | + let mut state = state; |
29 | 20 | for nu in 0..ROUNDS {
|
30 |
| - state = add_constant_plus(state, nu as usize); |
31 |
| - state = apply_s_box(state); |
| 21 | + add_constant_plus(&mut state, nu as usize); |
| 22 | + apply_s_box(&mut state); |
32 | 23 | state = rotate_rows(state);
|
33 |
| - state = mix_columns(state); |
| 24 | + mix_columns(&mut state); |
34 | 25 | }
|
35 |
| - matrix_to_block(state) |
36 |
| -} |
37 |
| - |
38 |
| -fn block_to_matrix(block: [u8; 128]) -> Matrix { |
39 |
| - const ROWS: usize = 16; |
40 |
| - const COLS: usize = 8; |
41 |
| - |
42 |
| - let mut matrix = [[0u8; COLS]; ROWS]; |
43 |
| - for i in 0..ROWS { |
44 |
| - for j in 0..COLS { |
45 |
| - matrix[i][j] = block[i * COLS + j]; |
46 |
| - } |
47 |
| - } |
48 |
| - matrix |
49 |
| -} |
50 |
| - |
51 |
| -fn matrix_to_block(matrix: Matrix) -> [u8; 128] { |
52 |
| - const ROWS: usize = 16; |
53 |
| - const COLS: usize = 8; |
54 |
| - |
55 |
| - let mut block = [0u8; ROWS * COLS]; |
56 |
| - for i in 0..ROWS { |
57 |
| - for j in 0..COLS { |
58 |
| - block[i * COLS + j] = matrix[i][j]; |
59 |
| - } |
60 |
| - } |
61 |
| - block |
| 26 | + state |
62 | 27 | }
|
63 | 28 |
|
64 |
| -fn rotate_rows(mut state: Matrix) -> Matrix { |
65 |
| - const ROWS: usize = 16; |
66 |
| - let cols = 8; |
67 |
| - |
68 |
| - let mut temp = [0u8; ROWS]; |
69 |
| - let mut shift: i32 = -1; |
70 |
| - for i in 0..cols { |
71 |
| - if i == cols - 1 { |
72 |
| - shift = 11; |
73 |
| - } else { |
74 |
| - shift += 1; |
75 |
| - } |
76 |
| - for col in 0..ROWS { |
77 |
| - temp[(col + shift as usize) % ROWS] = state[col][i]; |
78 |
| - } |
79 |
| - for col in 0..ROWS { |
80 |
| - state[col][i] = temp[col]; |
81 |
| - } |
82 |
| - } |
83 |
| - state |
| 29 | +fn rotate_rows(state: [u64; COLS]) -> [u64; COLS] { |
| 30 | + //shift amounts for each row (0-6: row index, 7: special case = 11) |
| 31 | + const SHIFTS: [usize; 8] = [0, 1, 2, 3, 4, 5, 6, 11]; |
| 32 | + |
| 33 | + array::from_fn(|col| { |
| 34 | + let rotated_bytes = array::from_fn(|row| { |
| 35 | + let shift = SHIFTS[row]; |
| 36 | + let src_col = (col + COLS - shift) % COLS; |
| 37 | + let src_bytes = state[src_col].to_be_bytes(); |
| 38 | + src_bytes[row] |
| 39 | + }); |
| 40 | + u64::from_be_bytes(rotated_bytes) |
| 41 | + }) |
84 | 42 | }
|
85 | 43 |
|
86 |
| -pub(crate) fn t_xor_l(block: [u8; 128]) -> [u8; 128] { |
87 |
| - let mut state = block_to_matrix(block); |
| 44 | +pub(crate) fn t_xor_l(state: [u64; COLS]) -> [u64; COLS] { |
| 45 | + let mut state = state; |
88 | 46 | for nu in 0..ROUNDS {
|
89 |
| - state = add_constant_xor(state, nu as usize); |
90 |
| - state = apply_s_box(state); |
| 47 | + add_constant_xor(&mut state, nu as usize); |
| 48 | + apply_s_box(&mut state); |
91 | 49 | state = rotate_rows(state);
|
92 |
| - state = mix_columns(state); |
| 50 | + mix_columns(&mut state); |
93 | 51 | }
|
94 |
| - matrix_to_block(state) |
| 52 | + state |
95 | 53 | }
|
0 commit comments