# Is a random length-extension worth the effort?

I'm conceiving an application that uses cryptographic tools and concepts for securing data. I know that's difficult and risky, therefore I prefer to ask around before implementing anything.

When using generic length-extension for hash functions, such as SHA256d where, if I'm correct, "d" stands for the number of times the hash gets re-hashed, I wondered if using a random value for "d" (within certain limits) could do anything to improve security.

The application would be a tad slower when finding out the correct value of "d" for a particular hash, but wouldn't it be justified by the annoyance caused to the attacker ?

This would be in case where the attacker has the source code (which isn't so far fetched if he already has access to the data) and could easily find out the value of "d".

• Note that what you are using is not "length-extension", but precautions made against "length extension attacks". – Paŭlo Ebermann Apr 26 '12 at 11:50

I'll assume $SHA256_d(M)$ is $SHA256(M)$ when $d=0$, else $SHA256(SHA256_{d-1}(M))$.

$SHA256_1$ is protected against length extension attacks.

The only sizable benefit that I see in parameterizing $d$ is that it allows tuning a slow down of the computation intended as a protection against brute force attacks. However there are more flexible primitives for that purpose, like PBKDF2 or Scrypt, and Scrypt is considerably safer for similar slowdown.

Leaving $d$ unknown to improve security is almost pointless. An adversary can have a rough figure about $d$ by a variety of side channels, e.g. duration of the computation. And an adversary knowing $SHA256_d(M)$ but neither $d$ nor $M$ is annoyed by a factor of less than 4 by not knowing $d$ if she knows that $M$ is in her dictionary. She does as follows:

1. Chooses a small starting $n>0$ per some guess of $d$, or just $n=1$.
2. Computes $SHA256_n(X)$ for all the $X$ in the dictionary, comparing the known $SHA256_d$ with the $SHA256$ obtained at each of the $n$ steps, proclaiming success (with high probability) if there is a match.
3. Having ruled out all values of $d$ up to $n$, she doubles $n$ and continues at 2.

If she happens to have enough memory (as much as needed to store as many hashes as entries in the dictionary) she can store the last result obtained for each entry at step 2, and reuse that later; the penalty falls to a factor of less than 2. Update: further, with the same memory, increasing $n$ by $1+\lfloor Log(n)\rfloor$ at step 3 makes the penalty factor become arbitrarily close to 1 as $d$ grows (this can be tuned-up for low $d$ by changing the constant and the base of the logarithm).

AFAIK the d stands for double, and simply means that the input gets hashed twice. i.e. SHA-256d = SHA-256(SHA-256(m)). It's not a configurable parameter, since hashing more often has no benefit, unless you want a slow down, but there are better constructions for that case.

Hashing twice prevents length-extension attacks, but reduces performance, especially for short messages. I'm not sure in which situations this defense is important, but there are some where it is clearly unnecessary, such as for a hash function used in HMAC, since HMAC is already immune to length extensions.