use crate::generics::WyHashVariant;
use crate::util::wy_rotate;
#[derive(Copy, Clone)]
pub struct WyHash32 {
_private: (),
}
impl WyHashVariant for WyHash32 {
#[inline(always)]
fn mul_mum(a: u64, b: u64) -> (u64, u64) {
let hh = (a >> 32) * (b >> 32);
let ll = (a as u32 as u64) * (b as u32 as u64);
let hl = (a >> 32) * (b as u32 as u64);
let lh = (a as u32 as u64) * (b >> 32);
(wy_rotate(hl) ^ hh, wy_rotate(lh) ^ ll)
}
}
#[cfg(test)]
#[cfg(feature = "std")]
mod test {
use super::*;
use crate::generics::test::*;
const TEST_VECTOR: TestVector = [
("", 0, 0x4b80acaa567a5c84),
("a", 1, 0xb78e7daf065068fa),
("abc", 2, 0xd176a04d1bbbff00),
("wyhash", 3, 0xb27a7d813cd8bcdc),
("message digest", 4, 0x3b7e054046616be3),
("abcdefghijklmnopqrstuvwxyz", 5, 0xec124cc1dfaaf40a),
("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 6, 0x4745dfacef9c61cb),
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 7, 0xd3ad9a6fbad6eafe),
("12345678901234567890123456789012345678901234567890123456789012345678901234567890", 8, 0x8d310928e8f89d37),
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()`~-_=+[{]};:,<.>/?", 9, 0x117e23eaf7259a56),
];
#[rustfmt::skip]
const GENERATE_SECRET_TEST_VECTOR: [(u64, [u64; 4]); 10] = [
(0x0, [ 0x56d81b53c9e16ad1, 0x7427a6a969a5b8c3, 0xcab8c98b1d2eac4b, 0x39f0a52dcce8692d]),
(0x1, [ 0xaa6a4b3a2bca8e27, 0x95aaa3e1b1a9a92d, 0xe1c3c666cc93d22d, 0xca71e49539aaf0e1]),
(0x2, [ 0x87c5e8e4662ec3b1, 0xa9a53c1e964de427, 0x996336c571ca1765, 0xc99c8d8e63b2960f]),
(0x3, [ 0x53e8d8a327e2a687, 0x0f4eca8db85c740f, 0xac0fc687c3c3ca95, 0x3a394e9c1d271ec3]),
(0x4, [ 0x1e3959c3a936d195, 0x66d4e1636693741d, 0xaa4d7478c574788b, 0x9c17874d63c59a99]),
(0x5, [ 0xaaca5cb1c61d6653, 0x59d439722dd17447, 0x71b24d17958d8d2b, 0x874e3c3671749c39]),
(0x6, [ 0xc9366371e8272d71, 0x5c93d13996c3b8c5, 0xac960f8e956a3371, 0x3ca566991bb4c969]),
(0x7, [ 0x27e2594be8d478a9, 0x2b1d744d4b1eb165, 0xe2656917e1990f47, 0x72e4b253936695c9]),
(0x8, [ 0xa3951e4eaa1b3693, 0x552ed8b2a9c32b93, 0x72a666aa1ed1f08d, 0xb28e9578e8e8d171]),
(0x9, [ 0x6a2ee8594d361d69, 0x96746aac470fcc35, 0x8e72d47174c393a5, 0xd2e48b1771e474a3]),
];
const EXTENDED_TEST_VECTOR: ExtendedTestVector = [
(0, 0x4b80acaa567a5c84u64),
(1, 0xf4d6babc623413cbu64),
(2, 0x33bcbc7c16534995u64),
(3, 0xd2a2f48f6f76868fu64),
(4, 0x24dcaf7dfd053b04u64),
(5, 0xdba1f7bd99a41852u64),
(6, 0xa8c532dbd68620acu64),
(7, 0x4c90bdb5d2f10a9fu64),
(8, 0x34cb23888c74aaf6u64),
(9, 0xd691726b6b9e3ff1u64),
(10, 0xc3cac02fa1deccadu64),
(11, 0x70c2e407f14cc049u64),
(12, 0x0b07fe1d24435decu64),
(13, 0x350a2c90f60b74a4u64),
(14, 0x63067f0ab4ee160eu64),
(15, 0x2310acc47cee0924u64),
(16, 0xc59ad274d3bc0bfeu64),
(17, 0x4622e3070a32ea11u64),
(18, 0x85dbc199ea2467bfu64),
(19, 0xb82bd53d0a84ee59u64),
(20, 0x93ff08769555ea36u64),
(21, 0x8aa89d80c712e7a8u64),
(22, 0x0239272637b59813u64),
(23, 0x9c2b3b66ea7a1940u64),
(24, 0xc54172c76e09ec16u64),
(25, 0x360de87e229071b4u64),
(26, 0x27a21b39cdc07467u64),
(27, 0x0806c510f32fdd04u64),
(28, 0x549d962d730d2aaeu64),
(29, 0xb3261afd93a6941au64),
(30, 0xf7af604fd62b7430u64),
(31, 0xdd2583ce299fa1b2u64),
(32, 0xb7c1b788b49b8283u64),
(33, 0xa5b7fb6e4a2479fbu64),
(34, 0x67982fc9bf0ecd9fu64),
(35, 0xf3579d64131c3b66u64),
(36, 0xa9a0fed45165d3a4u64),
(37, 0x733934e00e257c57u64),
(38, 0xa4e22f0b3d4346f7u64),
(39, 0x2af16a2561f14f01u64),
(40, 0x9fee6a293eec61f8u64),
(41, 0x7f2d2487bc08b095u64),
(42, 0x147d054901144774u64),
(43, 0xf71dd6dcebfdbf6au64),
(44, 0xeae96c7e03ab2e89u64),
(45, 0x16c0785b8b15d44au64),
(46, 0xf03737eea59fc9f3u64),
(47, 0x15f8c86c006956b5u64),
(48, 0xca4621d9b62f8f38u64),
(49, 0xea92d235d32fb6a8u64),
(50, 0x6f90269b70c69f77u64),
(51, 0xe776985c576ef082u64),
(52, 0xb35ab3374da886d3u64),
(53, 0x16536028be894c3du64),
(54, 0xfd3fc21c3a9be100u64),
(55, 0x79ecc98aa93f26d7u64),
(56, 0x1c56ed673bebd996u64),
(57, 0xae76810dd7d34c7fu64),
(58, 0x0dd1d3a4523c0825u64),
(59, 0x00af729b18f9daf0u64),
(60, 0x1e6c14f5e6c97e7au64),
(61, 0x9f1c01a41f9cd573u64),
(62, 0x129cb0285ebb101du64),
(63, 0x84557d24231fd3f6u64),
(64, 0xa1489cd2d8d20c4bu64),
(65, 0x50a349beabe17ed7u64),
(66, 0xdd2a814a408f78e6u64),
(67, 0xf26552152e27c5d2u64),
(68, 0x7417ff4206aebd85u64),
(69, 0x9e3b14d9a0ba00b3u64),
(70, 0xaf4cc62ce54fd4fdu64),
(71, 0xd76f364e069a08f9u64),
(72, 0xfe07d7e9aac788a1u64),
(73, 0x206bf22e036791ffu64),
(74, 0xf37b6cb6f44d2a87u64),
(75, 0x378da81cda027835u64),
(76, 0x01b3b412eac3cc7cu64),
(77, 0xc45bd053a3e083ebu64),
(78, 0xb63d0cfbe4bf96edu64),
(79, 0xd906f7385921b990u64),
(80, 0x2eff6e684b628e3cu64),
(81, 0x6d8864c72afaa023u64),
(82, 0x29f635850c4e085fu64),
(83, 0x7d7425d22b1ab91au64),
(84, 0x447826b563795358u64),
(85, 0xf2b8f0575cc1af5cu64),
(86, 0x31609413a648ff75u64),
(87, 0x5deafc68e5fd755cu64),
(88, 0xdc77488324d8ffcbu64),
(89, 0x4207f6bca3f7e593u64),
];
#[test]
fn test_streaming() {
for (input, seed, result) in TEST_VECTOR.iter().cloned() {
let input = input.as_bytes();
let mut hasher = WyHash32::with_seed(seed).streamed();
hasher.write(input);
assert_eq!(hasher.finish(), result);
for chunksize in 1..=48 {
let mut hasher = WyHash32::with_seed(seed).streamed();
for chunk in input.chunks(chunksize) {
hasher.write(chunk);
}
assert_eq!(
hasher.finish(),
result,
"failed: chunksize: {}, seed: {}, chunks: {:?}",
chunksize,
seed,
input.chunks(chunksize).collect::<Vec<_>>()
);
}
}
}
#[test]
fn test() {
for (input, seed, result) in TEST_VECTOR.iter().cloned() {
let input = input.as_bytes();
let hasher = WyHash32::with_seed(seed);
assert_eq!(
hasher.hash(input),
result,
"input len: {}, seed: {}",
input.len(),
seed
);
}
}
#[test]
fn extended_test() {
for (seed_and_len, result) in EXTENDED_TEST_VECTOR.iter() {
let input = &EXTENDED_TEST_VECTOR_BUFFER[..*seed_and_len];
let hasher = WyHash32::with_seed(*seed_and_len as u64);
assert_eq!(
hasher.hash(input),
*result,
"length_and_len: {}",
seed_and_len
);
for chunksize in 1..=48 {
let mut hasher = WyHash32::with_seed(*seed_and_len as u64).streamed();
for chunk in input.chunks(chunksize) {
hasher.write(chunk);
}
assert_eq!(
hasher.finish(),
*result,
"failed: chunksize: {}, seed: {}, chunks: {:?}",
chunksize,
*seed_and_len as u64,
input.chunks(chunksize).collect::<Vec<_>>()
);
}
}
}
#[test]
fn test_generate_secret() {
for (seed, result) in GENERATE_SECRET_TEST_VECTOR.iter().cloned() {
assert_eq!(WyHash32::generate_secret(seed), result);
}
}
}