Ethereum hashes transaction bytes into a 32-byte digest before signing. What happens inside that calculation? Keccak-256 keeps a larger state, folds the input into it a block at a time, and reads only a small part of the result.

We will follow pad the input → absorb a block → mix the state → read the digest. All diagrams share one input: the letters a–z repeated to the selected length. At three bytes, that input is abc. The displayed states and digests are computed from those bytes.

Make room for padding

Keccak-256 processes 136 input bytes per block. Its ending is different from the one in SHA-256 ⁠: it does not append an eight-byte length field.

For a byte-aligned message, append 01, fill the remaining space with zeros, and set the highest bit of the block's final byte. Usually that final byte becomes 80. If just one byte is available, both markers occupy it: 01 | 80 = 81.

Fill 136-byte blocks
Input length3 B
abc
Block 1 · 136 bytes
61626301000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080
Input01 · start00 · fill80 · end
3 input bytes → 136 padded bytes

Compare 135 and 136 input bytes. At 135, 81 finishes the current block. At 136, the input already fills the block, so a whole additional block carries the ending. Even an empty message has one padded block. The colored cells are actual bytes, not a proportional sketch.

These byte values implement a bit-level rule called pad10*1: a starting 1, zero or more 0 bits, then a final 1. Keccak numbers bits within a byte from least significant to most significant, which is why the first marker is 01 rather than SHA-256's 80.

Keep a larger state

The internal state has 1,600 bits, or 200 bytes. Arrange it as a 5×5 grid of lanes, each a 64-bit word. A lane is just eight bytes interpreted as a number; it is not a separate hash.

Two regions have different roles:

RegionSizeDirect input/output
Rate1,088 bits · 136 bytes · 17 lanesReceives input blocks; supplies output bytes
Capacity512 bits · 64 bytes · 8 lanesNo direct input XOR or output extraction

Both regions participate in every permutation. Capacity is not unused space, nor is it a secret key. It is state that the sponge interface does not expose directly.

We label a lane A[x,y]. In the diagrams, x increases to the right and y increases downward. Bytes visit lanes in the order x + 5y, starting with A[0,0]. The first seventeen positions are the rate.

Absorb one block

Start with all 200 state bytes set to zero. XOR the first padded block into the rate, leaving the capacity unchanged at this absorption step. Then run the permutation over the entire state.

For a later block, continue from that permutation's output. Do not reset the state. XOR the next block into the same rate positions and permute again.

Absorb into the state
Input length3 B
Rate · 136 BCapacity · 64 B
25 lanes × 8 bytes · lane 0 = A[0,0]
Incoming state lane0000000000000000
XOR with input lane · little-endian0000000001636261
After absorption · before permutation0000000001636261
↓ Keccak-f[1600] · 24 rounds
Same position after permutation4fa945ea7a65034e

Select a lane to compare its incoming value, input word, and result. At 137 input bytes there are two blocks; selecting the second makes the carried state visible. Capacity lanes receive no input word but can change during the permutation.

Bytes enter each lane least significant first. With abc, the first eight padded bytes are 61 62 63 01 00 00 00 00. As a 64-bit number, that is 0000000001636261. The apparent reversal is byte order, not another hashing operation.

This repeated input-and-mixing process is the absorbing phase of a sponge construction. The rate determines how much input enters per permutation; the capacity remains internal while the two regions mix.

Mix twenty-five lanes

The permutation is Keccak-f[1600]. It keeps the state size fixed and runs 24 rounds. Each round contains five steps, always in the same order:

StepWhat changesWhere information travels
θ · thetaXOR a correction into each laneAcross columns
ρ · rhoRotate bits within each laneBetween bit positions
π · piMove lanes to new coordinatesAcross the grid
χ · chiCombine three lanes with XOR, NOT, ANDAcross rows, nonlinearly
ι · iotaXOR a round constant into A[0,0]Break round symmetry
One round · five steps
Round 0
Input to this step · outlined cells contribute to the selected lane
Selected lane before step0000000001636261
D[0] = 0000000000000001
A[0,0] after θ · Columns0000000001636260

The matrix shows the state entering the selected step. Select a lane to see the complete 64-bit value below it; the matrix previews are shortened so all 25 positions remain visible. The round slider covers rounds 0–23 of the selected block's permutation.

Theta first XORs the five lanes in each column to get a column parity. For column xx, combine the parity to its left with a one-bit rotation of the parity to its right. XOR that correction into every lane in column xx.

