Պարզ թվերի կոդ

1999 թվականի հոկտեմբերին 16-ամյա նորվեգացի Ջոն Լեխ Յոհանսենի գլխավորած խումբը թողարկեց DeCSS ծրագիրը՝ DVD վերարտադրության պաշտպանությունը շրջանցելու համար։ CSS-ը օգտագործում էր 40-բիթանոց կոդավորում, որի բանալիները բաշխվում էին լիցենզավորված արտադրողներին՝ DVD վերարտադրությունը սահմանափակելու համար։ Քանի որ կոդի տարածումը ընկնում էր ԱՄՆ DMCA օրենքի շրջանակներում և օրենսդրորեն արգելված էր, ակտիվիստները փնտրում էին կոդը մաթեմատիկական էության տեսքով քողարկելու եղանակներ։


Այնուհետև Ֆիլ Քարմոդին կառուցեց պարզ թիվ, որը gzip դեկոմպրեսիայից հետո երկուական ձևով մեկնաբանելիս պարունակում է DeCSS-ի ամբողջական սկզբնական կոդը: DeCSS ալգորիթմի միջուկը կարող է իրականացվել TypeScript-ում հետևյալ կերպ, որտեղ բիթային գործողությունները ուղղակիորեն քարտեզագրում են հատվածի դեկկոդավորման տրամաբանությունը::

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++;
    }
}

Պարզ թվի սկզբունքն այն է, որ ամբողջ ելակետային կոդը մեկնաբանվի որպես մեկ, ամբողջական ամբողջ թիվ: Քանի որ ոչ մի տրված ֆայլ երբեք պարզ թիվ չէ, թիվը արհեստականորեն լրացվում է լրացուցիչ բայթերով (լրացում): Այս լրացումը մեծանում է ցիկլով մինչև պարզության թեստը, ինչպիսին է Միլլեր-Ռաբինի թեստը, հաստատի, որ թիվը պարզ է: Հետևյալ գեներատորը օգտագործում է վերը նկարագրված DeCSS կոդը և փնտրում է համապատասխան պարզ թվի ներկայացում::

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));

Պարզ թվերի հնարքը երբեք առանձին դատական գործի առարկա չի եղել, և դրա կարիքը նույնպես չկար։ Չնայած Կարմոդիի սկզբնական պարզ թիվն ուներ 1401 նիշ, այն չափազանց փոքր էր այդ ժամանակվա ամենամեծ պարզ թվերի ցուցակների առաջին համարների համար։ Ավելի ուշ նա ստեղծեց 1905 նիշանոց տարբերակ, որը արհեստականորեն մեծացված էր զրոյական բայթերով, որպեսզի հասնի ECPP վարկանիշային աղյուսակի տասներորդ տեղին։ Այս հաջողությունը ցույց տվեց մաքուր մաթեմատիկայի գրաքննության անհնարինությունը, քանի որ թիվը ցուցակում իր տեղը վաստակել է միայն իր մաթեմատիկական հատկությունների հիման վրա։

Վերադառնալ