I came across a SHA-256 implementation that seems not to conform to the standard and because I can't change the implementation I would like to know if it's safe for use or can be a potential weakness.

For the last 32 byte block instead of performing this: (As copied from wikipedia)

Add the compressed chunk to the current hash value:
h0 := h0 + a
h1 := h1 + b
h2 := h2 + c
h3 := h3 + d
h4 := h4 + e
h5 := h5 + f
h6 := h6 + g
h7 := h7 + h

It overwrites the current hash value:

h0 := a
h1 := b
h2 := c
h3 := d
h4 := e
h5 := f
h6 := g
h7 := h

Aside from this difference, the implementation in question is equivalent to the pseudo code in wikipedia. It does not produce equivalent output to a correct implementation of SHA-256.

  • $\begingroup$ The "came across a SHA-256 implementation" part of the question is hard to swallow. But whatever, that falls into the more general case of what's considered there. $\endgroup$
    – fgrieu
    Commented Jul 1, 2018 at 14:02
  • $\begingroup$ If you hash something longer than 1 block with a normal implementation and something with this implementation, do they return the same result? $\endgroup$
    – Ella Rose
    Commented Jul 1, 2018 at 14:40
  • $\begingroup$ They don't return the same result $\endgroup$
    – Gu1234
    Commented Jul 1, 2018 at 14:46
  • 2
    $\begingroup$ If the implementation does not produce the correct results it is a failed implementation, don't use and report it. $\endgroup$
    – zaph
    Commented Jul 1, 2018 at 15:45
  • 1
    $\begingroup$ with just those changes in my code, I cannot replicate your examples, therefore there must be other changes $\endgroup$ Commented Jul 2, 2018 at 10:44

4 Answers 4


Quoting zaph from the comments:

If the implementation does not produce the correct results it is a failed implementation, don't use and report it.

This is pretty much the correct course of action, assuming that the algorithm is supposed to be SHA-256.

Cryptanalysis of the incorrectly implemented algorithm would be non-productive, unless your goal is to maliciously exploit the protocol that is using this hash function.


It is possible that the author was attempting to be clever or obscure and made such a modification intentionally. There may not be much you will be able to do to help the situation if that is the case; Even if you present collisions/preimages, you may simply garner hostility from the author/users (see the drama around IOTA for an example).


One obvious weakness that this SHA-256 varient would have would be an increased weakness to preimage attacks. As far as we know, finding a preimage with standard SHA-256 takes an expected $O(2^{256})$ operations; however with this version, that reduces to $O(2^{128})$. This occurs because the last block processing is invertible, and so the attacker can perform a meet-in-the-middle attack at next-to-last state.

Of course, $O(2^{128})$ effort is still infeasible, however it is still far less than what we get from standard SHA-256.


You're not showing the full code, or even telling what the implementation in question is, so we can't know if it's just a quirk of the implementation. But changing the algorithm would change the outputs, which should be immediately obvious if the program is supposed to be interoperable with anything else that uses SHA-256. That should cause problems even before someone considers doing an actual attack on the hash.

If the program is something that will only ever be used with itself and uses a broken hash, then it's just insecure. If they haven't bothered to use a correct implementation of SHA-256, they'll probably have made other implementation mistakes, too.

  • 2
    $\begingroup$ I used snippets from wikipedia because the implementation is compatible with the pseudo code in wikipedia except for the difference I described. If it's indeed a weakness I prefer telling the writer about the problem before I expose it. The implementation does produce different digest and therefore not compatible with SHA-256. $\endgroup$
    – Gu1234
    Commented Jul 1, 2018 at 12:10

SHA256 expects the data you are hashing to be in 512 bit sized blocks, with padding added to the end of the message if needed to fit the block size. If the length of the message you are hashing, including padding, is not equally divisible by 512 then the hash result has an undefined behavior based on the implementation of sha256. The calling software is expected to handle the padding of the message always.

In practice though you will generally see that digests taken of irregularly sized blocks tend to produce the same result in software, because the sha256 objects are created on the heap and typically destroyed after operating on a single piece of data. So the state machine is reset by the destructor in that case.

Otherwise if a sha256 object is instantiated and kept in scope while performing hashes on unpredictable data, meaning it isn't always the same exact data being hashed in a row, then you will start to see it become corrupted usually as the output shows up as some constraint in the program being broken or the program crashing.

  • 4
    $\begingroup$ The question asks about a particular faulty implementation of SHA-256, and you're answering it from an un-related programming aspect. $\endgroup$
    – DannyNiu
    Commented Nov 27, 2022 at 4:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.