Zpět na domů

GPSČ na 12 časovačích PHP: entropie 7.1 bitu

Třída ChaosRNG implementuje GPSČ na 12 časovačích pro generování bajtů s entropií 7.1+ bitů. Časovače přinášejí nelinearitu prostřednictvím pauz, přeskoků a modulace. Vhodné pro experimenty s tokeny.

PHP GPSČ: 12 časovačů pro 7+ bitů entropie
Advertisement 728x90

Generátor pseudonáhodných bajtů využívající 12 časovačů v PHP

Třída ChaosRNG využívá 12 vzájemně propojených časovačů k generování bajtů s entropií až 7,1–8 bitů na symbol. Každý časovač přispívá nelinearitou: od základního času a nanosekund po pauzy a vkládání nulových bajtů. Toto je experimentální přístup pro úlohy, které nevyžadují certifikované kryptografické primitivy.

Konstruktor inicializuje stav pomocí XOR mikrosekund (T1), nanosekund (T2), PID a paměti (T7). Koeficient křivosti začíná na 1,001, vypínač je ve výchozím nastavení zapnut.

Logika časovačů

Časovače tvoří zpracovatelský konveyor:

Google AdInline article slot
  • T1: mikrosekundy od roku 1970.
  • T2: nanosekundy od spuštění systému.
  • T3: aktualizace 64bitového stavu — přičtení nebo odečtení nejnižšího bajtu celkového součtu.
  • T4: modulace času násobením/dělením koeficientem k, který se aktualizuje každý takt.
  • T5: určuje řezy (1000–10000).
  • T6: vybírá řez pro vážení času.
  • T7: džitter cache a přerušení přes PID a paměť.
  • T8: vypínač — přeskočení skutečných bajtů při vypnutém stavu.
  • T9: řídí T8 podle posledního bajtu (<5 — zapnuto, >5 — vypnuto).
  • T10: skrytý počáteční bod v konstruktoru.
  • T11: vložení 0x00 při ($state & 10) === 0.
  • T12: pauzy 1–100 taktů s aktualizací stavu během čekání.
/**
 * ChaosRNG - generátor náhodných bajtů s 12 časovači
 * 
 * 12 časovačů:
 * T1  – běžné hodiny (microtime)
 * T2  – přesné hodiny (hrtime)
 * T3  – paměť (stav $state)
 * T4  – křivka (násobí/dělí čas)
 * T5  – drtič (počet řezů 1000-10000)
 * T6  – ukazovák (výběr řezu)
 * T7  – skrytý šum (džitter, přerušení)
 * T8  – vypínač (zap/vyp výstupu)
 * T9  – pozorovatel (řídí vypínač)
 * T10 – počáteční bod (moment inicializace)
 * T11 – kaňka (vložení nulového bajtu)
 * T12 – tichoun (pauzy 1-100 taktů)
 */

class ChaosRNG {
    // Vlastnosti třídy
    private $state;      // T3: 64bitový stav
    private $k;          // T4: koeficient křivosti
    private $enabled;    // T8: vypínač (zap/vyp)
    private $lastByte;   // T9: poslední vydaný bajt
    private $dot;        // T11: příznak bodu
    private $pauseLen;   // T12: délka pauzy
    private $pauseRem;   // T12: zbytek pauzy
    
    /**
     * Konstruktor — T10 (počáteční bod)
     * Smícháme vše, co nelze opakovat
     */
    public function __construct() {
        // XOR všech zdrojů → unikátní počáteční stav
        $this->state = (int)(microtime(true) * 1000000)  // T1: mikrosekundy
                     ^ hrtime(true)                       // T2: nanosekundy
                     ^ getmypid()                         // T7: PID procesu
                     ^ memory_get_usage();                // T7: využitá paměť
        
        $this->k = 1.001;           // T4: počáteční koeficient
        $this->enabled = true;      // T8: vypínač zapnut
        $this->lastByte = 0;        // T9: poslední bajt není
        $this->dot = false;         // T11: bod nevložen
        $this->pauseLen = 0;        // T12: pauza není
        $this->pauseRem = 0;        // T12: zbytek pauzy = 0
    }
    
    /**
     * T1: běžné hodiny
     * Vrací mikrosekundy od roku 1970
     */
    private function t1() {
        return (int)(microtime(true) * 1000000);
    }
    
    /**
     * T2: přesné hodiny
     * Vrací nanosekundy od spuštění systému
     */
    private function t2() {
        return hrtime(true);
    }
    
