# Is “Bit Independence” of SHA-2 hashes secure?

I know bit independence is good in SHA2 function output, but is it truly 100% secure? For example:

• Y = SHA512(secretKeyNonce256bit)
• A = first 32ytes / 256bits of Y, used as message encryption key
• B = next 16bytes/128bits used as authentication HMAC key for message
• C = next 16bytes/128bits used as access code. NON-SECRET, and known to message carrier. If user provides this code, he is given the encrypted message by the carrier.

Does having knowledge of C yield some insight into A,B? Would it be better to instead use C2=first 16 bits of SHA256(C) ?

One weakness, which extra SHA does not prevent, is if secretKey were derived from a crummy password [not the case here], C would be valuable to whoever attempted brute-like password guessing, because if a tried password produces C, it is likely that the password is correct & can produce correct A, B. Some people may mention 128bit HMAC is on a weaker side, but I think 128 / 64bit collision resistance is sufficient for my application.

• Is there some concatenation that you're not showing, or do you really have one thing called "secretKeyNonce256bit"? $\;$ – user991 Jun 10 '15 at 13:01
• Ricky: secretKeyNonce256bit = random unique "nonce" 256bit key for each message. – Sean Jun 10 '15 at 15:30

## 1 Answer

There is no known exploitable relationships between the words (32/64 bit "chunks") of SHA-2 but this is always a source of cryptanalysis. There are some academic weaknesses against reduced round variants of SHA-2 but nothing against the full cipher. Still hashes are cheap so why not just use multiple hash functions?

Seed = HASH(secret)  <- This should be a KDF instead see below
A = HASH(Seed)
B = HASH(A)
C = HASH(B)


If you need less bits you can just chop them down (it is good enough for NIST). Here is another option.

> Seed = HASH(secret)  <- This should be a KDF instead see below
> A = HASH(Seed XOR ConstantA)
> B = HASH(Seed XOR ConstantB)
> C = HASH(Seed XOR ConstantC)


Keep the constants the same same length as the output of HASH to avoid a biased result.

## Use a KDF

I am assuming "secretKeyNonce256bit" is really a human generated password. Using a simple unsalted hash to derive a key from a low entropy secret is a bad practice. You say "not the case here" but it is unclear if you mean it is not a password or not a "weak password". If "secretKeyNonce256bit" is a 64 byte random value from a CSPRNG then ignore this but if it is the result of any human selection you really should be using a true KDF (like PBKDF2, Bcrypt or Scrypt).

• Thanks for the answer. secretKeyNonce256bit is indeed from CSPRNG, and used only one time. I saw that MD5 output is not bit-independent, as claimed in: crypto.stackexchange.com/questions/517/… ), and got worried that some weaknesses may exist or be eventually discovered in SHA2 in this area. Interesting alternative about using "seed XOR constants". I think I will use extra hash C2=first 16 bits of SHA256(C) just to guard against any future cryptanalysis of bit-independence. – Sean Jun 10 '15 at 15:44
• Indeed; I'd recommend the seed XOR constant myself. – Joshua Jul 14 '17 at 22:03