# SIMD-COLLISION ripemd160, λ=24: 48-bit truncated collision

## Answer

```json
{"algo":"ripemd160","lambda":24,"inputA":"imd-ripemd160-6310951","inputB":"imd-ripemd160-41544419"}
```

Both inputs are plain utf8 (ASCII) strings, hashed as-is with no trailing newline and no `0x` decoding.
The same JSON is committed as `collision.json` at the repository root.

| | input (utf8) | RIPEMD-160 digest |
|---|---|---|
| A | `imd-ripemd160-6310951` | `c2ea4890fa22` `22c5e49449b42e0cd9b96a0643c7` |
| B | `imd-ripemd160-41544419` | `c2ea4890fa22` `bb5dafdfe1a46b7d6508f1295d6a` |

The first 48 bits (6 bytes, MSB first) are `c2ea4890fa22` for both. The digests differ from byte 7 onward, so this is a truncated collision only, not a full RIPEMD-160 collision.

## Facts (measured in this workspace)

- **The digests above were computed three ways and agree.**
  - Python 3.12.3 `hashlib.new("ripemd160")`, backed by the system OpenSSL 3.0.13.
  - The `openssl dgst -provider legacy -provider default -ripemd160` command line, fed with `printf %s`.
  - Node v24.21.0 `crypto.createHash('ripemd160')`.
- **The implementation is RIPEMD-160.** `RIPEMD-160("abc")` came out as `8eb208f7e05d987a9b044a8e98c6b087f15a0bfc`. That matches the published test vector as I recall it; I did not fetch the specification page during this run.
- **The inputs are distinct.** They differ in length (21 and 22 bytes).
- **The search was a plain birthday search.** `tools/find_collision.py` hashed the 48,000,000 strings `imd-ripemd160-<i>` for `i` in 0..47,999,999, bucketed and sorted the 48-bit prefixes, and found 6 repeated prefixes. It took about 56 s on one core, and it reports the pair with the smallest index.
- **The script re-checks its own result.** It asserts that the inputs differ and the 6-byte prefixes match before writing `collision.json`.

## Inferences

- **Six hits is in line with expectation.** For N random 48-bit values the expected number of colliding pairs is about N²/2⁴⁹, which is about 4.1 for N = 4.8·10⁷. This is consistent with the stated cost of about 2²⁴ evaluations for a first collision.
- **The search is reproducible.** It is deterministic, so `python3 tools/find_collision.py` should give the same pair on any machine whose `hashlib` exposes `ripemd160`. With OpenSSL 3 that depends on the build or on the legacy provider being available.

## Uncertainty

- **Input interpretation by the SIMD verifier.** The task allows "hex 0x... or utf8". I assumed that a string without a `0x` prefix is hashed as its utf8 bytes. If the verifier instead treats every input as hex, these inputs would be rejected, since they are not valid hex. The equivalent hex forms are:
  - A: `0x696d642d726970656d643136302d36333130393531`
  - B: `0x696d642d726970656d643136302d3431353434343139`
- **Truncation convention.** I took "48 bits MSB" to mean the first 6 bytes of the digest in standard output order, which is the first 12 hex characters.

## Unanswered questions

- The SIMD verifier itself was not available here, so its acceptance of this file is untested.
