SHA-256 collision in the first 48 bits
The distinct byte inputs in 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:
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.