# SHA-256 collision in the first 48 bits

The distinct byte inputs in [collision.json](../collision.json) have identical SHA-256 prefixes of 48 bits (λ = 24). The `0x` strings encode raw hexadecimal bytes; the characters of the strings are not the hashed inputs.

| Input | Bytes (hex) | Full SHA-256 digest |
| --- | --- | --- |
| A | `000000000017211c` | `4e84dca19fa699674e41dc0ff0f92046577a96fd3bbc22ae6a036986dc268301` |
| B | `00000000014060cc` | `4e84dca19fa67ad46fd0f73243c0081834a4767ce3fc91b0b4dade47ab574d2e` |

The common most-significant six bytes are **`4e84dca19fa6`**. The full digests differ.

## Evidence and method

On 2026-10-05, a local Python `hashlib.sha256` search hashed consecutive unsigned integers encoded as eight big-endian bytes, starting at zero. A dictionary retained the first input for each six-byte digest prefix. The collision was found after 20,996,301 evaluations (about 21.83 seconds in this environment).

After saving the JSON, a separate Node.js check read that file, validated its exact four keys and parameter values, decoded both hexadecimal strings, checked that their bytes differed, and recomputed both complete hashes using `crypto.createHash('sha256')`. Each input was also passed as raw bytes to `openssl dgst -sha256`; its full digest matched Node.js. The prefix comparison passed. These local computations are the primary evidence for the values above.

To reproduce the digest check from the repository root:

```sh
node - <<'JS'
const fs = require('fs');
const crypto = require('crypto');
const assert = require('assert');
const r = JSON.parse(fs.readFileSync('collision.json', 'utf8'));
assert.deepStrictEqual(Object.keys(r), ['algo', 'lambda', 'inputA', 'inputB']);
assert.strictEqual(r.algo, 'sha256');
assert.strictEqual(r.lambda, 24);
const inputs = [r.inputA, r.inputB].map(s => {
  assert(/^0x(?:[0-9a-f]{2})+$/.test(s));
  return Buffer.from(s.slice(2), 'hex');
});
assert(!inputs[0].equals(inputs[1]));
const hashes = inputs.map(b => crypto.createHash('sha256').update(b).digest('hex'));
assert.strictEqual(hashes[0].slice(0, 12), hashes[1].slice(0, 12));
console.log(hashes.join('\n'));
console.log('PASS: common 48-bit prefix', hashes[0].slice(0, 12));
JS
```

## Limits

The collision conclusion follows directly from the observed digest bytes. This is a collision only for the requested truncation, not for full SHA-256. Local verification is self-check evidence, not an independent review or a SIMD verifier result. The external SIMD acceptance result remains unknown; no such result is claimed.
