# Report: RIPEMD-160 collision truncated to 48 bits (λ=24)

## Answer
```json
{"algo":"ripemd160","lambda":24,"inputA":"imd-70e373fa6b0c","inputB":"imd-4a68f5e58b32"}
```
Both inputs are UTF-8 strings (no `0x` prefix), 16 bytes each.

## Evidence (facts — observed locally)
| Input (UTF-8) | RIPEMD-160 (full) | First 48 bits |
|---|---|---|
| `imd-70e373fa6b0c` | `6754b6bedcc20d1f056655815402ccc730cfe019` | `6754b6bedcc2` |
| `imd-4a68f5e58b32` | `6754b6bedcc2e8469fe77a98de29629c6d1eb47c` | `6754b6bedcc2` |

- Two independent implementations gave identical digests: Python `hashlib.new('ripemd160')` and
  `openssl dgst -ripemd160` (via `printf %s "<input>" | openssl dgst -ripemd160`).
- Implementation sanity check: `hashlib` returns `9c1185a5c5e9fc54612808977ee8f548b2258d31` for the
  empty string, which matches the published RIPEMD-160 test vector (Dobbertin, Bosselaers, Preneel,
  "RIPEMD-160: A Strengthened Version of RIPEMD", test vectors at
  https://homes.esat.kuleuven.be/~bosselae/ripemd160.html).
- The inputs differ, and the full digests diverge after the 12th hex digit, so this is a genuine
  48-bit-prefix collision, not a full collision.
- `tools/verify_collision.py` reproduces the check and prints `OK`.

## Method
Floyd cycle finding (Pollard rho) on f(x) = RIPEMD160("imd-" ‖ hex(x))[:6] over 48-bit states,
starting from x0 = 0. Tortoise/hare met after 2,849,673 steps; the cycle entry was found after
2,728,823 further steps; the two distinct predecessors of the entry point are the colliding inputs.
About 1.4 × 10^7 hash evaluations in total, 17 s in CPython. Memory use is constant.

## Inferences
- The expected cost of a generic birthday search on an n-bit output is about √(πN/2) evaluations,
  with N = 2^48, i.e. about 2^24.3. Our run used fewer than the ~3 × 2^24 expected for Floyd, which
  fits normal variance. Nothing here relies on a structural weakness of RIPEMD-160.

## Uncertainty / unanswered
- The verifier's exact input parsing is not documented here beyond "hex 0x... or utf8". We avoided a `0x`
  prefix so the strings are read as UTF-8. If the verifier read them differently (for example, as
  bare hex), the bytes hashed would change and the check would fail. Not tested against the SIMD verifier.
- The result says nothing about the collision resistance of full 160-bit RIPEMD-160. No practical
  full collision is publicly known as of this writing (not re-checked against current literature in this run).
