It's not the fastest general purpose hash --- but it's not supposed to be. It's supposed to be performant enough to be used as a default, and in being a default, it's supposed to take a pretty common attack off the table.
It's the right default. In the rare situations where container hashing winds up high on the profile, the faster hash should be the optional hash.
[edit]
Also, as a slight additional nitpick to the article, the term "cryptographic hash," when used in isolation, typically implies collision resistance, and SipHash is specifically not collision resistant due to its small output size.
I studied SipHash a while ago and implemented a SIMD version but that performed slower (needs 4x64 bit int vectors and doesn't allow any instruction level parallelism). I'm sure that you could make a faster hash function with 4x32 bit vectors using similar ARX (add-rotate-xor) networks but I'm not smart enough to do the cryptanalysis.
There's a new hash function called HighwayHash which was about 11GB/s but the implementation is very tied to Intel CPUs (SSE4.1 or AVX512) and uses 4x64 bit vectors. And no cryptanalysis on that either, although it looks like it has similar characteristics to SipHash.
Hash table keys are typically quite short, so going crazy with SIMD to push the throughput might not be a great idea.
SipHash is the only hash function that has credible cryptanalysis against key recovery and collisions.
E.g. FNV1 is trivially simple to generate collisions against.
Yes, it's non-reversable, and it doesn't allow easy seed-independent multi collisions as with other hash functions. But one hash function used in a hash table can never be secure. The collision resolution adds the security part. (or/plus some other schemes which are obviously over your head).
Collision resistance is a separate property which can be fulfilled without one way property.
Maybe you want hash numbers that are not predictable by an attacker, but sip hash is not salted either. Plus salting does not require a cryptographic hash either.
Siphash isn't a cryptographic hash function. It's a keyed hash function designed not to leak the key.
This is the definition of a Hash Function. Not a cryptographic Hash Function.
Cryptographic Hashes should NEVER collide, on any inputs, ever, period. The moment it is found too, the algorithm is considered depreciated. This is why MD5 shouldn't be used anymore, there is a generalized algorithm for producing collisions.
Cryptographic hashes are overkill for HashTables/HashMaps because you can't use 128/256/512bit address spaces unless your attempt to store all the information in the galaxy or observable universe. And modern computers just aren't there yet. Also they are very slow.
So when your masking a 512bit output, down to 16bits of your HashTable you just lose the will never collide guarantee. Then something that operates at 10GB/s, and can collide sounds better then something that runs at 150MB/s and will still collide anyways.
No, a hash function is just any function which can be used to put values into a hash map. If your inputs are numbers, modulo will work fine as a hash function, but is obviously not one-way.
>Cryptographic Hashes should NEVER collide, on any inputs, ever, period.
This is obviously not possible, as the output of the cryptographic hash function is of fixed-length while the input is variable-length. Finding collision just needs to be hard, not impossible.
modulo will work fine as a hash function, but is obviously not one-way.
Modulo is a one way trap door operation.Proof via arrogance:
X % 100 = 50
Solve for X
Solution X = F(n) where F(n) = 100*n+50 (for all n > 1)
This does indeed meet the requirements of a hash functions. Modulu is a bad hash function because it is poorly distributed. Cryptographic Hashes should NEVER collide, on any inputs, ever, period.
>This is obviously not possible
NIPS says if you observe 2 inputs of a cryptographic hash which compute to the same digest the hash is considered depreciated. So yes my definition is correct.Obviously yes all cryptographic hashes aren't unique for every input. As they maybe N bytes long. And simply a logic will tell you there is more information in N bytes of data vs 64 bytes (512bits).
The real issue is, prove it. Testing even the 512bit address space will take you longer then the heat death of the universe, so good luck!
https://en.wikipedia.org/wiki/Trapdoor_function
Note that the definition is about a pre-image, not necessarily the input used to create it in the first place.
Second, that definition is absolutely not correct. "Never" would require that the size of the output of the hash function be equivalent to the size of the universe of possible inputs, which it obviously isn't. There's a very important difference between "never be observed in practice" and "never, period." You're not using the language precisely, and that's very dangerous when talking about hashing and cryptography.
None of those properties is needed for indexing into hash table. Good collision resistance is all that is required and salting for more paranoid cases.
> you just lose the will never collide guarantee
There is no such guarantee, in fact, the opposite is guaranteed.
It's just very unlikely that you get a collision - that's a desirable property of any hash function -, and it should be hard to create a collision because the function is hard to reverse - that's a desirable property of any cryptographic hash function, as the OP laid out.
No it doesn't. These are independent properties. That is, collision resistance does not imply onewayness, and onewayness does not imply collision resistance.
Collision Resistance: it is hard to find x != x' such that h(x) = h(x')
One Wayness: Given y, an n-bit string randomly chosen from the output space of h(), it is hard to find any x such that h(x) = y.
Proof that CR does not imply OW: Suppose g() is collision resistant and outputs n bits. Define h(x) to be 0x if x is n bits long, otherwise 1x. Collisions are hard to find: if y starts with 1 there are no collisions, and if it starts with 0 then you'd need to find a collision in g(), which is collision resistant. h() is not one way: given a random y in the output space, with probability 1/2 it is trivial to find an x such that h(x) = y.
Proof that OW does not imply CR: Suppose that g() is one-way. Define h(x) = g(x) with the last bit truncated. h() is one-way because you cannot invert h without inverting g(). h() is not collision resistant because for any x, h(x0) = h(x1)