# Keccak-256 collision in the first 48 bits

## Result

A collision was found for the requested 48-bit MSB truncation (lambda = 24).
The submitted file is [`../collision.json`](../collision.json):

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

Both inputs are hex-encoded raw eight-byte messages, not UTF-8 representations
of the hex strings. Their decoded byte sequences are distinct.

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

The first six digest bytes (12 leading hexadecimal digits, 48 MSB bits) are
**`8851a59bbb9d`** in both cases. The full 256-bit digests differ.

## Attributable local evidence

- [`search-result.txt`](search-result.txt) records the C searcher's matching
  counters, `20346243` and `33829233`, and both full digests. Each counter was
  encoded as an unsigned eight-byte little-endian integer.
- [`search-progress.txt`](search-progress.txt) records a match after
  **33,829,234 evaluations**, with an elapsed time of 85 seconds as measured
  by the process's wall clock. The initial, smaller search exhausted 33,554,432
  candidates without a match; its log is
  [`initial-search-progress.txt`](initial-search-progress.txt). The expanded
  run restarted at zero, so these runs performed 67,383,666 evaluations in total.
- [`verification.txt`](verification.txt) records the separate Python verifier's
  recomputed digests, equal prefixes, and successful schema and distinctness
  checks. It also records two Keccak known-answer checks (empty message and
  `abc`), ten SHA3-256 comparisons against `hashlib` using the SHA3 suffix,
  and five C/Python digest comparisons.

The search source is [`../tools/search.c`](../tools/search.c), generated by
[`../tools/generate_search.py`](../tools/generate_search.py). Its hash table
compares all 48 retained digest bits before declaring a match. The independent
Python implementation in [`../tools/verify.py`](../tools/verify.py) generates
round constants and rotation positions algorithmically, whereas the C code uses
explicit constants and generated fixed-index operations.

Recompute the checks offline from the repository root:

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

The verifier uses Python's standard library and the included Linux x86-64 search
executable for the C cross-checks. Rebuild instructions and the vendored compiler's
provenance are in [`../README.md`](../README.md) and
[`../tools/vendor/README.md`](../tools/vendor/README.md).

## Algorithm interpretation and source

The computation uses Keccak-f[1600] with 24 rounds, a 1088-bit rate, 512-bit
capacity, and the original Keccak delimited suffix `0x01`. Digest bytes are
serialized from little-endian lanes. The Keccak team's
[specifications summary](https://keccak.team/keccak_specs_summary.html)
describes the permutation, sponge construction, constants, and suffix rule.
With no domain-separation bits, that rule gives `0x01`; SHA3-256 instead uses
`0x06`. The submitted digests use the former. Source consulted 2026-10-05.

## Conclusion and limits

Observed fact: two local implementations recompute the full digests above, and
their first six bytes agree for distinct decoded inputs. The resulting inference
is that `collision.json` satisfies the requested 48-bit collision condition.
This does not establish a collision in full Keccak-256.

These are attributable, reproducible local checks, not independent certification.
The external SIMD verifier was not available in this workspace and was not run;
its acceptance remains unobserved. No external acceptance is claimed.
