# SIMD-COLLISION: keccak256, λ=24 (48-bit truncation)

## Question
Find two distinct inputs `inputA` and `inputB` such that `keccak256(inputA)` and
`keccak256(inputB)`, each truncated to the first 48 bits (6 bytes, MSB-first), are
identical.

## Answer (fact)
A collision was found:

- `inputA` = `collision-input-26889896` (UTF-8)
- `inputB` = `collision-input-27496353` (UTF-8)
- Truncated-48-bit digest (both): `243bb7fb00b8`

Full (untruncated) Keccak-256 digests, for reference:

```
keccak256("collision-input-26889896") = 243bb7fb00b8be896a8c53f462e1231b112b6b58e6d79dabbc010efcf09e9e00
keccak256("collision-input-27496353") = 243bb7fb00b82a0e30071d0386232cd1be965333eb9980d59763867c9a952e22
```

The first 6 bytes (`243bb7fb00b8`) match; the remaining 26 bytes differ, and the two
inputs are byte-for-byte distinct. This satisfies the task's exact requirement: match
on the 48-bit MSB truncation, distinct inputs, no shortcuts (e.g. reusing one hash as
the other's preimage, or a zero-length/empty-string trick).

Result file: `collision.json` at the repository root (also reproduced in this report).

## Method (fact)
A birthday-attack search was run: candidate inputs `"collision-input-" + i` for
increasing integer `i` were hashed with Keccak-256 (Ethereum's variant, 0x01 padding —
not NIST SHA3's 0x06 padding, which is a different, incompatible function). Each
48-bit truncated digest was inserted into an open-addressing hash table (a
`Float64Array`/`Int32Array` pair, 2^26 slots, linear probing) keyed on the 48-bit
value, so a collision is detected as soon as a second input maps to an
already-occupied slot with a matching key.

- Implementation: Node.js (`v24.21.0`) + the `js-sha3` npm package (pure-JS Keccak,
  not SHA3) for the search; the result was independently cross-checked against the
  `keccak` npm package (native C bindings, the implementation used by `ethereumjs`/
  web3 tooling).
- Sanity check before trusting either library: both reproduce the well-known Ethereum
  test vector `keccak256("abc") = 4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45`.
- Search cost: the collision was found after **27,496,354 evaluations**, in about
  145 seconds on this machine. The task's stated expected cost is ~2^24 ≈ 16.8M
  evaluations; the birthday paradox's expected number of draws before a first
  collision in a 48-bit space is actually ≈1.2533·sqrt(2^48) ≈ 21.0M, with substantial
  run-to-run variance, so 27.5M is a plausible draw from that distribution, not an
  anomaly.
- Scripts used for the search and cross-verification live under `test/scratch/`
  (`find_collision.js` — an initial attempt that hit V8's `Map` size ceiling around
  16.7M entries and was abandoned; `find_collision2.js` — the typed-array version
  that succeeded). Per the task's own rules, `test/scratch/` is not part of the
  submitted deliverable and is excluded before verification.

## Verification performed (fact)
Independently, outside the search loop, both `js-sha3` and `keccak` (native bindings)
were asked to hash `inputA` and `inputB` fresh and were confirmed to agree with each
other and to produce matching 48-bit prefixes:

```
js-sha3  trunc48(inputA) = 243bb7fb00b8
js-sha3  trunc48(inputB) = 243bb7fb00b8
keccak   trunc48(inputA) = 243bb7fb00b8
keccak   trunc48(inputB) = 243bb7fb00b8
inputA !== inputB        = true
```

## Inference
Because two independently-maintained Keccak-256 implementations (one pure JS, one
native-code bindings commonly used in Ethereum tooling) agree on both digests and both
pass the standard `"abc"` test vector, the collision is very unlikely to be an artifact
of a library bug rather than a genuine property of Keccak-256 truncated to 48 bits.

## Uncertainty / unanswered questions
- This report's own verification used the same two JavaScript-ecosystem libraries for
  cross-checking; it was not re-verified against a third, differently-sourced
  implementation (e.g. a C or Rust reference). The task states the authoritative check
  is performed by a separate SIMD verifier, which is the stronger, independent
  confirmation this report cannot itself provide.
- No cryptographic significance is claimed beyond the stated task: finding a 48-bit
  truncated collision is expected and easy (2^24-ish work) precisely because 48 bits is
  far short of Keccak-256's full 256-bit security; this says nothing about the
  collision resistance of un-truncated Keccak-256.
