# Hashing or encrypting twice to increase security?

Over on the bitcoin forums I asked why the bitcoin client computes SHA-256(SHA-256(x)) as its cryptographic hash for a variety of purposes. The leading theory--since the bitcoin author has disappeared--seems to be that from a security standpoint it could be sort-of analogous to upping the number of rounds in SHA-256 from 64 to 128, thereby providing a margin of safety as it is probable that the first preimage attack against SHA-256 (if such a thing exists) wouldn't work against SHA-256(SHA-256(x)), giving time to transition to a new hash function.

First of all, is that true? Would hashing twice make it any more difficult to mount a preimage attack, at least for certain types of attacks?

If the answer is yes, my related question is: is there a mode for encrypting twice to provide a similar increase in security? How would one feed the result of the 1st round of encryption into the setup of the 2nd (or 3rd)? Would you use the same key twice? Would you derive the 2nd key from (a hash of) the ciphertext of the first round (and the 3rd round from the 2nd, etc.)? Would you need an odd number of rounds and alternate Encrypt(Decrypt(Encrypt())) like Triple-DES does to prevent a meet-in-the-middle attack? How would this interact with the various modes of symmetric key encryption? Anything else I'm not thinking of that I would have to know about this if I were to implement it in a real product?

-

For a second preimage attack:

hash(x) = hash(y) implies hash(hash(x) = hash(hash(y))

So it wouldn't protect against a direct preimage attack. Bitcoin builds a Merkle tree for a b c like this: hash(hash(hash(a)+hash(b))+hash(hash(c)+hash(c))).

You can see again that if someone found a c' that has the same SHA-256 hash as c, they could substitute it and the final result would still be the same.

While it's true that this might improve resistance to first preimage attacks, there aren't any obvious cases where those would matter -- an attacker typically would have the plaintext that generated the hash. (And preimage attacks on addresses seem far fetched, given that the ECDSA operation is in there.)

-
So is there any reason to perform hash(hash(x)), in general? –  maaku Sep 27 '11 at 15:42
I think an argument could be made that it might provide better protection against an attack where an attacker, given only the hash, attempts to find text that hashes to that. (But in every realistic Bitcoin situation, the attacker would have more than just the hash.) –  David Schwartz Sep 27 '11 at 16:39
–  LamonteCristo Mar 19 '13 at 17:03

Yes (to the encrypting part of the titular question). In fact, Bruce Schneier has recommended encrypting using multiple rounds for AES due to attacks (each word a link):

Cryptography is all about safety margins. If you can break n round of a cipher, you design it with 2n or 3n rounds. What we're learning is that the safety margin of AES is much less than previously believed. And while there is no reason to scrap AES in favor of another algorithm, NST should increase the number of rounds of all three AES variants. At this point, I suggest AES-128 at 16 rounds, AES-192 at 20 rounds, and AES-256 at 28 rounds. Or maybe even more; we don't want to be revising the standard again and again.

Edit: Apparently, my understanding of this was incorrect. The number of rounds is internal to the algorithm and not "multiple encryption operations". By design, AES has 10 rounds for 128-bit keys, 12 rounds for 192-bit keys, and 14 rounds for 256-bit keys.