# Keccak-256 collision for the first 48 bits

A collision was found and locally verified for λ = 24 (48 retained bits).
The deliverable is [`../collision.json`](../collision.json), containing exactly:

```json
{"algo":"keccak256","lambda":24,"inputA":"0x8375360100000000","inputB":"0x7131040200000000"}
```

The `0x` strings encode raw eight-byte messages, not UTF-8 hexadecimal text.
The messages are distinct.

## Observed evidence

| Input | Full Keccak-256 digest |
| --- | --- |
| `0x8375360100000000` | `8851a59bbb9d6231d46ab9566296d3aed4afb5cd4212a1f68a094142b0366868` |
| `0x7131040200000000` | `8851a59bbb9d27a12c8340ba34a0ac8820e6315e00542945f74d66f4ef53a9b1` |

Both digests start with **`8851a59bbb9d`**, the same six bytes (12 hexadecimal
digits, 48 most significant bits in the displayed digest). The full digests differ.

The deterministic [search](../tools/search.cjs) enumerated eight-byte little-endian
integers from zero and stored six-byte digest prefixes in a hash table. The match
was between counters 20,346,243 and 33,829,233, after 33,829,234 candidate
evaluations and 598.235 seconds of measured search time. The candidate count
excludes setup and verification hashes. The raw search evidence is recorded in
[`search-result.json`](search-result.json).

The search used the original Keccak-256 padding (delimiter `0x01`, 136-byte
rate) and all 24 permutation rounds. Its dependency is the vendored
[`@noble/hashes` 1.8.0 implementation](../vendor/noble-hashes/sha3.js).
[Dependency provenance](../vendor/PROVENANCE.md) records the upstream archive
URL, checksum, and license location. No network access is needed to reproduce.

## Local verification

Run from the repository root:

```sh
python3 tools/verify.py
```

The [dependency-free Python verifier](../tools/verify.py) uses a separate 64-bit
lane implementation. It checked the exact JSON key set, algorithm, integer λ,
decoded input distinctness, and equality of the first six digest bytes. It
recomputed both complete digests as shown above and returned `verified: true`.
Its captured output is [`verification.json`](verification.json).

The Python implementation also passed embedded empty-message and `abc` digest
checks. During development, it agreed with the vendored JavaScript API on 15
additional deterministic inputs of lengths 0, 1, 7, 8, 31, 32, 64, 134, 135, 136,
137, 271, 272, 273, and 1,024 bytes, covering padding and multi-block boundaries.
The search's direct permutation setup was checked against the library's public
hash API for counters 0, 1, 123456, and 4294967295.

## Conclusion and limits

The locally recomputed digests establish a collision under the requested 48-bit
truncation. This conclusion is based on executable checks and the concrete
values above; no estimated birthday cost is used as proof.

These are self-checks with two implementations, not an independent reviewer or
SIMD acceptance result. The external SIMD verifier was not available in this
workspace and has not been run here. No collision of the full 256-bit digests is
claimed. There are no remaining local failures or unanswered input-encoding
questions; external acceptance remains unobserved.
