I am implementing SHA-512 on 64-bit Linux in C. SHA-512 accepts 128 bits as the length of data to be hashed. Currently I am taking two 64-bit long int
s to comprise the 128-bit value but I am puttingg zeros intentionally to the first 64 bits and the length is stored in the remaining lower 64 bits. Why am I doing this?
Well I think on 64-bit architectures, I probably won't ever get a value more than 264 or can I? Is this the right way to implement SHA-512 on 64-bit architecture or is there any way to cater 128-bit values on 64-bit architectures that I don't know? The point to note is that I am implementing SHA-512 according to FIPS 180-3.
Any help would highly appreciated.
I hope that by "64 bit long ints", you really mean unsigned long ints... Seriously, don't do your own SHA-512 implementation until you fully understand how bigint arithmetic is done using smaller integers.
If you want to implement something conforming, then use the full 128 bit. If you use one single function call to hash the complete block, you will hardly need the full 128 bit, 64 will be ok. But to be conforming, you should allow to hash a complete block in packets. Thus you have 3 functions like these:
Init - Initializes the internal state for the next hashing.
Add - Adds a block of data to the current hashing, with internal buffering of incomplete blocks and internal count of the 128 bit size. It takes a block of memory, so a clean C-style interface would use size_t
for the number of bytes. However, a 64 bit unsigned integer is good enough for the intended purpose and simplifies the counting.
Finish - Does the padding, completes the hashing and returns the final hash value.
Obviously, this approach needs an additional externally visible struct to hold the current state.