Source: ripemd160.zig • ripemd160.wasm.tsTests: ripemd160.test.ts
Try it Live
Run RIPEMD160 examples in the interactive playground
RIPEMD160
RIPEMD160 is a cryptographic one-way hash function producing a 20-byte digest, designed as an alternative to SHA-1.Ethereum Context
Mainnet algorithm - Available as EVM precompile at address 0x03 for Bitcoin address compatibility. Rarely used in practice but required for Bitcoin-Ethereum bridges.Overview
RIPEMD160 (RACE Integrity Primitives Evaluation Message Digest 160-bit) is a cryptographic hash function that produces a 20-byte (160-bit) digest from arbitrary-length input data. Developed in 1996 as an alternative to MD5 and SHA-1, RIPEMD160 is part of the RIPEMD family designed by the COSIC research group. While largely superseded by SHA-256 and SHA-3 for general cryptography, RIPEMD160 remains important in blockchain technology:- Bitcoin addresses: Combined with SHA256 for address generation (Base58Check encoding)
- Ethereum precompile: Address 0x03 for Bitcoin-Ethereum interoperability
- Address derivation: Creates shorter address representations (20 bytes vs 32 bytes)
- Legacy compatibility: Maintained for Bitcoin protocol compatibility
Implementations
- Pure Zig: Custom RIPEMD160 implementation following Bitcoin Core reference
- WARNING: Zig implementation is UNAUDITED custom crypto code
- Uses constant-time operations to resist timing attacks
- TypeScript: Uses @noble/hashes legacy module for JavaScript environments
- WASM: Available via ripemd160.wasm.ts for browser environments
- C FFI fallback: For platforms without native Zig support
Quick Start
- Basic Hashing
- Bitcoin Address
API Reference
RIPEMD160.hash(data: Uint8Array | string): Uint8Array
Compute RIPEMD160 hash of byte array or string.
Accepts both Uint8Array and string inputs. Strings are UTF-8 encoded before hashing.
Parameters:
data: Input data to hash (Uint8Array or string)
Uint8Array - 20-byte hash
Example:
RIPEMD160.hashString(str: string): Uint8Array
Compute RIPEMD160 hash of UTF-8 string.
Parameters:
str: Input string
Uint8Array - 20-byte hash
Example:
RIPEMD160.hashHex(hex: string): Uint8Array
Compute RIPEMD160 hash of hex string.
Parameters:
hex: Hex string (with or without 0x prefix)
Uint8Array - 20-byte hash
Example:
RIPEMD160.from(input: Uint8Array | string): Uint8Array
Constructor pattern - auto-detects input type and hashes accordingly.
Parameters:
input: Data to hash (Uint8Array or string)
Uint8Array - 20-byte hash
Example:
Type Definition
Constants
Test Vectors
Official RIPEMD160 test vectors:Security Considerations
Collision Resistance
RIPEMD160 provides ~80-bit security against collision attacks due to its 160-bit output size. This is considered adequate for Bitcoin addresses where collision resistance prevents address conflicts.Preimage Resistance
Finding a specific input that produces a given RIPEMD160 hash requires ~2^160 operations, which remains computationally infeasible.Birthday Paradox
The 160-bit output means collisions become probable after ~2^80 random inputs (birthday bound). This is acceptable for address generation where inputs are not randomly chosen, but insufficient for applications requiring strong collision resistance.Bitcoin Context
In Bitcoin, RIPEMD160 is never used alone for security-critical operations:- Always combined with SHA256 (double hashing)
- Address collisions require breaking both SHA256 and RIPEMD160
- Compact 20-byte addresses reduce blockchain storage
Known Vulnerabilities
- No practical collision or preimage attacks exist as of 2025
- RIPEMD128 (128-bit variant) has theoretical weaknesses, but RIPEMD160 remains secure
- Primarily replaced by SHA-256/SHA-3 for new applications due to larger security margin
Performance
Implementation
- TypeScript: Uses @noble/hashes pure TypeScript implementation from legacy.js
- Zig/Native: Custom RIPEMD160 implementation following Bitcoin Core reference
- WARNING: Zig implementation is UNAUDITED custom crypto code
- Uses constant-time operations to resist timing attacks
- Pure software implementation (no hardware acceleration available)
- WASM: Available via ripemd160.wasm.ts for browser environments
Benchmarks
Typical performance (varies by platform):- Native (Zig): ~150-250 MB/s
- WASM: ~80-150 MB/s
- Pure JS: ~50-100 MB/s
Performance vs Other Hashes
Implementation Details
TypeScript Implementation
Uses @noble/hashes legacy module:WASM
Available viaripemd160.wasm.ts for browser environments. Compiled from Zig with wasm32-wasi target.
Use Cases
Bitcoin P2PKH Address
Pay-to-PubKey-Hash (most common Bitcoin address):Bitcoin P2SH Address
Pay-to-Script-Hash addresses:Why Bitcoin Uses Both SHA256 and RIPEMD160
- Redundancy: If one algorithm is broken, the other provides backup security
- Compact addresses: RIPEMD160’s 20-byte output reduces address size
- Historical: Design decision made in 2009 when both were considered secure
- No single point of failure: Requires breaking both algorithms for address collision
Not Recommended For
- New cryptocurrencies: Use SHA256, Keccak256, or Blake2b instead
- General hashing: SHA256 provides better security margins
- Password hashing: Use proper password hash functions (Argon2, bcrypt, scrypt)
- File integrity: SHA256 is more widely supported and faster on modern hardware
Related
- SHA256 - Used with RIPEMD160 in Bitcoin addresses
- Keccak256 - Ethereum’s hash function
- Blake2 - Modern high-performance alternative
- Address Primitive - Ethereum 20-byte addresses