C[x]=⨁y=04A[x,y],D[x]=C[x−1]⊕ROTL⁡1(C[x+1])C[x]=\bigoplus_{y=0}^{4} A[x,y],\qquad D[x]=C[x-1]\oplus\operatorname{ROTL}_1(C[x+1]) A′[x,y]=A[x,y]⊕D[x]A'[x,y]=A[x,y]\oplus D[x]

Column indexes wrap modulo five. The outlined columns in the theta view provide the two parities; the selected lane contributes its original value as well.

Rho rotates each lane left by its fixed offset. Pi then moves that rotated lane from (x,y)(x,y) to (y, 2x+3y mod 5)(y,\,2x+3y\bmod5). These operations redistribute existing bits; neither introduces a new message block.

Chi uses the current lane and its next two neighbors in the same row:

A′[x,y]=A[x,y]⊕(¬A[x+1,y]∧A[x+2,y])A'[x,y]=A[x,y]\oplus\bigl(\neg A[x+1,y]\land A[x+2,y]\bigr)

All lanes in this equation come from the state before chi. Updating a lane and immediately using that changed value for its neighbor would compute the wrong function. NOT is restricted to 64 bits.

Iota changes only A[0,0] by XORing a fixed round constant. Round zero uses 0000000000000001. The offsets and constants are public parameters of the algorithm, not keys. The Keccak specification summary lists the complete tables.

Read the digest

After the final padded block has been absorbed and permuted, serialize the rate lanes in the same order used for input. Each lane becomes eight bytes, least significant first.

Keccak-256 needs only 32 output bytes. Those fit inside the 136-byte rate, so take the first four lanes. No extra permutation is needed between the last absorption permutation and this output.

Read the first 32 bytes
Final lane · numeric hex4fa945ea7a65034e
↓ Serialize least-significant byte first
Output bytes · left to right4e 03 65 7a ea 45 a9 4f
Keccak-256 · 32 bytes4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45

The full 200-byte state still exists internally. The digest exposes only its first 32 serialized bytes. The 256 in Keccak-256 describes the output length, not the state size or input-block size.

A general sponge can produce more output by reading the rate, permuting again, and reading another rate-sized portion. That is the squeezing phase. Keccak-256 stops after 32 bytes; an application cannot change its digest length and still call the result Keccak-256.

The permutation itself is reversible if its entire state is known. That does not make the hash reversible: the digest leaves most state bits unobserved, and the original input may have contained many blocks. Seeing a changed input spread across the state illustrates diffusion; it is not by itself a proof of cryptographic security.

Three similar names

Keccak-256 and SHA3-256 use the same state size, rate, capacity, and permutation. For byte-aligned inputs, the distinguishing change is the delimited suffix: Keccak-256 starts the ending with 01; SHA3-256 uses 06. If only one byte remains, their endings become 81 and 86 respectively.

That small input difference passes through the whole permutation and changes the digest. SHA-256 is a different design altogether: 64-byte input blocks, 32-bit words, a message schedule, and compression rounds. Its 32-byte output length does not make it interchangeable with either one.

Same input · three digests
Input length3 B
Keccak-256 · ending starts with 014e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45
SHA3-256 · ending starts with 063a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532
SHA-256 · different constructionba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

At length zero, Keccak-256 begins c5d24601, SHA3-256 begins a7ffc6f8, and SHA-256 begins e3b0c442. These empty-input vectors are a useful first check that a library is using the intended algorithm. The complete values are shown above.

SHA3-256's suffix and sponge parameters are specified in FIPS 202. Ethereum uses Keccak-256, including Solidity's keccak256. Substituting sha3_256 from another library produces the wrong Ethereum digest.

Bytes before the hash

The hash function sees bytes, not the intent behind them. UTF-8 text "0x1234" consists of six bytes; decoding hexadecimal 0x1234 produces two. Hashing those two inputs gives different results even when both callers say they are hashing “0x1234”.

For a transaction ⁠, the protocol defines the serialized bytes to hash. EIP-191 ⁠ adds a message prefix. EIP-712 ⁠ combines a domain hash with a structured-message hash. Those formats decide which bytes enter Keccak-256; the sponge then applies the same calculation.

That separation matters when debugging signatures. First reproduce the exact input bytes, then check the hash algorithm. A correct Keccak implementation cannot compensate for a missing prefix, different field order, or incorrect byte encoding.