Skip to content

SHA-256 Explained: How the SHA-2 Compression Function Works

A deep dive into SHA-256: the SHA-2 compression function, 64 rounds, message schedule, Ch/Maj/Σ functions, padding, and why SHA-256 remains secure in 2026.

Published on 9 min read

SHA-256 is the workhorse of modern cryptography. It anchors TLS certificates, signs Git commits, validates package checksums, and secures the Bitcoin blockchain. Yet most engineers treat it as an opaque box that turns bytes into a 64-character hex string. This article opens that box. We will walk through the SHA-2 design, the padding rules, the message schedule, and the 64-round compression function that does the real work, then explain why SHA-256 is still a safe default in 2026.

If you want the broader picture of what a cryptographic hash is and why it matters, start with our pillar guide on how hashing works, then come back here for the SHA-256 internals.

Where SHA-2 Came From

SHA-256 belongs to the SHA-2 family, designed by the NSA and published by NIST in 2001 as part of FIPS 180-2. It was introduced to replace SHA-1, whose 160-bit output and weakening collision resistance were already a concern. SHA-2 is not a single algorithm but a set of related functions sharing one structural skeleton: SHA-224, SHA-256, SHA-384, SHA-512, and the later additions SHA-512/224 and SHA-512/256.

All of them are built on the Merkle–Damgård construction: the message is padded, split into fixed-size blocks, and fed sequentially through a compression function that mixes each block into a running internal state called the chaining value. The final chaining value is the digest. This is the same high-level shape used by MD5 and SHA-1 (see SHA-1 explained), which is why all three share a particular structural weakness we will return to: length extension.

The Numbers That Define SHA-256

SHA-256 operates on these fixed parameters:

  • 256-bit output — a 32-byte digest, usually shown as 64 hex characters.
  • 512-bit message blocks — the input is processed 64 bytes at a time.
  • 32-bit words — all arithmetic is on 32-bit unsigned integers, modulo 2³².
  • Eight working variables, labeled a through h, each 32 bits, forming the 256-bit state.
  • 64 rounds in the compression function.

The eight working variables are initialized from a fixed 256-bit initial hash value (often called the IV). For SHA-256, these eight constants are derived from the fractional parts of the square roots of the first eight prime numbers (2, 3, 5, 7, 11, 13, 17, 19). Taking a fraction of an irrational number and reading off its leading bits is a classic "nothing-up-my-sleeve" technique: it produces values that look random but are publicly verifiable, so no one can suspect a hidden backdoor baked into a chosen constant.

The Round Constants

The compression function uses 64 round constants, one per round, conventionally written as the array K[0..63]. These are generated the same way as the IV but from a different source: the fractional parts of the cube roots of the first 64 prime numbers. Again, the point is transparency. Anyone can recompute them from a definition that predates the algorithm, which is why SHA-2 constants are trusted in a way that arbitrary magic numbers would not be.

I will not reproduce the exact hex here to avoid transcription errors; the authoritative values live in FIPS 180-4. What matters conceptually is their origin (cube roots of small primes) and their role (injecting round-dependent, non-symmetric values so each of the 64 rounds behaves differently).

Padding the Message

Before any block is processed, the input is padded so its total length is a multiple of 512 bits. The scheme is deterministic and reversible:

  1. Append a single 1 bit.
  2. Append 0 bits until the length is congruent to 448 modulo 512.
  3. Append the original message length, in bits, as a 64-bit big-endian integer.

That trailing length field is what fills the final 64 bits of the last block (448 + 64 = 512). Encoding the length prevents trivial collisions between messages that would otherwise pad to the same block boundary. Because the maximum encodable length is 2⁶⁴ − 1 bits, SHA-256 has a theoretical input cap, far beyond any practical message.

Expanding the Block: The Message Schedule

Each 512-bit block is first parsed into sixteen 32-bit words, W[0] through W[15]. The compression function needs one word per round — 64 of them — so the schedule expands those 16 words into 64.

The expansion uses two helper functions, lowercase σ0 and σ1 (sigma), each combining bitwise rotations and a logical shift:

σ0(x) = ROTR(x, 7)  XOR ROTR(x, 18) XOR SHR(x, 3)
σ1(x) = ROTR(x, 17) XOR ROTR(x, 19) XOR SHR(x, 10)

for t from 16 to 63:
    W[t] = σ1(W[t-2]) + W[t-7] + σ0(W[t-15]) + W[t-16]   (mod 2^32)

ROTR is a circular right rotation; SHR is a plain right shift that discards bits. The combination of rotations and shifts diffuses each input bit across many schedule words, so a single flipped input bit ripples through dozens of rounds — the avalanche effect in action.

The 64-Round Compression Function

