Zurück zur Startseite

PRNG auf 12 Timern PHP: Entropie 7.1 Bits

ChaosRNG-Klasse implementiert PRNG auf 12 Timern zur Generierung von Bytes mit 7.1+ Bits Entropie. Timer führen Nichtlinearität durch Pausen, Sprünge und Modulation ein. Geeignet für Experimente mit Tokens.

PHP PRNG: 12 Timer für 7+ Bits Entropie
Advertisement 728x90

ChaosRNG: PHP-Pseudozufallsgenerator mit 12 Timern

Die ChaosRNG-Klasse nutzt 12 miteinander verknüpfte Timer, um Bytes mit einer Entropie von bis zu 7,1–8 Bits pro Byte zu erzeugen. Jeder Timer trägt zur Nichtlinearität bei – von Basiszeit und Nanosekunden bis hin zu Pausen und Nullbyte-Einfügungen. Dieser experimentelle Ansatz eignet sich für Aufgaben, die keine zertifizierten kryptografischen Primitiven benötigen.

Der Konstruktor initialisiert den Zustand durch XOR von Mikrosekunden (T1), Nanosekunden (T2), PID und Speicherverbrauch (T7). Der Verzerrungsfaktor startet bei 1,001, der Schalter ist standardmäßig aktiviert.

Timer-Logik

Die Timer bilden eine Verarbeitungspipeline:

Google AdInline article slot
  • T1: Mikrosekunden seit 1970.
  • T2: Nanosekunden seit Systemstart.
  • T3: Aktualisiert 64-Bit-Zustand durch Addition oder Subtraktion des niedrigsten Bytes des Totals.
  • T4: Moduliert die Zeit durch Multiplikation/Division mit Faktor k, der jeden Zyklus aktualisiert wird.
  • T5: Bestimmt Scheiben (1000–10000).
  • T6: Wählt Scheibe für Zeitgewichtung aus.
  • T7: Cache- und Interrupt-Jitter über PID und Speicher.
  • T8: Schalter – überspringt echte Bytes, wenn aus.
  • T9: Steuert T8 basierend auf letztem Byte (<5 ein, >5 aus).
  • T10: Versteckter Startpunkt im Konstruktor.
  • T11: Fügt 0x00 ein, wenn ($state & 10) === 0.
  • T12: Pausiert 1–100 Zyklen mit Zustandsaktualisierungen während der Wartezeit.
/**
 * ChaosRNG - Zufallsbyte-Generator mit 12 Timern
 * 
 * 12 Timer:
 * T1  – Standarduhr (microtime)
 * T2  – Hochauflösende Uhr (hrtime)
 * T3  – Speicher (Zustand $state)
 * T4  – Verzerrer (multipliziert/dividiert Zeit)
 * T5  – Scheider (1000-10000 Scheiben)
 * T6  – Auswähler (Scheiben-Selektor)
 * T7  – Versteckte Rauschquelle (Jitter, Interrupts)
 * T8  – Schalter (Ein/Aus-Ausgabe)
 * T9  – Beobachter (steuert Schalter)
 * T10 – Startpunkt (Init-Moment)
 * T11 – Nullbyte (Nullbyte-Einfügung)
 * T12 – Pauser (1-100 Zyklus-Pausen)
 */

class ChaosRNG {
    // Klassen-Eigenschaften
    private $state;      // T3: 64-Bit-Zustand
    private $k;          // T4: Verzerrungsfaktor
    private $enabled;    // T8: Schalter (Ein/Aus)
    private $lastByte;   // T9: letztes Ausgabebyte
    private $dot;        // T11: Nullbyte-Flag
    private $pauseLen;   // T12: Pausenlänge
    private $pauseRem;   // T12: Pauserest
    
    /**
     * Konstruktor — T10 (Startpunkt)
     * Mischt alle nicht wiederholbaren Quellen
     */
    public function __construct() {
        // XOR aller Quellen → einzigartiger Initialzustand
        $this->state = (int)(microtime(true) * 1000000)  // T1: Mikrosekunden
                     ^ hrtime(true)                       // T2: Nanosekunden
                     ^ getmypid()                         // T7: Prozess-PID
                     ^ memory_get_usage();                // T7: Speicherverbrauch
        
        $this->k = 1.001;           // T4: Initialfaktor
        $this->enabled = true;      // T8: Schalter ein
        $this->lastByte = 0;        // T9: kein letztes Byte
        $this->dot = false;         // T11: kein Nullbyte eingefügt
        $this->pauseLen = 0;        // T12: keine Pause
        $this->pauseRem = 0;        // T12: Rest 0
    }
    
    /**
     * T1: Standarduhr
     * Gibt Mikrosekunden seit 1970 zurück
     */
    private function t1() {
        return (int)(microtime(true) * 1000000);
    }
    
    /**
     * T2: Hochauflösende Uhr
     * Gibt Nanosekunden seit Start zurück
     */
    private function t2() {
        return hrtime(true);
    }
    
