128 and 256 bit use 6 and 10 finalization rounds; all HighwayHash variants now frozen.
diff --git a/Makefile b/Makefile index 0136603..06c8fbb 100644 --- a/Makefile +++ b/Makefile
@@ -1,8 +1,8 @@ # We assume X64 unless HH_POWER or HH_AARCH64 are defined. override CPPFLAGS += -I. -override CXXFLAGS += -std=c++11 -Wall -O3 -fPIC -override LDFLAGS += -lpthread +override CXXFLAGS += -std=c++11 -Wall -O3 -fPIC -pthread +override LDFLAGS += -pthread SIP_OBJS := $(addprefix obj/, \ sip_hash.o \ @@ -100,10 +100,12 @@ [ ! -d bin ] || $(RM) -r -- bin/ [ ! -d lib ] || $(RM) -r -- lib/ +# Mode bits are from issue #58, thanks to yurivict for suggesting. install: lib/libhighwayhash.a lib/libhighwayhash.so mkdir -p $(DESTDIR)/$(LIBDIR) mkdir -p $(DESTDIR)/$(INCDIR)/highwayhash - install -m0755 lib/libhighwayhash.* $(DESTDIR)/$(LIBDIR) - install -m0755 highwayhash/*.h $(DESTDIR)/$(INCDIR)/highwayhash/ + install -m0444 lib/libhighwayhash.a $(DESTDIR)/$(LIBDIR) + install -m0555 lib/libhighwayhash.so $(DESTDIR)/$(LIBDIR) + install -m0444 highwayhash/*.h $(DESTDIR)/$(INCDIR)/highwayhash/ .PHONY: clean distclean all install
diff --git a/README.md b/README.md index 0de1b9e..d4084f0 100644 --- a/README.md +++ b/README.md
@@ -105,7 +105,7 @@ Interestingly, it is about twice as fast as a SIMD implementation using SSE4.1 (https://goo.gl/80GBSD). This is presumably due to the lack of SIMD bit rotate -instructions. +instructions prior to AVX-512. SipHash13 is a faster but weaker variant with one mixing round per update and three during finalization. @@ -137,14 +137,13 @@ ## Versioning and stability -SipHash and HighwayHash64 are 'fingerprint functions' whose input -> hash +Now that 21 months have elapsed since their initial release, we have declared +all (64/128/256 bit) variants of HighwayHash frozen, i.e. unchanging forever. + +SipHash and HighwayHash are 'fingerprint functions' whose input -> hash mapping will not change. This is important for applications that write hashes to persistent storage. -Now that 17 months have elapsed since its initial release, we consider -HighwayHash64 (and the C++ variant that returns HHResult64) frozen. -Note that the 128 and 256 bit versions may still change pending external review. - ## Speed measurements To measure the CPU cost of a hash function, we can either create an artificial @@ -161,9 +160,9 @@ It uses CPU fences and robust statistics to minimize variability, and also avoids unrealistic branch prediction effects. -We compile the C++ implementations with a patched GCC 4.9 and run on a single -core of a Xeon E5-2690 v3 clocked at 2.6 GHz. CPU cost is measured as cycles per -byte for various input sizes: +We compile the 64-bit C++ implementations with a patched GCC 4.9 and run on a +single idle core of a Xeon E5-2690 v3 clocked at 2.6 GHz. CPU cost is measured +as cycles per byte for various input sizes: Algorithm | 8 | 31 | 32 | 63 | 64 | 1024 ---------------- | ----- | ---- | ---- | ---- | ---- | ---- @@ -183,11 +182,11 @@ ## CPU requirements -SipTreeHash[13] requires an AVX2-capable CPU (e.g. Haswell). HighwayHash +SipTreeHash(13) requires an AVX2-capable CPU (e.g. Haswell). HighwayHash includes a dispatcher that chooses the best available (AVX2, SSE4.1, VSX or portable) implementation at runtime, as well as a directly callable function -template that can only run on the CPU for which it was built. SipHash[13] and -ScalarSipTreeHash[13] have no particular CPU requirements. +template that can only run on the CPU for which it was built. SipHash(13) and +ScalarSipTreeHash(13) have no particular CPU requirements. Our x86 implementations use custom vector classes with overloaded operators (e.g. `const V4x64U a = b + c`) for type-safety and improved readability vs. @@ -356,6 +355,6 @@ * vector256.h and vector128.h contain wrapper classes for AVX2 and SSE4.1. By Jan Wassenberg <jan.wassenberg@gmail.com> and Jyrki Alakuijala -<jyrki.alakuijala@gmail.com>, updated 2017-08-15 +<jyrki.alakuijala@gmail.com>, updated 2017-12-29 This is not an official Google product.
diff --git a/c/highwayhash.c b/c/highwayhash.c index 89bf33b..d878d20 100644 --- a/c/highwayhash.c +++ b/c/highwayhash.c
@@ -124,13 +124,6 @@ Update(permuted, state); } -static void FinalPermutes(HighwayHashState* state) { - PermuteAndUpdate(state); - PermuteAndUpdate(state); - PermuteAndUpdate(state); - PermuteAndUpdate(state); -} - static void ModularReduction(uint64_t a3_unmasked, uint64_t a2, uint64_t a1, uint64_t a0, uint64_t* m1, uint64_t* m0) { uint64_t a3 = a3_unmasked & 0x3FFFFFFFFFFFFFFFull; @@ -139,18 +132,31 @@ } static uint64_t HighwayHashFinalize64(HighwayHashState* state) { - FinalPermutes(state); + int i; + for (i = 0; i < 4; i++) { + PermuteAndUpdate(state); + } return state->v0[0] + state->v1[0] + state->mul0[0] + state->mul1[0]; } static void HighwayHashFinalize128(HighwayHashState* state, uint64_t hash[2]) { - FinalPermutes(state); + int i; + for (i = 0; i < 6; i++) { + PermuteAndUpdate(state); + } hash[0] = state->v0[0] + state->mul0[0] + state->v1[2] + state->mul1[2]; hash[1] = state->v0[1] + state->mul0[1] + state->v1[3] + state->mul1[3]; } static void HighwayHashFinalize256(HighwayHashState* state, uint64_t hash[4]) { - FinalPermutes(state); + int i; + /* We anticipate that 256-bit hashing will be mostly used with long messages + because storing and using the 256-bit hash (in contrast to 128-bit) + carries a larger additional constant cost by itself. Doing extra rounds + here hardly increases the per-byte cost of long messages. */ + for (i = 0; i < 10; i++) { + PermuteAndUpdate(state); + } ModularReduction(state->v1[1] + state->mul1[1], state->v1[0] + state->mul1[0], state->v0[1] + state->mul0[1], state->v0[0] + state->mul0[0], &hash[1], &hash[0]);
diff --git a/highwayhash/benchmark.cc b/highwayhash/benchmark.cc index fc6ce32..6b4d1f8 100644 --- a/highwayhash/benchmark.cc +++ b/highwayhash/benchmark.cc
@@ -28,7 +28,6 @@ #include "highwayhash/compiler_specific.h" #include "highwayhash/instruction_sets.h" #include "highwayhash/nanobenchmark.h" -#include "highwayhash/os_specific.h" #include "highwayhash/robust_statistics.h" // Which functions to enable (includes check for compiler support) @@ -207,14 +206,14 @@ #if BENCHMARK_SIP -uint64_t RunSip(const size_t size) { +uint64_t RunSip(const void*, const size_t size) { const HH_U64 key2[2] HH_ALIGNAS(16) = {0, 1}; char in[kMaxBenchmarkInputSize]; memcpy(in, &size, sizeof(size)); return SipHash(key2, in, size); } -uint64_t RunSip13(const size_t size) { +uint64_t RunSip13(const void*, const size_t size) { const HH_U64 key2[2] HH_ALIGNAS(16) = {0, 1}; char in[kMaxBenchmarkInputSize]; memcpy(in, &size, sizeof(size)); @@ -225,14 +224,14 @@ #if BENCHMARK_SIP_TREE -uint64_t RunSipTree(const size_t size) { +uint64_t RunSipTree(const void*, const size_t size) { const HH_U64 key4[4] HH_ALIGNAS(32) = {0, 1, 2, 3}; char in[kMaxBenchmarkInputSize]; memcpy(in, &size, sizeof(size)); return SipTreeHash(key4, in, size); } -uint64_t RunSipTree13(const size_t size) { +uint64_t RunSipTree13(const void*, const size_t size) { const HH_U64 key4[4] HH_ALIGNAS(32) = {0, 1, 2, 3}; char in[kMaxBenchmarkInputSize]; memcpy(in, &size, sizeof(size)); @@ -243,7 +242,7 @@ #if BENCHMARK_FARM -uint64_t RunFarm(const size_t size) { +uint64_t RunFarm(const void*, const size_t size) { char in[kMaxBenchmarkInputSize]; memcpy(in, &size, sizeof(size)); return farmhash::Fingerprint64(reinterpret_cast<const char*>(in), size); @@ -255,13 +254,13 @@ Measurements* measurements) { DurationsForInputs input_map(in_sizes.data(), in_sizes.size(), 40); #if BENCHMARK_SIP - MeasureAndAdd(&input_map, "SipHash", RunSip, measurements); - MeasureAndAdd(&input_map, "SipHash13", RunSip13, measurements); + MeasureAndAdd(&input_map, "SipHash", &RunSip, measurements); + MeasureAndAdd(&input_map, "SipHash13", &RunSip13, measurements); #endif #if BENCHMARK_SIP_TREE && defined(__AVX2__) - MeasureAndAdd(&input_map, "SipTreeHash", RunSipTree, measurements); - MeasureAndAdd(&input_map, "SipTreeHash13", RunSipTree13, measurements); + MeasureAndAdd(&input_map, "SipTreeHash", &RunSipTree, measurements); + MeasureAndAdd(&input_map, "SipTreeHash13", &RunSipTree13, measurements); #endif #if BENCHMARK_FARM @@ -305,7 +304,6 @@ } // namespace highwayhash int main(int argc, char* argv[]) { - highwayhash::PinThreadToRandomCPU(); // No argument or t => table if (argc < 2 || argv[1][0] == 't') { highwayhash::PrintTable();
diff --git a/highwayhash/hh_avx2.h b/highwayhash/hh_avx2.h index 2912a31..db44f53 100644 --- a/highwayhash/hh_avx2.h +++ b/highwayhash/hh_avx2.h
@@ -131,10 +131,9 @@ } HH_INLINE void Finalize(HHResult128* HH_RESTRICT result) { - Update(Permute(v0)); - Update(Permute(v0)); - Update(Permute(v0)); - Update(Permute(v0)); + for (int n = 0; n < 6; n++) { + Update(Permute(v0)); + } const V2x64U sum0(_mm256_castsi256_si128(v0 + mul0)); const V2x64U sum1(_mm256_extracti128_si256(v1 + mul1, 1)); @@ -143,10 +142,9 @@ } HH_INLINE void Finalize(HHResult256* HH_RESTRICT result) { - Update(Permute(v0)); - Update(Permute(v0)); - Update(Permute(v0)); - Update(Permute(v0)); + for (int n = 0; n < 10; n++) { + Update(Permute(v0)); + } const V4x64U sum0 = v0 + mul0; const V4x64U sum1 = v1 + mul1;
diff --git a/highwayhash/hh_portable.h b/highwayhash/hh_portable.h index e02b30e..9da024d 100644 --- a/highwayhash/hh_portable.h +++ b/highwayhash/hh_portable.h
@@ -65,7 +65,8 @@ // 'Length padding' differentiates zero-valued inputs that have the same // size/32. mod32 is sufficient because each Update behaves as if a // counter were injected, because the state is large and mixed thoroughly. - const uint64_t mod32_pair = (static_cast<uint64_t>(size_mod32) << 32) + size_mod32; + const uint64_t mod32_pair = + (static_cast<uint64_t>(size_mod32) << 32) + size_mod32; for (int lane = 0; lane < kNumLanes; ++lane) { v0[lane] += mod32_pair; } @@ -95,29 +96,26 @@ } HH_INLINE void Finalize(HHResult64* HH_RESTRICT result) { - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); + for (int n = 0; n < 4; n++) { + PermuteAndUpdate(); + } *result = v0[0] + v1[0] + mul0[0] + mul1[0]; } HH_INLINE void Finalize(HHResult128* HH_RESTRICT result) { - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); + for (int n = 0; n < 6; n++) { + PermuteAndUpdate(); + } (*result)[0] = v0[0] + mul0[0] + v1[2] + mul1[2]; (*result)[1] = v0[1] + mul0[1] + v1[3] + mul1[3]; } HH_INLINE void Finalize(HHResult256* HH_RESTRICT result) { - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); + for (int n = 0; n < 10; n++) { + PermuteAndUpdate(); + } ModularReduction(v1[1] + mul1[1], v1[0] + mul1[0], v0[1] + mul0[1], v0[0] + mul0[0], &(*result)[1], &(*result)[0]);
diff --git a/highwayhash/hh_sse41.h b/highwayhash/hh_sse41.h index a2a86da..b1f223d 100644 --- a/highwayhash/hh_sse41.h +++ b/highwayhash/hh_sse41.h
@@ -109,10 +109,9 @@ HH_INLINE void Finalize(HHResult64* HH_RESTRICT result) { // Mix together all lanes. - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); + for (int n = 0; n < 4; n++) { + PermuteAndUpdate(); + } const V2x64U sum0 = v0L + mul0L; const V2x64U sum1 = v1L + mul1L; @@ -121,10 +120,9 @@ } HH_INLINE void Finalize(HHResult128* HH_RESTRICT result) { - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); + for (int n = 0; n < 6; n++) { + PermuteAndUpdate(); + } const V2x64U sum0 = v0L + mul0L; const V2x64U sum1 = v1H + mul1H; @@ -133,10 +131,9 @@ } HH_INLINE void Finalize(HHResult256* HH_RESTRICT result) { - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); + for (int n = 0; n < 10; n++) { + PermuteAndUpdate(); + } const V2x64U sum0L = v0L + mul0L; const V2x64U sum1L = v1L + mul1L;
diff --git a/highwayhash/hh_vsx.h b/highwayhash/hh_vsx.h index 398737f..1e32cfe 100644 --- a/highwayhash/hh_vsx.h +++ b/highwayhash/hh_vsx.h
@@ -156,28 +156,25 @@ HH_INLINE void Finalize(HHResult64* HH_RESTRICT result) { // Mix together all lanes. - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); + for (int n = 0; n < 4; n++) { + PermuteAndUpdate(); + } const PPC_VEC_U64 hash = v0L + v1L + mul0L + mul1L; *result = hash[0]; } HH_INLINE void Finalize(HHResult128* HH_RESTRICT result) { - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); + for (int n = 0; n < 6; n++) { + PermuteAndUpdate(); + } const PPC_VEC_U64 hash = v0L + mul0L + v1H + mul1H; StoreUnaligned(hash, *result); } HH_INLINE void Finalize(HHResult256* HH_RESTRICT result) { - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); - PermuteAndUpdate(); + for (int n = 0; n < 10; n++) { + PermuteAndUpdate(); + } const PPC_VEC_U64 sum0L = v0L + mul0L; const PPC_VEC_U64 sum1L = v1L + mul1L; const PPC_VEC_U64 sum0H = v0H + mul0H;
diff --git a/highwayhash/highwayhash_test.cc b/highwayhash/highwayhash_test.cc index b0f8b88..4687b5e 100644 --- a/highwayhash/highwayhash_test.cc +++ b/highwayhash/highwayhash_test.cc
@@ -28,9 +28,11 @@ #endif #include "highwayhash/data_parallel.h" +#include "highwayhash/highwayhash_target.h" #include "highwayhash/instruction_sets.h" // Define to nonzero in order to print the (new) golden outputs. +// WARNING: HighwayHash is frozen, so the golden values must not change. #define PRINT_RESULTS 0 namespace highwayhash { @@ -59,7 +61,7 @@ // Called when any test fails; exits immediately because one mismatch usually // implies many others. void OnFailure(const char* target_name, const size_t size) { - printf("Mismatch at size %zu\n", size); + printf("Mismatch at size %zu for target %s\n", size, target_name); #ifdef HH_GOOGLETEST EXPECT_TRUE(false); #endif @@ -128,6 +130,7 @@ return targets.load(); } +// WARNING: HighwayHash is frozen, so the golden values must not change. const HHResult64 kExpected64[kMaxSize + 1] = { 0x907A56DE22C26E53ull, 0x7EAB43AAC7CDDD78ull, 0xB8D0569AB0B53D62ull, 0x5C6BEFAB8A463D80ull, 0xF205A46893007EDAull, 0x2B8A1668E4A94541ull, @@ -152,204 +155,206 @@ 0x6E0DA4F64188155Aull, 0xB755BA4B50D7D4A1ull, 0x887A3484647479BDull, 0xAB8EEBE9BF2139A0ull, 0x75542C5D4CD2A6FFull}; +// WARNING: HighwayHash is frozen, so the golden values must not change. const HHResult128 kExpected128[kMaxSize + 1] = { - {0x0679D1E884C28A7Cull, 0x2BCA2547F904748Dull}, - {0x7F3A39BCC2D897B9ull, 0x4A7E113CA064D91Full}, - {0x6AB34B92C5AB85BFull, 0xED7AC546689D76C2ull}, - {0xAC6AF8405A4A7DBEull, 0xD78FB7953256C3E1ull}, - {0x5A6E8CF789B86448ull, 0x834EF47C1BEDC218ull}, - {0x8EBFE0B573F425A3ull, 0xBCFCC410CB84325Aull}, - {0xA1E19717CAB8F1D6ull, 0x2AA50671881F877Dull}, - {0x0B595302950DA1ECull, 0x46932DE27204B388ull}, - {0x02FB033F200F89D4ull, 0xFEC3D7BB3B421F92ull}, - {0x0A5479D46CC1EADEull, 0x0C16A2D5A0F1C3DEull}, - {0xF759E41DDD621106ull, 0xB43D70116E004750ull}, - {0x980010BC36A4E98Full, 0x27479317AE00BBD1ull}, - {0x3BABF3B23761A379ull, 0xACCDC28E0256F326ull}, - {0x5780CD04269E142Eull, 0xBB70EE3F23BDEDA9ull}, - {0x4A401F1937E99EC3ull, 0x4B3D1385D6B4E214ull}, - {0x045C6EDE080E2CB0ull, 0x7327B45D2132DC89ull}, - {0x97E1624BEB1C1756ull, 0xB7137E1B69D45024ull}, - {0x31DBA8E3DB0BF012ull, 0x3E66E6A78A729B16ull}, - {0x34D6DF1B5D8AF2A7ull, 0x4F1A47FCBC39EB55ull}, - {0xE2C6BE2D47E5DCBCull, 0xD2FF85284E307C1Full}, - {0xDA681E06098EC892ull, 0x71AD98355019FED1ull}, - {0xC4FBD72B1F2FC30Bull, 0x327549B6C9FDEDD5ull}, - {0x14F429D1C20F0EB5ull, 0x228B40C92F3FA369ull}, - {0xF5C9535333206D01ull, 0xB6FC46FCCA65F9CCull}, - {0x3049FAD9DB729D2Dull, 0xB84C931C45F781EAull}, - {0x7C6FFE6F3706DC04ull, 0x4F94583806AE3C62ull}, - {0x9EF95EB28BE1CCE0ull, 0xAD9D5B96A0D15BFEull}, - {0x63D0ED54AF2985E6ull, 0xDFAFB1B6485C1B01ull}, - {0xA46C8A2FE498D46Cull, 0xF4DBAEC0FF03BAD6ull}, - {0xED978A0FBB3E5158ull, 0x060D144D57FBE6FDull}, - {0x53F1D80C8922E4E5ull, 0x1324880D932140C9ull}, - {0xDD363B03563870CEull, 0x0DFDB79F4F34184Bull}, - {0x4E702701AE65DB38ull, 0x1B67E0A2E2DBFB04ull}, - {0x240DA388551D0822ull, 0x2FF1BB584AC4BD61ull}, - {0x3FAFB8B7C26499ABull, 0x072516308E889132ull}, - {0x0AB452339406AB22ull, 0x751DBB7FF9472D42ull}, - {0x83BA782DB6EB1186ull, 0x4391544D9318DC29ull}, - {0x25077ECDAAB201E8ull, 0x695E0E95446D63A2ull}, - {0x1AF0BF12F91F17D4ull, 0x5BB8FF299368D22Cull}, - {0x338C09CBAF701E38ull, 0xA7D24D5E7C06DC78ull}, - {0x5AB58D6555D28B56ull, 0xE781413A9AE1310Full}, - {0xB0281CD10BCA7B89ull, 0xF49873B45C0F7274ull}, - {0x67EEBD6D71E57B06ull, 0x9421CB1DB54EEDDFull}, - {0x00DAB867E37EDA65ull, 0x6477E454191E213Full}, - {0x9AF9C4817C24C82Eull, 0xAE3A73522F311EEBull}, - {0xD8A334E30D23C6E6ull, 0xAF57EF86CCCF12FFull}, - {0x0353A48FC9E139DDull, 0x27D5626170A7DD0Full}, - {0x0DA12E888EB61876ull, 0x67B17DF10CB365CDull}, - {0x967CD764883A5E85ull, 0x570D7C9A774A6AB4ull}, - {0xA8DF13980C81E533ull, 0x9C33FE4797F87F1Aull}, - {0xCABB59F53AE75FF2ull, 0x6D25512E77172E7Aull}, - {0xB24E7F0C7DA62BE7ull, 0x2442F94890F57D89ull}, - {0x7DCBA0A5B9689BBDull, 0x700FC8D13DA4CC60ull}, - {0x1E8E014B97A9F828ull, 0xF858EFCA33E8A502ull}, - {0x4DAF4E31F34D10C7ull, 0x47E382D0A5A8C613ull}, - {0x577CAB4EF626BB28ull, 0xF6ED27E594C5795Full}, - {0x989188C958586C96ull, 0x8B3A2CB0D5B48FD9ull}, - {0x13CC58F5A076C088ull, 0x932A0FD21D4B422Cull}, - {0xD067380DAD885647ull, 0xC1020E396B31BB4Aull}, - {0x47D05A73072758D0ull, 0x5CF6075A0AEB5D78ull}, - {0x54441D7AE94E2D4Eull, 0x3B4F67953ABD3EA4ull}, - {0xEDD4250C3733EEBCull, 0x26E365AA1167C723ull}, - {0x92D02D2A641DA598ull, 0x3DAF5EB24A0C2A94ull}, - {0xAE6CF7FE2D76CA56ull, 0xC7918532A42D2F5Dull}, - {0xAD24762A08D96F1Bull, 0x729083EC59FA8DF7ull}}; + {0x0FED268F9D8FFEC7ull, 0x33565E767F093E6Full}, + {0xD6B0A8893681E7A8ull, 0xDC291DF9EB9CDCB4ull}, + {0x3D15AD265A16DA04ull, 0x78085638DC32E868ull}, + {0x0607621B295F0BEBull, 0xBFE69A0FD9CEDD79ull}, + {0x26399EB46DACE49Eull, 0x2E922AD039319208ull}, + {0x3250BDC386D12ED8ull, 0x193810906C63C23Aull}, + {0x6F476AB3CB896547ull, 0x7CDE576F37ED1019ull}, + {0x2A401FCA697171B4ull, 0xBE1F03FF9F02796Cull}, + {0xA1E96D84280552E8ull, 0x695CF1C63BEC0AC2ull}, + {0x142A2102F31E63B2ull, 0x1A85B98C5B5000CCull}, + {0x51A1B70E26B6BC5Bull, 0x929E1F3B2DA45559ull}, + {0x88990362059A415Bull, 0xBED21F22C47B7D13ull}, + {0xCD1F1F5F1CAF9566ull, 0xA818BA8CE0F9C8D4ull}, + {0xA225564112FE6157ull, 0xB2E94C78B8DDB848ull}, + {0xBD492FEBD1CC0919ull, 0xCECD1DBC025641A2ull}, + {0x142237A52BC4AF54ull, 0xE0796C0B6E26BCD7ull}, + {0x414460FFD5A401ADull, 0x029EA3D5019F18C8ull}, + {0xC52A4B96C51C9962ull, 0xECB878B1169B5EA0ull}, + {0xD940CA8F11FBEACEull, 0xF93A46D616F8D531ull}, + {0x8AC49D0AE5C0CBF5ull, 0x3FFDBF8DF51D7C93ull}, + {0xAC6D279B852D00A8ull, 0x7DCD3A6BA5EBAA46ull}, + {0xF11621BD93F08A56ull, 0x3173C398163DD9D5ull}, + {0x0C4CE250F68CF89Full, 0xB3123CDA411898EDull}, + {0x15AB97ED3D9A51CEull, 0x7CE274479169080Eull}, + {0xCD001E198D4845B8ull, 0xD0D9D98BD8AA2D77ull}, + {0x34F3D617A0493D79ull, 0x7DD304F6397F7E16ull}, + {0x5CB56890A9F4C6B6ull, 0x130829166567304Full}, + {0x30DA6F8B245BD1C0ull, 0x6F828B7E3FD9748Cull}, + {0xE0580349204C12C0ull, 0x93F6DA0CAC5F441Cull}, + {0xF648731BA5073045ull, 0x5FB897114FB65976ull}, + {0x024F8354738A5206ull, 0x509A4918EB7E0991ull}, + {0x06E7B465E8A57C29ull, 0x52415E3A07F5D446ull}, + {0x1984DF66C1434AAAull, 0x16FC1958F9B3E4B9ull}, + {0x111678AFE0C6C36Cull, 0xF958B59DE5A2849Dull}, + {0x773FBC8440FB0490ull, 0xC96ED5D243658536ull}, + {0x91E3DC710BB6C941ull, 0xEA336A0BC1EEACE9ull}, + {0x25CFE3815D7AD9D4ull, 0xF2E94F8C828FC59Eull}, + {0xB9FB38B83CC288F2ull, 0x7479C4C8F850EC04ull}, + {0x1D85D5C525982B8Cull, 0x6E26B1C16F48DBF4ull}, + {0x8A4E55BD6060BDE7ull, 0x2134D599058B3FD0ull}, + {0x2A958FF994778F36ull, 0xE8052D1AE61D6423ull}, + {0x89233AE6BE453233ull, 0x3ACF9C87D7E8C0B9ull}, + {0x4458F5E27EA9C8D5ull, 0x418FB49BCA2A5140ull}, + {0x090301837ED12A68ull, 0x1017F69633C861E6ull}, + {0x330DD84704D49590ull, 0x339DF1AD3A4BA6E4ull}, + {0x569363A663F2C576ull, 0x363B3D95E3C95EF6ull}, + {0xACC8D08586B90737ull, 0x2BA0E8087D4E28E9ull}, + {0x39C27A27C86D9520ull, 0x8DB620A45160932Eull}, + {0x8E6A4AEB671A072Dull, 0x6ED3561A10E47EE6ull}, + {0x0011D765B1BEC74Aull, 0xD80E6E656EDE842Eull}, + {0x2515D62B936AC64Cull, 0xCE088794D7088A7Dull}, + {0x91621552C16E23AFull, 0x264F0094EB23CCEFull}, + {0x1E21880D97263480ull, 0xD8654807D3A31086ull}, + {0x39D76AAF097F432Dull, 0xA517E1E09D074739ull}, + {0x0F17A4F337C65A14ull, 0x2F51215F69F976D4ull}, + {0xA0FB5CDA12895E44ull, 0x568C3DC4D1F13CD1ull}, + {0x93C8FC00D89C46CEull, 0xBAD5DA947E330E69ull}, + {0x817C07501D1A5694ull, 0x584D6EE72CBFAC2Bull}, + {0x91D668AF73F053BFull, 0xF98E647683C1E0EDull}, + {0x5281E1EF6B3CCF8Bull, 0xBC4CC3DF166083D8ull}, + {0xAAD61B6DBEAAEEB9ull, 0xFF969D000C16787Bull}, + {0x4325D84FC0475879ull, 0x14B919BD905F1C2Dull}, + {0x79A176D1AA6BA6D1ull, 0xF1F720C5A53A2B86ull}, + {0x74BD7018022F3EF0ull, 0x3AEA94A8AD5F4BCBull}, + {0x98BB1F7198D4C4F2ull, 0xE0BC0571DE918FC8ull}}; +// WARNING: HighwayHash is frozen, so the golden values must not change. const HHResult256 kExpected256[kMaxSize + 1] = { - {0xC6DC0C823434863Full, 0x6A42CCB644CBFAD9ull, 0x18DEF6A60EA5D873ull, - 0x3596F663D00D1225ull}, - {0x00518B3D2BD22424ull, 0xE5791619BF612E97ull, 0xF4DAF07017FAF99Dull, - 0xE36AE62C5509B5D6ull}, - {0x81021CC5067D8526ull, 0xBEEFC1BC87A6911Aull, 0xE2AEC605F80657FEull, - 0x3C6576B5DF982327ull}, - {0x118D72C0B5DB2C70ull, 0x0BE2E64BF538CA74ull, 0x667B33FE41DDAA74ull, - 0xB6199539303E13E1ull}, - {0x4AC9B8B2E4FD873Bull, 0xDE0FE265A45FFC97ull, 0x1FC1476F896ADA3Bull, - 0x7680B4AE30B371E7ull}, - {0x518ABC6B5E88214Full, 0xFD62A05B2B06026Bull, 0x9C978E8B38DBE795ull, - 0x41412401886FF054ull}, - {0x2DEDEF0832BEA7D9ull, 0x44EFE0AEAB7944FCull, 0x09AA7C9374A1E980ull, - 0x714DB8B507C507FBull}, - {0x6FA2135DE3D3D3AAull, 0xC0EEA9A890E36156ull, 0xFAC1DB8C817DB095ull, - 0x7B42789096836327ull}, - {0x27257C518B1FFC5Cull, 0x26CC8E669DA1AB0Full, 0xCD7B17C661A0A680ull, - 0x31D0A7EC0AA3B9BFull}, - {0xB91869900A1AF26Cull, 0x95B0D74B7FF20B43ull, 0x2A6CABF6F931B575ull, - 0x69734DC9E66A1965ull}, - {0xDD7DA31F5C4DD30Full, 0x08940D249A0A7B69ull, 0xAE7D3AD1C5EA81F2ull, - 0x96701DB5C6602B21ull}, - {0x2E4A230847E64687ull, 0xF96176C38E48B038ull, 0x9ED0B88A3026E1BCull, - 0x9AAB5DCA46FCFE19ull}, - {0x3E5CF04BFBAC2642ull, 0x591A3581001709DFull, 0xA0288F5FA63C10A2ull, - 0x85B94D3641A2C108ull}, - {0x454A95FAD8901350ull, 0x5546E8E75D2AC833ull, 0xCF5FF2ACB4B5F2C1ull, - 0x14F314318028D62Eull}, - {0x0DED251FB81F34A9ull, 0xC42111DB31618AA6ull, 0xC1C3352B70B00C5Dull, - 0xDC8947DBC398F0C2ull}, - {0xC591A100AB4E9E72ull, 0x4CCFD2A7B0D8D911ull, 0x6FEDFDDE1BA3F770ull, - 0x03E5C5A2F6E708A1ull}, - {0x537C42CC5E7B448Aull, 0xA7343E04249B2231ull, 0x2CB51D697EFE9B6Dull, - 0x589D83141A699A97ull}, - {0x3F7E6EA60343B870ull, 0x4E27E907E296D4D7ull, 0x87525BF1AABBF794ull, - 0x6B03C4DC206EC628ull}, - {0x741BA4D7A856E03Cull, 0x3798422CB64C9AFAull, 0xB1D89C9720D33FDDull, - 0x08DE607FC4E3B5C3ull}, - {0x77D77342C85BA466ull, 0xA01C603C58F6D97Eull, 0x342AF0A7309EA4EAull, - 0x9C958EB3F6A64B94ull}, - {0x9EDCADDD1FFC763Full, 0xBD9BAA6E9BE936EFull, 0xAAB0F78F1A4A94F7ull, - 0xE71D9CA601DA4C02ull}, - {0xE3AA0D0A422BF888ull, 0x07734C8173411035ull, 0x8A085019DE545AF6ull, - 0xBC3C520B1221A779ull}, - {0x16170C02C5E5439Dull, 0x45C6004513BFC174ull, 0x35CF3AD65D225EC8ull, - 0xE10BAA702D37C90Eull}, - {0x6BD63B47EA43ABC6ull, 0xCC08BE8A651E24C0ull, 0xB564F0FC6FF8998Aull, - 0x3EE409A34232E589ull}, - {0xD6CEE5574355BB81ull, 0x8E31FF40B271A16Dull, 0xC3ECEDBEEACCCAE9ull, - 0x19386CD3A23B92E9ull}, - {0x32475E05D248DBB1ull, 0xF2396A122830E72Cull, 0xB88395678C0DB899ull, - 0x8BD410A22A247066ull}, - {0x0BFA3B3C4775EB43ull, 0x496596C36FB2A200ull, 0xA00F533EF150D7DDull, - 0xB5D70BBCABB572C4ull}, - {0x932B0ED33ED691B1ull, 0xB58394EDCEA3C53Dull, 0xB935E0786B132755ull, - 0x3E0998322B3F74BAull}, - {0xE21F2CE1BDD156A7ull, 0x764518A56E1363B5ull, 0x461251D3EC39B93Full, - 0x33C1FE46C9664CC4ull}, - {0x8ABD3F6184C9CD7Dull, 0x8195816637017FC0ull, 0x284B3E93524765DEull, - 0x56147BDBA9362D0Eull}, - {0x1F050672342807B6ull, 0x9B0AD1091A83910Dull, 0xF23AD4A58C3B1E21ull, - 0xCC986EC0BEA16781ull}, - {0x053164DEF96B10CEull, 0x1D5ADA15E36D8F6Cull, 0x06FB43534C0472EFull, - 0x021C0ED1FDEA0948ull}, - {0xF62BA4C5A665E602ull, 0x490D89FD89430C56ull, 0x18F423BE8A9B7E3Cull, - 0x769E5DDA4DCAC619ull}, - {0xDABD25FAF07A6684ull, 0xACA85CD21536B927ull, 0xAC05E050B4E3D3D1ull, - 0xBE427B2475CCD981ull}, - {0x89A2B35A34F89F8Cull, 0x1A0E51B2875D34E6ull, 0xBA573CF45E123919ull, - 0x1C50815B08F1138Aull}, - {0x3390CCBE60F2AFF7ull, 0xD9E2D245643E79C2ull, 0x1104A78F85D3CDF5ull, - 0x7E55F38F9C53A58Full}, - {0xC189AE1A9D456C0Eull, 0x06AA4C3D4204A40Full, 0x4B383405A9D451A9ull, - 0x7EA34CBCAEF0C31Eull}, - {0xB45FA7CC19AE4DDFull, 0x306C418E9BA67420ull, 0xDF16D80D4D48C096ull, - 0xD3169E50BC8D75CCull}, - {0x5894367013710C89ull, 0xD39EE6D584E76AF3ull, 0x5C55A414BCDDE505ull, - 0x8FA97D561CB174BFull}, - {0x87355749D59F39DDull, 0x26B8B311E72C50F4ull, 0x1911A8CBCE53E37Bull, - 0x5C256452C39B95F6ull}, - {0x8B9E87C9ABC82821ull, 0x12A5FC06B69CDC2Dull, 0xF95104FF805E5E1Dull, - 0xE5D4D2257AD5592Eull}, - {0x5A89242B02E1E048ull, 0x771602AAD1880A7Eull, 0x0F34507608387843ull, - 0x7AFB45F3EA4F0F24ull}, - {0x3BE3800150FDDE00ull, 0x7871908FF91AD81Aull, 0xA00E07F351BB15C1ull, - 0x429658E7FD10D11Aull}, - {0x2B2B1A6CD1BA454Cull, 0xF19E8CA5C022308Aull, 0xAEFA0EB6F7C3CF74ull, - 0x21F4330A5258E7C7ull}, - {0xD1C806622910A9BEull, 0xFE224EF598F541B1ull, 0xB95A435AEC4DD849ull, - 0xD942A277AB57E68Eull}, - {0x16BF7116E8D2B328ull, 0xB37DC98EA931FC13ull, 0x18E8859A592C8C11ull, - 0x11590F16C4C61716ull}, - {0xD046122D4C7B24AEull, 0xBD0899DFD7345611ull, 0x91AAECB50DE6DFF9ull, - 0x6EDC4896BAA90FFAull}, - {0x2FE97B8135EA956Dull, 0xFBA50900FB4EF23Cull, 0x0BC907363F7EA368ull, - 0xA5C982D3094BCEE2ull}, - {0x247BFB5BA3A0F245ull, 0x6ACBDD4AFFDB03EBull, 0xA4237427D373B619ull, - 0xFA9C041D302B728Cull}, - {0xF93109909D6B80EFull, 0xD1321A6BEE302794ull, 0xD63E1E7985C458D3ull, - 0x644CD44F6C6FDE95ull}, - {0xD0522C663FBE65B0ull, 0x78F366F302EA33F5ull, 0xB9ED66D1CB87C891ull, - 0x0CEB2298BA9D1C1Aull}, - {0x60D60E9B569264E8ull, 0xE34447A5741417EAull, 0x04522108BDF3AFC3ull, - 0x90F4FE2D585B25FAull}, - {0xAF411662AAB81B12ull, 0x3AD58EBBA1BA2F39ull, 0x73E0E8EB5879E37Dull, - 0xCE0E8F8F613D3FC5ull}, - {0xCA756CB9E1FDF1C6ull, 0x89731D81712D34BDull, 0xBF520B2D830959C2ull, - 0xD35ED12BB24CE9EFull}, - {0x5FB2B65ABF038045ull, 0x3F2D32F8532E14D6ull, 0x06443CC95CDD58C8ull, - 0x30FC6FBE8CCE8EB8ull}, - {0x94A9774F02848D73ull, 0x83F9AFC4C0B48768ull, 0xDB7BF5FBD9B25A26ull, - 0x7F7D50266FFA639Bull}, - {0x352A775C646259DDull, 0xB2B532B472539832ull, 0x9981AE050A2FB38Cull, - 0xE13641E804F6DC00ull}, - {0x080E005A04E73352ull, 0x0314F6EA196A210Cull, 0x29EA80869CE307A4ull, - 0x4FABEB9ADE04BE00ull}, - {0x5674A4A533335ADFull, 0x3C7C0650FF6C585Bull, 0x384E4F8246446812ull, - 0xAE2DADA5E0EB6D81ull}, - {0xB6CE794A89B0A1F7ull, 0x0DC2B87EC9473CDDull, 0x349A006CA2899C88ull, - 0x4B411CB7DF6BF33Cull}, - {0xD79BB5606CE6BDAFull, 0x4040EA447818A5C1ull, 0x53D58C5710475284ull, - 0x3DA8730E092608BAull}, - {0x5900A2DAA12E085Cull, 0x80D490C510C493DDull, 0x4BDF17B0247C8D1Bull, - 0xA8649490D6CFCE67ull}, - {0xFBDAB07B10180D47ull, 0xED6C196BDC43E292ull, 0xE7D494077FA2791Dull, - 0xC7108D4FD01BBF85ull}, - {0x4365D6236E6AE467ull, 0xB3D540909D4308A5ull, 0xE38207ABD4588D68ull, - 0xBBD42849A8C92313ull}, - {0x064DB5FE415126F5ull, 0x248AF8FB29A9C595ull, 0x508633A742B3FFF7ull, - 0x24CFDCA800C34770ull}}; + {0xDD44482AC2C874F5ull, 0xD946017313C7351Full, 0xB3AEBECCB98714FFull, + 0x41DA233145751DF4ull}, + {0xEDB941BCE45F8254ull, 0xE20D44EF3DCAC60Full, 0x72651B9BCB324A47ull, + 0x2073624CB275E484ull}, + {0x3FDFF9DF24AFE454ull, 0x11C4BF1A1B0AE873ull, 0x115169CC6922597Aull, + 0x1208F6590D33B42Cull}, + {0x480AA0D70DD1D95Cull, 0x89225E7C6911D1D0ull, 0x8EA8426B8BBB865Aull, + 0xE23DFBC390E1C722ull}, + {0xC9CFC497212BE4DCull, 0xA85F9DF6AFD2929Bull, 0x1FDA9F211DF4109Eull, + 0x07E4277A374D4F9Bull}, + {0xB4B4F566A4DC85B3ull, 0xBF4B63BA5E460142ull, 0x15F48E68CDDC1DE3ull, + 0x0F74587D388085C6ull}, + {0x6445C70A86ADB9B4ull, 0xA99CFB2784B4CEB6ull, 0xDAE29D40A0B2DB13ull, + 0xB6526DF29A9D1170ull}, + {0xD666B1A00987AD81ull, 0xA4F1F838EB8C6D37ull, 0xE9226E07D463E030ull, + 0x5754D67D062C526Cull}, + {0xF1B905B0ED768BC0ull, 0xE6976FF3FCFF3A45ull, 0x4FBE518DD9D09778ull, + 0xD9A0AFEB371E0D33ull}, + {0x80D8E4D70D3C2981ull, 0xF10FBBD16424F1A1ull, 0xCF5C2DBE9D3F0CD1ull, + 0xC0BFE8F701B673F2ull}, + {0xADE48C50E5A262BEull, 0x8E9492B1FDFE38E0ull, 0x0784B74B2FE9B838ull, + 0x0E41D574DB656DCDull}, + {0xA1BE77B9531807CFull, 0xBA97A7DE6A1A9738ull, 0xAF274CEF9C8E261Full, + 0x3E39B935C74CE8E8ull}, + {0x15AD3802E3405857ull, 0x9D11CBDC39E853A0ull, 0x23EA3E993C31B225ull, + 0x6CD9E9E3CAF4212Eull}, + {0x01C96F5EB1D77C36ull, 0xA367F9C1531F95A6ull, 0x1F94A3427CDADCB8ull, + 0x97F1000ABF3BD5D3ull}, + {0x0815E91EEEFF8E41ull, 0x0E0C28FA6E21DF5Dull, 0x4EAD8E62ED095374ull, + 0x3FFD01DA1C9D73E6ull}, + {0xC11905707842602Eull, 0x62C3DB018501B146ull, 0x85F5AD17FA3406C1ull, + 0xC884F87BD4FEC347ull}, + {0xF51AD989A1B6CD1Full, 0xF7F075D62A627BD9ull, 0x7E01D5F579F28A06ull, + 0x1AD415C16A174D9Full}, + {0x19F4CFA82CA4068Eull, 0x3B9D4ABD3A9275B9ull, 0x8000B0DDE9C010C6ull, + 0x8884D50949215613ull}, + {0x126D6C7F81AB9F5Dull, 0x4EDAA3C5097716EEull, 0xAF121573A7DD3E49ull, + 0x9001AC85AA80C32Dull}, + {0x06AABEF9149155FAull, 0xDF864F4144E71C3Dull, 0xFDBABCE860BC64DAull, + 0xDE2BA54792491CB6ull}, + {0xADFC6B4035079FDBull, 0xA087B7328E486E65ull, 0x46D1A9935A4623EAull, + 0xE3895C440D3CEE44ull}, + {0xB5F9D31DEEA3B3DFull, 0x8F3024E20A06E133ull, 0xF24C38C8288FE120ull, + 0x703F1DCF9BD69749ull}, + {0x2B3C0B854794EFE3ull, 0x1C5D3F969BDACEA0ull, 0x81F16AAFA563AC2Eull, + 0x23441C5A79D03075ull}, + {0x418AF8C793FD3762ull, 0xBC6B8E9461D7F924ull, 0x776FF26A2A1A9E78ull, + 0x3AA0B7BFD417CA6Eull}, + {0xCD03EA2AD255A3C1ull, 0x0185FEE5B59C1B2Aull, 0xD1F438D44F9773E4ull, + 0xBE69DD67F83B76E4ull}, + {0xF951A8873887A0FBull, 0x2C7B31D2A548E0AEull, 0x44803838B6186EFAull, + 0xA3C78EC7BE219F72ull}, + {0x958FF151EA0D8C08ull, 0x4B7E8997B4F63488ull, 0xC78E074351C5386Dull, + 0xD95577556F20EEFAull}, + {0x29A917807FB05406ull, 0x3318F884351F578Cull, 0xDD24EA6EF6F6A7FAull, + 0xE74393465E97AEFFull}, + {0x98240880935E6CCBull, 0x1FD0D271B09F97DAull, 0x56E786472700B183ull, + 0x291649F99F747817ull}, + {0x1BD4954F7054C556ull, 0xFFDB2EFF7C596CEBull, 0x7C6AC69A1BAB6B5Bull, + 0x0F037670537FC153ull}, + {0x8825E38897597498ull, 0x647CF6EBAF6332C1ull, 0x552BD903DC28C917ull, + 0x72D7632C00BFC5ABull}, + {0x6880E276601A644Dull, 0xB3728B20B10FB7DAull, 0xD0BD12060610D16Eull, + 0x8AEF14EF33452EF2ull}, + {0xBCE38C9039A1C3FEull, 0x42D56326A3C11289ull, 0xE35595F764FCAEA9ull, + 0xC9B03C6BC9475A99ull}, + {0xF60115CBF034A6E5ull, 0x6C36EA75BFCE46D0ull, 0x3B17C8D382725990ull, + 0x7EDAA2ED11007A35ull}, + {0x1326E959EDF9DEA2ull, 0xC4776801739F720Cull, 0x5169500FD762F62Full, + 0x8A0DD0D90A2529ABull}, + {0x935149D503D442D4ull, 0xFF6BB41302DAD144ull, 0x339CB012CD9D36ECull, + 0xE61D53619ECC2230ull}, + {0x528BC888AA50B696ull, 0xB8AEECA36084E1FCull, 0xA158151EC0243476ull, + 0x02C14AAD097CEC44ull}, + {0xBED688A72217C327ull, 0x1EE65114F760873Full, 0x3F5C26B37D3002A6ull, + 0xDDF2E895631597B9ull}, + {0xE7DB21CF2B0B51ADull, 0xFAFC6324F4B0AB6Cull, 0xB0857244C22D9C5Bull, + 0xF0AD888D1E05849Cull}, + {0x05519793CD4DCB00ull, 0x3C594A3163067DEBull, 0xAC75081ACF119E34ull, + 0x5AC86297805CB094ull}, + {0x09228D8C22B5779Eull, 0x19644DB2516B7E84ull, 0x2B92C8ABF83141A0ull, + 0x7F785AD725E19391ull}, + {0x59C42E5D46D0A74Bull, 0x5EA53C65CA036064ull, 0x48A9916BB635AEB4ull, + 0xBAE6DF143F54E9D4ull}, + {0x5EB623696D03D0E3ull, 0xD53D78BCB41DA092ull, 0xFE2348DC52F6B10Dull, + 0x64802457632C8C11ull}, + {0x43B61BB2C4B85481ull, 0xC6318C25717E80A1ull, 0x8C4A7F4D6F9C687Dull, + 0xBD0217E035401D7Cull}, + {0x7F51CA5743824C37ull, 0xB04C4D5EB11D703Aull, 0x4D511E1ECBF6F369ull, + 0xD66775EA215456E2ull}, + {0x39B409EEF87E45CCull, 0x52B8E8C459FC79B3ull, 0x44920918D1858C24ull, + 0x80F07B645EEE0149ull}, + {0xCE8694D1BE9AD514ull, 0xBFA19026526836E7ull, 0x1EA4FDF6E4902A7Dull, + 0x380C4458D696E1FEull}, + {0xD189E18BF823A0A4ull, 0x1F3B353BE501A7D7ull, 0xA24F77B4E02E2884ull, + 0x7E94646F74F9180Cull}, + {0xAFF8C635D325EC48ull, 0x2C2E0AA414038D0Bull, 0x4ED37F611A447467ull, + 0x39EC38E33B501489ull}, + {0x2A2BFDAD5F83F197ull, 0x013D3E6EBEF274CCull, 0xE1563C0477726155ull, + 0xF15A8A5DE932037Eull}, + {0xD5D1F91EC8126332ull, 0x10110B9BF9B1FF11ull, 0xA175AB26541C6032ull, + 0x87BADC5728701552ull}, + {0xC7B5A92CD8082884ull, 0xDDA62AB61B2EEEFBull, 0x8F9882ECFEAE732Full, + 0x6B38BD5CC01F4FFBull}, + {0xCF6EF275733D32F0ull, 0xA3F0822DA2BF7D8Bull, 0x304E7435F512406Aull, + 0x0B28E3EFEBB3172Dull}, + {0xE698F80701B2E9DBull, 0x66AE2A819A8A8828ull, 0x14EA9024C9B8F2C9ull, + 0xA7416170523EB5A4ull}, + {0x3A917E87E307EDB7ull, 0x17B4DEDAE34452C1ull, 0xF689F162E711CC70ull, + 0x29CE6BFE789CDD0Eull}, + {0x0EFF3AD8CB155D8Eull, 0x47CD9EAD4C0844A2ull, 0x46C8E40EE6FE21EBull, + 0xDEF3C25DF0340A51ull}, + {0x03FD86E62B82D04Dull, 0x32AB0D600717136Dull, 0x682B0E832B857A89ull, + 0x138CE3F1443739B1ull}, + {0x2F77C754C4D7F902ull, 0x1053E0A9D9ADBFEAull, 0x58E66368544AE70Aull, + 0xC48A829C72DD83CAull}, + {0xF900EB19E466A09Full, 0x31BE9E01A8C7D314ull, 0x3AFEC6B8CA08F471ull, + 0xB8C0EB0F87FFE7FBull}, + {0xDB277D8FBE3C8EFBull, 0x53CE6877E11AA57Bull, 0x719C94D20D9A7E7Dull, + 0xB345B56392453CC9ull}, + {0x37639C3BDBA4F2C9ull, 0x6095E7B336466DC8ull, 0x3A8049791E65B88Aull, + 0x82C988CDE5927CD5ull}, + {0x6B1FB1A714234AE4ull, 0x20562E255BA6467Eull, 0x3E2B892D40F3D675ull, + 0xF40CE3FBE41ED768ull}, + {0x8EE11CB1B287C92Aull, 0x8FC2AAEFF63D266Dull, 0x66643487E6EB9F03ull, + 0x578AA91DE8D56873ull}, + {0xF5B1F8266A3AEB67ull, 0x83B040BE4DEC1ADDull, 0x7FE1C8635B26FBAEull, + 0xF4A3A447DEFED79Full}, + {0x90D8E6FF6AC12475ull, 0x1A422A196EDAC1F2ull, 0x9E3765FE1F8EB002ull, + 0xC1BDD7C4C351CFBEull}}; void RunTests() { // TODO(janwas): detect number of cores.
diff --git a/highwayhash/highwayhash_test_target.h b/highwayhash/highwayhash_test_target.h index 02904ae..56ae960 100644 --- a/highwayhash/highwayhash_test_target.h +++ b/highwayhash/highwayhash_test_target.h
@@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -#ifndef HIGHWAYHASH_HIGHWAYHASH_TARGET_H_ -#define HIGHWAYHASH_HIGHWAYHASH_TARGET_H_ +#ifndef HIGHWAYHASH_HIGHWAYHASH_TEST_TARGET_H_ +#define HIGHWAYHASH_HIGHWAYHASH_TEST_TARGET_H_ // Tests called by InstructionSets::RunAll, so we can verify all // implementations supported by the current CPU. @@ -87,4 +87,4 @@ } // namespace highwayhash -#endif // HIGHWAYHASH_HIGHWAYHASH_TARGET_H_ +#endif // HIGHWAYHASH_HIGHWAYHASH_TEST_TARGET_H_
diff --git a/highwayhash/vector_test.cc b/highwayhash/vector_test.cc index d9f0256..e9ff81f 100644 --- a/highwayhash/vector_test.cc +++ b/highwayhash/vector_test.cc
@@ -27,13 +27,14 @@ void NotifyFailure(const char* target, const size_t size) { const size_t lane_bits = (size & 0xFF) * 8; - const size_t lane_index = size >> 8; + const size_t lane_index = (size >> 8) & 0xFF; + const size_t line = (size >> 16); #ifdef HH_GOOGLETEST EXPECT_TRUE(false) << "VectorTest failed for " << target << " T=" << lane_bits - << ", lane " << lane_index; + << ", lane " << lane_index << ", line " << line; #else - printf("VectorTest failed for %10s T=%zu, lane=%zu\n", target, lane_bits, - lane_index); + printf("VectorTest failed for %10s T=%zu, lane=%zu, line=%zu\n", target, + lane_bits, lane_index, line); #endif }
diff --git a/highwayhash/vector_test_target.cc b/highwayhash/vector_test_target.cc index f9eed7f..2ed3c0f 100644 --- a/highwayhash/vector_test_target.cc +++ b/highwayhash/vector_test_target.cc
@@ -48,20 +48,22 @@ #endif template <class T> -void NotifyIfUnequal(const V<T>& v, const T expected, const HHNotify notify) { +void NotifyIfUnequal(const V<T>& v, const T expected, const size_t line, + const HHNotify notify) { T lanes[V<T>::N] HH_ALIGNAS(32); Store(v, lanes); for (size_t i = 0; i < V<T>::N; ++i) { if (lanes[i] != expected) { - notify(TargetName(HH_TARGET), (i << 8) | sizeof(T)); + notify(TargetName(HH_TARGET), (line << 16) | (i << 8) | sizeof(T)); } } } template <class T> -void NotifyIfUnequal(const T& t, const T expected, const HHNotify notify) { +void NotifyIfUnequal(const T& t, const T expected, const size_t line, + const HHNotify notify) { if (t != expected) { - notify(TargetName(HH_TARGET), sizeof(T)); + notify(TargetName(HH_TARGET), (line << 16) | sizeof(T)); } } @@ -92,42 +94,42 @@ // broadcast const V<T> v2(2); - NotifyIfUnequal(v2, T(2), notify); + NotifyIfUnequal(v2, T(2), __LINE__, notify); // assign from V const V<T> v3(3); V<T> v3b; v3b = v3; - NotifyIfUnequal(v3b, T(3), notify); + NotifyIfUnequal(v3b, T(3), __LINE__, notify); // equal const V<T> veq(v3 == v3b); - NotifyIfUnequal(veq, MaxValue<T>()(), notify); + NotifyIfUnequal(veq, MaxValue<T>()(), __LINE__, notify); // Copying to, and constructing from intrinsic yields same result. typename V<T>::Intrinsic nv2 = v2; V<T> v2b(nv2); - NotifyIfUnequal(v2b, T(2), notify); + NotifyIfUnequal(v2b, T(2), __LINE__, notify); // .. assignment also works. V<T> v2c; v2c = nv2; - NotifyIfUnequal(v2c, T(2), notify); + NotifyIfUnequal(v2c, T(2), __LINE__, notify); const V<T> add = v2 + v3; - NotifyIfUnequal(add, T(5), notify); + NotifyIfUnequal(add, T(5), __LINE__, notify); const V<T> sub = v3 - v2; - NotifyIfUnequal(sub, T(1), notify); + NotifyIfUnequal(sub, T(1), __LINE__, notify); const V<T> vand = v3 & v2; - NotifyIfUnequal(vand, T(2), notify); + NotifyIfUnequal(vand, T(2), __LINE__, notify); const V<T> vor = add | v2; - NotifyIfUnequal(vor, T(7), notify); + NotifyIfUnequal(vor, T(7), __LINE__, notify); const V<T> vxor = v3 ^ v2; - NotifyIfUnequal(vxor, T(1), notify); + NotifyIfUnequal(vxor, T(1), __LINE__, notify); } // SSE does not allow shifting uint8_t, so instantiate for all other types. @@ -135,19 +137,19 @@ void TestShifts(const HHNotify notify) { const V<T> v1(1); // Shifting out of right side => zero - NotifyIfUnequal(v1 >> 1, T(0), notify); + NotifyIfUnequal(v1 >> 1, T(0), __LINE__, notify); // Simple left shift - NotifyIfUnequal(v1 << 1, T(2), notify); + NotifyIfUnequal(v1 << 1, T(2), __LINE__, notify); // Sign bit constexpr int kSign = (sizeof(T) * 8) - 1; constexpr T max = MaxValue<T>()(); constexpr T sign = ~(max >> 1); - NotifyIfUnequal(v1 << kSign, sign, notify); + NotifyIfUnequal(v1 << kSign, sign, __LINE__, notify); // Shifting out of left side => zero - NotifyIfUnequal(v1 << (kSign + 1), T(0), notify); + NotifyIfUnequal(v1 << (kSign + 1), T(0), __LINE__, notify); } template <class T> @@ -162,30 +164,30 @@ } // Aligned load const V<T> v4 = Load<V<T>>(lanes); - NotifyIfUnequal(v4, T(4), notify); + NotifyIfUnequal(v4, T(4), __LINE__, notify); // Aligned store T lanes4[n] HH_ALIGNAS(32); Store(v4, lanes4); - NotifyIfUnequal(Load<V<T>>(lanes4), T(4), notify); + NotifyIfUnequal(Load<V<T>>(lanes4), T(4), __LINE__, notify); // Unaligned load const V<T> vu = LoadUnaligned<V<T>>(lanes + 1); Store(vu, lanes4); - NotifyIfUnequal(lanes4[n - 1], T(5), notify); + NotifyIfUnequal(lanes4[n - 1], T(5), __LINE__, notify); for (size_t i = 1; i < n - 1; ++i) { - NotifyIfUnequal(lanes4[i], T(4), notify); + NotifyIfUnequal(lanes4[i], T(4), __LINE__, notify); } // Unaligned store StoreUnaligned(v4, lanes + n / 2); size_t i; for (i = 0; i < 3 * n / 2; ++i) { - NotifyIfUnequal(lanes[i], T(4), notify); + NotifyIfUnequal(lanes[i], T(4), __LINE__, notify); } // Subsequent values remain unchanged. for (; i < 2 * n; ++i) { - NotifyIfUnequal(lanes[i], T(5), notify); + NotifyIfUnequal(lanes[i], T(5), __LINE__, notify); } }
diff --git a/java/com/google/highwayhash/HighwayHash.java b/java/com/google/highwayhash/HighwayHash.java index 68075ef..7be30d5 100644 --- a/java/com/google/highwayhash/HighwayHash.java +++ b/java/com/google/highwayhash/HighwayHash.java
@@ -136,7 +136,10 @@ * @return 64-bit hash */ public long finalize64() { - finalPermutes(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); done = true; return v0[0] + v1[0] + mul0[0] + mul1[0]; } @@ -150,7 +153,12 @@ * @return array of size 2 containing 128-bit hash */ public long[] finalize128() { - finalPermutes(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); done = true; long[] hash = new long[2]; hash[0] = v0[0] + mul0[0] + v1[2] + mul1[2]; @@ -167,7 +175,16 @@ * @return array of size 4 containing 256-bit hash */ public long[] finalize256() { - finalPermutes(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); + permuteAndUpdate(); done = true; long[] hash = new long[4]; modularReduction(v1[1] + mul1[1], v1[0] + mul1[0], @@ -236,13 +253,6 @@ (v0[1] >>> 32) | (v0[1] << 32)); } - private void finalPermutes() { - permuteAndUpdate(); - permuteAndUpdate(); - permuteAndUpdate(); - permuteAndUpdate(); - } - private void modularReduction(long a3_unmasked, long a2, long a1, long a0, long[] hash, int pos) { long a3 = a3_unmasked & 0x3FFFFFFFFFFFFFFFL;