En octubre de 1999, un grupo liderado por el entonces joven noruego Jon Lech Johansen, de 16 años, lanzó el programa DeCSS para eludir la protección de reproducción de DVD del Sistema de Criptografía de Contenido (CSS). CSS utilizaba cifrado de 40 bits, cuyas claves se distribuían a los fabricantes autorizados, para restringir la reproducción de DVD. Dado que la distribución del código estaba sujeta a la DMCA estadounidense y estaba legalmente prohibida, los activistas buscaron maneras de disfrazar el código como una entidad matemática.
Phil Carmody construyó un número primo que, al interpretarse en binario tras la descompresión con gzip, contiene el código fuente completo de DeCSS. El núcleo del algoritmo DeCSS se puede implementar en TypeScript de la siguiente manera, donde las operaciones de bits corresponden directamente a la lógica de descifrado de sectores.:
function CSSdescramble(sec: Uint8Array, key: Uint8Array): void {
let t1: number, t2: number, t3: number, t4: number, t5: number, t6: number;
const end = 0x800;
t1 = (key[0] ^ sec[0x54]) | 0x100;
t2 = key[1] ^ sec[0x55];
const keyView = new DataView(key.buffer, key.byteOffset);
const secView = new DataView(sec.buffer, sec.byteOffset);
t3 = (keyView.getUint32(2, true) ^ secView.getUint32(0x56, true)) >>> 0;
t4 = t3 & 7;
t3 = (t3 * 2 + 8 - t4) >>> 0;
let offset = 0x80;
t5 = 0;
while (offset < end) {
t4 = CSStab2[t2] ^ CSStab3[t1];
t2 = t1 >>> 1;
t1 = ((t1 & 1) << 8) ^ t4;
t4 = CSStab5[t4];
t6 = (((((((t3 >>> 3) ^ t3) >>> 1) ^ t3) >>> 8) ^ t3) >>> 5) & 0xff;
t3 = (((t3 << 8) >>> 0) | t6) >>> 0;
t6 = CSStab4[t6];
t5 += t6 + t4;
sec[offset] = CSStab1[sec[offset]] ^ (t5 & 0xff);
t5 >>>= 8;
offset++;
}
}
El principio que subyace a los números primos consiste en interpretar todo el código fuente como un único número entero. Dado que ningún archivo es un número primo, este se incrementa artificialmente con bytes adicionales (relleno). Este relleno se incrementa en un bucle hasta que una prueba de primalidad, como la prueba de Miller-Rabin, confirma que el número es primo. El siguiente generador utiliza el código DeCSS descrito anteriormente y busca una representación de número primo correspondiente.:
import { isPrime } from 'crypto-utils-lib'; // Hypothetical library for primality testing
async function generateIllegalPrime(code: string): Promise<bigint | null> {
const encoder = new TextEncoder();
const bytes = encoder.encode(code);
let hexBase = Array.from(bytes)
.map(b => b.toString(16).padStart(2, '0'))
.join('');
// Start bei 1, da 0x00 immer gerade und damit keine Primzahl ist
for (let i = 1; i < 256; i++) {
const candidateHex = hexBase + i.toString(16).padStart(2, '0');
const candidateInt = BigInt('0x' + candidateHex);
if (await isPrime(candidateInt)) {
return candidateInt;
}
}
return null;
}
const source = `void CSSdescramble(unsigned char *sec, unsigned char *key) { ... }`;
generateIllegalPrime(source).then(p => console.log(p));
El truco de los números primos nunca fue objeto de un juicio aparte, ni tampoco lo necesitaba. Aunque el número primo original de Carmody tenía 1401 dígitos, era demasiado pequeño para figurar en las listas de los números primos más grandes de la época. Posteriormente, creó una versión de 1905 dígitos, inflada artificialmente con bytes nulos, para alcanzar el décimo puesto en la clasificación ECPP . Este éxito demostró la imposibilidad de censurar las matemáticas puras, ya que el número se ganó su lugar en la lista únicamente por sus propiedades matemáticas.