HighwayHash: Fast hashing at over 10 GB/s per core in Golang
blog.minio.io
blog.minio.io
BenchmarkHighwayHash 11986.98 MB/s
BenchmarkSHA256_AVX512 3552.74 MB/s
BenchmarkBlake2b 972.38 MB/s
BenchmarkSHA1 950.64 MB/s
BenchmarkMD5 684.18 MB/s
BenchmarkSHA512 562.04 MB/s
BenchmarkSHA256 383.07 MB/sUnfortunately I'm not familiar enough with the details of the collision resistance properties of the other hash functions here to know how they compare. Could someone elaborate on the specifics of why HighwayHash compares poorly in terms of collision resistance to the others in the benchmark?
https://github.com/fwessels/HashCompare/blob/master/README.m...
It's easier to make it faster to write it in assembly were you can hand tune all the instructions when you are already thinking that low level.
Perhaps not a concern for Blake, but timing attacks are real. It you need to make your function operate constant time then your compiler is likely working against you.
The standard distribution of Golang has been historically non-receptive to the notion of providing intrinsics, the capability for inlining assembly function calls (note: not inlining assembly source), and in general proposals to trivially extend the language or standard library to address performance concerns whose need would not be considered controversial in any other context (I'm not talking about generics, here). In quite a few cases it has been communicated that certain features will never be made available because fuck you that's why, although in recent releases there has been a trend of backtracking on these "promises" under the onslaught of justifiable need.
These conscious "trade-offs" severely impact the specific cases where dedicated hardware instructions exist that are capable of providing sometimes orders of magnitude improvement but are not yet encapsulated by builtins or blessed with snowflake exceptions in the standard library.
Your options for implementing the kinds of compute-bound tight loops which benefit from specialized instructions in Golang are: 1) Write the whole thing in Golang assembly so you only pay the price of a function call once on entry (Let's call this 0.4ns for a 2.5GHz CPU using a single cycle latency instruction per operation) 2) Use hilarious bit twiddling hacks that the compiler can inline which perform the equivalent operation with 10-20 cycle latency (4-8ns) 3) Use a Golang assembly library which presents a single invocation of the hardware instruction as a Golang function and have all of the gains absorbed by the function call overhead (~10ns) 4) Use the primitives available via the standard library to implement the function (as a general rule not worth wasting the time to optimize and comparatively benchmark for this class of function) 5) Fork golang, implement what you need, offer it as a pull request, and have upstream tell you to just go back to C or assembly if you care about performance (Literally.) 6) Target gccgo/(llgo?) (much better for this specific class of function but less performant in other areas, a different set of trade-offs).
In short: optimization trade-offs.
But they still didn't put their hash to external scrutinity, still waiting for the pull request to get it tested with smhasher.
And I just added Highwayhash now to smhasher by myself and my initial analysis was confirmed. It's the 2nd slowest of all tested good hashes, only behind Siphash. Every other is simplier and faster. Chi-Square on the lower 32bits was 0.00 so it's really a good one. But I see no usecase for it, really.
Offline attacks to find collisions are irrelevant because revealing the key breaks the security model.
Saying you can recover the key from side-channel attacks on probe sequences is actually a claim that SipHash/HighwayHash are not secure PRFs.
If you're not making these claims, you're not communicating very well what your security claims are.
My hash tables are secure against known seeds BTW, every hash table should. Almost all use cases make it trivial to get to the seed in certain ways. Calling a hash table secure relying on a secured random seed is theatre, and securing is actually simplier and faster than relying on a broken model and slow hash functions.
I don't have anything against recommendations to use all bits in the hash output, or good collision handling, just these unfounded security claims about key recovery.