Today you confirm a longer, two-block message against its official digest through the public API, then meet length extension - a real property of the Merkle-Damgard design that explains why a raw hash is not a message authentication code.
Hash a two-block message end to end and match the published digest.
This 56-byte message is a published NIST test vector chosen precisely because it
crosses a block boundary: as you saw in lesson 11, 56 bytes forces padding into a
second block, so hashing it end to end exercises the full chaining path -
Compress running twice with the state threaded between. Matching its digest,
248d6a61...19db06c1, confirms your whole pipeline works on real multi-block
input, not just the single-block “abc”.
The chaining that makes this work also has a famous consequence worth understanding:
length extension. Because the digest is the internal hash state after the last
block, anyone who knows Sum256(message) and the message’s length can keep hashing
from that state, computing Sum256(message || padding || extra) without knowing
the original message. That is why you must never authenticate a message by hashing
a secret key in front of it (Sum256(key || message)) - an attacker can extend it.
The correct fix is HMAC, a keyed construction built on top of the hash, which is
exactly what the next lesson builds.
msg := []byte("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")want := "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"// Hex(msg) == want