If you have ever written a Solidity smart contract or inspected an Ethereum transaction, you have encountered Keccak256. It is the cryptographic hash function at the heart of Ethereum, used for everything from generating function selectors to verifying data integrity on-chain. This guide explains what Keccak256 is, how it works, and why Ethereum chose it over standard SHA-3.
What is a Cryptographic Hash Function?
Before diving into Keccak256, it helps to understand what a cryptographic hash function does. A hash function takes an input of any size and produces a fixed-size output, called a digest or hash. A good cryptographic hash function has three properties:
- Deterministic: The same input always produces the same output.
- Pre-image resistant: Given a hash, it is computationally infeasible to find the original input.
- Collision resistant: It is extremely difficult to find two different inputs that produce the same hash.
These properties make hash functions essential for digital signatures, data integrity checks, and blockchain systems.
Keccak256: The Hash Behind Ethereum
Keccak256 is a member of the Keccak family of hash functions, designed by Guido Bertoni, Joan Daemen, Michael Peeters, and Gilles Van Assche. In 2012, the Keccak algorithm won the NIST hash function competition and was selected as the basis for the SHA-3 standard.
However, here is where it gets confusing: Ethereum uses Keccak256, not SHA-3 (FIPS 202). When NIST standardized SHA-3, they made a small but significant change to the padding scheme. Keccak256 uses a padding byte of 0x01, while the finalized SHA-3-256 uses 0x06. This means the two functions produce different outputs for the same input.
Keccak256 vs SHA-3-256: The Key Difference
| Property | Keccak256 | SHA-3-256 (FIPS 202) |
|---|---|---|
| Algorithm | Keccak sponge construction | Same algorithm |
| Output size | 256 bits (32 bytes) | 256 bits (32 bytes) |
| Padding byte | 0x01 | 0x06 |
| Used by | Ethereum, Solidity | NIST standard applications |
| Same output? | No | No |
This distinction matters. If you use a standard SHA-3 library to compute what you think is a Keccak256 hash, you will get the wrong result. Always use a library that explicitly implements Keccak256, such as js-sha3 in JavaScript or pysha3 in Python.
Quick Example
Hashing the string "hello" with both functions:
Keccak256("hello") = 0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8
SHA-3-256("hello") = 0x3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392Same input, completely different outputs. This is why the distinction matters. You can verify this yourself using our Keccak256 Hash Generator — paste hello and confirm the hash matches the Keccak256 result above.
How Keccak256 Works Internally
Keccak256 uses a construction called the sponge construction. Unlike traditional Merkle-Damgard hash functions (like SHA-1 and SHA-2), the sponge construction works in two phases:
1. Absorb Phase
The input message is padded and divided into blocks. Each block is XORed into a portion of the internal state, and then the entire state is permuted using a function called Keccak-f.
2. Squeeze Phase
After all input blocks have been absorbed, output blocks are extracted from the state. For Keccak256, only one squeeze iteration is needed because the output size (256 bits) is smaller than the rate.
The State
Keccak operates on a state of 1600 bits, organized as a 5 x 5 x 64 three-dimensional array. The state is divided into two parts:
- Rate (r): 1088 bits — the portion that interacts with input and output
- Capacity (c): 512 bits — the portion that provides security
The security level is determined by the capacity: Keccak256 provides 128-bit security against collision attacks and 256-bit security against pre-image attacks.
State (1600 bits)
├── Rate (1088 bits): absorbs input, produces output
└── Capacity (512 bits): security parameter, never directly exposedHow Ethereum Uses Keccak256
Keccak256 is deeply embedded in Ethereum's architecture. Here are the most important uses:
1. Function Selectors
When you call a function on a smart contract, Ethereum needs a way to identify which function you are calling. It does this by taking the Keccak256 hash of the function signature and using the first 4 bytes as the selector.
// Function signature: "transfer(address,uint256)"
// Keccak256 hash: 0xa9059cbb2ab09eb219583f4a59a5d0623ade346d962bcd4e46b11da047c9049b
// Function selector (first 4 bytes): 0xa9059cbbThis is why when you look at raw transaction data on Etherscan, the first 4 bytes of the input data tell you which function was called. Try it yourself: paste transfer(address,uint256) into our Keccak256 Hash Generator and check the function selector output.
2. Event Topics
Solidity events use Keccak256 to generate topic hashes. The first topic of a logged event is the Keccak256 hash of the event signature.
// Event: Transfer(address indexed from, address indexed to, uint256 value)
// Topic 0: keccak256("Transfer(address,address,uint256)")
// = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef3. Storage Slot Computation
Solidity uses Keccak256 to determine where dynamic data (mappings and dynamic arrays) is stored in contract storage.
// For a mapping: mapping(address => uint256) balances;
// Storage slot for balances[addr] = keccak256(abi.encode(addr, slot_of_balances))4. Address Derivation
Ethereum addresses are derived from public keys using Keccak256. The process takes the last 20 bytes of the Keccak256 hash of the public key.
Public Key (64 bytes) → Keccak256 → Last 20 bytes → Ethereum Address5. EIP-55 Checksum Addresses
The mixed-case checksum encoding of Ethereum addresses (EIP-55) also uses Keccak256. The hash of the lowercase hex address determines which characters should be capitalized.
Keccak256 in Solidity
Solidity provides keccak256() as a built-in function. It is one of the most commonly used functions in smart contract development.
// Hashing a string
bytes32 hash = keccak256(abi.encodePacked("hello"));
// Hashing multiple values (packed encoding)
bytes32 hash = keccak256(abi.encodePacked(addr, amount, nonce));
// Hashing structured data (standard encoding)
bytes32 hash = keccak256(abi.encode(addr, amount));abi.encode vs abi.encodePacked
A common source of bugs is choosing between abi.encode and abi.encodePacked:
- abi.encode: Pads each argument to 32 bytes. Unambiguous. Use for hashing structured data.
- abi.encodePacked: Concatenates arguments without padding. More gas efficient but can cause hash collisions with dynamic types.
// These produce different hashes:
keccak256(abi.encode("ab", "c")) // Different from below
keccak256(abi.encode("a", "bc")) // Different — padded to 32 bytes each
// DANGER: These produce the SAME hash:
keccak256(abi.encodePacked("ab", "c")) // Same as below!
keccak256(abi.encodePacked("a", "bc")) // Same! Both pack to "abc"Warning: This is a well-known vulnerability. When hashing multiple dynamic-length values, use abi.encode to avoid collisions. Learn more in our ABI Encoding guide.
Using Keccak256 in JavaScript
For frontend and Node.js applications, you can compute Keccak256 hashes using the js-sha3 library:
import { keccak256 } from 'js-sha3';
// Hash a UTF-8 string
const hash = '0x' + keccak256('hello');
// 0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8
// Hash hex bytes
const hash = '0x' + keccak256(Buffer.from('48656c6c6f', 'hex'));Or using ethers.js:
import { keccak256, toUtf8Bytes } from 'ethers';
const hash = keccak256(toUtf8Bytes('hello'));Common Use Cases
| Use Case | Input | Output |
|---|---|---|
| Function selector | "transfer(address,uint256)" | First 4 bytes of hash |
| Commit-reveal scheme | keccak256(value, secret) | Commitment hash |
| Merkle tree leaf | keccak256(abi.encode(data)) | Leaf node hash |
| CREATE2 address | keccak256(0xff, deployer, salt, initCodeHash) | Contract address |
| EIP-712 typed data | keccak256(structured_data) | Signing hash |
Security Considerations
Keccak256 is considered cryptographically secure. No practical attacks have been found against the full-round Keccak256. However, there are important implementation considerations:
- Do not use for passwords: Hash functions alone are not suitable for password storage. Use bcrypt, scrypt, or Argon2 instead.
- Beware of hash collisions with encodePacked: As shown above, packing dynamic types can lead to unintended collisions.
- On-chain randomness:
keccak256(block.timestamp, block.prevrandao)is not truly random. Miners and validators can influence these values.
Frequently Asked Questions
Is Keccak256 the same as SHA-3?
No. While Keccak won the SHA-3 competition, NIST modified the padding before standardizing it as SHA-3 (FIPS 202). Ethereum uses the original Keccak256, which produces different hashes than SHA-3-256.
Why did Ethereum choose Keccak256 over SHA-256?
Ethereum was designed before SHA-3 was finalized. The developers chose Keccak256 because it was the competition winner and considered the most secure option. SHA-256 (used by Bitcoin) is from the SHA-2 family, which uses a fundamentally different construction (Merkle-Damgard vs sponge).
Can Keccak256 be reversed?
No. Like all secure cryptographic hash functions, Keccak256 is a one-way function. Given a hash output, it is computationally infeasible to determine the original input. This property is essential for its use in blockchain systems.
How much gas does keccak256 cost in Solidity?
The KECCAK256 opcode costs 30 gas plus 6 gas per 32-byte word of input data. For a 32-byte input, the total cost is 36 gas — making it one of the cheaper operations in the EVM.
Try It Yourself
Ready to compute some Keccak256 hashes? Use our free Keccak256 Hash Generator to hash any text or hex input instantly in your browser.
Related Tools
- Keccak256 Hash Generator — Compute Keccak256 hashes online
- ABI Encoder/Decoder — Encode and decode smart contract function calls
- Checksum Address Converter — Convert Ethereum addresses to EIP-55 checksum format