# SHA-256 truncated to 48 bits: collision evidence

The requested collision was found and saved in [collision.json](../collision.json).
The JSON has exactly the four requested keys, with `algo` equal to `sha256`
and `lambda` equal to the integer `24`.

## Observed results

Inputs are hex-encoded raw bytes: decode the characters following `0x` before
hashing; do not hash the hexadecimal text itself. Each input is 29 bytes.

| Input | Raw bytes in hexadecimal |
| --- | --- |
| A | `4964656e746974794d442d7368613235362d34383a0000000000312972` |
| B | `4964656e746974794d442d7368613235362d34383a00000000019532c6` |

Full SHA-256 digests, recomputed locally:

```text
A: 3dd9cd223c0f13cfc439ea2a71b5ca03dcc4667d07e4fbae736cf8ba9e3346ff
B: 3dd9cd223c0f347113b9245e646fa2d758f2d6b0f63fd336e83b9fea3d6be1de
```

The decoded inputs differ. The first six bytes (48 most significant bits) of
both digests are `3dd9cd223c0f`. Their full digests differ, so this is a
collision for the requested truncation only.

## Evidence and reproduction

The source of these observations is the local execution of
[tools/find_collision.py](../tools/find_collision.py) and
[tools/verify_collision.py](../tools/verify_collision.py), not an external claim.
The search generated 33,554,432 inputs before detecting this pair. Messages
consist of the ASCII bytes `IdentityMD-sha256-48:` followed by an eight-byte
unsigned counter in big-endian order. The search partitions digests by their
first byte, then compares the next five bytes within each partition.

Run from the repository root:

```sh
python3 tools/verify_collision.py
```

The verifier checks the JSON keys and values, decodes both inputs, checks that
they differ, computes SHA-256 using Python's `hashlib`, and cross-checks each
full digest using `openssl dgst -sha256 -binary`. It then compares the first
six digest bytes. The recorded result was:

```text
PASS: distinct inputs share first 48 bits 3dd9cd223c0f
```

The OpenSSL executable reported version `OpenSSL 3.0.13 30 Jan 2024`.
The delivered search uses only Python's standard library. The optional
cross-check requires a locally installed OpenSSL executable; verification of
the JSON itself needs no network or downloaded dependency.

## Conclusion and limits

The conclusion that this pair satisfies the requested 48-bit collision follows
directly from the distinct decoded inputs and equal six-byte digest prefixes.
All evidence above is a local self-check. Python and the OpenSSL CLI can share
the same underlying cryptographic library, so the cross-check is not asserted
to be an independent cryptographic implementation or independent review.
The assignment's SIMD verifier has not been run here, and its acceptance
remains unobserved. No claim of a full SHA-256 collision is made.
