RIPEMD: Deep Dive

In the early 1990s, Europe wanted its own cryptographic primitives—independent of American designs. The result was RIPEMD, a hash function born from a multinational research project that would eventually find its way into Bitcoin. This is the complete story of the RIPEMD family.

Origins: The RIPE Project (1988-1992)

RIPEMD stands for RACE Integrity Primitives Evaluation Message Digest. It was developed as part of the RIPE project, an initiative funded by the European Commission's RACE program (Research and Development in Advanced Communications Technologies in Europe).

The original RIPEMD was designed in 1992, heavily based on Ronald Rivest's MD4. Like MD4, it processed 512-bit blocks and produced a 128-bit hash. The design used two parallel computation lines—a distinctive feature that would carry forward to all RIPEMD variants.

The 1996 Redesign

By 1995, Hans Dobbertin had found weaknesses in both MD4 and the original RIPEMD. He demonstrated collisions in reduced-round versions of RIPEMD, exploiting similarities to the vulnerable MD4.

In response, Dobbertin joined forces with Antoon Bosselaers and Bart Preneel at the COSIC research group (Katholieke Universiteit Leuven, Belgium) to create strengthened variants. In 1996, they published four new designs:

Variant Output Size Security Level Status
RIPEMD-128 128 bits 64-bit Broken (2013)
RIPEMD-160 160 bits 80-bit Secure
RIPEMD-256 256 bits 64-bit* Secure (limited)
RIPEMD-320 320 bits 80-bit* Secure (limited)

*RIPEMD-256 and RIPEMD-320 provide the same collision resistance as RIPEMD-128 and RIPEMD-160 respectively—the longer output is for applications needing more bits, not more security.

The RIPEMD Family at a Glance

Original RIPEMD (1992)

  • Output: 128 bits
  • Block size: 512 bits
  • Steps: 96 total (two parallel lines × 3 rounds × 16 steps)
  • Status: BROKEN — Collision found in 2004 with complexity ~2¹⁸

RIPEMD-128 (1996)

  • Output: 128 bits
  • Block size: 512 bits
  • Steps: 128 total (two parallel lines × 4 rounds × 16 steps)
  • Status: BROKEN — Full collision attack published in 2013

RIPEMD-160 (1996)

  • Output: 160 bits (20 bytes)
  • Block size: 512 bits (64 bytes)
  • Steps: 160 total (two parallel lines × 5 rounds × 16 steps)
  • Status: Secure — Best attack reaches 40/80 steps (2023)

RIPEMD-256 (1996)

  • Output: 256 bits
  • Block size: 512 bits
  • Steps: 128 total (same as RIPEMD-128, with cross-line chaining)
  • Status: Secure, but collision resistance = RIPEMD-128

RIPEMD-320 (1996)

  • Output: 320 bits
  • Block size: 512 bits
  • Steps: 160 total (same as RIPEMD-160, with cross-line chaining)
  • Status: Secure, but collision resistance = RIPEMD-160

RIPEMD-160: The Flagship

RIPEMD-160 is by far the most widely used variant. It's the only RIPEMD function you should consider using today.

Test Vectors

Verified with OpenSSL:

RIPEMD-160("") =
9c1185a5c5e9fc54612808977ee8f548b2258d31

RIPEMD-160("a") =
0bdc9d2d256b3ee9daae347be6f4dc835a467ffe

RIPEMD-160("abc") =
8eb208f7e05d987a9b044a8e98c6b087f15a0bfc

RIPEMD-160("message digest") =
5d0689ef49d2fae572b881b123a85ffa21595f36

RIPEMD-160("The quick brown fox jumps over the lazy dog") =
37f332f68db77bd9d7edd4969571ad671cf9dd3b

Notice the 40-character hexadecimal output (160 bits = 20 bytes = 40 hex characters).

Algorithm Structure

RIPEMD-160 follows the Merkle–Damgård construction:

  1. Padding: The message is padded to a multiple of 512 bits (same as MD4/MD5)

  2. Initialization: Five 32-bit state variables are set to fixed constants:

    h0 = 0x67452301
    h1 = 0xEFCDAB89
    h2 = 0x98BADCFE
    h3 = 0x10325476
    h4 = 0xC3D2E1F0
    

    These match SHA-1's initial values exactly. The first four (h0-h3) also match MD4 and MD5, which use only four state variables.

  3. Compression: Each 512-bit block is processed through two parallel lines, each performing 80 steps (5 rounds × 16 steps), for 160 total steps per block.

  4. Finalization: The outputs of both lines are combined with the previous state using modular addition.