Now the core. The eight working variables a..h are initialized from the current chaining value (the IV for the first block, or the previous block's output otherwise). The compression function then runs 64 rounds, each updating the state using the round's schedule word W[t] and constant K[t].

Two more pairs of helper functions appear here. The uppercase Σ0 and Σ1 (used on the working variables, with different rotation amounts than the lowercase σ), and the two nonlinear mixers Ch (choose) and Maj (majority):

Σ0(x) = ROTR(x, 2)  XOR ROTR(x, 13) XOR ROTR(x, 22)
Σ1(x) = ROTR(x, 6)  XOR ROTR(x, 11) XOR ROTR(x, 25)

Ch(e, f, g)  = (e AND f) XOR ((NOT e) AND g)
Maj(a, b, c) = (a AND b) XOR (a AND c) XOR (b AND c)

Ch uses e as a selector: for each bit, it picks the corresponding bit of f where e is 1 and of g where e is 0. Maj outputs the majority bit among a, b, c. Both are nonlinear, which is essential — a purely linear function would be trivially invertible.

Each round computes two 32-bit temporaries, T1 and T2, then shifts the eight variables down like a pipeline:

for t from 0 to 63:
    T1 = h + Σ1(e) + Ch(e, f, g) + K[t] + W[t]   (mod 2^32)
    T2 = Σ0(a) + Maj(a, b, c)                     (mod 2^32)
    h = g
    g = f
    f = e
    e = d + T1                                    (mod 2^32)
    d = c
    c = b
    b = a
    a = T1 + T2                                   (mod 2^32)

Notice the asymmetry: T1 folds in the message schedule, the round constant, and the Ch/Σ1 mixing of the "lower" half of the state, while T2 mixes only the "upper" half via Maj/Σ0. After 64 such rounds, every output bit depends on every input bit through a deep, nonlinear, well-diffused tangle.

Feeding Forward: The Davies–Meyer Step

After the 64 rounds finish, the algorithm does not simply output a..h. It adds them back, word by word and modulo 2³², into the chaining value that existed before the block was processed:

H[0] = H[0] + a
H[1] = H[1] + b
...
H[7] = H[7] + h

This final addition is the Davies–Meyer feed-forward. Feeding the pre-block state back into the post-round state is what turns an invertible block-cipher-like permutation into a one-way compression function. Without it, an attacker who knew the output could run the rounds backwards to recover the input. With it, inversion would require solving for a fixed point, which is believed to be infeasible. The concatenated final H[0..7] is the 256-bit digest.

The SHA-512 Family and Truncated Variants

SHA-512 shares the exact same structure but scales every dimension up:

  • 64-bit words instead of 32-bit.
  • 1024-bit blocks instead of 512-bit.
  • 80 rounds instead of 64.
  • A different IV (square roots of primes, read to 64 bits) and 80 round constants (cube roots of primes, to 64 bits).
  • Different rotation amounts inside the σ and Σ functions, tuned for 64-bit words.

The truncated variants are derived from these two engines:

  • SHA-224 runs the SHA-256 engine with a different IV and outputs only the first 224 bits.
  • SHA-384 runs the SHA-512 engine with a different IV, truncated to 384 bits.
  • SHA-512/224 and SHA-512/256 also use the SHA-512 engine with distinct IVs, truncated to 224 and 256 bits respectively.

A practical note: on 64-bit CPUs, SHA-512 (and thus SHA-512/256) often runs faster than SHA-256, because it processes more data per round on the native 64-bit registers — though dedicated SHA-256 hardware instructions (Intel/ARM SHA extensions) flip that balance back on supported chips.

Security Status in 2026

As of 2026, SHA-256 has no practical collision or preimage attacks. The best published collision results reach only a small number of reduced rounds, far short of the full 64. Brute-force collision resistance sits at roughly 2¹²⁸ operations (the birthday bound for a 256-bit output) and preimage resistance at roughly 2²⁵⁶ — both comfortably out of reach. SHA-2's safety margin has only grown more reassuring as it has withstood two decades of cryptanalysis. This is a sharp contrast with SHA-1, where real-world collisions exist, and MD5, which is thoroughly broken; for a side-by-side comparison see MD5 vs SHA-256 vs SHA-3.

The Length-Extension Caveat

There is one structural property worth understanding. Because SHA-256 is a Merkle–Damgård hash that outputs its full internal state, it is vulnerable to length-extension attacks. If an attacker knows SHA256(secret || message) and the length of the input, they can resume the hash from that digest and compute SHA256(secret || message || padding || extra) for attacker-chosen extrawithout knowing the secret. The published digest is, in effect, a saved chaining value an attacker can continue from.

This breaks naive hash(secret || message) authentication schemes. The standard fix is HMAC, which nests two hash calls with a keyed inner and outer pass so the attacker never sees a directly resumable state. If you build any kind of message authentication, use HMAC-SHA-256 rather than concatenating a secret yourself — read our HMAC explained guide for the construction.

Notably, the truncated variants SHA-512/256 and SHA-384 are immune to length extension, because they discard part of the final state — the attacker can no longer reconstruct the full chaining value needed to continue. SHA-3 (Keccak), which uses a sponge construction instead of Merkle–Damgård, is also length-extension resistant by design; see SHA-3 / Keccak explained.

Try It Yourself

Want to see padding, the message schedule, and the compression rounds turn input into a digest? You can generate a SHA-256 hash in your browser with our tool. It runs entirely client-side — the implementation is compiled from Rust to WebAssembly, so nothing you type is ever uploaded to a server. It is a fast way to confirm checksums or experiment with how a single changed character avalanches across the whole output.

Conclusion

SHA-256 earns its place as a default through careful, transparent design: nothing-up-my-sleeve constants from the roots of small primes, a 64-round compression function built on the nonlinear Ch and Maj mixers, deep diffusion via the σ/Σ rotations and the message schedule, and a Davies–Meyer feed-forward that makes the whole thing one-way. Its only notable quirk — length extension — is well understood and cleanly solved by HMAC or by choosing SHA-512/256.

For general-purpose hashing in 2026, SHA-256 remains the secure, well-supported choice. To see it work on your own input, generate a SHA-256 hash in your browser — privately, with nothing leaving your machine.

Related articles

A deep, developer-focused guide to how cryptographic hash functions work — properties, Merkle–Damgård vs sponge constructions, the birthday bound, and where each family fits.
MD5 vs SHA-256 vs SHA-3 compared — output size, internal construction, speed, security status, and a clear decision guide for integrity, security, and password use cases.
How SHA-3 works: the Keccak sponge construction, the 1600-bit state, the θ ρ π χ ι permutation, rate vs capacity, SHAKE XOFs, and how it differs from SHA-2.