parent
57f3877378
commit
d6ba6a9199
@ -1 +1,183 @@ |
||||
pub const MAX_PHRASE_LENGTH: usize = 27; |
||||
use packed_simd::FromBits; |
||||
use packed_simd::u32x8; |
||||
use packed_simd::u8x32; |
||||
|
||||
pub const MAX_PHRASE_LENGTH: usize = 31; |
||||
|
||||
#[allow(unused_assignments)] |
||||
pub fn compute_hashes(messages: [u8x32; 8], messages_length: usize) -> [u32; 8] { |
||||
let mut a: u32x8 = u32x8::splat(0x67452301); |
||||
let mut b: u32x8 = u32x8::splat(0xefcdab89); |
||||
let mut c: u32x8 = u32x8::splat(0x98badcfe); |
||||
let mut d: u32x8 = u32x8::splat(0x10325476); |
||||
|
||||
let trailer = u8x32::splat(0).replace(messages_length, b' ' ^ 0x80); |
||||
let mut messages_bytes: [u32; 64] = [0; 64]; |
||||
{ |
||||
macro_rules! write_bytes { |
||||
($i: expr) => { |
||||
u32x8::from_bits(messages[$i] ^ trailer).write_to_slice_unaligned(&mut messages_bytes[($i*8)..]) |
||||
} |
||||
} |
||||
write_bytes!(0); |
||||
write_bytes!(1); |
||||
write_bytes!(2); |
||||
write_bytes!(3); |
||||
write_bytes!(4); |
||||
write_bytes!(5); |
||||
write_bytes!(6); |
||||
write_bytes!(7); |
||||
} |
||||
|
||||
macro_rules! get_m_value { |
||||
($i: expr) => { |
||||
u32x8::new( |
||||
messages_bytes[0*8 + $i], |
||||
messages_bytes[1*8 + $i], |
||||
messages_bytes[2*8 + $i], |
||||
messages_bytes[3*8 + $i], |
||||
messages_bytes[4*8 + $i], |
||||
messages_bytes[5*8 + $i], |
||||
messages_bytes[6*8 + $i], |
||||
messages_bytes[7*8 + $i], |
||||
) |
||||
}; |
||||
} |
||||
|
||||
let m0: u32x8 = get_m_value!(0); |
||||
let m1: u32x8 = get_m_value!(1); |
||||
let m2: u32x8 = get_m_value!(2); |
||||
let m3: u32x8 = get_m_value!(3); |
||||
let m4: u32x8 = get_m_value!(4); |
||||
let m5: u32x8 = get_m_value!(5); |
||||
let m6: u32x8 = get_m_value!(6); |
||||
let m7: u32x8 = get_m_value!(7); |
||||
let m14: u32x8 = u32x8::splat((messages_length as u32) * 8); |
||||
|
||||
macro_rules! lrot { |
||||
($f: expr, $s: expr) => (($f << $s) | ($f >> (32-$s))); |
||||
} |
||||
|
||||
macro_rules! blend { |
||||
($mask: expr, $a: expr, $b: expr) => { |
||||
// andnot (_mm256_andnot_si256) is not implemented in packed_simd
|
||||
($a & $mask) | ($b & !$mask) |
||||
} |
||||
} |
||||
|
||||
macro_rules! step { |
||||
($f: expr, $s: expr, $k: expr, $m: expr) => { |
||||
let f = $f + a + u32x8::splat($k) + $m; |
||||
a = d; |
||||
d = c; |
||||
c = b; |
||||
b = b + lrot!(f, $s); |
||||
}; |
||||
($f: expr, $s: expr, $k: expr) => { |
||||
let f = $f + a + u32x8::splat($k); |
||||
a = d; |
||||
d = c; |
||||
c = b; |
||||
b = b + lrot!(f, $s); |
||||
}; |
||||
} |
||||
|
||||
{ |
||||
macro_rules! step_1 { |
||||
() => (blend!(b, c, d)); |
||||
} |
||||
|
||||
step!(step_1!(), 7, 0xd76aa478, m0); |
||||
step!(step_1!(), 12, 0xe8c7b756, m1); |
||||
step!(step_1!(), 17, 0x242070db, m2); |
||||
step!(step_1!(), 22, 0xc1bdceee, m3); |
||||
step!(step_1!(), 7, 0xf57c0faf, m4); |
||||
step!(step_1!(), 12, 0x4787c62a, m5); |
||||
step!(step_1!(), 17, 0xa8304613, m6); |
||||
step!(step_1!(), 22, 0xfd469501, m7); |
||||
step!(step_1!(), 7, 0x698098d8); |
||||
step!(step_1!(), 12, 0x8b44f7af); |
||||
step!(step_1!(), 17, 0xffff5bb1); |
||||
step!(step_1!(), 22, 0x895cd7be); |
||||
step!(step_1!(), 7, 0x6b901122); |
||||
step!(step_1!(), 12, 0xfd987193); |
||||
step!(step_1!(), 17, 0xa679438e, m14); |
||||
step!(step_1!(), 22, 0x49b40821); |
||||
} |
||||
|
||||
{ |
||||
macro_rules! step_2 { |
||||
() => (blend!(d, b, c)); |
||||
} |
||||
|
||||
step!(step_2!(), 5, 0xf61e2562, m1); |
||||
step!(step_2!(), 9, 0xc040b340, m6); |
||||
step!(step_2!(), 14, 0x265e5a51); |
||||
step!(step_2!(), 20, 0xe9b6c7aa, m0); |
||||
step!(step_2!(), 5, 0xd62f105d, m5); |
||||
step!(step_2!(), 9, 0x02441453); |
||||
step!(step_2!(), 14, 0xd8a1e681); |
||||
step!(step_2!(), 20, 0xe7d3fbc8, m4); |
||||
step!(step_2!(), 5, 0x21e1cde6); |
||||
step!(step_2!(), 9, 0xc33707d6, m14); |
||||
step!(step_2!(), 14, 0xf4d50d87, m3); |
||||
step!(step_2!(), 20, 0x455a14ed); |
||||
step!(step_2!(), 5, 0xa9e3e905); |
||||
step!(step_2!(), 9, 0xfcefa3f8, m2); |
||||
step!(step_2!(), 14, 0x676f02d9, m7); |
||||
step!(step_2!(), 20, 0x8d2a4c8a); |
||||
} |
||||
|
||||
{ |
||||
macro_rules! step_3 { |
||||
() => (b ^ (c ^ d)); |
||||
} |
||||
|
||||
step!(step_3!(), 4, 0xfffa3942, m5); |
||||
step!(step_3!(), 11, 0x8771f681); |
||||
step!(step_3!(), 16, 0x6d9d6122); |
||||
step!(step_3!(), 23, 0xfde5380c, m14); |
||||
step!(step_3!(), 4, 0xa4beea44, m1); |
||||
step!(step_3!(), 11, 0x4bdecfa9, m4); |
||||
step!(step_3!(), 16, 0xf6bb4b60, m7); |
||||
step!(step_3!(), 23, 0xbebfbc70); |
||||
step!(step_3!(), 4, 0x289b7ec6); |
||||
step!(step_3!(), 11, 0xeaa127fa, m0); |
||||
step!(step_3!(), 16, 0xd4ef3085, m3); |
||||
step!(step_3!(), 23, 0x04881d05, m6); |
||||
step!(step_3!(), 4, 0xd9d4d039); |
||||
step!(step_3!(), 11, 0xe6db99e5); |
||||
step!(step_3!(), 16, 0x1fa27cf8); |
||||
step!(step_3!(), 23, 0xc4ac5665, m2); |
||||
} |
||||
|
||||
{ |
||||
macro_rules! step_4 { |
||||
() => (c ^ (b | !d)); |
||||
} |
||||
|
||||
step!(step_4!(), 6, 0xf4292244, m0); |
||||
step!(step_4!(), 10, 0x432aff97, m7); |
||||
step!(step_4!(), 15, 0xab9423a7, m14); |
||||
step!(step_4!(), 21, 0xfc93a039, m5); |
||||
step!(step_4!(), 6, 0x655b59c3); |
||||
step!(step_4!(), 10, 0x8f0ccc92, m3); |
||||
step!(step_4!(), 15, 0xffeff47d); |
||||
step!(step_4!(), 21, 0x85845dd1, m1); |
||||
step!(step_4!(), 6, 0x6fa87e4f); |
||||
step!(step_4!(), 10, 0xfe2ce6e0); |
||||
step!(step_4!(), 15, 0xa3014314, m6); |
||||
step!(step_4!(), 21, 0x4e0811a1); |
||||
step!(step_4!(), 6, 0xf7537e82, m4); |
||||
|
||||
// Since we ignore b, c, d values in the end,
|
||||
// the remaining three iterations are unnecessary,
|
||||
// as the value of a after iteration 64 is equal
|
||||
// to the value of b after iteration 61
|
||||
a = b + u32x8::splat(0x67452301); |
||||
|
||||
let mut result: [u32; 8] = [0; 8]; |
||||
a.write_to_slice_unaligned(&mut result); |
||||
result |
||||
} |
||||
} |
||||
|
@ -0,0 +1,9 @@ |
||||
#![feature(map_into_keys_values)] |
||||
|
||||
pub mod anagram_finder; |
||||
pub mod anagram_logger; |
||||
pub mod dictionary_builder; |
||||
pub mod hash_computer; |
||||
pub mod permutations_cache; |
||||
pub mod read_lines; |
||||
pub mod vector_alphabet; |
@ -0,0 +1 @@ |
||||
use permutohedron::Heap; |
@ -0,0 +1,57 @@ |
||||
use packed_simd::u8x32; |
||||
|
||||
extern crate trustpilot_challenge_rust; |
||||
use trustpilot_challenge_rust::hash_computer; |
||||
|
||||
fn prepare_message(message_string: &str) -> u8x32 { |
||||
let mut bytes_static: [u8; 32] = [0; 32]; |
||||
let bytes = message_string.as_bytes(); |
||||
for i in 0..bytes.len() { |
||||
bytes_static[i] = bytes[i]; |
||||
} |
||||
|
||||
bytes_static[bytes.len()] = b' '; |
||||
|
||||
u8x32::from(bytes_static) |
||||
} |
||||
|
||||
fn prepare_messages(message_strings: [&str; 8]) -> [u8x32; 8] { |
||||
let mut result: [u8x32; 8] = [u8x32::splat(0); 8]; |
||||
for i in 0..8 { |
||||
result[i] = prepare_message(message_strings[i]); |
||||
} |
||||
result |
||||
} |
||||
|
||||
#[test] |
||||
fn it_computes_hashes() { |
||||
let messages: [&str; 8] = /*[""; 8];*/[ |
||||
"DAPUpOGHw620yalJA0vjFPK7ThgHyAN", |
||||
"4xRslaTeBCNyRu2EiIDueEx3BTbIP5H", |
||||
"kFPd2zk60eEFpNwgEOZAcyDcxRVv0Y8", |
||||
"bm6VQr6w9plie0G8XoOb4wChJXB0vCm", |
||||
"gbFrtHcqOTkeG1QxT8YEMSio1ahAYNq", |
||||
"T0GmOLB2WH04oIrhB3JCyPHFxI8UOow", |
||||
"TWUCy0B0JG5KjQvsu4YUFC5IR5ByS2W", |
||||
"VXqOIzYdLIqx6tw8LJbR7SqR5iYgTlQ" |
||||
]; |
||||
|
||||
let expected: [u128; 8] = [ |
||||
0xC6F9E9B203CEA81A7BA28BE276B96A6F, |
||||
0x45BF15D8B08E1AEADE1305B8E43B8F2C, |
||||
0x7AA53B4627C8DD3714F2874EDE04DA7D, |
||||
0x93B650B474B6FDE6B902A76B1DDA10BB, |
||||
0xBBF89511DAC63A516ADDB9BEC79241A5, |
||||
0x7E53E601351A47500BF4A2B7EAD077C3, |
||||
0xFC6FEB2CC3191198E87ECB9D7626580A, |
||||
0xCED45BA82BD1BDCF546255CB6A530FE3, |
||||
]; |
||||
|
||||
let messages_simd = prepare_messages(messages); |
||||
|
||||
let hashes = hash_computer::compute_hashes(messages_simd, messages[0].len()); |
||||
|
||||
for i in 0..8 { |
||||
assert_eq!((expected[i] >> 96) as u32, hashes[i].to_be()); |
||||
} |
||||
} |
Loading…
Reference in new issue