use crate::generics::WyHashVariant;
use crate::util::wy_rotate;
#[derive(Copy, Clone)]
pub struct WyHash32Condom {
_private: (),
}
impl WyHashVariant for WyHash32Condom {
#[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);
(a ^ wy_rotate(hl) ^ hh, b ^ wy_rotate(lh) ^ ll)
}
}
#[cfg(test)]
#[cfg(feature = "std")]
mod test {
use super::*;
use crate::generics::test::*;
const TEST_VECTOR: TestVector = [
("",0, 0xeea54221671289db),
("a",1, 0xac4d02accfbeae5f),
("abc",2, 0xe6a807320c2ecb45),
("wyhash",3, 0x193194dc4d7ae61d),
("message digest",4, 0x62fb33aec500aa9),
("abcdefghijklmnopqrstuvwxyz",5, 0xd5b2f2a561107e8f),
("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",6, 0xdc0cb661c3a5717e),
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",7, 0xda836825fca55370),
("12345678901234567890123456789012345678901234567890123456789012345678901234567890",8, 0x46b1039fe4e9ed20),
("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()`~-_=+[{]};:,<.>/?",9, 0x1720cb8c72189461),
];
#[rustfmt::skip]
const GENERATE_SECRET_TEST_VECTOR: [(u64, [u64; 4]); 10] = [
(0x0, [ 0x1b99a3391da93a1d, 0x78a6a9a98e8795b1, 0xe45cd83956d4591d, 0xe4968be12bb86ac3]),
(0x1, [ 0x5ad82e99651e8e2b, 0xa993c3394e4b3c63, 0xc54b4e4bb85995a9, 0xe274d4696a8dd20f]),
(0x2, [ 0x9a35563aca2de44d, 0x9593a59359716c71, 0x5c8e338d7447c54d, 0x665a937278b1d88d]),
(0x3, [ 0x4bb1ace499a34da5, 0x2b9a8e8e2e552b69, 0xe81d17e81bd1f047, 0xc6e81e36539c8bc5]),
(0x4, [ 0x56a6b1ac9639394d, 0x8d4d3ce8a66aca65, 0xf0a6ac6a2d478d53, 0x39c6a6b15c2de239]),
(0x5, [ 0x1b4da54799aa3335, 0xe82ec678c9a50f95, 0x397499e14e932bc9, 0x4d695a4dd463ac2d]),
(0x6, [ 0x875c4e0f6a952e1b, 0x3a8ea55a69c36a87, 0x7456aa633533b493, 0x9695e84da6e2c363]),
(0x7, [ 0x3cb2b18b781b8769, 0xa94b879a55d4a31d, 0x8e3a2753934d7163, 0x9c17cce165175517]),
(0x8, [ 0x93a68ef0a9d43ad1, 0x1d4753391eb19ab1, 0x8b36c68756397159, 0xe893c56c3cc3e853]),
(0x9, [ 0x4b6a3acac91b9cb1, 0x8e3c694dc9d86a0f, 0xaa2772b44ef01d55, 0xe1b11be22b6c4e1b]),
];
const EXTENDED_TEST_VECTOR: ExtendedTestVector = [
(0, 0xeea54221671289dbu64),
(1, 0x020dd805695fc9eau64),
(2, 0x33af332bbf5c9234u64),
(3, 0x537caa1f96a07a21u64),
(4, 0x5b937d3918b03427u64),
(5, 0x00cd6d0d8b25806eu64),
(6, 0x8b95df2cdc0a6228u64),
(7, 0x0d78f4861e71a79du64),
(8, 0xe92a71a082d5fab3u64),
(9, 0x5355df371ef800ceu64),
(10, 0xf9d899203066423cu64),
(11, 0xa1eae7ff8f78bf13u64),
(12, 0x5af17e7eef210373u64),
(13, 0x6e613cd3184da253u64),
(14, 0x3e1ba8003dfc7992u64),
(15, 0x99aacc4d775059acu64),
(16, 0x6331047b9e708282u64),
(17, 0x0883b8dae86ca6c3u64),
(18, 0xf785b14ce090e08eu64),
(19, 0x02b1a401361aa789u64),
(20, 0x17a30b7d5ae318c7u64),
(21, 0x90b8e7a43a25660bu64),
(22, 0x7dfdd0bf60a1250fu64),
(23, 0xd5e78b11dacaccd6u64),
(24, 0x65bee070ba4c8110u64),
(25, 0xec2cdcdd17ab8c29u64),
(26, 0x47287af2d365ba3cu64),
(27, 0xa5a3e4cf39c7160eu64),
(28, 0x4899fac01efb933eu64),
(29, 0x67384cc63cd7c8acu64),
(30, 0xd27bfbc2a2d3eac1u64),
(31, 0x3a9f7b220e2bf222u64),
(32, 0xb8a204cef1457013u64),
(33, 0x4081d84535383e70u64),
(34, 0xa4756d9516a80cc7u64),
(35, 0x72e1d8b42b4d146bu64),
(36, 0x266a25b74a3151d7u64),
(37, 0x27d9f919c5be9195u64),
(38, 0x12c278e155532207u64),
(39, 0x65a631b85343b8f2u64),
(40, 0x7ded684962edd62du64),
(41, 0x9037050a2a44485cu64),
(42, 0x2351e370d40fd2c7u64),
(43, 0x1eefaa3c7edc4689u64),
(44, 0x578d921d5d55bab3u64),
(45, 0xb43038c904896b8fu64),
(46, 0x8e47d05f5d29860cu64),
(47, 0xdc592bda10ad8d49u64),
(48, 0x7577fd8b9180a386u64),
(49, 0x3ba1a2369b07f5f6u64),
(50, 0x6b145894e9881814u64),
(51, 0x3ec2e61b38dffd10u64),
(52, 0xab20eee97d635eb1u64),
(53, 0x8002818b7b5044f2u64),
(54, 0x11df779270f4a4b2u64),
(55, 0x086866ef240dd476u64),
(56, 0xfb8c21696ac39f0bu64),
(57, 0x8fdc8f0be7e9b480u64),
(58, 0xc00775ad06f4f739u64),
(59, 0x84a1666391a9580du64),
(60, 0x5dce484a6cbc46e9u64),
(61, 0x34217cc36cb14a63u64),
(62, 0x1c62e7ae82902269u64),
(63, 0x9140fbc329ab1960u64),
(64, 0x4f5c1648ac9afbeau64),
(65, 0x1677fce470e1a07bu64),
(66, 0x503b5ab4ca36e5c9u64),
(67, 0xd373c09fde0e770bu64),
(68, 0xcbe3c0bb6f6a91d8u64),
(69, 0xb3b5baa53e21b1c3u64),
(70, 0x71c1f519064b6a14u64),
(71, 0x78ce84779fb58c5du64),
(72, 0xc970371e56ab1452u64),
(73, 0x7c5845ede0515c3au64),
(74, 0xd5478f981786fe25u64),
(75, 0x4107ed3def81fe76u64),
(76, 0x745242d260bc49b6u64),
(77, 0xea830819a4a334fau64),
(78, 0x93a12835843cf4e7u64),
(79, 0x2b5639a41e360d38u64),
(80, 0x3396a3191b1a2579u64),
(81, 0x27381a78006c56a9u64),
(82, 0x477669819f338d4bu64),
(83, 0x7fc41434a2c61294u64),
(84, 0x9d7374c51692f396u64),
(85, 0xf6ee34eaaed19adau64),
(86, 0xbcccf2482d285196u64),
(87, 0x92d04ffc87eb5fc5u64),
(88, 0xce3da2cf9b1d9262u64),
(89, 0xd44e342f275ce012u64),
];
#[test]
fn test_hasher() {
for (input, seed, result) in TEST_VECTOR.iter().cloned() {
let input = input.as_bytes();
let mut hasher = WyHash32Condom::with_seed(seed).streamed();
hasher.write(input);
assert_eq!(hasher.finish(), result);
for chunksize in 1..=48 {
let mut hasher = WyHash32Condom::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 = WyHash32Condom::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 = WyHash32Condom::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 = WyHash32Condom::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!(WyHash32Condom::generate_secret(seed), result);
}
}
}