Skip to main content
This page is a placeholder. All examples on this page are currently AI-generated and are not correct. This documentation will be completed in the future with accurate, tested examples.

Overview

Address: 0x0000000000000000000000000000000000000003 Introduced: Frontier The RIPEMD160 precompile implements the RIPEMD-160 cryptographic hash function, producing a 20-byte hash of arbitrary input data. RIPEMD-160 is used in Bitcoin for generating addresses from public keys. This precompile enables Ethereum contracts to verify Bitcoin addresses, validate Bitcoin-style address generation, and interact with systems using RIPEMD-160.

Gas Cost

Formula: 600 + 120 * ceil(input_length / 32)
  • Base cost: 600 gas
  • Per-word cost: 120 gas per 32-byte word
  • Partial words round up
Examples:
  • 0 bytes: 600 gas
  • 32 bytes: 720 gas (600 + 120*1)
  • 33 bytes: 840 gas (600 + 120*2)
  • 64 bytes: 840 gas (600 + 120*2)

Input Format

Accepts arbitrary-length byte array. No restrictions on input size.

Output Format

Offset | Length | Description
-------|--------|-------------
0      | 12     | Zero padding (left-padded to 32 bytes)
12     | 20     | RIPEMD-160 hash of input
Total output length: 32 bytes (20-byte hash + 12 bytes padding) The hash is right-aligned in a 32-byte word with 12 leading zero bytes.

Usage Example

import { execute, PrecompileAddress } from '@tevm/voltaire/precompiles';
import { Hardfork } from '@tevm/voltaire/primitives/Hardfork';

// Hash some data
const input = new TextEncoder().encode("Hello, Bitcoin!");

// Calculate required gas
const words = Math.ceil(input.length / 32);
const gasNeeded = 600n + 120n * BigInt(words);

// Execute precompile
const result = execute(
  PrecompileAddress.RIPEMD160,
  input,
  gasNeeded,
  Hardfork.CANCUN
);

if (result.success) {
  // Extract 20-byte hash from right side
  const hash = result.output.slice(12, 32);
  console.log('RIPEMD-160 hash:', hash);
  console.log('Gas used:', result.gasUsed);
} else {
  console.error('Error:', result.error);
}

Error Conditions

  • Out of gas (insufficient for 600 + 120 * ceil(len/32))

Use Cases

  • Bitcoin address generation: Generate Bitcoin P2PKH addresses from public keys
  • Bitcoin integration: Verify Bitcoin address ownership in Ethereum contracts
  • Cross-chain bridges: Validate Bitcoin-style addresses
  • Legacy cryptography: Interface with systems using RIPEMD-160

Implementation Details

  • Zig: Uses RIPEMD-160 implementation from crypto module, left-pads output to 32 bytes
  • TypeScript: Wraps Ripemd160.hash from crypto module, applies padding
  • Integration: Standalone, no dependencies on other primitives
  • Output format: Right-aligned 20-byte hash in 32-byte word

Bitcoin Address Generation

Bitcoin P2PKH addresses use RIPEMD-160:
// Bitcoin address generation:
// 1. SHA-256 hash of public key
const sha256Hash = executeSHA256(publicKey);

// 2. RIPEMD-160 hash of SHA-256 hash
const ripemd160Hash = executeRIPEMD160(sha256Hash.output);

// 3. Add version byte (0x00 for mainnet)
// 4. Double SHA-256 for checksum
// 5. Base58 encode

Performance Considerations

RIPEMD-160 is the most expensive hash precompile (600 base gas vs 60 for SHA256, 30 for Keccak256). The high cost reflects its computational complexity and relatively rare usage. Gas costs favor larger inputs:
  • Per-byte cost: ~3.75 gas/byte
  • 10x more expensive than SHA-256 per byte
Use SHA-256 or Keccak256 for general-purpose hashing when RIPEMD-160 compatibility is not required.

Test Vectors

import * as Hex from '@tevm/voltaire/Hex';
import { Bytes32 } from '@tevm/voltaire/primitives/Bytes32';

// Test 1: Empty input
const input1 = new Uint8Array(0);
// Expected: 9c1185a5c5e9fc54612808977ee8f548b2258d31 (20 bytes, padded to 32)
const expected1 = Bytes32('0x0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31');

// Test 2: Small input
const input2 = Hex('0x0102030405');
// Gas: 600 + 120 * ceil(5/32) = 600 + 120*1 = 720
// Output: 32 bytes (12 zero padding + 20 hash bytes)

// Test 3: Exact 32-byte boundary
const input3 = Hex('0x' + '00'.repeat(32));
// Gas: 600 + 120 * 1 = 720

References

Specifications