The Dual-Line Architecture

RIPEMD-160's signature feature is its parallel computation lines. Each 512-bit message block is processed through two independent pipelines (left and right), which use:

  • Different Boolean functions (applied in different orders)
  • Different round constants
  • Different rotation amounts
  • Different message word permutations

At the end of processing each block, the results from both lines are combined. This dual-line design provides defense in depth—an attacker must find differential paths that work simultaneously in both lines.

Boolean Functions

Each line uses five Boolean functions, applied across five rounds of 16 steps each:

Round Function Expression
0 f₁ x ⊕ y ⊕ z
1 f₂ (x ∧ y) ∨ (¬x ∧ z)
2 f₃ (x ∨ ¬y) ⊕ z
3 f₄ (x ∧ z) ∨ (y ∧ ¬z)
4 f₅ x ⊕ (y ∨ ¬z)

The left and right lines apply these functions in opposite orders:

  • Left line: f₁ → f₂ → f₃ → f₄ → f₅
  • Right line: f₅ → f₄ → f₃ → f₂ → f₁

Round Constants

In RIPEMD literature, "rounds" typically refers to individual steps within the compression function.

Left line constants (K):

Rounds Constant
0-15 0x00000000
16-31 0x5A827999
32-47 0x6ED9EBA1
48-63 0x8F1BBCDC
64-79 0xA953FD4E

