For uniterated SHA-256 of salted password, should the password precede the salt? This is a follow-up to this question (thanks to answers from @fgrieu and @kelalaka
) about the format of a salt when hashing a salted password.

I realize this is pretty much academic, as the proposed uniterated SHA-256 of a salted password is already acknowledged to be much less secure than trusted password storage algorithms (scrypt, Argon2, PBKDF2, etc.). And, this may be a very obvious point, but I haven't found anything mentioning it (quite the opposite).

Nevertheless, considering the use of this (ill-advised, but currently available) approach, when concatenating salt &amp; password, if the salt precedes the password, wouldn't that allow an attacker to optimize away the salt when doing a dictionary or brute force attack, and speed up the results?

Here's my thought:  A SHA-256 hash is a left-to-right processing of the source data. While processing the data, the SHA-256 code could be modified to take a snapshot of the intermediate algorithmic values (variables) as the salt is being processed, but just before the first password character is read. This would be done once to collect the values. Then a further modification of the SHA-256 code, which allowed the hash for each try to begin with the intermediate values previously stored. This would allow only the characters of the test passwords to be processed on each try, eliminating the overhead of processing the (presumably 256-bit) salt, but still providing the correct SHA-256 result.

Again, assuming no iterations, and no nested hashing, wouldn't it be better for the password to precede the salt, so that the attacker had to process the salt data to obtain the correct SHA-256 value for every try?
We are considering two hypothetical password hashes


$(S_i,P_i)\mapsto H_i=\operatorname{SHA-256}(S_i\mathbin\|P_i)$
$(S_i,P_i)\mapsto H_i=\operatorname{SHA-256}(P_i\mathbin\|S_i)$


As pointed in the question, both are un-iterated, thus very weak under the attack model where the salt $S_i$ and hashes $H_i$ leak, and the adversary is after $P_i$ (for a particular $i$, or worse for one of any $i$).

An important thing is what we put in the salt $S_i$: that should include both a fixed string $F$ dependent on the instantiation (e.g the name of the server), and a user-unique string (e.g. userid, login, email, random) $U_i$. The term $U_i$ helps because with $U_i$ adversaries can not attack multiple logins simultaneously, they must perform a hash for each password tested for each login. The term $F$ prevents amortizing attack work across multiple servers, and makes the hash slower, thus more secure.

The least feeble option is probably $H_i=\operatorname{SHA-256}(P_i\mathbin\|U_i\mathbin\|F)$, with $F$ as large as possible. The password should be first for the reason in the question: that blocks optimizations where some of the hash's internal operations is reused across multiple $P_i$. For the same reason, $U_i$ should be second.

But when $P_i\mathbin\|U_i\mathbin\|F$ is short (less than 64 bytes), the order is nearly immaterial, because that fits in the same first padded block of message of SHA-256, thus an attacker can not precompute any full compression in SHA-256, at worse some of very few rounds among 64.

Thus if for some strange reason (like a device operated on small battery and very little RAM) one can't go for an iterated password hash and must use plain SHA-256, then put the constant part $F$ of the salt last, and make it as long as practical; and rather put the password before the salt.

As an aside, if a long $F$ is obtained by repeating a shorter string (which allows arbitrary long $F$ with only little RAM), it should have an odd length, in order to reduce the potential for optimization of the message expansion of SHA-256.



P.S. per comment: While the $U_i$ part of the salt must be in the database, $F$ needs not, at least in each entry, especially if it is long. I have been assuming that $F$ is public, not "pepper" (that is, semi-secret). If there is some pepper $K$ (that is, a tentatively secret key, by opposition to salt that is assumed fully public), it should be early in the hashed data, in contact with $P_i$ or otherwise in the first 64 bytes; and backed up other than in the database in case the whole thing needs to be restored on a different machine.