# Construct an encryption algorithm using hash function [duplicate]

We know that Cryptographic hash function is generally a one-way function where we can't retrieve the original message. On the other hand, encryption is a two-way-function where we get the original message from the encrypted message or vice versa. So, in a normal sense, we can't use hash function to construct an encryption algorithm.

What I want to know is, if it’s theoretically possible to somehow create an encryption algorithm using a hash function, or if any encryption algorithm uses hash function in any part of their algorithm?

-

## marked as duplicate by e-sushi♦, AFS, Gilles, rath, John DetersMar 29 '14 at 13:20

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

It is quite easy to turn a hash function into a stream cipher. Look at the sci.crypt posting for "New Symmetric Encryption Algorithm" from July 2013 for how to not do this, as well as a lot of good comments on how to do it the right way – Richie Frame Mar 24 '14 at 9:27
With slight modifications, you can reach one of the Sponge construction schemes. There seem to be other examples of 'leaky hash functions' around as well, where the hash is modified to leak a keystream as it runs. – figlesquidge Mar 24 '14 at 9:27
Don't think this is a dupe of that question, because that is just one of several ways of making a cipher from a hash function. – figlesquidge Mar 24 '14 at 18:12

## 4 Answers

In "Applied Cryptography" by Bruce Schneier, section 14.11, “Using One-Way Hash Functions”, he shows how to use a hash function as a block cipher in CFB mode:

$$C_i = p_i \oplus H(k || C_{i-1}) \\ P_i = Ci \oplus H(k || C_{i-1})$$

Schneier continues:

The security of this scheme depends on the security of the one-way hash function...While these constructions can be secure, they depend on the choice of the underlying one-way hash function. A good one-way hash function doesn't necessarily make a secure encryption algorithm...For example, linear cryptanalysis is not a viable attack against one-way hash functions, but works against encryption algorithms...

-
Without checking the exact text, I am pretty sure he also wrote in Applied Cryptography, that this is not save without a proper cryptanalysis. Hash functions work differently than encryption functions. For example differential cryptanalysis doesn't do anything in hash functions, but it can break encryption. – tylo Mar 25 '14 at 13:44
From section 14.11 "The security of this scheme depends on the security of the one-way hash function...While these constructions can be secure, they depend on the choice of the underlying one-way hash function. A good one-way hash function doesn't necessarily make a secure encryption algorithm...For example, linear cryptanalysis is not a viable attack against one-way hash functions, but works against encryption algorithms..." – TomS Mar 25 '14 at 14:36
If you have a hash function that is provably secure as a cryptographic PRNG, such as Skein, then the construction above is equivalent to CTR mode. – TomS Mar 25 '14 at 16:19
Skein works... because it is built upon threefish, which is a blockcipher. The proof that Skein is a PRNG is built upon Threefish being a PRP. So basically the proof of security is along the lines "We design a secure encryption scheme, which is based on a secure hash function, which is based on a secure encryption scheme. And we assume this encryption scheme to be secure. So our final design must also be secure." – tylo Mar 25 '14 at 17:02

Theoretically, there are several ways to turn a hash function into an encryption system. However, the Devil is in the details. A cryptographic hash function is a function which is resistant to preimages, second preimages, and collisions. As far as I know, it has not been proven that these conditions are sufficient to build a stream cipher. In fact, what we want is a random oracle (there are subtleties with regards to definition, that I will not detail here).

We have no proof that cryptographic functions really exist. We also have no proof that random oracles really exist. And we do not know how to build a random oracle out of a cryptographic hash function. We do know how to build a secure hash function out of a random oracle. However, we also have strong indications that random oracles cannot actually exist, at least in a general sense. Basically we grope in the dark: we have candidates like SHA-256, which appear to be "quite strong" as hash function, and also are reasonably oraclish as far as we known. In fact, the length extension attack is proof enough that SHA-256 is not a random oracle, but this can be fixed by using SHA-256 on fixed-length inputs, or by invoking it as part of more convoluted structures like HMAC.

In any case, if you have a hash-function-with-oracle-powers, then it is rather easy to generate a pseudo random stream from a secret key, by hashing K||n where K is the secret key and n is a counter. By XORing this key-dependent pseudo-random stream with the data to encrypt, you have a stream cipher.

To make a block cipher, you can use a Feistel network where your hash function is used as "confusion function" for each round, although there again there are details (you must inject round subkeys at that point). The theoretical analysis is due to Luby and Rackoff, back in the 1980s. It can be proven that four rounds are sufficient, subject to some details; e.g. if you are targeting $n$-bit blocks, the proof works up to security level $2^{n/2}$ or so (if I remember it correctly). Variants imply unbalanced networks, which allow for better security at the expense of more rounds (see the Thorp shuffle).

Theoretical upper limit for Feistel schemes is that such a scheme is necessarily an even permutation, so if you have $n$-bit blocks and know the encryption of $2^n-2$ distinct plaintexts, you can guess the encryption of the two plaintext blocks that you don't know with probability $1$, instead of probability $0.5$ for a truly pseudorandom permutation. You would be very hard-pressed to find a practical situation where this point actually matters in any way.

Another theoretical method which does not involve a Feistel scheme at all is described in that article: it is a generic method to turn a "seekable pseudorandom stream" (e.g. the hash-based stream cipher alluded to above) into a generic pseudo-random permutation. The implementation overhead is huge, so nobody does that in practice. It still shows that a PRP can be generically built out of a PRF without the (slight) limitations implied by Feistel networks.

-

There are arguments for both sides:

• Yes, you can. In Feistel networks, the $F$ function is always evaluated in the same direction, not need for inversion. Similar constructions work as well. Or just XOR a hash value to your message (like in a stream cipher, but block-wise), and make the hash value dependent on the key (and any other input of your choice).
• No, you shouldn't. There is simply no cryptanalysis of hash functions with respect to linear characteristics, etc. Collision resistance doesn't provide anything and preimage resistance doesn't provide necessary properties. Often for statistical evaluation of hash functions it is requires that changing 1 bit triggers a change of half the bits in the hash value, but this doesn't help either.

What it comes down to is your intention. If it's just as an exercise, sure you can do that. If you want to use that in practice, you shouldn't. The risk that it isn't secure is just too high and there is no reason to use this instead of state-of-the-art encryption. The main question is, why would you want to use a hash function for something it isn't designed for? Hash functions and blockciphers are similar, but they have their own goals and their own methods for cryptanalysis. Using one for the other is just not intended.

-

Yes, it can. I recently posed a question about this: Hash Based Encryption (fast & simple), how well would this compare to AES? but apparently similar ideas existed before, and there probably many other ways to do it. In my proposal, I simply use the hash function as a deterministic (using the password and block index as seed) yet strong and cryptographically secure random generator, and XOR the data with it.

-