# is it safe to combine scrypt with other hash algorithms?

I'm currently writing a file encryption program, and I designed this scheme to derive a key from user input password:

layer1 = sha256(sha256(...sha256(password ,salt1), salt1), salt1)


I'm repeating the layer1 process about 10000 times or more and after that, I pass the layer1 to scrypt with a random salt:

layer2 = scrypt(base64(layer1), salt2)


and then I pass the layer2 to shake256 with another random salt:

key = shake256(base64(layer2), salt3)


I'm not a crypto designer or cryptoanalist, so I don't know whether this will cause weaknesses or not.

• Generally answers become better if you indicate why you have 3 layers of hashing. What are your requirements / goals? There may be good reasons for them (upgrading the # iterations / work factor later, deriving multiple keys) or they may have been added willy-nilly; we don't know. Jun 4 at 12:08
• Also if you want a higher work factor, why not just increase the scrypt work factor? Adding more code gives more opportunity to screw up and leak data. Jun 4 at 13:37
• @MaartenBodewes I agree that layer3 is meaningless, but I added layer 1 to balance RAM and CPU usage. I wanted to achieve this balance by reducing the working factor of layer two and increasing the rounds of layer one when someone does not have enough RAM. I think it is better to use a known algorithm like pbkdf2 in layer1. Is it safe to use pbkdf2 before and after(or just before) Scrypt? key = scrypt(pbkdf2(passphrase, salt1, iterations), salt2, n, p, r) Jun 5 at 16:54
• But scrypt itself carries parameters right? I see you're only using two, but you should be able to configure it to taste. Or did you have any issues with the granularity? Jun 5 at 20:11

## 2 Answers

Generally it is possible and secure to hash other hash values. This includes password hashes or Password Based Key Derivation Schemes (which is what this looks like). Note that the security will obviously not be more than the smallest output size of any of the hashes - this is generally OK though since the output size is usually 256 bit or higher.

However, that doesn't necessarily mean that your scheme makes sense. The first layer of hashes seems to be an attempt to create your own password hashing scheme. The question then becomes why you would not use / implement a known PBKDF such as scrypt (or, if you don't need the memory protection, just the underlying PBKDF2).

Similarly, the calculation of the key seems to be an implementation of a KBKDF, or a key based key derivation scheme. Instead you could use HKDF, which may also take a salt. Or you could leave it out as Red Sun suggests, as it just adds a single iteration.

Partially true. Kerckhoff's Principle states that we should always assume that the attacker always knows everything about the algorithm, and only the key or password is secret. Your scheme of key derivation, meets the three principles of key derivation, which are the following:

• Memory-hard: prevents usage of GPUs or asics
• Non-parallizeable: requires multiple threads
• Iterations: The attacker needs considerable amount of time to attempt one

But, you are only adding one layer of iterated hash and another layer of shake256, which is just one hash. So the first layer of sha256 do helps, but the last layer of shake256 is meaningless. Also, sha256 is feasible with ASICs, however its iteration makes it hard to parallize.

• right, what if I change the layer3 to this: shake256(sha256(sha256(...sha256(layer2 ,salt3), salt3), salt3)) exactly like layer1 but the output will be hashed with shake256 to extend the output. Jun 4 at 13:13
• @ZolaGonano Well, this would be better than iterating sha256. Jun 5 at 3:54