#pragma once
#include "Platform.h"
#include "Types.h"
#include <algorithm>
#include "MurmurHash1.h"
#include "MurmurHash2.h"
#include "MurmurHash3.h"
#include "PMurHash.h"
#define XXH_INLINE_ALL
#include "xxhash.h"
#include "metrohash/metrohash64.h"
#include "metrohash/metrohash128.h"
#include "cmetrohash.h"
#include "opt_cmetrohash.h"
#if defined(HAVE_SSE42) && (defined(__x86_64__) || defined(__aarch64__))
#include "metrohash/metrohash64crc.h"
#include "metrohash/metrohash128crc.h"
#endif
#ifdef HAVE_AHASH_C
#include "ahash.h"
#endif
#include "fasthash.h"
#include "jody_hash32.h"
#include "jody_hash64.h"
#include "tifuhash.h"
#include "floppsyhash.h"
#include "siphash.h"
#include "vmac.h"
#include "tabulation.h"
static inline bool BadHash_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { UINT32_C(0) };
return true;
}
void BadHash(const void *key, int len, uint32_t seed, void *out);
static inline bool sumhash_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { UINT32_C(0) };
return true;
}
void sumhash(const void *key, int len, uint32_t seed, void *out);
void sumhash32(const void *key, int len, uint32_t seed, void *out);
void DoNothingHash(const void *key, int len, uint32_t seed, void *out);
void NoopOAATReadHash(const void *key, int len, uint32_t seed, void *out);
void crc32(const void *key, int len, uint32_t seed, void *out);
static inline bool crc32c_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { UINT32_C(0x111c2232) };
return true;
}
#if defined(HAVE_SSE2)
void hasshe2_test(const void *key, int len, uint32_t seed, void *out);
#endif
#if defined(HAVE_SSE42)
# ifndef HAVE_BROKEN_MSVC_CRC32C_HW
void crc32c_hw_test(const void *key, int len, uint32_t seed, void *out);
void crc64c_hw_test(const void *key, int len, uint32_t seed, void *out);
# endif
# if defined(__SSE4_2__) && (defined(__i686__) || defined(_M_IX86) || defined(__x86_64__))
void crc32c_hw1_test(const void *key, int len, uint32_t seed, void *out);
# endif
static inline bool crc64c_bad_seeds(std::vector<uint64_t> &seeds)
{
seeds = std::vector<uint64_t> { UINT64_C(0) };
return true;
}
void CityHashCrc64_test(const void *key, int len, uint32_t seed, void *out);
void CityHashCrc128_test(const void *key, int len, uint32_t seed, void *out);
#endif
#if defined(HAVE_CLMUL) && !defined(_MSC_VER)
extern "C" uint32_t crc32_pclmul_le_16(unsigned char const *buffer, size_t len,
uint32_t crc32);
void crc32c_pclmul_test(const void *key, int len, uint32_t seed, void *out);
static inline bool crc32c_pclmul_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { UINT32_C(0) };
return true;
}
static inline bool need_minlen64_align16(pfHash hash) {
return hash == crc32c_pclmul_test;
}
void falkhash_test_cxx(const void *key, int len, uint32_t seed, void *out);
#else
static inline bool need_minlen64_align16(pfHash hash) {
return false;
}
#endif
size_t fibonacci(const char *key, int len, uint32_t seed);
inline void fibonacci_test(const void *key, int len, uint32_t seed, void *out) {
*(size_t *)out = fibonacci((const char *)key, len, seed);
}
size_t FNV2(const char *key, int len, size_t seed);
inline void FNV2_test(const void *key, int len, uint32_t seed, void *out) {
*(size_t *)out = FNV2((const char *)key, len, (size_t)seed);
}
uint32_t FNV32a(const void *key, int len, uint32_t seed);
static inline bool FNV32a_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { UINT32_C(0x811c9dc5) };
return true;
}
inline void FNV32a_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *)out = FNV32a((const char *)key, len, seed);
}
uint32_t FNV32a_YoshimitsuTRIAD(const char *key, int len, uint32_t seed);
static inline bool FNV32a_YT_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { UINT32_C(0x811c9dc5) };
return true;
}
inline void FNV32a_YT_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *)out = FNV32a_YoshimitsuTRIAD((const char *)key, len, seed);
}
#ifdef HAVE_INT64
uint32_t FNV1A_Totenschiff(const char *key, int len, uint32_t seed);
inline void FNV1A_Totenschiff_test(const void *key, int len, uint32_t seed,
void *out) {
*(uint32_t *)out = FNV1A_Totenschiff((const char *)key, len, seed);
}
uint32_t FNV1A_Pippip_Yurii(const char *key, int wrdlen, uint32_t seed);
inline void FNV1A_PY_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *)out = FNV1A_Pippip_Yurii((const char *)key, len, seed);
}
#endif
uint64_t FNV64a(const char *key, int len, uint64_t seed);
inline void FNV64a_test(const void *key, int len, uint32_t seed, void *out) {
*(uint64_t *)out = FNV64a((const char *)key, len, (uint64_t)seed);
}
static inline bool fletcher_bad_seeds(std::vector<uint64_t> &seeds)
{
seeds = std::vector<uint64_t> { UINT64_C(0) };
return true;
}
uint64_t fletcher2(const char *key, int len, uint64_t seed);
inline void fletcher2_test(const void *key, int len, uint32_t seed, void *out) {
*(uint64_t *) out = fletcher2((const char *)key, len, (uint64_t)seed);
}
uint64_t fletcher4(const char *key, int len, uint64_t seed);
inline void fletcher4_test(const void *key, int len, uint32_t seed, void *out) {
*(uint64_t *) out = fletcher2((const char *)key, len, (uint64_t)seed);
}
uint32_t Bernstein(const char *key, int len, uint32_t seed);
static inline bool Bernstein_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { UINT32_C(0) };
return true;
}
inline void Bernstein_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *) out = Bernstein((const char *)key, len, seed);
}
uint32_t sdbm(const char *key, int len, uint32_t hash);
static inline bool sdbm_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { UINT32_C(0) };
return true;
}
inline void sdbm_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *) out = sdbm((const char *)key, len, seed);
}
uint32_t x17(const char *key, int len, uint32_t h);
inline void x17_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *) out = x17((const char *)key, len, seed);
}
uint32_t JenkinsOOAT(const char *key, int len, uint32_t hash);
inline void JenkinsOOAT_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *) out = JenkinsOOAT((const char *)key, len, seed);
}
uint32_t JenkinsOOAT_perl(const char *key, int len, uint32_t hash);
inline void JenkinsOOAT_perl_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *) out = JenkinsOOAT_perl((const char *)key, len, seed);
}
uint32_t GoodOAAT(const char *key, int len, uint32_t hash);
inline void GoodOAAT_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *) out = GoodOAAT((const char *)key, len, seed);
}
uint32_t MicroOAAT(const char *key, int len, uint32_t hash);
inline void MicroOAAT_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *) out = MicroOAAT((const char *)key, len, seed);
}
uint32_t SuperFastHash (const char * data, int len, int32_t hash);
static inline bool SuperFastHash_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { UINT32_C(0) };
return true;
}
inline void SuperFastHash_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t*)out = SuperFastHash((const char*)key, len, seed);
}
uint32_t lookup3(const char *key, int len, uint32_t hash);
inline void lookup3_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *) out = lookup3((const char *)key, len, seed);
}
uint32_t MurmurOAAT(const char *key, int len, uint32_t hash);
inline void MurmurOAAT_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *) out = MurmurOAAT((const char *)key, len, seed);
}
uint32_t Crap8(const uint8_t * key, uint32_t len, uint32_t seed);
inline void Crap8_test(const void *key, int len, uint32_t seed, void *out) {
*(uint32_t *) out = Crap8((const uint8_t *)key, len, seed);
}
void CityHash32_test(const void *key, int len, uint32_t seed, void *out);
void CityHash64noSeed_test(const void *key, int len, uint32_t seed, void *out);
void CityHash64_test(const void *key, int len, uint32_t seed, void *out);
inline void CityHash64_low_test(const void *key, int len, uint32_t seed, void *out) {
uint64_t result;
CityHash64_test(key, len, seed, &result);
*(uint32_t *)out = (uint32_t)result;
}
void CityHash128_test(const void *key, int len, uint32_t seed, void *out);
void FarmHash32_test ( const void * key, int len, uint32_t seed, void * out );
void FarmHash64_test ( const void * key, int len, uint32_t seed, void * out );
void FarmHash64noSeed_test ( const void * key, int len, uint32_t seed, void * out );
void FarmHash128_test ( const void * key, int len, uint32_t seed, void * out );
void farmhash32_c_test ( const void * key, int len, uint32_t seed, void * out );
void farmhash64_c_test ( const void * key, int len, uint32_t seed, void * out );
void farmhash128_c_test ( const void * key, int len, uint32_t seed, void * out );
void SpookyHash32_test ( const void * key, int len, uint32_t seed, void * out );
void SpookyHash64_test ( const void * key, int len, uint32_t seed, void * out );
void SpookyHash128_test ( const void * key, int len, uint32_t seed, void * out );
uint32_t MurmurOAAT ( const char * key, int len, uint32_t seed );
void MurmurHash2_test ( const void * key, int len, uint32_t seed, void * out );
void MurmurHash2A_test ( const void * key, int len, uint32_t seed, void * out );
void siphash_test ( const void * key, int len, uint32_t seed, void * out );
void siphash13_test ( const void * key, int len, uint32_t seed, void * out );
void halfsiphash_test ( const void * key, int len, uint32_t seed, void * out );
extern "C" void chaskey_c ( const void * key, int len, uint64_t seed, void * out );
extern "C" void chaskey_init();
inline void
chaskey_test(const void *input, int len, uint32_t seed, void *out)
{
uint64_t lseed = (uint64_t)seed;
chaskey_c (input, len, lseed, out);
}
inline void MurmurHash1_test ( const void * key, int len, uint32_t seed, void * out )
{
*(uint32_t*)out = MurmurHash1(key,len,seed);
}
inline void MurmurHash2_test ( const void * key, int len, uint32_t seed, void * out )
{
*(uint32_t*)out = MurmurHash2(key,len,seed);
}
inline void MurmurHash2A_test ( const void * key, int len, uint32_t seed, void * out )
{
*(uint32_t*)out = MurmurHash2A(key,len,seed);
}
#if __WORDSIZE >= 64
inline void MurmurHash64A_test ( const void * key, int len, uint32_t seed, void * out )
{
*(uint64_t*)out = MurmurHash64A(key,len,seed);
}
#endif
#ifdef HAVE_INT64
static void MurmurHash64B_seed_init(uint32_t &seed) {
if ((seed & 0x10) == 0x10)
seed++;
}
inline void MurmurHash64B_test ( const void * key, int len, uint32_t seed, void * out )
{
*(uint64_t*)out = MurmurHash64B(key,len,seed);
}
#endif
inline void jodyhash32_test( const void * key, int len, uint32_t seed, void * out ) {
*(uint32_t*)out = jody_block_hash32((const jodyhash32_t *)key, (jodyhash32_t) seed, (size_t) len);
}
#ifdef HAVE_INT64
inline void jodyhash64_test( const void * key, int len, uint32_t seed, void * out ) {
*(uint64_t*)out = jody_block_hash((const jodyhash_t *)key, (jodyhash_t) seed, (size_t) len);
}
#endif
inline void xxHash32_test( const void * key, int len, uint32_t seed, void * out ) {
*(uint32_t*)out = (uint32_t) XXH32(key, (size_t) len, (unsigned) seed);
}
#ifdef HAVE_INT64
inline void xxHash64_test( const void * key, int len, uint32_t seed, void * out ) {
*(uint64_t*)out = (uint64_t) XXH64(key, (size_t) len, (unsigned long long) seed);
}
#endif
#define restrict
#include "xxh3.h"
#ifdef HAVE_INT64
static inline bool xxh3_bad_seeds(std::vector<uint64_t> &seeds) {
return false;
}
inline void xxh3_test( const void * key, int len, uint32_t seed, void * out ) {
*(uint64_t*)out = (uint64_t) XXH3_64bits_withSeed(key, (size_t) len, seed);
}
#endif
inline void xxh3low_test( const void * key, int len, uint32_t seed, void * out ) {
*(uint32_t*)out = (uint32_t) XXH3_64bits_withSeed(key, (size_t) len, seed);
}
#ifdef HAVE_INT64
inline void xxh128_test( const void * key, int len, uint32_t seed, void * out ) {
*(XXH128_hash_t*)out = XXH128(key, (size_t) len, seed);
}
inline void xxh128low_test( const void * key, int len, uint32_t seed, void * out ) {
*(uint64_t*)out = (uint64_t) (XXH128(key, (size_t) len, seed).low64);
}
#ifdef HAVE_INT64
inline void metrohash64_test ( const void * key, int len, uint32_t seed, void * out ) {
MetroHash64::Hash((const uint8_t *)key, (uint64_t)len, (uint8_t *)out, seed);
}
inline void metrohash64_1_test ( const void * key, int len, uint32_t seed, void * out ) {
metrohash64_1((const uint8_t *)key, (uint64_t)len, seed, (uint8_t *)out);
}
inline void metrohash64_2_test ( const void * key, int len, uint32_t seed, void * out ) {
metrohash64_2((const uint8_t *)key, (uint64_t)len, seed, (uint8_t *)out);
}
inline void metrohash128_test ( const void * key, int len, uint32_t seed, void * out ) {
MetroHash128::Hash((const uint8_t *)key, (uint64_t)len, (uint8_t *)out, seed);
}
inline void metrohash128_1_test ( const void * key, int len, uint32_t seed, void * out ) {
metrohash128_1((const uint8_t *)key, (uint64_t)len, seed, (uint8_t *)out);
}
inline void metrohash128_2_test ( const void * key, int len, uint32_t seed, void * out ) {
metrohash128_2((const uint8_t *)key, (uint64_t)len, seed, (uint8_t *)out);
}
#endif
#if defined(HAVE_SSE42) && (defined(__x86_64__) || defined(__aarch64__)) && !defined(_MSC_VER)
inline void metrohash64crc_1_test ( const void * key, int len, uint32_t seed, void * out ) {
metrohash64crc_1((const uint8_t *)key, (uint64_t)len, seed, (uint8_t *)out);
}
inline void metrohash64crc_2_test ( const void * key, int len, uint32_t seed, void * out ) {
metrohash64crc_2((const uint8_t *)key, (uint64_t)len, seed, (uint8_t *)out);
}
inline void metrohash128crc_1_test ( const void * key, int len, uint32_t seed, void * out ) {
metrohash128crc_1((const uint8_t *)key, (uint64_t)len, seed, (uint8_t *)out);
}
inline void metrohash128crc_2_test ( const void * key, int len, uint32_t seed, void * out ) {
metrohash128crc_2((const uint8_t *)key, (uint64_t)len, seed, (uint8_t *)out);
}
#endif
inline void cmetrohash64_1_test ( const void * key, int len, uint32_t seed, void * out ) {
cmetrohash64_1((const uint8_t *)key,(uint64_t)len,seed,(uint8_t *)out);
}
inline void cmetrohash64_1_optshort_test ( const void * key, int len, uint32_t seed, void * out ) {
cmetrohash64_1_optshort((const uint8_t *)key,(uint64_t)len,seed,(uint8_t *)out);
}
inline void cmetrohash64_2_test ( const void * key, int len, uint32_t seed, void * out ) {
cmetrohash64_2((const uint8_t *)key,(uint64_t)len,seed,(uint8_t *)out);
}
#endif
inline void fasthash32_test ( const void * key, int len, uint32_t seed, void * out ) {
*(uint32_t*)out = fasthash32(key, (size_t) len, seed);
}
#ifdef HAVE_INT64
inline void fasthash64_test ( const void * key, int len, uint32_t seed, void * out ) {
*(uint64_t*)out = fasthash64(key, (size_t) len, (uint64_t)seed);
}
#ifdef HAVE_AHASH_C
inline void ahash64_test ( const void * key, int len, uint32_t seed, void * out ) {
*(uint64_t*)out = ahash64(key, (size_t) len, (uint64_t)seed);
}
#endif
#endif
void mum_hash_test(const void * key, int len, uint32_t seed, void * out);
static inline bool mum_hash_bad_seeds(std::vector<uint64_t> &seeds)
{
seeds = std::vector<uint64_t> { UINT64_C(0) };
return true;
}
inline void mum_low_test ( const void * key, int len, uint32_t seed, void * out ) {
uint64_t result;
mum_hash_test(key, len, seed, &result);
*(uint32_t*)out = (uint32_t)result;
}
#define T1HA0_RUNTIME_SELECT 0
#ifdef HAVE_AESNI
# define T1HA0_AESNI_AVAILABLE 1
#else
# define T1HA0_AESNI_AVAILABLE 0
#endif
#include "t1ha.h"
inline void t1ha2_atonce_test(const void * key, int len, uint32_t seed, void * out)
{
*(uint64_t*)out = t1ha2_atonce(key, len, seed);
}
inline void t1ha2_stream_test(const void * key, int len, uint32_t seed, void * out)
{
t1ha_context_t ctx;
t1ha2_init(&ctx, seed, 0);
t1ha2_update(&ctx, key, len);
*(uint64_t*)out = t1ha2_final(&ctx, NULL);
}
inline void t1ha2_atonce128_test(const void * key, int len, uint32_t seed, void * out)
{
*(uint64_t*)out = t1ha2_atonce128((uint64_t*)out + 1, key, len, seed);
}
inline void t1ha2_stream128_test(const void * key, int len, uint32_t seed, void * out)
{
t1ha_context_t ctx;
t1ha2_init(&ctx, seed, 0);
t1ha2_update(&ctx, key, len);
*(uint64_t*)out = t1ha2_final(&ctx, (uint64_t*)out + 1);
}
inline void t1ha1_64le_test(const void * key, int len, uint32_t seed, void * out)
{
*(uint64_t*)out = t1ha1_le(key, len, seed);
}
inline void t1ha1_64be_test(const void * key, int len, uint32_t seed, void * out)
{
*(uint64_t*)out = t1ha1_be(key, len, seed);
}
inline void t1ha0_32le_test(const void * key, int len, uint32_t seed, void * out)
{
*(uint64_t*)out = t1ha0_32le(key, len, seed);
}
inline void t1ha0_32be_test(const void * key, int len, uint32_t seed, void * out)
{
*(uint64_t*)out = t1ha0_32be(key, len, seed);
}
#if T1HA0_AESNI_AVAILABLE
#ifndef _MSC_VER
inline void t1ha0_ia32aes_noavx_test(const void * key, int len, uint32_t seed, void * out)
{
*(uint64_t*)out = t1ha0_ia32aes_noavx(key, len, seed);
}
#endif
#if defined(__AVX__)
inline void t1ha0_ia32aes_avx1_test(const void * key, int len, uint32_t seed, void * out)
{
*(uint64_t*)out = t1ha0_ia32aes_avx(key, len, seed);
}
#endif
#if defined(__AVX2__)
inline void t1ha0_ia32aes_avx2_test(const void * key, int len, uint32_t seed, void * out)
{
*(uint64_t*)out = t1ha0_ia32aes_avx2(key, len, seed);
}
#endif
#endif
#if defined(HAVE_SSE42) && defined(__x86_64__)
#include "clhash.h"
void clhash_init();
void clhash_seed_init(size_t &seed);
void clhash_test (const void * key, int len, uint32_t seed, void * out);
#endif
void halftime_hash_style64_test(const void *key, int len, uint32_t seed, void *out);
void halftime_hash_style128_test(const void *key, int len, uint32_t seed, void *out);
void halftime_hash_style256_test(const void *key, int len, uint32_t seed, void *out);
void halftime_hash_style512_test(const void *key, int len, uint32_t seed, void *out);
void halftime_hash_init();
void halftime_hash_seed_init(size_t &seed);
#ifdef __SIZEOF_INT128__
void multiply_shift_init();
void multiply_shift_seed_init(uint32_t &seed);
bool multiply_shift_bad_seeds(std::vector<uint64_t> &seeds);
void multiply_shift (const void * key, int len, uint32_t seed, void * out);
void pair_multiply_shift (const void *key, int len, uint32_t seed, void *out);
void poly_mersenne_init();
void poly_mersenne_seed_init(uint32_t &seed);
void poly_1_mersenne (const void* key, int len, uint32_t seed, void* out);
void poly_2_mersenne (const void* key, int len, uint32_t seed, void* out);
void poly_3_mersenne (const void* key, int len, uint32_t seed, void* out);
void poly_4_mersenne (const void* key, int len, uint32_t seed, void* out);
#endif
#ifdef __SIZEOF_INT128__
inline void tabulation_init() {
size_t seed = 2;
tabulation_seed_init(seed);
}
inline void tabulation_test (const void * key, int len, uint32_t seed, void * out) {
*(uint64_t*)out = tabulation_hash(key, len, seed);
}
#endif
inline void tabulation_32_init() {
size_t seed = 0;
tabulation_32_seed_init(seed);
}
inline void tabulation_32_test (const void * key, int len, uint32_t seed, void * out) {
*(uint32_t*)out = tabulation_32_hash(key, len, seed);
}
void HighwayHash_init();
void HighwayHash64_test (const void * key, int len, uint32_t seed, void * out);
#ifdef HAVE_INT64
#include "wyhash.h"
static inline bool wyhash_bad_seeds(std::vector<uint64_t> &seeds)
{
seeds = std::vector<uint64_t> { 0x14cc886e, 0x1bf4ed84 };
return true;
}
inline void wyhash_test (const void * key, int len, uint32_t seed, void * out) {
*(uint64_t*)out = wyhash(key, (uint64_t)len, (uint64_t)seed, _wyp);
}
inline void wyhash32low (const void * key, int len, uint32_t seed, void * out) {
*(uint32_t*)out = 0xFFFFFFFF & wyhash(key, (uint64_t)len, (uint64_t)seed, _wyp);
}
#endif
static inline bool wyhash32_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> {
UINT32_C(0x429dacdd), UINT32_C(0xd637dbf3),
};
return true;
}
#ifdef HAVE_BIT32
#include "wyhash32.h"
inline void wyhash32_test (const void * key, int len, uint32_t seed, void * out) {
*(uint32_t*)out = wyhash32(key, (uint64_t)len, (unsigned)seed);
}
#endif
#ifdef HAVE_INT64
#include "o1hash.h"
inline void o1hash_test (const void * key, int len, uint32_t seed, void * out) {
*(uint64_t*)out = o1hash(key, (uint64_t)len);
}
#include "mir-hash.h"
static inline bool mirhash_bad_seeds(std::vector<uint64_t> &seeds)
{
seeds = std::vector<uint64_t> { 0x0, 0x5e74c778, 0xa521f17b, 0xe0ab70e3 };
return true;
}
inline void mirhash_test (const void * key, int len, uint32_t seed, void * out) {
*(uint64_t*)out = mir_hash(key, (uint64_t)len, (uint64_t)seed);
}
static inline bool mirhash32_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { 0x0, 0x5e74c778, 0xa521f17b, 0xe0ab70e3 };
return true;
}
inline void mirhash32low (const void * key, int len, uint32_t seed, void * out) {
*(uint32_t*)out = 0xFFFFFFFF & mir_hash(key, (uint64_t)len, (uint64_t)seed);
}
inline void mirhashstrict_test (const void * key, int len, uint32_t seed, void * out) {
*(uint64_t*)out = mir_hash_strict(key, (uint64_t)len, (uint64_t)seed);
}
static inline bool mirhashstrict32low_bad_seeds(std::vector<uint32_t> &seeds)
{
seeds = std::vector<uint32_t> { 0x7fcc747f };
return true;
}
inline void mirhashstrict32low (const void * key, int len, uint32_t seed, void * out) {
*(uint32_t*)out = 0xFFFFFFFF & mir_hash_strict(key, (uint64_t)len, (uint64_t)seed);
}
static void mirhash_seed_init(uint32_t &seed)
{
std::vector<uint64_t> bad_seeds;
mirhash_bad_seeds(bad_seeds);
for (uint64_t s : bad_seeds) {
if (s == seed) {
seed++; break;
}
if ((s << 32) & seed) {
seed++; break;
}
}
}
static void mirhash32_seed_init(uint32_t &seed)
{
std::vector<uint32_t> bad_seeds;
mirhash32_bad_seeds(bad_seeds);
while (std::find(bad_seeds.begin(), bad_seeds.end(), (uint32_t)seed) != bad_seeds.end())
seed++;
}
#ifndef _MSC_VER
void tsip_init();
void tsip_test (const void * key, int len, uint32_t seed, void * out);
extern "C" uint64_t tsip(const unsigned char *seed, const unsigned char *m, uint64_t len);
extern "C" uint64_t seahash(const char *key, int len, uint64_t seed);
inline void seahash_test (const void *key, int len, uint32_t seed, void *out) {
*(uint64_t*)out = seahash((const char *)key, len, (uint64_t)seed);
}
inline void seahash32low (const void *key, int len, uint32_t seed, void *out) {
uint64_t result = seahash((const char *)key, len, (uint64_t)seed);
*(uint32_t*)out = (uint32_t)(UINT64_C(0xffffffff) & result);
}
#endif
#endif
#include "md5.h"
inline void md5_128(const void *key, int len, uint32_t seed, void *out) {
md5_context md5_ctx;
md5_starts( &md5_ctx );
md5_ctx.state[0] ^= seed;
md5_update( &md5_ctx, (unsigned char *)key, len );
md5_finish( &md5_ctx, (unsigned char *)out );
}
inline void md5_32(const void *key, int len, uint32_t seed, void *out) {
unsigned char hash[16];
md5_context md5_ctx;
md5_starts( &md5_ctx );
md5_ctx.state[0] ^= seed;
md5_update( &md5_ctx, (unsigned char *)key, len );
md5_finish( &md5_ctx, hash );
memcpy(out, hash, 4);
}
#include "sha1.h"
inline void sha1_160(const void *key, int len, uint32_t seed, void *out) {
SHA1_CTX context;
SHA1_Init(&context);
context.state[0] ^= seed;
SHA1_Update(&context, (uint8_t*)key, len);
SHA1_Final(&context, (uint8_t*)out);
}
void SHA1_Update(SHA1_CTX *context, const uint8_t *data, const size_t len);
inline void sha1_32a(const void *key, int len, uint32_t seed, void *out) {
SHA1_CTX context;
uint8_t *digest = (uint8_t *)out;
SHA1_Init(&context);
context.state[0] ^= seed;
SHA1_Update(&context, (uint8_t *)key, len);
unsigned i;
uint8_t finalcount[8];
uint8_t c;
for (i = 0; i < 8; i++) {
finalcount[i] =
(uint8_t)(context.count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8));
}
c = 0200;
SHA1_Update(&context, &c, 1);
while ((context.count[0] & 504) != 448) {
c = 0000;
SHA1_Update(&context, &c, 1);
}
SHA1_Update(&context, finalcount, 8);
for (i = 0; i < 4; i++) { digest[i] = (uint8_t)(context.state[i >> 2] >> ((3 - (i & 3)) * 8));
}
}
#include "tomcrypt.h"
#ifndef _MAIN_CPP
extern
#endif
hash_state ltc_state;
int blake2b_init(hash_state * md, unsigned long outlen,
const unsigned char *key, unsigned long keylen);
inline void blake2b160_test(const void *key, int len, uint32_t seed, void *out)
{
blake2b_init(<c_state, 20, NULL, 0);
ltc_state.blake2b.h[0] ^= seed; blake2b_process(<c_state, (unsigned char *)key, len);
blake2b_done(<c_state, (unsigned char *)out);
}
inline void blake2b224_test(const void *key, int len, uint32_t seed, void *out)
{
blake2b_init(<c_state, 28, NULL, 0);
ltc_state.blake2b.h[0] ^= seed;
blake2b_process(<c_state, (unsigned char *)key, len);
blake2b_done(<c_state, (unsigned char *)out);
}
inline void blake2b256_test(const void *key, int len, uint32_t seed, void *out)
{
blake2b_init(<c_state, 32, NULL, 0);
ltc_state.blake2b.h[0] ^= seed;
blake2b_process(<c_state, (unsigned char *)key, len);
blake2b_done(<c_state, (unsigned char *)out);
}
inline void blake2b256_64(const void *key, int len, uint32_t seed, void *out)
{
unsigned char buf[32];
blake2b_init(<c_state, 32, NULL, 0);
ltc_state.blake2b.h[0] ^= seed;
blake2b_process(<c_state, (unsigned char *)key, len);
blake2b_done(<c_state, buf);
memcpy(out, buf, 8);
}
int blake2s_init(hash_state * md, unsigned long outlen,
const unsigned char *key, unsigned long keylen);
inline void blake2s128_test(const void * key, int len, uint32_t seed, void * out)
{
blake2s_init(<c_state, 16, NULL, 0);
ltc_state.blake2s.h[0] ^= seed;
blake2s_process(<c_state, (unsigned char *)key, len);
blake2s_done(<c_state, (unsigned char *)out);
}
inline void blake2s160_test(const void * key, int len, uint32_t seed, void * out)
{
blake2s_init(<c_state, 20, NULL, 0);
ltc_state.blake2s.h[0] ^= seed;
blake2s_process(<c_state, (unsigned char *)key, len);
blake2s_done(<c_state, (unsigned char *)out);
}
inline void blake2s224_test(const void * key, int len, uint32_t seed, void * out)
{
blake2s_init(<c_state, 28, NULL, 0);
ltc_state.blake2s.h[0] ^= seed;
blake2s_process(<c_state, (unsigned char *)key, len);
blake2s_done(<c_state, (unsigned char *)out);
}
inline void blake2s256_test(const void * key, int len, uint32_t seed, void * out)
{
blake2s_init(<c_state, 32, NULL, 0);
ltc_state.blake2s.h[0] ^= seed;
blake2s_process(<c_state, (unsigned char *)key, len);
blake2s_done(<c_state, (unsigned char *)out);
}
inline void blake2s256_64(const void * key, int len, uint32_t seed, void * out)
{
unsigned char buf[32];
blake2s_init(<c_state, 32, NULL, 0);
ltc_state.blake2s.h[0] ^= seed;
blake2s_process(<c_state, (unsigned char *)key, len);
blake2s_done(<c_state, buf);
memcpy(out, buf, 8);
}
inline void sha2_224(const void *key, int len, uint32_t seed, void *out)
{
sha224_init(<c_state);
ltc_state.sha256.state[0] ^= seed;
ltc_state.sha256.state[0] += len; sha224_process(<c_state, (unsigned char *)key, len);
sha224_done(<c_state, (unsigned char *)out);
}
inline void sha2_224_64(const void *key, int len, uint32_t seed, void *out)
{
unsigned char buf[28];
sha224_init(<c_state);
ltc_state.sha256.state[0] ^= seed;
ltc_state.sha256.state[0] += len; sha224_process(<c_state, (unsigned char *)key, len);
sha224_done(<c_state, buf);
memcpy(out, buf, 8);
}
inline void sha2_256(const void *key, int len, uint32_t seed, void *out)
{
sha256_init(<c_state);
ltc_state.sha256.state[0] ^= seed;
ltc_state.sha256.state[0] += len; sha256_process(<c_state, (unsigned char *)key, len);
sha256_done(<c_state, (unsigned char *)out);
}
inline void sha2_256_64(const void *key, int len, uint32_t seed, void *out)
{
unsigned char buf[32];
sha256_init(<c_state);
ltc_state.sha256.state[0] ^= seed;
ltc_state.sha256.state[0] += len; sha256_process(<c_state, (unsigned char *)key, len);
sha256_done(<c_state, buf);
memcpy(out, buf, 8);
}
inline void rmd128(const void *key, int len, uint32_t seed, void *out)
{
rmd128_init(<c_state);
ltc_state.rmd128.state[0] ^= seed;
rmd128_process(<c_state, (unsigned char *)key, len);
rmd128_done(<c_state, (unsigned char *)out);
}
inline void rmd160(const void *key, int len, uint32_t seed, void *out)
{
rmd160_init(<c_state);
ltc_state.rmd160.state[0] = 0x67452301UL ^ seed;
rmd160_process(<c_state, (unsigned char *)key, len);
rmd160_done(<c_state, (unsigned char *)out);
}
inline void rmd256(const void *key, int len, uint32_t seed, void *out)
{
rmd256_init(<c_state);
ltc_state.rmd256.state[0] ^= seed;
rmd256_process(<c_state, (unsigned char *)key, len);
rmd256_done(<c_state, (unsigned char *)out);
}
inline void sha3_256_64(const void *key, int len, uint32_t seed, void *out)
{
unsigned char buf[32];
sha3_256_init(<c_state);
ltc_state.sha3.s[0] ^= seed;
sha3_process(<c_state, (unsigned char *)key, len);
sha3_done(<c_state, buf);
memcpy(out, buf, 8);
}
inline void sha3_256(const void *key, int len, uint32_t seed, void *out)
{
sha3_256_init(<c_state);
ltc_state.sha3.s[0] ^= seed;
sha3_process(<c_state, (unsigned char *)key, len);
sha3_done(<c_state, (unsigned char *)out);
}
inline void wysha(const void *key, int len, unsigned seed, void *out) {
uint64_t s[4] = {wyhash(key, len, seed + 0, _wyp), wyhash(key, len, seed + 1, _wyp),
wyhash(key, len, seed + 2, _wyp), wyhash(key, len, seed + 3, _wyp)};
memcpy(out, s, 32);
}
#if defined(HAVE_AESNI) && defined(__SIZEOF_INT128__) && \
(defined(__x86_64__) || defined(_M_AMD64) || defined(__i386__) || defined(_M_IX86))
#define HAVE_MEOW_HASH
#include "meow_hash_x64_aesni.h"
inline void MeowHash128_test(const void *key, int len, unsigned seed, void *out) {
*(int unsigned *)MeowDefaultSeed = seed;
meow_u128 h = MeowHash(MeowDefaultSeed, (meow_umm)len, (void*)key);
((uint64_t *)out)[0] = MeowU64From(h, 0);
((uint64_t *)out)[1] = MeowU64From(h, 1);
}
inline void MeowHash64_test(const void *key, int len, unsigned seed, void *out) {
*(int unsigned *)MeowDefaultSeed = seed;
meow_u128 h = MeowHash(MeowDefaultSeed, (meow_umm)len, (void*)key);
*(uint64_t *)out = MeowU64From(h, 0);
}
inline void MeowHash32_test(const void *key, int len, unsigned seed, void *out) {
*(int unsigned *)MeowDefaultSeed = seed;
meow_u128 h = MeowHash(MeowDefaultSeed, (meow_umm)len, (void*)key);
*(uint32_t *)out = MeowU32From(h, 0);
}
#endif
#if defined(HAVE_SHANI) && defined(__x86_64__)
extern "C" void sha1_process_x86(uint32_t *state, const uint8_t *data, uint32_t length);
extern "C" void sha256_process_x86(uint32_t *state, const uint8_t *data, uint32_t length);
inline void sha1ni(const void *key, int len, uint32_t seed, void *out)
{
uint32_t state[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
state[0] ^= seed;
if (len < 64) {
uint8_t padded[64];
memcpy (padded, key, len);
memset (&padded[len], 0, 64-len);
state[0] += len;
sha1_process_x86(state, (const uint8_t*)padded, 64);
} else if (len % 64) {
uint32_t lenpadded = len + (64 - len % 64);
uint8_t *padded = (uint8_t*)malloc (lenpadded);
memcpy (padded, key, len);
memset (&padded[len], 0, lenpadded-len);
state[0] += len;
sha1_process_x86(state, (const uint8_t*)padded, lenpadded);
free (padded);
} else {
sha1_process_x86(state, (const uint8_t*)key, (uint32_t)len);
}
memcpy(out, state, 20);
}
inline void sha1ni_32(const void *key, int len, uint32_t seed, void *out)
{
uint32_t state[5] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
state[0] ^= seed;
if (len < 64) {
uint8_t padded[64];
memcpy (padded, key, len);
memset (&padded[len], 0, 64-len);
state[0] += len;
sha1_process_x86(state, (const uint8_t*)padded, 64);
} else if (len % 64) {
uint32_t lenpadded = len + (64 - len % 64);
uint8_t *padded = (uint8_t*)malloc (lenpadded);
memcpy (padded, key, len);
memset (&padded[len], 0, lenpadded-len);
state[0] += len;
sha1_process_x86(state, (const uint8_t*)padded, lenpadded);
free (padded);
} else {
sha1_process_x86(state, (const uint8_t*)key, (uint32_t)len);
}
*(uint32_t *)out = *(uint32_t *)state;
}
inline void sha2ni_256(const void *key, int len, uint32_t seed, void *out)
{
uint32_t state[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
state[0] ^= seed;
if (len < 64) {
uint8_t padded[64];
memcpy (padded, key, len);
memset (&padded[len], 0, 64-len);
state[0] += len; sha256_process_x86(state, (const uint8_t*)padded, 64);
} else if (len % 64) {
uint32_t lenpadded = len + (64 - len % 64);
uint8_t *padded = (uint8_t*)malloc (lenpadded);
memcpy (padded, key, len);
memset (&padded[len], 0, lenpadded-len);
state[0] += len;
sha256_process_x86(state, (const uint8_t*)padded, lenpadded);
free (padded);
} else {
sha256_process_x86(state, (const uint8_t*)key, (uint32_t)len);
}
memcpy(out, state, 32);
}
inline void sha2ni_256_64(const void *key, int len, uint32_t seed, void *out)
{
uint32_t state[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
state[0] ^= seed;
if (len < 64) {
uint8_t padded[64];
memcpy (padded, key, len);
memset (&padded[len], 0, 64-len);
state[0] += len;
sha256_process_x86(state, (const uint8_t*)padded, 64);
} else if (len % 64) {
uint32_t lenpadded = len + (64 - len % 64);
uint8_t *padded = (uint8_t*)malloc (lenpadded);
memcpy (padded, key, len);
memset (&padded[len], 0, lenpadded-len);
state[0] += len;
sha256_process_x86(state, (const uint8_t*)padded, lenpadded);
free (padded);
} else {
sha256_process_x86(state, (const uint8_t*)key, (uint32_t)len);
}
*(uint64_t *)out = *(uint64_t *)state;
}
#endif
#ifdef HAVE_SSE2
void farsh32_test ( const void * key, int len, unsigned seed, void * out );
void farsh64_test ( const void * key, int len, unsigned seed, void * out );
void farsh128_test ( const void * key, int len, unsigned seed, void * out );
void farsh256_test ( const void * key, int len, unsigned seed, void * out );
#endif
extern "C" {
#include "blake3/blake3_impl.h"
inline void blake3c_test ( const void * key, int len, unsigned seed, void * out )
{
blake3_hasher hasher;
#if 1
blake3_hasher_init (&hasher);
hasher.key[0] ^= (uint32_t)seed;
hasher.chunk.cv[0] ^= (uint32_t)seed;
#else#endif
blake3_hasher_update (&hasher, (uint8_t*)key, (size_t)len);
blake3_hasher_finalize (&hasher, (uint8_t*)out, BLAKE3_OUT_LEN);
}
}
#ifdef HAVE_BLAKE3
typedef struct rust_array {
char *ptr;
size_t len;
} rs_arr;
extern "C" rs_arr *blake3_hash (const rs_arr *input);
inline void blake3_test ( const void * key, int len, unsigned seed, void * out )
{
rs_arr input;
rs_arr *result;
input.ptr = (char*)key;
input.len = (size_t)len;
result = blake3_hash (&input);
memcpy (out, result->ptr, 32);
}
inline void blake3_64 ( const void * key, int len, unsigned seed, void * out )
{
rs_arr input;
rs_arr *result;
input.ptr = (char*)key;
input.len = (size_t)len;
result = blake3_hash (&input);
*(uint64_t *)out = *(uint64_t *)result->ptr;
}
#endif
#ifndef DEBUG
#include "PMP_Multilinear_test.h"
#endif
#include "beamsplitter.h"
#include "discohash.h"
#if defined(HAVE_SSE2) && defined(HAVE_AESNI) && !defined(_MSC_VER)
uint64_t aesnihash(uint8_t *in, unsigned long src_sz, uint32_t seed);
inline void aesnihash_test ( const void * key, int len, unsigned seed, void * out )
{
uint64_t result = aesnihash ((uint8_t *)key, (unsigned long)len, (uint32_t)seed);
*(uint64_t *)out = result;
}
#endif
#ifdef HAVE_INT64
#include "prvhash/prvhash64.h"
inline void prvhash64_64mtest ( const void * key, int len, unsigned seed, void * out )
{
*(uint64_t*)out = prvhash64_64m ((const uint8_t *)key, len, (uint64_t)seed);
}
inline void prvhash64_64test ( const void * key, int len, unsigned seed, void * out )
{
uint8_t hash[16] = {0};
prvhash64 ((const uint8_t *)key, len, hash, 8, (uint64_t)seed, NULL);
memcpy (out, hash, 8);
}
inline void prvhash64_128test ( const void * key, int len, unsigned seed, void * out )
{
uint8_t hash[32] = {0};
prvhash64 ((const uint8_t *)key, len, hash, 16, (uint64_t)seed, NULL);
memcpy (out, hash, 16);
}
#include "prvhash/prvhash64s.h"
#define PRVHASH64S_PAR 4
inline void prvhash64s_64test ( const void * key, int len, unsigned seed, void * out )
{
PRVHASH64S_CTX ctx;
uint64_t SeedXOR[ PRVHASH64S_PAR ] = { (uint64_t)seed, (uint64_t)seed, (uint64_t)seed, (uint64_t)seed };
prvhash64s_init( &ctx, (uint8_t* const)out, 8, SeedXOR, 0 );
prvhash64s_update( &ctx, (const uint8_t*)key, (size_t)len );
prvhash64s_final( &ctx );
}
inline void prvhash64s_128test ( const void * key, int len, unsigned seed, void * out )
{
PRVHASH64S_CTX ctx;
uint64_t SeedXOR[ PRVHASH64S_PAR ] = { (uint64_t)seed, (uint64_t)seed, (uint64_t)seed, (uint64_t)seed };
prvhash64s_init( &ctx, (uint8_t* const)out, 16, SeedXOR, 0 );
prvhash64s_update( &ctx, (const uint8_t*)key, (size_t)len );
prvhash64s_final( &ctx );
}
#endif
#include "mx3/mx3.h"
inline void mx3hash64_test ( const void * key, int len, uint32_t seed, void * out ) {
*(uint64_t*)out = mx3::hash((const uint8_t*)(key), (size_t) len, (uint64_t)seed);
}
extern "C" {
#include "pengyhash.h"
}
inline void pengyhash_test ( const void * key, int len, uint32_t seed, void * out ) {
*(uint64_t*)out = pengyhash (key, (size_t) len, seed);
}
#if defined(HAVE_SSE42) && (defined(__x86_64__) || defined(__aarch64__)) && !defined(_MSC_VER)
#include "umash.hpp"
#endif
extern "C" {
void asconhashv12_64 ( const void * key, int len, uint32_t seed, void * out );
void asconhashv12_256 ( const void * key, int len, uint32_t seed, void * out );
}
void nmhash32_test ( const void * key, int len, uint32_t seed, void * out );
void nmhash32x_test ( const void * key, int len, uint32_t seed, void * out );
#ifdef HAVE_INT64
extern "C" {
#include "pearson_hash/pearsonb.h"
inline void pearsonb64_test ( const void * key, int len, uint32_t seed, void * out ) {
*(uint64_t*)out = pearsonb_hash_64 ((const uint8_t*)key, (size_t) len, (uint64_t) seed);
}
inline void pearsonb128_test ( const void * key, int len, uint32_t seed, void * out ) {
pearsonb_hash_128 ((uint8_t*)out, (const uint8_t*)key, (size_t) len, (uint64_t) seed);
}
inline void pearsonb256_test ( const void * key, int len, uint32_t seed, void * out ) {
pearsonb_hash_256 ((uint8_t*)out, (const uint8_t*)key, (size_t) len, (uint64_t) seed);
}
#if defined(HAVE_SSE42) && defined(__x86_64__)
#include "pearson_hash/pearson.h"
inline void pearson64_test ( const void * key, int len, uint32_t seed, void * out ) {
*(uint64_t*)out = pearson_hash_64 ((const uint8_t*)key, (size_t) len, seed);
}
inline void pearson128_test ( const void * key, int len, uint32_t seed, void * out ) {
pearson_hash_128 ((uint8_t*)out, (const uint8_t*)key, (size_t) len);
}
inline void pearson256_test ( const void * key, int len, uint32_t seed, void * out ) {
pearson_hash_256 ((uint8_t*)out, (const uint8_t*)key, (size_t) len);
}
#endif
}
#endif