Skip to main content

Overview

The Keccak-256 inline provides an optimized implementation of the Keccak hash function (also known as SHA-3) with 256-bit output. It’s commonly used in Ethereum and other blockchain applications.

API Reference

Keccak256

Main hasher struct supporting both streaming and one-shot hashing.
pub struct Keccak256 {
    // Internal state - users don't need to access directly
}

Methods

new() -> Self
Creates a new Keccak-256 hasher.
let mut hasher = Keccak256::new();
update(&mut self, input: &[u8])
Writes data to the hasher incrementally.
let mut hasher = Keccak256::new();
hasher.update(b"hello ");
hasher.update(b"world");
finalize(self) -> [u8; 32]
Finalizes the hash and returns the 32-byte digest.
let hash = hasher.finalize();
digest(input: &[u8]) -> [u8; 32]
Computes Keccak-256 hash in one call. Optimized for performance.
let hash = Keccak256::digest(b"hello world");

Usage Examples

Ethereum Address Generation

use keccak256_inline::Keccak256;

#[jolt::provable]
fn compute_ethereum_address(public_key: &[u8; 64]) -> [u8; 20] {
    let hash = Keccak256::digest(public_key);
    let mut address = [0u8; 20];
    address.copy_from_slice(&hash[12..32]);
    address
}

Merkle Tree Hashing

use keccak256_inline::Keccak256;

#[jolt::provable]
fn hash_pair(left: [u8; 32], right: [u8; 32]) -> [u8; 32] {
    let mut hasher = Keccak256::new();
    hasher.update(&left);
    hasher.update(&right);
    hasher.finalize()
}

Streaming Large Data

use keccak256_inline::Keccak256;

#[jolt::provable]
fn hash_transaction(tx_data: &[&[u8]]) -> [u8; 32] {
    let mut hasher = Keccak256::new();
    for field in tx_data {
        hasher.update(field);
    }
    hasher.finalize()
}

Implementation Details

Keccak-f[1600] Permutation

The core operation is the Keccak-f[1600] permutation function, which operates on a 1600-bit state (25 × 64-bit words). The inline uses a single custom instruction:
  • KECCAK_F (funct3=0x00, funct7=0x01): Performs the full 24-round Keccak-f[1600] permutation

Memory Layout

  • State: 200 bytes (25 × 64-bit words)
  • Rate: 136 bytes (absorption rate for Keccak-256)
  • Capacity: 64 bytes (security parameter)
  • Output: 32 bytes

Sponge Construction

Keccak uses the sponge construction:
  1. Absorb phase: XOR input into state, permute
  2. Squeeze phase: Extract output from state
For Keccak-256:
  • Rate = 136 bytes (1088 bits)
  • Capacity = 64 bytes (512 bits)
  • Security level = 256 bits

Padding

Keccak uses the following padding scheme:
padding = 0x01 || 0x00...00 || 0x80
  • First byte after message: 0x01
  • Last byte of block: 0x80
  • If they overlap (single-byte padding): 0x81

Alignment Optimization

The digest() function includes alignment-aware optimizations:
let is_aligned = input.as_ptr() as usize % 8 == 0;
if is_aligned {
    absorb_aligned(&mut state, block);
} else {
    absorb_unaligned(&mut state, block);
}
This provides optimal performance regardless of input buffer alignment.

Performance Characteristics

  • Block size: 136 bytes per permutation
  • Optimization: Aligned memory access when possible
  • Zero-copy: Direct state manipulation without intermediate buffers

Type Definitions

pub const NUM_LANES: usize = 25;
pub type Keccak256State = [u64; NUM_LANES];

Feature Flags

  • host: Enables reference implementation for host-side execution
    • Guest code: Compile WITHOUT this feature
    • Prover code: Compile WITH this feature

Constants

pub const INLINE_OPCODE: u32 = 0x0B;
pub const KECCAK256_FUNCT3: u32 = 0x00;
pub const KECCAK256_FUNCT7: u32 = 0x01;
pub const KECCAK256_NAME: &str = "KECCAK256_INLINE";

Comparison with Standard Implementation

When compared to the Rust sha3 crate:
  • Cycle count: ~10-100x reduction in VM cycles
  • Proving time: Proportionally faster proof generation
  • Compatibility: Identical output to sha3::Keccak256

Safety Considerations

The implementation uses unsafe for:
  • Inline assembly for the Keccak-f permutation instruction
  • Raw pointer operations for zero-copy state access
  • Endianness conversions on big-endian platforms
All unsafe code is encapsulated within safe APIs and thoroughly tested.

Source Code Location

jolt-inlines/keccak256/
├── src/
│   ├── lib.rs          # Module definitions and constants
│   ├── sdk.rs          # Public API (Keccak256 struct)
│   ├── exec.rs         # Host-side reference implementation
│   └── sequence_builder.rs  # Instruction sequence generation
└── Cargo.toml

See Also

  • SHA-256 - Alternative hash function (SHA-2 family)
  • BLAKE2 - BLAKE2b hash function
  • BLAKE3 - BLAKE3 hash function
  • Inlines Overview - General information about cryptographic inlines

Build docs developers (and LLMs) love