# Keccak-256 collision truncated to 48 bits

The distinct eight-byte inputs in [`collision.json`](../collision.json) produce
the same first six Keccak-256 digest bytes: **`3fc82665f648`**.

| Field | Observed value |
| --- | --- |
| Algorithm | `keccak256` |
| Lambda | `24` (requested truncation: 48 bits) |
| Input A, raw bytes in hex | `0xee62600000000000` |
| Input B, raw bytes in hex | `0xbef60b0300000000` |
| Full digest A | `3fc82665f6489d151e686056b06d4966bc39914f8bc4e080721ca720701f4c11` |
| Full digest B | `3fc82665f64840951a2d3e46bf6111e71264921338aa56445f74313272f8708a` |
| Shared first 48 bits, MSB prefix | `3fc82665f648` |

## Method and attributable evidence

The supplied [`C search`](../tools/search.c) hashes little-endian eight-byte
counters, stores the first six digest bytes, sorts them, and finds adjacent
duplicates. A first batch of 33,554,432 counters starting at zero found none.
The successful run searched 67,108,864 counters starting at zero, including the
first batch again. Thus 100,663,296 hash evaluations were performed across both
runs, covering 67,108,864 unique inputs. The returned counters were 6,316,782 and
51,115,710. The successful run's [log](search.txt) records 6.843 seconds for
hashing and 31.783 seconds through collision discovery on this execution host.

The implementation uses Keccak-f[1600] with 24 rounds, a 1088-bit rate, and a
512-bit capacity. The permutation and sponge construction follow the
[Keccak team's specification summary](https://keccak.team/keccak_specs_summary.html).
The Keccak-256 delimited padding suffix is `0x01`; SHA3-256 uses `0x06`, as
documented by [AMD/Xilinx's Keccak-256 implementation documentation](https://xilinx.github.io/Vitis_Libraries/security/2021.2/guide_L1/internals/keccak256.html).
The `0x` inputs are decoded into bytes before hashing; they are not hashed as
hexadecimal text. Truncation selects digest bytes 0 through 5 in their normal
output order, equivalent to the first 12 hex digits above.

The separate, dependency-free [`Python verifier`](../tools/verify.py) recomputed
both complete digests. It uses a matrix permutation, generates rotation offsets
and round constants, and does not consume C search state or hash output. Before
checking the collision, it passed known-answer tests for Keccak-256 of the empty
message and `abc`. It also passed nine comparisons with Python's `hashlib`
SHA3-256 after switching to the SHA-3 suffix, including block-boundary cases.
The [captured verification output](verification.txt) records the schema,
distinct-input, and prefix-equality checks and the full digests.

Reproduce the checks offline from the repository root:

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

Search build and reproduction commands are in the [README](../README.md).
No external package installation or network access is required for verification.

## Conclusion and limits

**Observed fact:** the local verifier computes distinct full digests whose first
48 bits match. **Inference:** these results satisfy the requested truncated
collision condition. This is not a collision of the full 256-bit digests.

**Uncertainty / unanswered external check:** SIMD acceptance has not been run in
this environment. Both implementations and their checks were produced during
this task; the separate verification implementation is not an independent
reviewer. These results provide reproducible local evidence, not an external
certification. No claim is made about minimum search cost or a general weakness
in full-length Keccak-256.