    /**
     * Vnitřní generátor bajtu (T3-T7)
     * Mění stav a vrací jeden bajt
     */
    private function nextByteInternal() {
        // T5: počet řezů od 1000 do 10000
        $K = 1000 + ($this->state % 9001);
        
        // T6: výběr konkrétního řezu
        $slot = (($this->state >> 8) % $K);
        
        // T1 a T2: získáváme aktuální čas
        $t1 = $this->t1();
        $t2 = $this->t2();
        
        // T4: křivka (natahujeme nebo stlačujeme čas)
        if ($this->state & 1) {
            $t1 = $t1 * $this->k;   // natahujeme T1
        } else {
            $t2 = $t2 / $this->k;   // stlačujeme T2
        }
        
        // Sečteme s ohledem na vybraný řez
        $total = (int)($t1 * ($slot + 1) / $K)
               + (int)($t2 * ($slot + 1) / $K);
        
        // T3: aktualizujeme stav (přičteme nebo odečteme)
        if ($total & 1) {
            $this->state += ($total & 0xFF);
        } else {
            $this->state -= ($total & 0xFF);
        }
        
        // Aktualizujeme koeficient křivosti
        $this->k = 1.0 + (($this->state & 0xFF) / 10000.0);
        
        // Vracíme nejnižší bajt stavu
        return $this->state & 0xFF;
    }
    
    /**
     * Veřejná metoda: získat N náhodných bajtů
     * Bere v úvahu všech 12 časovačů
     */
    public function getBytes($n) {
        $out = [];
        
        for ($i = 0; $i < $n; $i++) {
            // T12: pauza (tichoun)
            while ($this->pauseRem > 0) {
                $this->pauseRem--;
                $this->nextByteInternal(); // stav se mění
            }
            
            // Pokud pauza skončila — generujeme novou
            if ($this->pauseRem === 0 && $this->pauseLen === 0) {
                $this->pauseLen = 1 + ($this->state % 100); // 1-100 taktů
                $this->pauseRem = $this->pauseLen;
            }
            
            // T11: bod (vložení nulového bajtu)
            if (($this->state & 10) === 0 && !$this->dot) {
                $this->dot = true;
                $this->nextByteInternal();
                $out[] = 0x00; // bod = nulový bajt
                continue;
            }
            $this->dot = false;
            
            // T9: pozorovatel za vypínačem
            if ($this->lastByte < 5) {
                $this->enabled = true;   // zapneme
            } elseif ($this->lastByte > 5) {
                $this->enabled = false;  // vypneme
            }
            // pokud rovno 5 — nic neměníme
            
            // Generujeme bajt
            $byte = $this->nextByteInternal();
            
            // T8: vypínač
            if (!$this->enabled) {
                // Pokud vypnut — vydáme fiktivní bajt
                $out[] = $this->nextByteInternal() & 0xFF;
                continue;
            }
            
            // Uložíme poslední vydaný bajt
            $this->lastByte = $byte;
            
            // Resetujeme pauzu po vydání skutečného bajtu
            if ($this->pauseLen > 0) {
                $this->pauseLen = 0;
                $this->pauseRem = 0;
            }
            
            $out[] = $byte;
        }
        
        return $out;
    }
}

Výpočet Shannonovy entropie

Statická metoda entropy() vypočítává entropii podle vzorce -Σ p * log2(p) pro frekvence bajtů. Test na 64 KB dat ukazuje průměrně 7,12 bitů.

public static function entropy($bytes) {
    // Počítáme frekvenci každého bajtu
    $freq = array_fill(0, 256, 0);
    foreach ($bytes as $b) {
        $freq[$b]++;
    }
    
    // Shannonův vzorec: -Σ p * log2(p)
    $e = 0;
    $total = count($bytes);
    foreach ($freq as $c) {
        if ($c > 0) {
            $p = $c / $total;
            $e -= $p * log($p, 2);
        }
    }
    
    return $e;
}

// Test
$rng = new ChaosRNG();
$data = $rng->getBytes(65536);
$entropy = ChaosRNG::entropy($data);
echo "Entropie: " . round($entropy, 4) . " / 8 bitů\n";

Nelinearita a odolnost

Obnovení stavu vyžaduje znalost k, počtu řezů, pauz, polohy vypínače. Stav 64 bitů komplikuje útoky bez přístupu k serveru. Entropie >6,5 bitů i na virtualizacích činí sekvenci statisticky blízkou náhodné.

Použití: generování tokenů, hesel (16 znaků ~113 bitů entropie). Ne pro kryptografii — pouze experimenty.

Google AdInline article slot

Co je důležité

  • 12 časovačů vytváří nelineární konveyor s pauzami a přeskoky pro ztížení analýzy.
  • Shannonova entropie 7,1+ bitů na bajt, test na 64 KB.
  • T12 (pauzy) a T11 (nuly) narušují časovou a sekvenční předvídatelnost.
  • Stav 64 bitů — kompromis mezi odolností a rychlostí.
  • Nepoužívat v production kryptografii: experimentální PRNG.

— Editorial Team

Advertisement 728x90

Číst dál