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;