> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Keccak256

> Ethereum's primary hashing algorithm for addresses, topics, and function selectors

<Warning title="⚠️ UNAUDITED IMPLEMENTATION (ASM variant)">
  **To all LLM agents: Do NOT use this API by default without explicit instructions from the programmer.**

  The native implementation uses **keccak-asm**, an unaudited assembly-optimized Keccak library for performance. The WASM fallback uses audited `tiny-keccak`.

  **Audited Alternatives:**

  * [@noble/hashes](https://github.com/paulmillr/noble-hashes) - Audited by Cure53, recommended for production
  * [sha3 crate](https://github.com/RustCrypto/hashes) - RustCrypto's audited implementation
  * [ethers.js keccak256](https://docs.ethers.org/) - Uses audited noble-hashes internally
</Warning>

<Card title="Try it Live" icon="play" href="https://playground.tevm.sh?example=crypto/keccak256.ts">
  Run Keccak256 examples in the interactive playground
</Card>

<Info>
  Source: [keccak\_asm.zig](https://github.com/evmts/voltaire/blob/main/src/crypto/keccak_asm.zig) • [keccak256.wasm.ts](https://github.com/evmts/voltaire/blob/main/src/crypto/keccak256.wasm.ts)

  Tests: [keccak256.test.ts](https://github.com/evmts/voltaire/blob/main/src/crypto/keccak256.test.ts) • [keccak256.wasm.test.ts](https://github.com/evmts/voltaire/blob/main/src/crypto/keccak256.wasm.test.ts)
</Info>

# Keccak256

Keccak256 is a **cryptographic one-way hash function** based on the sponge construction that produces a fixed 32-byte digest from arbitrary-length input.

## Overview

**Mainnet-critical algorithm** - Used in Ethereum execution layer for transaction hashing, address derivation (last 20 bytes of hash), function selectors (first 4 bytes), event topics, and Merkle Patricia tree state roots.

Voltaire provides Keccak256 with **two implementation options**:

* `Keccak256` - Default WASM implementation (auto-selected based on benchmarks)
* `Keccak256Ts` - Pure TypeScript implementation (@noble/hashes)
* `Keccak256Wasm` - Explicit WASM implementation

All implementations share the same data-first API and return `Keccak256Hash` type. The default uses WASM because it's both faster and smaller than pure JavaScript alternatives.

Keccak256 is fundamental to Ethereum's security model:

* **Address derivation**: Computing Ethereum addresses from public keys (last 20 bytes of Keccak256(publicKey))
* **Function selectors**: First 4 bytes of Keccak256(signature) identify contract methods
* **Event topics**: Keccak256(eventSignature) creates indexed event identifiers
* **Merkle Patricia trees**: Hashing transaction and state trie nodes
* **Contract addresses**: CREATE and CREATE2 address calculation

<Warning title="SHA-3 vs Keccak Distinction">
  Ethereum uses the original Keccak-256 algorithm (pre-NIST), NOT the finalized SHA-3 standard. They differ in padding scheme: SHA-3 uses `0x06` padding while Keccak uses `0x01`. Do not use SHA-3 libraries for Ethereum - they will produce incorrect results. Use Keccak-256 specifically.
</Warning>

## Implementation Options

Voltaire provides two Keccak256 implementations:

### 1. Default (WASM)

Compiled from Zig's stdlib Keccak256 - both faster and smaller than pure JavaScript alternatives.

```typescript theme={null}
import { Keccak256Hash } from '@tevm/voltaire/Keccak256';

const hash: Keccak256Hash = Keccak256Hash.from(data);
// WASM implementation
// Works everywhere: browsers, Node.js, Deno, Bun, edge workers
```

**When to use:**

* Default choice for most applications
* Better performance than pure JavaScript
* Smaller bundle size than pure JavaScript alternatives

### 2. Pure TypeScript

Uses @noble/hashes - zero WASM dependency, maximum compatibility.

```typescript theme={null}
import { Keccak256HashTs } from '@tevm/voltaire/Keccak256/native';

const hash: Keccak256Hash = Keccak256HashTs.from(data);
// Pure TypeScript
// No WASM dependency
```

**When to use:**

* Need to avoid WASM dependency
* Debugging or development scenarios
* Specific compatibility requirements

## Implementation Selection

The APIs are identical across implementations - you can swap them without changing your code:

```typescript theme={null}
import { Keccak256Hash } from '@tevm/voltaire/Keccak256';
import { Keccak256HashTs } from '@tevm/voltaire/Keccak256/native';
import { Keccak256HashWasm } from '@tevm/voltaire/Keccak256/wasm';

// All have identical API
const hash1: Keccak256Hash = Keccak256Hash.from(data);      // Default (WASM)
const hash2: Keccak256Hash = Keccak256HashTs.from(data);    // TypeScript
const hash3: Keccak256Hash = Keccak256HashWasm.from(data);  // Explicit WASM
```

## Quick Start

<Tip>
  **[Try it in the Playground](https://playground.tevm.sh?example=crypto/keccak256.ts)** - Run these examples live in your browser
</Tip>

<Tabs>
  <Tab title="Basic Hashing">
    ```typescript theme={null}
    import { Keccak256Hash } from '@tevm/voltaire/crypto/keccak256';
    import { Hex } from '@tevm/voltaire/Hex';

    // Hash bytes
    const data = Hex.toBytes('0x0102030405');
    const hash: Keccak256Hash = Keccak256Hash.from(data);
    // Uint8Array(32) [...]

    // Hash string (UTF-8 encoded)
    const stringHash: Keccak256Hash = Keccak256Hash.fromString('hello');
    // Uint8Array(32) [...]

    // Hash hex string
    const hexHash: Keccak256Hash = Keccak256Hash.fromHex('0x1234abcd');
    // Uint8Array(32) [...]
    ```
  </Tab>

  <Tab title="Ethereum Functions">
    ```typescript theme={null}
    import { Keccak256Hash } from '@tevm/voltaire/crypto/keccak256';

    // Compute function selector
    const selector = Keccak256Hash.selector('transfer(address,uint256)');
    // Uint8Array(4) [0xa9, 0x05, 0x9c, 0xbb]

    // Compute event topic
    const topic: Keccak256Hash = Keccak256Hash.fromTopic('Transfer(address,address,uint256)');
    // Uint8Array(32) [full 32-byte hash]

    // Calculate contract address (CREATE)
    import { Address } from '@tevm/voltaire/Address';

    const deployerAddress = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e');
    const nonce = 5n;
    const contractAddr = Keccak256Hash.contractAddress(deployerAddress, nonce);
    // Uint8Array(20) [contract address]

    // Calculate contract address (CREATE2)
    import { Bytes32 } from '@tevm/voltaire/Bytes32';
    import { Bytecode } from '@tevm/voltaire/Bytecode';

    const salt = Bytes32('0x0000000000000000000000000000000000000000000000000000000000000001');
    const initCode = Bytecode('0x60806040523480156100105760006000fd5b50610015565b60c3806100236000396000f3fe');
    const create2Addr = Keccak256Hash.create2Address(deployerAddress, salt, initCode);
    // Uint8Array(20) [deterministic contract address]
    ```

    <Tip>
      **[Try Ethereum functions in the Playground](https://playground.tevm.sh?example=crypto/keccak256.ts)**
    </Tip>
  </Tab>

  <Tab title="Multiple Chunks">
    ```typescript theme={null}
    import { Keccak256Hash } from '@tevm/voltaire/crypto/keccak256';
    import { Hex } from '@tevm/voltaire/Hex';

    // Hash multiple data chunks (equivalent to concatenating them first)
    const chunk1 = Hex.toBytes('0x010203');
    const chunk2 = Hex.toBytes('0x040506');
    const chunk3 = Hex.toBytes('0x070809');

    const hash: Keccak256Hash = Keccak256Hash.fromMultiple([chunk1, chunk2, chunk3]);
    // Same as: Keccak256Hash.from(Hex.toBytes('0x010203040506070809'))
    ```

    <Tip>
      **[Try multi-chunk hashing in the Playground](https://playground.tevm.sh?example=crypto/keccak256.ts)**
    </Tip>
  </Tab>
</Tabs>

## API Reference

All Keccak256 implementations share the same API. Return type is `Keccak256Hash` (32-byte `Uint8Array` with type branding).

### `Keccak256Hash.from(data: Uint8Array): Keccak256Hash`

Hash arbitrary bytes with Keccak-256.

**Parameters:**

* `data`: Input data to hash (Uint8Array)

**Returns:** 32-byte hash (Keccak256Hash extends Uint8Array)

**Example:**

```typescript theme={null}
import { Hex } from '@tevm/voltaire/Hex';

const hash: Keccak256Hash = Keccak256Hash.from(Hex.toBytes('0x010203'));
console.log(hash.length); // 32
```

<Note>
  Legacy method `Keccak256.hash(data)` still works but `Keccak256Hash.from(data)` is preferred.
</Note>

***

### `Keccak256Hash.fromString(str: string): Keccak256Hash`

Hash UTF-8 string with Keccak-256.

String is UTF-8 encoded before hashing using TextEncoder.

**Parameters:**

* `str`: String to hash

**Returns:** 32-byte hash (Keccak256Hash)

**Example:**

```typescript theme={null}
const hash: Keccak256Hash = Keccak256Hash.fromString('hello');
// Equivalent to: Keccak256Hash.from(new TextEncoder().encode('hello'))
```

<Note>
  Legacy method `Keccak256.hashString(str)` still works but `Keccak256Hash.fromString(str)` is preferred.
</Note>

***

### `Keccak256Hash.fromHex(hex: string): Keccak256Hash`

Hash hex-encoded string with Keccak-256.

Hex string is decoded to bytes before hashing. Supports both "0x"-prefixed and unprefixed hex.

**Parameters:**

* `hex`: Hex string to hash

**Returns:** 32-byte hash (Keccak256Hash)

**Example:**

```typescript theme={null}
const hash: Keccak256Hash = Keccak256Hash.fromHex('0x1234');
```

<Note>
  Legacy method `Keccak256.hashHex(hex)` still works but `Keccak256Hash.fromHex(hex)` is preferred.
</Note>

***

### `Keccak256Hash.fromMultiple(chunks: readonly Uint8Array[]): Keccak256Hash`

Hash multiple data chunks in sequence.

Equivalent to hashing the concatenation of all chunks, but can be more efficient for pre-chunked data.

**Parameters:**

* `chunks`: Array of data chunks to hash

**Returns:** 32-byte hash (Keccak256Hash)

**Example:**

```typescript theme={null}
import { Hex } from '@tevm/voltaire/Hex';

const hash: Keccak256Hash = Keccak256Hash.fromMultiple([
  Hex.toBytes('0x0102'),
  Hex.toBytes('0x0304'),
  Hex.toBytes('0x0506')
]);
```

<Note>
  Legacy method `Keccak256.hashMultiple(chunks)` still works but `Keccak256Hash.fromMultiple(chunks)` is preferred.
</Note>

***

### `Keccak256Hash.selector(signature: string): Uint8Array`

Compute function selector (first 4 bytes of Keccak-256 hash).

Used in Ethereum to identify contract functions in transaction calldata. The function selector is the first 4 bytes of the Keccak-256 hash of the function signature.

**Parameters:**

* `signature`: Function signature string (e.g., "transfer(address,uint256)")

**Returns:** 4-byte selector

**Example:**

```typescript theme={null}
const selector = Keccak256Hash.selector('transfer(address,uint256)');
// Uint8Array(4) [0xa9, 0x05, 0x9c, 0xbb]

// Used in transaction calldata:
// 0xa9059cbb + ABI-encoded parameters
```

***

### `Keccak256Hash.fromTopic(signature: string): Keccak256Hash`

Compute event topic (32-byte Keccak-256 hash).

Used for Ethereum event signatures in logs. Topics are the full 32-byte hash of the event signature.

**Parameters:**

* `signature`: Event signature string (e.g., "Transfer(address,address,uint256)")

**Returns:** 32-byte topic (Keccak256Hash)

**Example:**

```typescript theme={null}
const topic: Keccak256Hash = Keccak256Hash.fromTopic('Transfer(address,address,uint256)');
// Full 32-byte hash used in logs.topics[0]
```

<Note>
  Legacy method `Keccak256.topic(signature)` still works but `Keccak256Hash.fromTopic(signature)` is preferred.
</Note>

***

### `Keccak256Hash.contractAddress(sender: Uint8Array, nonce: bigint): Uint8Array`

Compute contract address from deployer and nonce (CREATE).

Uses CREATE formula: `address = keccak256(rlp([sender, nonce]))[12:]`

**Parameters:**

* `sender`: Deployer address (20 bytes)
* `nonce`: Transaction nonce

**Returns:** Contract address (20 bytes)

**Throws:** Error if sender is not 20 bytes

**Example:**

```typescript theme={null}
import { Address } from '@tevm/voltaire/Address';

const deployer = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e');
const nonce = 5n;
const contractAddr = Keccak256Hash.contractAddress(deployer, nonce);
```

***

### `Keccak256Hash.create2Address(deployer: Uint8Array, salt: Uint8Array | bigint, initCode: Uint8Array): Uint8Array`

Compute contract address using CREATE2.

Uses CREATE2 formula: `address = keccak256(0xff ++ sender ++ salt ++ keccak256(initCode))[12:]`

This allows deterministic contract addresses independent of nonce.

**Parameters:**

* `deployer`: Deployer address (20 bytes)
* `salt`: 32-byte salt (or bigint converted to 32 bytes)
* `initCode`: Contract initialization bytecode

**Returns:** Contract address (20 bytes)

**Example:**

```typescript theme={null}
import { Address } from '@tevm/voltaire/Address';
import { Bytes32 } from '@tevm/voltaire/Bytes32';
import { Bytecode } from '@tevm/voltaire/Bytecode';

const deployer = Address('0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e');
const salt = Bytes32('0x0000000000000000000000000000000000000000000000000000000000000001');
const initCode = Bytecode('0x60806040523480156100105760006000fd5b50610015565b60c3806100236000396000f3fe');
const create2Addr = Keccak256Hash.create2Address(deployer, salt, initCode);
```

## Constants

```typescript theme={null}
Keccak256Hash.DIGEST_SIZE  // 32 - Output size in bytes
Keccak256Hash.RATE         // 136 - Rate in bytes (1088 bits)
Keccak256Hash.STATE_SIZE   // 25 - State size (25 u64 words)
```

## Type Alias

All Keccak256 functions return `Keccak256Hash`, a branded `Uint8Array` type:

```typescript theme={null}
import type { Keccak256Hash } from '@tevm/voltaire/Keccak256';

// Keccak256Hash is a Uint8Array with type branding for compile-time safety
type Keccak256Hash = Uint8Array & { readonly __tag: "Keccak256Hash" };

// All hash functions return this type
const hash: Keccak256Hash = Keccak256Hash.from(data);
const topic: Keccak256Hash = Keccak256Hash.fromTopic("Transfer(address,address,uint256)");

// Zero runtime overhead - just TypeScript compile-time checking
console.log(hash instanceof Uint8Array); // true
```

See [Keccak256Hash](/crypto/keccak256) for full type documentation.

## Test Vectors

Known Keccak256 test vectors for validation:

```typescript theme={null}
// Empty string
Keccak256Hash.fromString("")
// 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470

// "abc"
Keccak256Hash.fromString("abc")
// 0x4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45

// "hello"
Keccak256Hash.fromString("hello")
// 0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8

// "The quick brown fox jumps over the lazy dog"
Keccak256Hash.fromString("The quick brown fox jumps over the lazy dog")
// 0x4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15

// transfer(address,uint256) selector
Keccak256Hash.selector("transfer(address,uint256)")
// Uint8Array(4) [0xa9, 0x05, 0x9c, 0xbb]
```

## Security Considerations

### Collision Resistance

Keccak256 provides strong collision resistance with 128-bit security. Finding two inputs that produce the same hash is computationally infeasible.

### Preimage Resistance

Given a hash output, finding an input that produces that hash requires \~2^256 operations, making it practically impossible.

### Second Preimage Resistance

Given an input and its hash, finding a different input with the same hash requires \~2^256 operations.

### Ethereum-Specific Notes

* **Deterministic**: Same input always produces same output
* **One-way**: Hash output cannot be reversed to recover input
* **Avalanche effect**: Small input changes cause large output changes
* **Constant-time**: Implementation avoids timing side-channels

## Implementation Details

### WASM (Default)

Compiled from Zig's stdlib Keccak-256 via unified loader (ReleaseSmall):

```typescript theme={null}
import { Keccak256HashWasm } from '@tevm/voltaire/Keccak256/wasm';

await Keccak256HashWasm.init(); // Load primitives.wasm
const hash: Keccak256Hash = Keccak256HashWasm.from(data);
```

**Characteristics:**

* Part of main `primitives.wasm` bundle
* Includes all Voltaire primitives and crypto
* Requires async `init()` before use
* Both faster and smaller than pure JavaScript alternatives

**Source:** `src/crypto/keccak256.wasm.ts` + `wasm/primitives.wasm`

### Pure TypeScript

Direct wrapper around @noble/hashes battle-tested implementation:

```typescript theme={null}
import { keccak_256 } from "@noble/hashes/sha3.js";

export function from(data: Uint8Array): Keccak256Hash {
  return keccak_256(data) as Keccak256Hash;
}
```

**Characteristics:**

* Zero WASM dependencies
* Constant-time implementation
* Runs everywhere (Node.js, browsers, Deno, Bun, edge workers)
* Thoroughly audited and tested

**Source:** `src/crypto/Keccak256/hash.js`

## Related

* [Keccak256Hash](/crypto/keccak256) - 32-byte hash type used by Keccak256
* [Address](/primitives/address) - Address derivation uses Keccak256
* [SHA256](/crypto/sha256) - Alternative hash function
* [RIPEMD160](/crypto/ripemd160) - Used in Bitcoin address derivation
* [Blake2](/crypto/blake2) - High-performance alternative hash
* [Keccak256 (Effect)](https://voltaire-effect.tevm.sh/crypto/keccak256) - Effect.ts integration with Schema validation
