I came across this excellent video, explaining how the SHA-256 algorithm works internally. I had always been excited to understand how a real-world hashing algorithm works internally. SHA-256 is one of the most popular hashing algorithms, so after getting my hands on that video, I knew I had to try and implement this on my own. This feels like once in a lifetime opportunity. So here I am after having implemented the algorithm on my own and feeling confident understanding how SHA-256 works. I want to pass on that same confidence to the readers of this blog (probably including me in a few months :D) along with code snippets. So, lets dive right into it...
Basic Operations
There are some basic operations that the SHA-256 algorithm builds on top of. Here is a list of those:
1. Shift Right - Shifts the bits of the original number pos bits to the right, dropping of things that slide of the end.
2. Rotate Right - Rotates pos bits in the original number. Very similar to shift but instead of dropping things off the end, it wraps them at the beginning (in a circular fashion)
7. Choice - Given three binary numbers x, y, z, depending on the bits of x, choses the corresponding bit in y if x bit is 1, or the corresponding bit in z if x bit is 0.
8. Majority - The result contains the majority bit out of each bit of x, y and z.
The SHA-256 Algorithm
The above picture shows the various steps of the SHA-256 algorithm. This is the SHA256 algorithm in code that I implemented:
Here is each of the steps broken down:
1. Convert the original message (usually string) in the binary format. (If the string is "abc", it gets converted to 011000010110001001100011, where first 8 bits are "a" (96 ASCII), next 8 are "b" (97 ASCII) and next 8 are "c" (98 ASCII).
2. Pad the binary message in such a way that the total number of bits in the padded message are a multiple of 512. Also, 65 bits of the padded message are reserved. A bit "1" is added right after the original message as a separator. Then there are a bunch of zeroes, and the last 64 bits encode the length of the original message.
3. Now that the message length is a multiple of 512, we just break it into message blocks which are 512 bits in length each.
4. Next step is to process each message block one by one and create a message schedule out of each block eventually compressing each of the message schedule.
5. In order to create a message schedule, we break down the 512 bit message block into 16 words of 32 bits each. However, a message schedule consists of 64 words. This is where the basic operations we defined above come into play. We use some combination of those to generate the remaining 48 words. At the end of all of this, we have transformed a 512-bit message block into 64, 32 bits word message schedule.
6. Now comes the heart of the SHA-256 algorithm, the compression stage. Now that we have 64 words of 32 bits size with us, we need to merge them in some way. SHA-256 does that by merging them down to 8, 32-bit hash values. These hash values are initialized as below:
They might look intimidating (anything in hexadecimal looks intimidating to me :D) but these are just the square roots of the first 8 primes. (Their fractional part, to be precise)
And these hash values, are the ones that store the final result after processing each message block. As shown in the block diagram above, the updated hash values after each step are used as an input in the next step. The square root of first 8 primes is the initial hash value with which all this process starts.
7. This process of creating a message schedule and compressing it is repeated for each message block. And the final hash values, generated after processing the last message block gives us the SHA-256 hash. We convert each hash value into the 8-length hexadecimal equivalent and concatenate all of them to generate the 64-length SHA-256 hash.
And that is how the SHA-256 algorithm works. Here is the full C++ source code for the algorithm:
I hope, this post gives you confidence around the SHA-256 algorithm and maybe even the motivation to implement it yourself (probably improving over my quick and kind of dirty implementation) in the programming language of your choice.
Comments
Post a Comment