Merkle–Damgård construction
In cryptography, the Merkle–Damgård construction or Merkle–Damgård hash function is a method of building collision-resistant cryptographic hash functions from collision-resistant one-way compression functions. This construction was used in the design of many popular hash algorithms such as MD5, SHA-1 and SHA-2.
The Merkle–Damgård construction was described in Ralph Merkle's Ph.D. thesis in 1979. Ralph Merkle and Ivan Damgård independently proved that the structure is sound: that is, if an appropriate padding scheme is used and the compression function is collision-resistant, then the hash function will also be collision-resistant.
The Merkle–Damgård hash function first applies an MD-compliant padding function to create an input whose size is a multiple of a fixed number — this is because compression functions cannot handle inputs of arbitrary size. The hash function then breaks the result into blocks of fixed size, and processes them one at a time with the compression function, each time combining a block of the input with the output of the previous round. In order to make the construction secure, Merkle and Damgård proposed that messages be padded with a padding that encodes the length of the original message. This is called length padding or Merkle–Damgård strengthening.
In the diagram, the one-way compression function is denoted by f, and transforms two fixed length inputs to an output of the same size as one of the inputs. The algorithm starts with an initial value, the initialization vector. The IV is a fixed value. For each message block, the compression function f takes the result so far, combines it with the message block, and produces an intermediate result. The last block is padded with zeros as needed and bits representing the length of the entire message are appended.
To harden the hash further, the last result is then sometimes fed through a finalisation function. The finalisation function can have several purposes such as compressing a bigger internal state into a smaller output hash size or to guarantee a better mixing and avalanche effect on the bits in the hash sum. The finalisation function is often built by using the compression function.
Security characteristics
The popularity of this construction is due to the fact, proven by Merkle and Damgård, that if the one-way compression function f is collision resistant, then so is the hash function constructed using it. Unfortunately, this construction also has several undesirable properties:- Second preimage attacks against long messages are always much more efficient than brute force.
- Multicollisions can be found with only a little more work than collisions.
- "Herding attacks", which combines the cascaded construction for multicollision finding with collisions found for a given prefix. This allows for constructing highly specific colliding documents, and it can be done for more work than finding a collision, but much less than would be expected to do this for a random oracle.
- Length extension: Given the hash of an unknown input X, it is easy to find the value of, where pad is the padding function of the hash. That is, it is possible to find hashes of inputs related to X even though X remains unknown. Length extension attacks were actually used to attack a number of commercial web message authentication schemes such as one used by Flickr.
Wide pipe construction
Therefore, in a final step a second compression function compresses the last internal hash value to the final hash value. This can be done as simply as discarding half of the last 2n-bit-output. SHA-512/224 and SHA-512/256 take this form since they are derived from a variant of SHA-512. SHA-384 and SHA-224 are similarly derived from SHA-512 and SHA-256, respectively, but the width of their pipe is much less than 2n.
Fast wide pipe construction
It has been demonstrated by Mridul Nandi and Souradyuti Paul that the Widepipe hash function can be made approximately twice as fast if the widepipe state can be divided in half in the following manner: one half is input to the succeeding compression function while the other half is combined with the output of that compression function.The main idea of the hash construction is to forward half of the previous chaining value forward to XOR it to the output of the compression function. In so doing the construction takes in longer message blocks every iteration than the original widepipe. Using the same function f as before, it takes n bit chaining values and n+m bits of the message. However, the price to pay is the extra memory used in the construction for feed-forward.
MD-compliant padding
As mentioned in the introduction, the padding scheme used in the Merkle–Damgård construction must be chosen carefully to ensure the security of the scheme. Mihir Bellare gives sufficient conditions for a padding scheme to possess to ensure that the MD construction is secure: the scheme must be "MD-compliant". Conditions:- is a prefix of
- If then
- If then the last block of is different from the last block of
Length padding example
To be able to feed the message to the compression function, the last block needs to be padded with constant data to a full block.But this is not enough since it would mean that distinct messages starting by the same data and terminated by zero or more bytes from the padding constant data would get fed into the reduction function using exactly the same blocks, producing the same final hash sum.
To prevent this, the first bit of the padded constant data must be changed. As the constant padding is generally made of zeroes, the first padding bit will be mandatorily changed into "1".
To harden the hash even further also, the length of the message can be added in an extra block.
To avoid ambiguity, the message length value must be itself resistant to length extension attacks. Most common implementations use a fixed bit-size and a fixed position at end of the last block for encoding the message length value, although this would according to logic presented on this page, be less effective than placing the length at the start of the message, where it itself is not liable to length extension attack, but requires knowledge prior to initiating checksumming of the length of data being checksummed, or insertion of multiple of such values, blockwise, within the checksum stream.
Now that is a bit wasteful since it means hashing one full extra block for a length value. So there is a slight speed optimisation that most hash algorithms use. If there is space enough among the zeros padded to the last block the length value can instead be padded there.
Note that storing the message length out-of-band in metadata, or otherwise embedded at the start of the message is an effective mitigation of the length extension attack, as long as invalidation of either the message length and checksum are both considered failure of integrity checking.