# SHA-256 truncated-48-bit collision (λ=24)

## Answer
`collision.json` (repo root, copy in `artifacts/collision.json`):

```json
{"algo":"sha256","lambda":24,"inputA":"imd-12192837","inputB":"imd-19093962"}
```

Inputs are UTF-8 strings (no `0x` prefix, so not hex).

## Evidence (facts — recomputed locally, reproducible)
| input (UTF-8) | full SHA-256 (OpenSSL `openssl dgst -sha256`) |
|---|---|
| `imd-12192837` | `c94563ba4883`4c66186fe07f1f2233f777eed615e843ce03144ade7e659074d9 |
| `imd-19093962` | `c94563ba4883`0d17ce781584012f36b6502808166df0a05236829c7c1c062211 |

- First 48 bits (6 bytes, MSB first) of both digests: `c94563ba4883` — identical.
- The full digests differ from byte 7 onward, and the inputs are distinct strings.
- Confirmed by two independent implementations: Node.js `crypto` (search + re-check) and the OpenSSL CLI.

Reproduce: `printf '%s' imd-12192837 | openssl dgst -sha256` (likewise for the other input).

## Method
`tools/find_collision.js` (Node.js, no dependencies) hashes `"imd-" + i` for i = 0,1,2,…,
takes the top 48 bits, and inserts them into an open-addressing hash table (2^26 slots)
until a repeat appears. The first collision was found after 19,093,963 evaluations
(≈2^24.19) in ~43 s on one core — consistent with the birthday bound
√(π/2 · 2^48) ≈ 2^24.3 expected evaluations.

## Inference / uncertainty
- Assumption: the verifier interprets inputs without a `0x` prefix as UTF-8 bytes, as the
  task format states. If it instead trimmed or normalised strings, these ASCII-only inputs are unaffected.
- Assumption: "truncated to 48 bits MSB" means the first 6 bytes of the big-endian digest as
  printed in hex. A different bit-order convention is not checked here.
- No external sources were needed; all claims are recomputations, not citations.

## Open questions
- None affecting the result; the verifier's exact parser was not available to inspect.
