The purpose of a checksum is to determine whether a message was transmitted error free. There are many ways to determine a checksum and one of the ways to do this is to use a cryptographic hash.
A cryptographic hash function has several useful properties to do this:
- A single bit change in the input produces a radical change in the output hash value. This means that even a small error in the input will result in a completely different checksum being computed.
- A collision is improbable to compute. This means that it is nearly impossible for two different sets if input data to produce the same checksum even on purpose, much less if it is due to a random error.
However, a problem with using a checksum like this is that it needs to be transmitted alongside the message. In one of our projects, it would needlessly complicate the protocol to require the checksum to be transmitted as well. We wanted to keep things simple.
So, we borrowed an idea from the block-chain world – proof of work (PoW).
Instead of using a checksum, we can alter the message slightly by padding it with a nonce in order to produce a checksum with a certain number of leading zeros (difficulty level). The receiver can simply compute and verify the message as error free if the received message with nonce result in a hash of a certain number of leading zeros.
It is also efficient on bandwidth as the nonce could be a small 32-bit value compared to a cryptographic hash that is at least 128-bits and typically 256-bits or more. So, instead of transmitting the checksum with the message, the nonce can be transmitted instead, and removed from the output message post checksum computation.
This is good enough as it will be able to detect an error in transmission. Any errors in the message (or the nonce) would result in a radically different checksum being computed. The chances of random errors producing a checksum with the same number of leading zeros, decreases with difficulty (level that can be tweaked).
While this will increase the complexity at the transmitter, for our specific use-case, this is not a problem as the data to be transmitted need only be computed once.
PS: The results can possibly be improved by using a HMAC or by signing and ensuring that the result of the HMAC/signature meets the difficulty level.