Right line constants (K'):

Rounds Constant
0-15 0x50A28BE6
16-31 0x5C4DD124
32-47 0x6D703EF3
48-63 0x7A6D76E9
64-79 0x00000000

The constants are derived from mathematical constants (square and cube roots of small primes).

Security Analysis

Original RIPEMD (BROKEN)

In August 2004, Xiaoyun Wang and her team—the same researchers who broke MD5—announced collisions in the original RIPEMD. The attack complexity was approximately 2¹⁸ hash operations, making it trivially exploitable.

RIPEMD-128 (BROKEN)

In 2013, Franck Landelle and Thomas Peyrin published "Cryptanalysis of Full RIPEMD-128" at EUROCRYPT. They demonstrated:

  • First collision attack on the full RIPEMD-128 compression function
  • First distinguisher on the full RIPEMD-128 hash function

Their attack exploited the dual-line structure by placing nonlinear differential parts in each computation branch and using a novel "merge" technique to combine partial solutions.

RIPEMD-160 (Secure)

RIPEMD-160 has withstood over 25 years of cryptanalysis. The attack progression (steps per parallel line):

Year Best Attack Steps Broken Complexity
2019 Collision 34/80
2023 (Feb) Collision 36/80 2⁶⁴·⁵
2023 (Dec) Collision 40/80 2⁴⁹·⁹

The full 80-step RIPEMD-160 (per line) remains unbroken. However, the steady progress in reduced-step attacks suggests the security margin is eroding.

Birthday attack baseline: For a 160-bit hash, generic collision resistance is 2⁸⁰ operations.

RIPEMD-256 and RIPEMD-320

These extended variants have received less cryptanalytic attention because:

  1. Their security level equals their shorter counterparts (RIPEMD-128/160)
  2. They're rarely used in practice
  3. SHA-256 and SHA-512 offer better security for similar output sizes

RIPEMD-160 in Bitcoin

RIPEMD-160's most prominent application is in Bitcoin address generation. Bitcoin uses a construction called HASH160:

HASH160(x) = RIPEMD-160(SHA-256(x))

Why This Design?

  1. Shorter addresses: RIPEMD-160 produces 20 bytes, compared to SHA-256's 32 bytes. This results in more compact Bitcoin addresses.

  2. Layered security: An attacker targeting a Bitcoin address must break both RIPEMD-160 and SHA-256, plus solve the elliptic curve discrete logarithm problem.

  3. Defense in depth: If either hash function is compromised, the other provides a fallback layer of protection.

Bitcoin Address Generation

The process for creating a Bitcoin address:

  1. Generate ECDSA public key (secp256k1 curve)
  2. Apply SHA-256 to the public key
  3. Apply RIPEMD-160 to the SHA-256 result → Public Key Hash
  4. Add version byte prefix
  5. Calculate checksum (double SHA-256, take first 4 bytes)
  6. Encode with Base58Check

The HASH160 output is used in:

  • P2PKH (Pay to Public Key Hash) — Legacy addresses starting with "1"
  • P2WPKH (Pay to Witness Public Key Hash) — Native SegWit addresses starting with "bc1q"

Performance Comparison

From the original RIPEMD-160 benchmarks (Pentium processor):

Algorithm Relative Speed
MD4 1.00 (baseline)
MD5 0.72
SHA-1 0.29
RIPEMD-160 0.24

RIPEMD-160 is approximately 4x slower than MD4. The dual-line architecture and additional rounds provide security at the cost of performance.

On modern hardware, this difference is negligible for most applications. For high-throughput scenarios, BLAKE2 or SHA-256 with hardware acceleration are better choices.

Should You Use RIPEMD?

Use RIPEMD-160 when:

  • Interoperating with Bitcoin or cryptocurrency systems
  • Working with legacy systems that require it
  • 160-bit output is specifically needed

Don't use RIPEMD when:

  • Starting a new project (use SHA-256, SHA-3, or BLAKE2)
  • You need the highest security margins
  • Performance is critical (SHA-256 with hardware acceleration is faster)

Never use:

  • Original RIPEMD — Broken
  • RIPEMD-128 — Broken
  • RIPEMD-256/320 — No advantage over RIPEMD-128/160

Generating RIPEMD-160 Hashes

Command Line (OpenSSL)

# Hash a string
echo -n "hello" | openssl dgst -ripemd160

# Hash a file
openssl dgst -ripemd160 filename.txt

Python

import hashlib

# Note: RIPEMD-160 may require enabling legacy algorithms in OpenSSL 3.x
message = b"hello"
hash_obj = hashlib.new('ripemd160')
hash_obj.update(message)
print(hash_obj.hexdigest())

JavaScript (Node.js)

const crypto = require('crypto');
const hash = crypto.createHash('ripemd160')
                   .update('hello')
                   .digest('hex');
console.log(hash);

Go

package main

import (
	"fmt"
	"golang.org/x/crypto/ripemd160"
)

func main() {
	hash := ripemd160.New()
	hash.Write([]byte("hello"))
	fmt.Printf("%x\n", hash.Sum(nil))
}

Note: Requires go get golang.org/x/crypto/ripemd160

C (OpenSSL)

#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>

int main() {
    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
    const EVP_MD *md = EVP_ripemd160();
    unsigned char hash[EVP_MAX_MD_SIZE];
    unsigned int hash_len;
    const char *message = "hello";

    EVP_DigestInit_ex(ctx, md, NULL);
    EVP_DigestUpdate(ctx, message, strlen(message));
    EVP_DigestFinal_ex(ctx, hash, &hash_len);
    EVP_MD_CTX_free(ctx);

    for (unsigned int i = 0; i < hash_len; i++)
        printf("%02x", hash[i]);
    printf("\n");

    return 0;
}

Compile: gcc -o ripemd160 ripemd160.c -lcrypto


Quick Reference

Variant Output Block Steps Security Status
RIPEMD 128 bits 512 bits 96 Broken (2004)
RIPEMD-128 128 bits 512 bits 128 64 bits Broken (2013)
RIPEMD-160 160 bits 512 bits 160 80 bits Secure
RIPEMD-256 256 bits 512 bits 128 64 bits Limited use
RIPEMD-320 320 bits 512 bits 160 80 bits Limited use

Timeline

Year Event
1988 RIPE project begins (EU RACE program)
1992 Original RIPEMD published
1995 Dobbertin finds weaknesses in reduced RIPEMD
1996 RIPEMD-128, 160, 256, 320 published by Dobbertin, Bosselaers, Preneel
2004 Wang et al. break original RIPEMD (~2¹⁸ collision)
2004 RIPEMD-160 and RIPEMD-128 adopted in ISO/IEC 10118-3
2009 Bitcoin launches, using HASH160 (RIPEMD-160 + SHA-256)
2013 Landelle & Peyrin break full RIPEMD-128
2023 Collision attacks reach 40/80 steps of RIPEMD-160
Today RIPEMD-160 remains secure; others deprecated

References