How Hash Algorithms Work (2007)
metamorphosite.com
metamorphosite.com
> A hash function is simply an algorithm that takes a string of any length and reduces it to a unique fixed length string.
Hash functions strive for uniqueness but unless it's precalculated to ensure that it's true (by hashing every combination or deriving the parameters of the hash function accordingly), it's not guaranteed. A cryptographic hash function gives a high probability of uniqueness but again it's not guaranteed.
> The word 'cat' will hash to something that no other word hashes too, but it will always hash to the same thing.
Say I have a (terrible) hash function H(X) => 1. Now "cat" will hash to the same value as the string "I don't understand hash functions".
No hash function strives for uniqueness. As long as the digest length is shorter than the input length, you can logically guarantee that there will be collisions. And since all general purpose hash functions allow arbitrary length input data, this is always the case. But what cryptographic hash functions strive for is the difficulty in finding a collision. It's mathematically guaranteed to be there, but finding it should cost a prohibitively large amount of time and computing resources. There are also non-cryptographic hashes that only strive for the unlikelihood of accidentally getting a collision and don't protect against heavily contrived input data.
Nope! For a known set of N inputs of length K, I can devise a hash function that maps then to a log2(N) bit result with zero collisions regardless of K.
> And since all general purpose hash functions allow arbitrary length input data, this is always the case.
It's not the arbitrary length data that breaks the uniqueness guarantee. It's that you can have 2^X + 1 entries where you only have X bits of hash result: https://en.wikipedia.org/wiki/Pigeonhole_principle
No you can have a fixed length and arbitrary text. Say the input could be 32 hex characters representing a UUID. The key distinction is whether there is a finite / known list of the possible inputs. If so, then it's possible to create a hash function the perfectly hashes them.
The point is that a function cannot bijectively compress arbitrary input into fixed output. Of course if you make the function itself depend on the input itself, then you can pull all sorts of tricks, but normally we do not call a simple lookup table a 'hash function', because they are very different things.
It's definitely possible. Here's a simplistic example. Say I have two strings:
A really long string that goes on for [truncated] ...
and Some other really long string goes on for [truncated] ...
I can create a hash function that looks at the first character at gives either a 0 or 1 depending on whether it's an "A". For that known data set it'll perfectly hash the two strings into two buckets.It's a very simplistic example but the same concept can be used to identify the minimum components of the inputs that would need to be looked at to create a unique hash function. It won't be a general hash function though; it's specific to that data set.
Note that this isn't useless either. It's common to have a fixed/known lists of strings that you want to do lookups upon.
But she doubles-down on the uniqueness claim later:
Each hash is unique but always repeatable The word 'cat' will hash to something that no other word hashes too, but it will always hash to the same thing.
This is such a large misunderstanding of hashing (as well as being obviously impossible) that it is hard to trust the rest of the article.
Don't hashing functions have collisions?
Usually you want a hash that maps similar strings to completely different output hashes (and I guess that's what the author actually wanted to describe). But that is not a necessity of a hash function, just a usual property.
He knows there are collisions, he just chose to start with the simplest explanation and add the useful details as he moves on. It's fine by me, even though engineers tend not to like that (they prefer accuracy from the word go).
1.46 x 10^48 = sha1 possible outputs
~7.5 x 10^5 = total English words [1]
If you computed all ~750,000 hashes for all known English words, none of the sha1 hashes will match sha1("cat"). I'm guessing that you still wouldn't get a collision if you include all words from all world languages.
For "words" to generate a collision, you'd have to increase the input domain by allowing "words" to mean any sequence of bytes (e.g. bytes of jpg image or audio file).
[1] https://en.oxforddictionaries.com/explore/how-many-words-are...
That is way overkill - the input domain could just be strings of words. Each word of a typical English text adds about one byte of entropy (2^8 states). We get a probable collision by having a number of text states around the square root of the number of hash states (because of the birthday paradox). So, sqrt(10^48) = 10^24 = (10^3)^8 which is about (2^10)^8. So the space of ordinary 10-word strings is big enough to give a sha-1 collision, without invoking inputs like binary files.
They do. The text is somewhat misleading and not properly explaining that.
All hash functions have collisions. But from a cryptographically secure hash function we expect that nobody is able to find such a collision. They exist, but the computational power to find one is not available to humans.
> Also, it should be computationally infeasible to find any other word which also hashes to '...'
This is wrong. There is something called a perfect hash function:
https://en.wikipedia.org/wiki/Perfect_hash_function
>a perfect hash function for a set S is a hash function that maps distinct elements in S to a set of integers, with no collisions. In mathematical terms, it is a total injective function.
They are very handy for hash tables with constant worst-case lookup time.
In the more general case, for a hash function with n bits output, the pigeon hole principle demands that we have a collision at least every 2^n inputs.
This is false or inaccurate at best too. More correct would be that it should be computationally infeasible for any one entity to have any reasonable chance to obtaining the inverse of a hash, in the foreseeable future.
With all hashing functions in existence, it's always theoretically possible to find the inverse, and that should be pointed out.
It's also worthwhile to note that the statement that a hash takes a string and reduces it to a fixed length string is a little misleading. They really work at the binary level and this is seen in the example where the input is converted to binary assuming ASCII and the output hex encoded.
The misleading part is about the reduction to a unique fixed length string; that's not possible unless the input domain is equal to (or smaller than) the output domain (and even then it's not necessary). Any other function is guaranteed to have collisions.
Saying they're unique is just very very wrong.
$ echo 'test' | sha1
4e1243bd22c66e76c2ba9eddc1f91394e57f9f83
:-P
echo -n 'test' | sha1
will give you the same output as the article by removing the new line. a94a8fe5ccb19ba61c4c0873d391e987982fbbd3Are there any technological advances or scenarios where the security of hash algorithms could be weakened (other than computers just getting fasters via ~Moore's Law).
?
The chances of a sha256 collision is essentially zero barring a vulnerability being found in sha2. Far more likely for a comet to wipe out earth in your lifetime.
Yes, but to answer the question if you can find the input from the hash, the answer is no because it's impossible to be 100% certain as many input can hash to the same value.
Of course this is assuming that the hash algorithm doesn't have any weaknesses you could exploit.
AKA rainbow tables, which explains why it is important not to use just a single word from the dictionary as a password.
For example, user passwords on a server should only be stored in hashed form (ideally with salt[1]). If an attacker gets access to that database, they will not be able to restore the original passwords without enormous computation costs.
The "why not" is harder two answer and I don't know all the details either. But the general idea is that the hashing algorithm contains irreversible operations where multiple (intermediate) inputs would result in the same (intermediate) output, so you cannot derive a unique input from the output.
A simple example for this is the modulo function: 9 mod 7 = 2, but also 16 mod 7 = 2. If you now see the result 2, the original number could have been 2, 9, 16, 23 or anything else of the form n*7 + 2.
There is currently not much reason to believe such techniques exist, except perhaps for persistent rumors that the NSA is running some computationally very extensive operations (maybe with custom-built chips) that might be put to use for direct attacks on some weaker cryptographic algorithms like 2DES, RC4, SHA1, or 1024 bit RSA. That's pure speculation, though.
Is "Step 5: Add '1' to the end"
Is this a delimiter for beginning of the padding or does it server some other purpose?
add a "rainbow tables" caveat to that.
Can anyone recommand resources about the actual design of (cryptographic) hash algorithms?