    /**
     * Interner Byte-Generator (T3-T7)
     * Aktualisiert Zustand und gibt ein Byte zurück
     */
    private function nextByteInternal() {
        // T5: Scheibenzahl 1000 bis 10000
        $K = 1000 + ($this->state % 9001);
        
        // T6: wähle spezifische Scheibe
        $slot = (($this->state >> 8) % $K);
        
        // T1 und T2: aktuelle Zeit holen
        $t1 = $this->t1();
        $t2 = $this->t2();
        
        // T4: Verzerrer (dehnen oder komprimieren)
        if ($this->state & 1) {
            $t1 = $t1 * $this->k;   // T1 dehnen
        } else {
            $t2 = $t2 / $this->k;   // T2 komprimieren
        }
        
        // Summe mit gewählter Scheibe
        $total = (int)($t1 * ($slot + 1) / $K)
               + (int)($t2 * ($slot + 1) / $K);
        
        // T3: Zustand aktualisieren (addieren oder subtrahieren)
        if ($total & 1) {
            $this->state += ($total & 0xFF);
        } else {
            $this->state -= ($total & 0xFF);
        }
        
        // Verzerrungsfaktor aktualisieren
        $this->k = 1.0 + (($this->state & 0xFF) / 10000.0);
        
        // Niedrigstes Zustandsbyte zurückgeben
        return $this->state & 0xFF;
    }
    
    /**
     * Öffentliche Methode: N Zufallsbytes holen
     * Berücksichtigt alle 12 Timer
     */
    public function getBytes($n) {
        $out = [];
        
        for ($i = 0; $i < $n; $i++) {
            // T12: Pause (Pauser)
            while ($this->pauseRem > 0) {
                $this->pauseRem--;
                $this->nextByteInternal(); // Zustand ändert sich
            }
            
            // Wenn Pause endet — neue erzeugen
            if ($this->pauseRem === 0 && $this->pauseLen === 0) {
                $this->pauseLen = 1 + ($this->state % 100); // 1-100 Zyklen
                $this->pauseRem = $this->pauseLen;
            }
            
            // T11: Nullbyte (Nullbyte-Einfügung)
            if (($this->state & 10) === 0 && !$this->dot) {
                $this->dot = true;
                $this->nextByteInternal();
                $out[] = 0x00; // Nullbyte
                continue;
            }
            $this->dot = false;
            
            // T9: Schalter-Beobachter
            if ($this->lastByte < 5) {
                $this->enabled = true;   // einschalten
            } elseif ($this->lastByte > 5) {
                $this->enabled = false;  // ausschalten
            }
            // bei ==5 keine Änderung
            
            // Byte erzeugen
            $byte = $this->nextByteInternal();
            
            // T8: Schalter
            if (!$this->enabled) {
                // Wenn aus — Dummy-Byte ausgeben
                $out[] = $this->nextByteInternal() & 0xFF;
                continue;
            }
            
            // Letztes Ausgabebyte speichern
            $this->lastByte = $byte;
            
            // Pause nach echtem Byte zurücksetzen
            if ($this->pauseLen > 0) {
                $this->pauseLen = 0;
                $this->pauseRem = 0;
            }
            
            $out[] = $byte;
        }
        
        return $out;
    }
}

Shannon-Entropie-Berechnung

Die statische Methode entropy() berechnet die Shannon-Entropie mit der Formel -Σ p * log2(p) für Bytehäufigkeiten. Tests mit 64 KB Daten ergeben im Durchschnitt 7,12 Bits.

public static function entropy($bytes) {
    // Bytehäufigkeiten zählen
    $freq = array_fill(0, 256, 0);
    foreach ($bytes as $b) {
        $freq[$b]++;
    }
    
    // Shannon-Formel: -Σ 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 Bits\n";

Nichtlinearität und Robustheit

Zur Wiederherstellung des Zustands muss man k, Scheibenzahl, Pausen und Schalterposition kennen. Der 64-Bit-Zustand erschwert Angriffe ohne Serverzugriff. Entropie >6,5 Bits sogar auf VMs macht die Sequenz statistisch nahezu zufällig.

Anwendungsfälle: Token- und Passwortgenerierung (16 Zeichen ~113 Bits Entropie). Nicht für Kryptografie – nur Experimente.

Google AdInline article slot

Wichtige Erkenntnisse

  • 12 Timer erzeugen eine nichtlineare Pipeline mit Pausen und Übersprüngen zur Verhinderung von Analysen.
  • Shannon-Entropie 7,1+ Bits pro Byte, getestet auf 64 KB.
  • T12 (Pausen) und T11 (Nullbytes) brechen zeitliche und sequenzielle Vorhersagbarkeit.
  • 64-Bit-Zustand balanciert Robustheit und Geschwindigkeit.
  • Nicht für Produktions-Krypto: experimenteller PRNG.

— Editorial Team

Advertisement 728x90

Weiterlesen