Cryptographic test vector 2026-11-05
A cryptographic test vector is a specified collection of algorithm inputs, parameters and expected outputs used to check an implementation. Exact byte encodings are part of the vector: a key displayed in hexadecimal represents bytes, not necessarily the displayed characters. A known-answer test compares a computed result with the supplied answer. RFC 4231 provides such vectors for several HMAC instantiations.[ref]
For its Test Case 1, use a key of twenty bytes each equal to hexadecimal 0b, and the eight ASCII message bytes spelling Hi There. HMAC with SHA-256 must produce
b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7.
The output has 64 hexadecimal digits, hence 32 bytes. The key has twenty bytes; using the forty ASCII characters obtained by writing 0b twenty times supplies a different key. Adding a newline to the message supplies different message bytes too.[ref]
A good vector identifies the complete algorithm variant. An unkeyed SHA-256 digest of that message is not the expected HMAC result, and SHA-512/256 is a different hash operation despite its equal digest length. HKDF additionally needs its salt, initial material, context and requested output length; its primary specification supplies all those fields together with the expected extraction and expansion results.[ref]
Passing a vector establishes agreement for those inputs. It does not prove collision resistance, key secrecy or a cryptographic protocol's security. Nor does one short input exercise every implementation path. Vectors covering long keys, truncation and boundary lengths can reveal mistakes that a single example misses; RFC 4231 includes separate cases for those behaviours.[ref]
A hash initialization vector is the initial internal state from which a specified cryptographic hash function begins processing a message. For the SHA-2 algorithms, it is a public, algorithm-defined sequence of state words. It is not a fresh per-message cryptographic nonce, a secret key or a cryptographic salt.[ref]
For an iterative hash, write the state update schematically as
where is one padded message block and is the algorithm's hash compression function. The digest is derived from the final state by the algorithm's output rule. Initial state, padding, compression and output rule together specify the function; agreeing on only the output width does not specify a hash.
An original comparison uses two specified algorithms. SHA-256 starts with the 32-bit word 6a09e667, while SHA-224 starts with c1059ed8. Both subsequently use the SHA-256-family compression structure, but their full initial states differ. Even the empty message is padded and processed, so its digest is not simply a printed initial state.[ref]
Computing the empty-message digests gives SHA-256
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
and SHA-224
d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f.
Keeping the first 28 bytes of the first result does not produce the second. Initialization acts before every subsequent block transformation; final truncation cannot substitute for it.
This also matters when implementing several hash variants with one compression routine. Resetting a context must restore the chosen variant's complete initial state and length counters. Accidentally reusing a previous message's final state computes a different function. A known-answer test for empty and short messages can expose such state-management mistakes, although passing finitely many vectors does not prove every update sequence correct.