Implementierung und Untersuchung von Algorithmen zur Produktion von pseudozufälligen Werten

Die Seite wird erstellt Keno Witt
 
WEITER LESEN
Gottfried Wilhelm Leibniz Universität Hannover
           Fakultät für Elektrotechnik und Informatik
                 Institut für Theoretische Informatik

                              Bachelorarbeit
        Implementierung und Untersuchung von Algorithmen
               zur Produktion von pseudozufälligen Werten

Tim Martin Berger
Matrikelnr. 1001 1842

Erstprüfer & Betreuer: PD Dr. Arne Meier
Zweitprüfer: Prof. Dr. Heribert Vollmer

Hannover, den 8. April 2021
Erklärung der Selbstständigkeit
Hiermit versichere ich, die vorliegende Bachelorarbeit selbstständig verfasst und keine
anderen als die angegebenen Quellen und Hilfsmittel verwendet zu haben. Die Arbeit
hat in gleicher oder ähnlicher Form noch keinem anderen Prüfungsamt vorgelegen.

Hannover, den 8. April 2021

       Tim Martin Berger
Inhaltsverzeichnis
1 Einleitung                                                                                                                                 1
  1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                         1
  1.2 Aufbau der Arbeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . .                                                            1

2 Theoretische Grundlagen                                                                                                                    2
  2.1 Zufall und Pseudozufall .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    2
  2.2 Pseudozufallsgeneratoren      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
      2.2.1 Prädiktoren . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    3
      2.2.2 Statistische Tests      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    4
      2.2.3 Einwegfunktionen        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    5

3 Anforderungen an Pseudozufallsgeneratoren                                                                                                  6
  3.1 Effizienz . . . . . . . . . . . . . . . . . .                     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    6
  3.2 Kryptographische Sicherheit . . . . . . .                         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    7
      3.2.1 Zufälligkeit . . . . . . . . . . . .                        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    7
      3.2.2 Unvorhersagbarkeit . . . . . . . .                          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    7
      3.2.3 Blackboxing . . . . . . . . . . . .                         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    7
      3.2.4 Wahl des Seeds . . . . . . . . . .                          .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .    8

4 Statistische Tests                                                                                                                         9
  4.1 Frequency (Monobit) Test . . . . .                    . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   10
  4.2 Runs Test . . . . . . . . . . . . . .                 . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   11
  4.3 Test for the Longest Run of Ones in                   a Block             .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   12
  4.4 Cumulative Sums Test . . . . . . .                    . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   14
  4.5 Weitere Tests . . . . . . . . . . . .                 . . . . .           .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   16

5 Blum-Micali-Generator                                                                                                                     17
  5.1 Konzept . . . . . . . . . . . . . . . .                   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   17
  5.2 Implementierung . . . . . . . . . . .                     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
      5.2.1 Diskrete Exponentialfunktion                        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
      5.2.2 Hardcore-Prädikat . . . . . .                       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   19
      5.2.3 Der Generator . . . . . . . . .                     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   20
5.3   Hilfsfunktionen . . . . . . . . . . . . . . . . . . . . . . . .                          .   .   .   .   .   .   .   21
         5.3.1 Teilerfremdheit . . . . . . . . . . . . . . . . . . . .                            .   .   .   .   .   .   .   21
         5.3.2 Primitivwurzeln . . . . . . . . . . . . . . . . . . . .                            .   .   .   .   .   .   .   22
   5.4   Untersuchung . . . . . . . . . . . . . . . . . . . . . . . . .                           .   .   .   .   .   .   .   23
         5.4.1 Patternerzeugung in Abhängigkeit der Primzahl p .                                  .   .   .   .   .   .   .   23
         5.4.2 Der Seed x gibt den Startwert des Patterns vor . .                                 .   .   .   .   .   .   .   24
         5.4.3 Die Menge möglicher Pattern ist durch g gegeben .                                  .   .   .   .   .   .   .   25
         5.4.4 Niedrige Seeds x fallen aus dem Muster . . . . . . .                               .   .   .   .   .   .   .   27
         5.4.5 Wahl des Tests für Patternerkennung entscheidend                                   .   .   .   .   .   .   .   28
         5.4.6 Schlussfolgerung . . . . . . . . . . . . . . . . . . . .                           .   .   .   .   .   .   .   30

6 Mersenne-Twister-Generator                                                                                                  32
  6.1 Implementierung . . . . . . . . . . .       .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   33
      6.1.1 Twist . . . . . . . . . . . . . .     .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   33
      6.1.2 Ausgabe der Pseudozufallszahl         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   34
  6.2 Untersuchung . . . . . . . . . . . . .      .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   35
      6.2.1 Bedeutung des Seeds . . . . .         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   35
      6.2.2 Rolle der Ausgabefunktion . .         .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   36
      6.2.3 Rolle der Twist-Funktion . . .        .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   .   37

7 Vergleich der Generatoren                                                                                                   39

8 Ausblick                                                                                                                    41
1 Einleitung

1.1 Motivation
Das Zufallsprinzip ist in vielen Bereichen der Informatik essenziell und dennoch ist es
von deterministischen Maschinen kaum umsetzbar. Doch insbesondere die IT-Sicherheit
macht sich den Zufall für die Verschlüsselung sensibler Daten zu Nutze. Ohne die
Einhaltung der Schutzziele der IT-Sicherheit, der Integrität, der Vertraulichkeit und
der Authentizität ist keine Internetseite und kein digitales System zu betreiben. Es gibt
allein 16,5 Millionen Internetseiten mit der Top-Level-Domain .de, Tendenz steigend [3].
Parallel dazu steigt nach Angaben des Berichts zur Lage der IT-Sicherheit in Deutsch-
land 2020 die Menge an Schadsoftware stetig [2]. Um sich gegen diese Angriffe zu
rüsten werden Verschlüsselungsmechanismen genormt und bedienen sich an umfassend
geprüften Verfahren zur Erzeugung der Schlüssel.
In der Regel ist die scheinbare Zufälligkeit der Zufallszahl durch Algorithmen bestimmt.
Aus diesem Grund lässt ich der Begriff des Zufalls nicht mehr im Zusammenhang mit
den gängigen Verfahren zur Schlüsselerzeugung anwenden. Stattdessen bedarf es einer
Abgrenzung zwischen echtem Zufall und der hier vorliegenden Pseudozufälligkeit und
einer wissenschaftliche Auseinandersetzung zur Erzeugung von Letzterem.

1.2 Aufbau der Arbeit
Zunächst werden einige theoretische Grundlagen erläutert, die später Anwendung
finden sollen. Bevor dann Pseudozufallsgeneratoren vorgestellt und analysiert werden,
sind Anforderungen aufzustellen, die zur Bewertung herangezogen werden. Geprüft
werden diese Anforderungen mittels statistischer Tests, Algorithmen zur Analyse von
Bitsequenzen, die von Pseudozufallsgeneratoren erzeugt werden. Die dann vorgestellten
Generatoren, der Blum-Micali -Generator und der Mersenne-Twister -Generator müssen
diese Tests dann durchlaufen. Dazu wurde ein Tool entwickelt, bei dem sich die Parameter
zur Erzeugung der Pseudozufallszahlen einzeln einstellen lassen, um diese dann in
statistischen Tests zu untersuchen. Anschließend folgt ein Vergleich beider Generatoren
und ein Ausblick darüber, wie man diese Arbeit fortführen könnte.

                                           1
2 Theoretische Grundlagen

2.1 Zufall und Pseudozufall
Von Zufall wird laut Definition gesprochen, wenn zwischen zwei Ereignissen kein kausaler
Zusammenhang besteht, oder auch, wenn die Einflussfaktoren für ein Ereignis bekannt
sind, diese jedoch nicht messen und nur rein statistisch voraussagen kann [10]. Eine
weitere Definition aus Complexity and Cryptography zieht die Kolmogorov-Chaitin-
Komplexität heran. Diese sagt aus, dass eine Zeichenkette dann zufällig ist, wenn diese
nicht durch Algorithmen zu erzeugen ist, die kürzer sind, als die Zeichenkette selbst
oder anders formuliert, wenn es keine Komprimierung für diese Zeichenkette gibt [12].
Im Umkehrschluss heißt das, dass jedes einzelne Bit einer Bitsequenz den Informati-
onsgehalt dieser Sequenz erweitert. In einer Zeichenkette der Länge k darf das Bit an
der Stelle n (mit 1 < n < k) nicht mit der Kenntnis über die Bits {1, ..., n − 1} in
probabilistischer Polynomialzeit (kurz P P ) zu berechnen sein, die Entropie muss also
maximal sein.

Definition 2.1 [11] Die Komplexitätsklasse PP ist die Klasse von Entscheidungs-
problemen, die von einer nichtdeterministischen Turing-Maschine, welche auf jeder
Entscheidungsstufe zwischen allen Transitionen entsprechend einer Wahrscheinlichkeits-
verteilung wählt, in Polynomialzeit mit einer Fehlerrate < 12 gelöst werden können.

Dass kein deterministischer Algorithmus echte Zufallszahlen erzeugen kann, wurde
bereits angedeutet. Echter Zufall erfordert Input über zusätzliche Hardware, wie über
die Tastatur. Dabei können das niederwertigste Bit (LSB) aus der Zeit in Millisekun-
den zwischen zwei Tastenanschlägen oder Zufallsbits aus atmosphärischem Rauschen
verwendet werden, wie es bei random.org angewandt wird [5]. Mit diesen Methoden
Zufallssequenzen für praktische Anwendungen zu erzeugen ist jedoch zu aufwändig und
nicht praktikabel, da die Erzeugung von Bitsequenzen mit 128 oder 256 Bits, wie sie
unter anderem im AES-Verschlüsselungsverfahren benutzt werden, zu lange dauert.
Stattdessen werden Pseudozufallsgeneratoren verwendet, um Pseudozufallszahlen zu
berechnen. Pseudozufallsgeneratoren sind deterministische Algorithmen, die eine echt
zufällige Bitsequenz der Länge k entgegennehmen und eine pseudozufällige Sequenz
der Länge l(k) > l erzeugen. Diese Pseudozufallszahl soll möglichst nah an der oben

                                           2
aufgeführten Definition für echten Zufall sein. Zwar ist zwangsläufig ein kausaler Zusam-
menhang zwischen den Bits gegeben, da jedes Bit mit den gleichen Anweisungsschritten
des Algorithmus erzeugt wird, es kann jedoch bewerkstelligt werden, dass dieser Zusam-
menhang nicht in probabilistischer Polynomialzeit berechenbar ist.

2.2 Pseudozufallsgeneratoren
Im Allgemeinen wird ein PP-Algorithmus, der eine Zeichenkette x ∈ {0, 1}k übergeben
bekommt und eine Zeichenkette G(x) der Länge l(k) > k produziert, als Pseudozufalls-
generator bezeichnet. Der Algorithmus hat aber noch eine Reihe weiterer Bedingungen
zu erfüllen, damit dieser als Pseudozufallsgenerator deklariert werden kann. John Tal-
bot und Dominic Welsh haben in Complexity and Cryptography einige Bedingungen
aufgestellt und bewiesen [16]. Die Wesentlichen werden im Folgenden kurz aufgezeigt.

2.2.1 Prädiktoren
Als Gegenspieler zu Pseudozufallsgeneratoren operieren Prädiktoren. Ein Prädiktor
P ist ein PP-Algorithmus, der mit möglichst hoher Genauigkeit das nächste Bit der
Ausgabe des Pseudozufallsgenerators G(x) unter Angabe des Startwerts x zu berechnen
versucht. Schon durch einfaches Raten ist bei zwei den möglichen Werten, die das Bit
annehmen kann, die Trefferwahrscheinlichkeit bei etwa 12 . Ist diese jedoch signifikant
höher als das so gilt, dass der ein Bitgenerator G kein Pseudozufallsgenerator ist.
Der Next-Bit-Test ist ein Algorithmus, der für einen Generator G und einen Prädiktor
P prüft, ob P die einzelnen Bits der erzeugten Bitsequenz G(x) richtig berechnen kann.

Pseudocode 1 : Next-Bit-Test [16]

 1   S e l e c t random x ∈R {0, 1}k and compute G(x) = y1 y2 ...yl(k) .
 2 Give t h e p r e d i c t o r P t h e i n p u t 1k .
 3 i←1
 4   w h i l e i ≤ l(k)
 5         P e i t h e r a s k s f o r t h e next b i t , yi , o r o u t p u t s a g u e s s b
 6         i f P o u t p u t s a g u e s s then
 7                t h e t e s t ends and P p a s s e s t h e t e s t i f f b = yi .
 8         else
 9                P i s g i v e n t h e next b i t yi
10                i ← i + 1.
11 end−w h i l e
12 P f a i l s s i n c e i t has not made a g u e s s .

                                                  3
Für jedes Bit in yi in G(x) gibt P entweder eine Prognose ab oder bekommt das
nächste Bit. P besteht, wenn eine richtige Prognose abgegeben wurde und schlägt
fehl, wenn keine Prognose abgegeben wurde. Nun kommt die Bewertung, ob G ein
Pseudozufallsgenerator ist. Dies ist der Fall genau dann, wenn die Wahrscheinlichkeit,
dass P für x ∈R {0, 1} den Next-Bit-Test besteht nicht signifikant größer ist als 12 :

                    P r[P besteht den Next-Bit-Test] ≤   1
                                                         2
                                                             + neg(k).

Diese Wahrscheinlichkeit ist signifikant größer, wenn deren Differenz zu   1
                                                                           2
                                                                               größer ist, als
die Funktion neg(k) (engl. negligible).

Definition 2.2 [7] Eine Funktion f : N → R heißt vernachlässigbar, wenn diese
schneller gegen Null konvergiert, als das Inverse jedes Polynoms.

                                                  1
                                     |f (n)| <                                          (2.1)
                                                 p(n)

Welcher Wert der Bestehenswahrscheinlichkeit des Prädiktors P als vernachlässigbar gilt,
wird in Abhängigkeit zur Länge k der Eingabe x des Generators G definiert. Je länger
der Eingabewert x für G ist, desto geringer fällt der vernachlässigbare Unterschied zu 12
aus.
Kann kein Prädiktor P , wie oben definiert, das nächste Bit xi einer Bitsequenz x
berechnen, so heißt x unvorhersagbar.

2.2.2 Statistische Tests
Mithilfe statistischer Tests wird die Definition von Pseudozufallsgeneratoren weiter
verfeinert. Diese dienen dazu, festzustellen, inwieweit sich Bits eines Pseudozufallsgene-
rators G von echten Zufallsbits unterscheiden.

Definition 2.3 [16] Ein statistischer Test T ist ein PP-Algorithmus, der für einen
gegebenen Eingabestring entweder 0 oder 1 zurück gibt.

Ein pseudozufälliges Erzeugnis G(x) soll nicht unterscheidbar von echtem Zufall sein.
Das heißt, dass die Wahrscheinlichkeit für einen statistischen Test T unter Eingabe
eines Pseudozufallswertes G(x) eine 1 ausgibt, sich nicht signifikant von der Wahr-
scheinlichkeit, dass unter Eingabe einer echten Zufallszahl y eine 1 ausgegeben wird,
unterscheiden darf.

                     |P r[T (G(x)) = 1] − P r[T (y) = 1]| ≤ neg(k).                     (2.2)

Ein Generator G ist genau dann ein Pseudozufallsgenerator, wenn dieser jeden erdenkli-
chen statistischen Test besteht. Dies ist jedoch die Schwierigkeit bei der Generierung

                                            4
von Zufall beziehungsweise Pseudozufall durch Algorithmen. Ein PP-Algorithmus G
muss konzeptionell so aufgebaut sein, dass dieser jeden Test T besteht und gleichzeitig
effizient sein muss, um für reelle Einsatzzwecke, wie der Verschlüsselung, praktikabel zu
bleiben.

2.2.3 Einwegfunktionen
Für die Erzeugung zufallsähnlicher Werte bedienen sich Pseudozufallsgeneratoren an
Einwegfunktionen, die folgendermaßen definiert sind.

Definition 2.4 [16] Eine Einwegfunktion f ist eine Funktion, für die es einen
Polynomialzeit-Algorithmus gibt, der den Funktionswert y = f (x) mit gegebenem x
berechnet, dessen Urbild x unter Kenntnis von y jedoch von keinem PP-Algorithmus
berechnet werden kann.

Bekannte Einwegfunktionen sind unter anderem die Primfaktorzerlegung oder der diskre-
te Logarithmus. Letzterer wird in einem späteren Abschnitt in dieser Arbeit präsentiert,
da auf diesem der Blum-Micali-Generator basiert. Die genannten Einwegfunktionen
berechnen eine natürliche Zahl. Unter Anwendung eines Hardcore-Prädikats wird aus
dieser dann das Pseudozufallsbit berechnet. Ein Prädikat ist im Allgemeinen eine
Funktion, die eine beliebig lange Eingabe entgegennimmt und einen Wahrheitswert
zurückgibt. Ein Hardcore-Prädikat erweitert diese Definition folgendermaßen:

Definition 2.5 [16] Ein Hardcore-Prädikat B : {0, 1}∗ → {0, 1} einer Einwegfunkti-
on f ist ein Prädikat, dessen Funktionswert unter Kenntnis von x effizient von ei-
nem Polynomialzeit-Algorithmus berechnet werden kann, wohingegen der Funktionswert
schwer zu berechnen ist, wenn ausschließlich f(x) bekannt ist.

Bei zwei möglichen Ausgabewerten, entweder 0 oder 1, bedeutet das, dass die Ausgabe
in je der Hälfte der Fälle 0 oder 1 annehmen kann.

                       |P r[B(x) = 0] − P r[B(x) = 1]| ≤ neg(k).                    (2.3)

Daraus folgt, dass es keinen Prädiktor geben kann, der mit einer signifikant höheren
Wahrscheinlichkeit die Ausgabe des Hardcore-Prädikats prognostiziert als 12 . Da bei
einer Quelle von echt-zufälligen Bits für jedes ausgegebene Bit die Wahrscheinlichkeit
von 12 gegeben ist, dass dieses eine 0 oder eine 1 annimmt, werden auch statistische
Tests keinen signifikanten Unterschied zwischen einer generierten Bitsequenz G(x) und
einer echt-zufälligen erkennen können. Voraussetzung dafür ist, dass der Generator
G die einzelnen Bits unter Anwendung einer Einwegfunktion und einem zugehörigem
Hardcore-Prädikat erzeugt.

                                           5
3 Anforderungen an
  Pseudozufallsgeneratoren
Pseudozufallsgeneratoren werden nicht ausschließlich für kryptographische Zwecke
benutzt, sondern in den verschiedensten Anwendungen, um unter anderem eine Ent-
scheidungsfindung durch den Computer zu simulieren. In einem solchen Kontext sind
die Pseudozufallszahlen nicht sicherheitsrelevant, demnach sind auch die Anforderungen
geringer. Nichtsdestotrotz sind hier ebenso Erzeugnisse erwünscht, die echtem Zufall
möglichst nahe kommen.
In Verschlüsselungsverfahren werden Pseudozufallszahlen als Schlüssel verwendet. Um
zu vermeiden, dass der Schlüssel bei einem Angriff mit einem effizienteren Algorithmus
als Brute-Force bestimmt werden kann, ist es wichtig, dass der Schlüssel jeden Wert
der Schlüsselmenge mit etwa der gleichen Wahrscheinlichkeit annehmen kann. Bei einer
typischen Schlüssellänge von 2048 Bits heißt das, dass jeder der 22048 Bitkombinationen
mit einer Wahrscheinlichkeit von 22048
                                   1
                                       als Schlüssel gewählt wird.

3.1 Effizienz
So unterschiedlich, wie die Einsatzzwecke sind, so verschieden streng sind auch die
Anforderungen zu formulieren. In jedem Einsatzfall ist jedoch gewünscht, dass der
Generator eine Bitsequenz einer beliebigen Länge effizient bestimmen kann. Das bedeutet,
dass der Generator die Bitsequenz in polynomieller Laufzeit bestimmen können muss.

Definition 3.1 Die Komplexitätsklasse P ist die Klasse der Entscheidungsprobleme, die
von einer deterministischen Turing-Maschine in Polynomialzeit gelöst werden können.
Die Entscheidungsprobleme der Komplexitätsklasse P gelten als effizient berechenbar.

Dass ein Generator ein P-Algorithmus ist, gilt als elementare Voraussetzung dafür, dass
dieser praktikabel verwendet werden kann. In dieser Arbeit werden die untersuchten
Generatoren einer Laufzeitanalyse unterzogen. Diese besteht aus einer mathematischen
Berechnung der Laufzeit aller Algorithmen, die Teil des zu untersuchenden Generators
sind, sowie einer Zeitmessung der Laufzeit bei der Berechnung einer Zufallszahl einer
bestimmten Länge.

                                           6
3.2 Kryptographische Sicherheit
In der Kryptographie gelten für Pseudozufallsgeneratoren noch weitere Anforderungen.
Verschiedene Organisationen überarbeiten regelmäßig die Definitionen für einen krypto-
graphisch sicheren Pseudozufallsgenerator, darunter das National Institute of Standards
and Technology (kurz NIST) [6]. Im folgenden Abschnitt werden diese Anforderungen
vorgestellt.

3.2.1 Zufälligkeit
Das NIST definiert Zufall wie folgt [6]:

      A random bit sequence could be interpreted as the result of the flips of an
     unbiased “fair” coin with sides that are labeled ”0” and ”1”, with each flip
     having a probability of exactly 12 of producing a ”0” or ”1”.

Die Schwierigkeit, diese Eigenschaft durch einen Algorithmus zu erreichen, wurde
bereits erläutert. Des Weiteren sind aber auch Methoden beschrieben worden, mit
denen Pseudozufall echtem Zufall sehr nahe kommt. Durch das Hardcore-Prädikat
einer Einwegfunktion wird die in dem Zitat genannte Verteilung mit vernachlässigbaren
Abweichungen erreicht.
Untereinander dürfen sich die Bits dabei nicht in der Wahrscheinlichkeit beeinflussen,
eine 0 oder eine 1 anzunehmen. Alle Elemente einer Bitsequenz sind somit unabhängig
voneinander zu erzeugen.

3.2.2 Unvorhersagbarkeit
Kein Prädiktor P sollte ein durch einen Pseudozufallsgenerator G erzeugtes Bit, mit einer
signifikant höheren Wahrscheinlichkeit als 12 , unter Kenntnis der von G bisher erzeugten
Bits, bestimmen können. Der Einsatz von Einwegfunktionen im Zusammenhang mit
Hardcore-Prädikaten ist eine Möglichkeit, um einen Prädiktor, der in probabilistischer
Polynomialzeit läuft, bei der Berechnung eines pseudozufälligen Bits zu täuschen.
Das impliziert auch, dass der Seed x, mit dem der Generator G den Pseudozufallswert
G(x) erzeugt, für jeden Prädiktor P unvorhersagbar sein muss. Ist dies nicht der Fall,
ließen sich die folgenden Bits von G(x) unter Anwendung des Algorithmus von G
mithilfe des Seeds berechnen.

3.2.3 Blackboxing
Aus den ersten beiden Bedingungen folgt, dass zwar das Prinzip, nach dem ein Pseudo-
zufallsgenerator G arbeitet, bekannt sein darf, aber der Pseudozufallsgenerator G selbst

                                           7
eine Blackbox sein muss. Die Ausgabe von G darf den inneren Zustand des Generators
nicht offenbaren, da durch diesen die zukünftig auszugebenden Bits zu bestimmen sind.
Die Sicherheit von G ist nur gewährleistet, wenn der Seed und weitere Parameter geheim
gehalten werden. Der Seed ist der einzige Bestandteil eines Pseudozufallsgenerators, der
trotz Determinismus die Ausgabe einer pseudozufälligen Bitsequenz ermöglicht, die un-
unterscheidbar von echtem Zufall ist. Daher ist ein Seed von einer nichtdeterministischen
Quelle zu wählen.

3.2.4 Wahl des Seeds
Da ein deterministischer Algorithmus qualitativ hochwertige Pseudozufallszahlen nur
mittels echtem Zufall erzeugen kann, steht und fällt die Sicherheit eines Generators
mit der Wahl des Seeds [16]. Verschiedene Quellen können dabei in Betracht gezogen
werden. Die Nutzung von atmosphärischem Rauschen oder der Zeit, zwischen zwei
Tastenanschlägen eines Nutzers, kann dafür verwendet werden.
Dabei wird stets das niederwertigste Bit (kurz LSB) verwendet, da bei diesem die
Wahrscheinlichkeit in etwa gleich verteilt ist, sodass jeder mögliche Wert angenommen
wird. Bei der Nutzung des höchstwertigsten Bits müsste angenommen werden, dass sehr
hohe Werte mit einer etwa gleich hohen Wahrscheinlichkeit erreicht werden, wie geringe
Werte. Das LSB nimmt abwechselnd eine 0 oder eine 1 an und ist somit die beste Wahl
für die Verwendung als Zufallsbit. Der Seed selbst muss zufällig und unvorhersagbar
sein, damit der Pseudozufallsgenerator diese Bedingungen auch erfüllen kann.
In dieser Arbeit wird die Ausgabe der Generatoren bezüglich der Wahl des Seeds
untersucht, wobei die Seeds je nach Experiment von random.org [5] bezogen oder selbst
gewählt werden. Dazu ist anzunehmen, dass die Nutzung von Seeds mit geringerem
Wert in einer Erzeugung qualitativ geringerer Pseudozufallszahlen resultiert. Diese
Hypothese wird auf ihre Richtigkeit überprüft.

                                           8
4 Statistische Tests
Die bisher formulierten Anforderungen an Pseudozufallsgeneratoren werden mittels
statistischer Tests überprüft. In Kapitel 2.2.2 wurden statistische Tests bereits genauer
beschrieben. Statistische Tests sind Algorithmen, die eine Bitsequenz auf Zufälligkeit
testen und diese dann als zufällig oder nicht zufällig bewerten [16]. Dies lässt dann auf
die Qualität des Generators schließen, der diese Bitsequenz generiert hat. Das NIST
hat eine Reihe statistischer Tests entwickelt [6]. Einige davon wurden im Zuge dieser
Arbeit implementiert und werden nachfolgend vorgestellt. Vorerst gilt es zu klären, wie
diese Tests zu interpretieren sind. Dabei ist zu beachten, dass keine endliche Menge
statistischer Tests vollständig sein kann. Daher können statistische Tests das Vorliegen
von Zufall nicht beweisen oder widerlegen, sondern indizieren nur, ob eine Bitsequenz
als zufällig oder nicht zufällig generiert betrachtet werden kann.
Getestet wird mit der Grundannahme, dass die vorliegende Sequenz zufällig ist. Diese
Annahme wird als Nullhypothese H0 bezeichnet. Durch statistische Tests wird H0
entweder bewiesen oder widerlegt. Dafür muss im Anschluss des Tests eine statistische
Auswertung stattfinden. Um auf die Richtigkeit von H0 zu prüfen, wird ein kritischer
Wert t bestimmt, der als Schwelle dient, ab der H0 akzeptiert oder abgelehnt wird. Unter
Anwendung des Tests wird dann für eine Bitsequenz ein Statistikwert S bestimmt, der
dann mit t verglichen wird, um den p-W ert auszurechnen.
Der p-W ert ist die Wahrscheinlichkeit, dass ein perfekter Zufallsgenerator eine Sequenz
ausgibt, die weniger zufällig ist, als die Getestete. Ein p-W ert von 1 lässt somit auf per-
fekten Zufall schließen und ein p-W ert von 0 auf völlige Unzufälligkeit. Schließlich wird
dieser p-W ert gegen das Signifikanzniveau α geprüft, das angibt, welche Wahrschein-
lichkeit der p-W ert unterschreiten muss, damit die Nullhypothese für eine Bitsequenz
verworfen wird. Da das NIST sich an den für α üblichen Wert von 0,01 gehalten hat [6],
wird dieser Wert auch in dieser Arbeit als Signifikanzniveau herangezogen.
Jeder vorgestellte Test besteht also aus zwei Bestandteilen. Zum einen bestehen diese
aus den Algorithmen zur Bestimmung des Statistikwertes. Die Algorithmen zu den
Tests werden in dieser Arbeit präsentiert. Zum anderen folgt darauf zur Bestimmung des
p-W ertes die statistische Auswertung. Sämtliche Berechnungen werden somit auf die
Ausgabe eines Wahrheitswertes geführt, der die Annahme von H0 , dass Zufall vorliegt,
bestätigt oder verwirft, wie es in Kapitel 2.2.2 beschrieben wird.

                                             9
Jeder Test gibt ein Tupel aus zwei Werten zurück. Der erste Wert ist der Statistikwert,
der zur graphischen Darstellung verwendet wird. Der zweite Wert ist das Resultat der
Auswertung, der p-W ert, nach dem H0 angenommen oder verworfen wird. Die Formel
zur Berechnung des p-W ertes wird im Anschluss an den Algorithmus zu jedem Test
präsentiert. Dabei wird je Test die Gaußsche Fehlerfunktion [1] verwendet, die wie folgt
definiert ist:                              Z ∞
                                          2          2
                              erf c(z) = √       e−u du.                           (4.1)
                                           n z

4.1 Frequency (Monobit) Test
Der Frequency Test, auch Monobit Test genannt, dient dazu das Verhältnis zwischen
der Anzahl der Nullen und der Einsen zu bestimmen [6].

Algorithmus 2 : Frequency (Monobit) Test [6]

1 def f r e q u e n c y _ t e s t ( s e q u e n c e ) :
2          z e r o = s e q u e n c e . count ( ’ 0 ’ )
3          one = s e q u e n c e . count ( ’ 1 ’ )
4          return z e r o / len ( s e q u e n c e ) , f r e q u e n c y _ s t a t i s t i c ( z e r o , one )

Das Verhältnis zwischen der Anzahl der Nullen und der Länge wird graphisch dargestellt
und ist der erste Rückgabewert in Zeile 4. Die Anzahl der Nullen und Einsen wird
zuvor bestimmt, um sie der Statistikfunktion zu übergeben. Darin wird der p-W ert für
eine Bitsequenz der Länge n mit einer Anzahl von x0 Nullen und x1 Einsen wie folgt
bestimmt:

    1. Berechnung von Sn mit Sn = x1 − x0 , wobei x0 der Variable zero (Zeile 2) und
       x1 der Variable one (Zeile 3) entspricht.
                                       |Sn |
    2. Berechnung von sobs =            √ .
                                         n

    3. Schließlich folgt die Berechnung des p-W ertes:
                                                                           
                                                                     sobs
                                               p-W ert = erf c       √          .                       (4.2)
                                                                       n

Wenn p-W ert ≥ α gilt, wird angenommen, dass die getestete Bitsequenz nach dem
Frequency Test zufällig ist. Wie oben erwähnt, wird für α der Wert 0,01 verwendet.
Nach der Formel ist für den p-W ert anzunehmen, dass im Verhältnis hohe Differenzen
zwischen Einsen und Nullen zur Verwerfung der Nullhypothese führen. Für belastbare
Ergebnisse wird empfohlen, dass für diesen Test Bitsequenzen von mindestens 100 Bits
verwendet werden.

                                                          10
4.2 Runs Test
Der Runs Test zählt die Anzahl der ununterbrochenen Folgen identischer Bits. Dabei
ist jede Folge vorher und hinterher von entgegengesetzten Bits umgeben [6].

Algorithmus 3 : Runs Test [6]

1 def r u n s _ t e s t ( s e q u e n c e ) :
2          total_runs = 1
3          for elem in range ( 1 , len ( s e q u e n c e ) ) :
4                 i f s e q u e n c e [ elem ] != s e q u e n c e [ elem − 1 ] :
5                        t o t a l _ r u n s += 1
6          return t o t a l _ r u n s , r u n s _ s t a t i s t i c ( s e q u e n c e )

Zur Bestimmung des Statistikwertes Vn (obs) wird beginnend beim zweiten Bit über die
Sequenz iteriert (Zeile 3) und der Zähler total_runs jedes Mal inkrementiert, wenn
sich das aktuelle Bit vom vorigen unterscheidet und somit eine neue Folge anfängt. Der
Zähler total_runs wird direkt mit 1 initialisiert (Zeile 2), da das erste Bit den Anfang
der ersten Folge darstellt, was durch die Schleife nicht festgestellt werden würde. Nun
wird der p-W ert bestimmt:

    1. Um den Runs Test durchzuführen, gilt das Bestehen des Frequency Tests als
       Voraussetzung. Daher wird zuvor das Verhältnis π der Einsen zur Länge der
       Sequenz bestimmt. Sei n die Länge der Sequenz und x1 die Anzahl der Einsen in
       ebendieser Sequenz: π = xni .

    2. Sei τ = π2 . Wenn |π − 12 | ≥ τ gilt, ist der Frequency Test nicht bestanden. Der
       Runs Test kann nun einem p-W ert von 0,0000 abgebrochen werden. Ansonsten
       wird mit Schritt drei fortgefahren.

    3. Nun wird der p-W ert berechnet. Dazu wird der Statistikwert Vn (obs) aus dem
       oben beschriebenen Algorithmus herangezogen. Die Formel lautet wie folgt:
                                                                                         
                                                          |Vn (obs) − 2nπ(1 − π)|
                               p-W ert = erf c                  √                             .   (4.3)
                                                               2 2nπ(1 − π)

Auch hier gilt bei einem p-W ert ≥ 0, 01, dass H0 für diese Sequenz akzeptiert wird.

Beispiel 3.1 Sei y = 10010 11001 mit n = 10 die zu untersuchende Sequenz. Dann
gilt π = 10
          5
            = 12 < √2n = τ und der Frequeny Test somit als bestanden. Die Menge der
Folgen lautet {1; 00; 1; 0; 11; 00; 1} und enthält sieben Elemente, so ist Vn (obs) = 7. Die

                                                        11
Sequenz y wird als zufällig angenommen, da sich folgender p-W ert ergibt:
                                                                !
                                |7 − 2 ∗ 10 ∗ 21 ∗ (1 − 12 )|
            p-W ert = erf c        √                                = 0.2059 ≥ 0, 01.   (4.4)
                                 2 2 ∗ 10 ∗ 12 ∗ (1 − 12 )

4.3 Test for the Longest Run of Ones in a Block
In diesem Test wird die zu testende Bitsequenz in M -Bit große Blöcke eingeteilt und in
diesen die längste ununterbrochene Folge von Einsen bestimmt. Es wird geprüft, ob
die Länge dieser Folge mit der erwarteten Länge der längsten Folge von Einsen einer
zufälligen Bitsequenz übereinstimmt [6].
Außer der zu testenden Sequenz gibt noch einige weitere Übergabeparameter. Diese
Übergabeparameter hängen von der Länge n der Sequenz ab und sind auf folgende
Weise zu wählen:

   • M      Die Länge M der gleich großen Blöcke ist abhängig von der Gesamtlänge
            n der Sequenz. Im Algorithmus 4 wird m anstelle von M verwendet.

                                  Minimum n           M
                                     128              8
                                     6272            128
                                   750.000          10.000

                             Tabelle 4.1: Länge M der Blöcke

   • vi     Die Längen der längsten in einem Block festgestellte Folgen werden in
            Klassen eingeteilt. Dabei orientieren sich die Klassen an der Blockgröße M .
            Die Frequenz vi entspricht der Häufigkeit, dass die längste in einem Block
            gefundene Folge der Länge der zugehörigen Klasse entspricht. Gegeben
            sind diese Klassen im Algorithmus durch die Liste v_values.

                        vi     M =8      M = 128       M = 10.000
                        v0      ≤1        ≤4             ≤ 10
                        v1       2         5              11
                        v2       3         6              12
                        v3      ≥4         7              13
                        v4                 8              14
                        v5                ≥9              15
                        v6                               ≥ 16

                 Tabelle 4.2: Einteilung der Frequenzen vi in Klassen

                                             12
• πi      Zu jede dieser Klassen vi gibt es eine Wahrscheinlichkeit πi , dass die längste
              Folge eines Blockes die Länge hat, die dieser Klasse zugeordnet sind. Diese
              Wahrscheinlichkeiten πi sind vorgegeben und entsprechen dem Übergabe-
              parameter pi_values aus dem Algorithmus. Der Übergabeparameter k
              gibt die Anzahl der Klassen, der verschiedenen zu messenden Frequenzen
              an.
    • K        Der Parameter K, dem Algorithmus als k übergeben, ist vorgegeben und
               hängt von M ab.

Algorithmus 4 : Test for the Longest Run of Ones in a Block [6]

 1 def l on ge s t_ on e s_ r un _t e st ( sequence , k , m, v_values , p i _ v a l u e s ) :
 2    # i n i t i a l i z e loop parameters
 3     block_count = int ( len ( s e q u e n c e ) / m)
 4     start = 0
 5     end = m
 6     # l i s t t o c o un t runs f o r e v e r y l e n g t h i n v _ v a l u e s
 7     f r e q u e n c i e s = [ 0 f o r _ in range ( k + 1 ) ]
 8     # go o v e r e v e r y b l o c k
 9     f o r _ in range ( block_count ) :
10             b l o c k = s e q u e n c e [ s t a r t : end ]
11             max_run = 0
12             curr_run = 0
13            # co un t l o n g e s t run i n c u r r e n t b l o c k
14             f o r b i t in b l o c k :
15                     i f b i t == ’ 1 ’ :
16                             curr_run += 1
17                             max_run = max( max_run , curr_run )
18                     else :
19                             max_run = max( max_run , curr_run )
20                             curr_run = 0
21            max( max_run , curr_run )
22            # compare w i t h NIST g i v e n v_value c l a s s e s
23             i f max_run < v_values [ 0 ] :
24                     f r e q u e n c i e s [ 0 ] += 1
25             f o r j in range ( k ) :
26                     i f max_run == v_values [ j ] :
27                             f r e q u e n c i e s [ j ] += 1
28             i f max_run > v_values [ k − 1 ] :
29                     f r e q u e n c i e s [ k ] += 1
30             s t a r t += m # g e t n e x t b l o c k
31             end += m
32     s t a t i s t i c = longest_ones_run_statistic ( frequencies ,
33                                                                  block_count , pi_values , k )
34     return v_values , f r e q u e n c i e s , s t a t i s t i c

                                                13
Der Algorithmus arbeitet wie folgt:

  1. Es wird eine Liste mit Nullen initialisiert, in denen die Häufigkeit der Frequenzen
     gezählt wird (Zeile 7). start und end (Zeile 3 und 4) sind die Grenzen des aktuell
     zu prüfenden Blockes.

  2. In der ersten Schleife (Zeile 9) wird über die Blöcke iteriert, in der zweiten Schleife
     (Zeile 14) über die Bits des jeweiligen Blockes, um die längste Folge von Einsen
     dieses Blockes zu bestimmen.

  3. Anschließend (Zeile 23 bis 29) wird die längste Folge des Blockes der jeweiligen
     Klasse zugeordnet. Mit dem Ende der ersten Schleife sind somit die Frequenzen
     der Klassen bekannt und im Anschluss werden die Statistiken berechnet.

Mit den gesammelten Frequenzen lässt sich der p-W ert berechnen:

  1. χ2 (obs) gibt an, wie groß die Übereinstimmung der festgestellten Frequenzen mit
     den erwarteten Frequenzen ist. In der Berechnung entspricht N der Anzahl der
     M -Bit Blöcke:
                                             K
                                           X    (vi − N πi )2
                                   2
                                 χ (obs) =                    .                  (4.5)
                                            i=0
                                                    N πi

  2. Schließlich lässt sich der p-W ert berechnen:

                                                     K χ2 (obs)
                                                                    
                              p-W ert = igamc          ,                 .            (4.6)
                                                     2     2

Die igamc()-Funktion stammt aus Handbook of Applied Mathematical Functions [1]
und wird auch als unvollständige Gammafunktion bezeichnet. Diese bekommt zwei
Werte übergeben. Die Definition sieht folgendermaßen aus:
                                                     Z   ∞
                                  γ(a, x)    1
                       P (a, x) ≡         ≡                  e−t ta−1 dt.             (4.7)
                                   Γ(a)     Γ(a)     x

Für diesen Test ist eine Länge n der zu testenden Sequenz von mindestens 128 Bits
erforderlich.

4.4 Cumulative Sums Test
Die kumulative Summe einer Bitsequenz der Länge n ist ein Random Walk mit der
Länge n, bei dem sich ein Wert xi der kumulativen Summe mit 1 ≤ i ≤ n aus der
Summe über alle Bits bj mit 1 ≤ j ≤ i berechnen lässt. Zur Normierung der kumulativen
Summe wird mit (-1, +1) anstelle von (0, 1) gerechnet [6].

                                            14
Algorithmus 5 : Cumulative Sums Test [6]

 1 def cumulative_sum_test ( s e q u e n c e ) :
 2         c o u n t s = [ 0 f o r _ in range ( len ( s e q u e n c e ) ) ]
 3         for i n d e x in range ( len ( s e q u e n c e ) ) :
 4                sub = 1
 5                i f s e q u e n c e [ i n d e x ] == ’ 0 ’ :
 6                       sub = −1
 7                i f index > 0 :
 8                       c o u n t s [ i n d e x ] = c o u n t s [ i n d e x − 1 ] + sub
 9                else :
10                       c o u n t s [ i n d e x ] = sub
11         s t a t i s t i c = c u s u m _ s t a t i s t i c ( len ( s e q u e n c e ) , a r r a y ( c o u n t s ) )
12         return counts , s t a t i s t i c

Zu Anfang wird eine Liste mit der Länge n, also der Länge der Sequenz, mit Nullen
initialisiert (Zeile 2). Anschließend wird in der Schleife (Zeile 3) über die Sequenz iteriert
und das entsprechende Element der kumulativen Summe gebildet. sub gibt für den
Bitwert an der Stelle i an, ob mit -1 oder mit +1 gerechnet werden muss (Zeile 4). Die
Schleife endet mit der Fallunterscheidung zur Prüfung, ob i = 0 gilt (Zeile 7) und der
Zeiger demzufolge auf das erste Bit zeigt. Dann erhält das erste Feld der kumulativen
Summe den Wert von sub (Zeile 10). Ansonsten muss der Wert von sub auf den Wert des
vorigen Feldes addiert werden, sodass die Summe aller bisherigen Elemente einbezogen
wird.
Mit dem resultierenden Feld S lässt sich der p-W ert berechnen:

     1. Zunächst ist das Maximum z = max1≤k≤n |Sk | der Partialsummen S zu bestimmen.

     2. Der p-W ert ergibt sich aus der Gleichung:

                                     ( nzX
                                         −1)/4 "                         !                        #
                                                          (4k + 1)z                    (4k − 1)z
              p-W ert = 1 −                         Φ       p                −Φ           √             +
                                         −n
                                                              (n                            n
                                   k=(      +1)/4
                                                                                                                   (4.8)
                                          z

                                       ( nzX
                                           −1)/4 "                        !                        #
                                                            (4k + 3)z                   (4k + 1)z
                                                      Φ       p                −Φ          √             .
                                                                (n                           n
                                    k=( −n
                                         z
                                           −3)/4

Die Standardnormalverteilung Φ ist gegeben durch [6]:
                                                           Z   z
                                                 1                    2 /2
                                         Φ(z) = √                  e−u       du.                                   (4.9)
                                                  2π         −∞

                                                          15
Auch für diesen Test wird eine Bitsequenz mit mindestens 100 Bits empfohlen. Die ge-
testete Sequenz kann als zufällig angenommen werden, wenn ein p-W ert ≥ 0, 01 erreicht
wird. Bei einer zufälligen Sequenz ist zu erwarten, dass unter den kumulativen Summem
keine großen Exkursionen von der x-Achse zu sehen sind [6]. Große Maximalwerte
deuten auf eine lange Folge von Nullen oder Einsen hin, woraufhin die Nullhypothese
H0 mit einer geringeren Wahrscheinlichkeit akzeptiert wird. Aber auch bei zu geringen
Werten wird H0 verdächtig, denn diese deuten auf eine zu gleiche Verteilung der Nullen
und Einsen hin.

4.5 Weitere Tests
Außer den genannten, vom NIST stammenden, statistischen Tests wurden zwei weitere
entwickelt. Diese dienen jedoch nur als erste Orientierungspunkte, damit sich der Beob-
achter ein vorläufiges Bild machen kann, ob für gegebene Sequenzen die Nullhypothese
H0 , dass diese Sequenzen als zufällig angenommen werden können, zutrifft. Zu diesen
Tests gibt es folglich keine statistische Auswertung. Durch deren graphische Darstellung
können jedoch die Ergebnisse weiterer durchgeführter Test, wie der beschriebenen,
erahnt werden.
Mit dem Longest Run in the Sequence Test ist zu erkennen, wie lang die längste Folge
der gesamten Sequenz ist. Zu geringe oder zu hohe Werte lassen auf eine große Gleich-
verteilung oder eine große Ungleichverteilung schließen. Dieser Test ist eine Ergänzung
zum Test for the Longest Run of Ones in a Block, da so auch Folgen erkannt werden
können, die länger sind als ein Block.
Der Distribution of Zeroes Test gibt für k Sequenzen an, wie groß in diesen Sequenzen
die Wahrscheinlichkeit ist, dass das Bit an der Stelle i den Wert Null hat. Daraus kann
schlussgefolgert werden, ob ein Generator Regelmäßigkeiten bei der Generierung der
Bitsequenzen aufweist.
Trotz aller Tests bleibt immer die Gefahr, das eine nicht zufällige Zeichenkette als
zufällig angenommen wird, da jede endliche Menge statistischer Tests um Tests erweiter-
bar ist, die die bisher gesammelten Informationen ergänzen. Auch das NIST hat noch
einige weitere Tests entwickelt [6]. In dieser Arbeit werden zur Bewertung der folgenden
Generatoren die beschriebenen statistischen Tests herangezogen.

                                          16
5 Blum-Micali-Generator
Der Blum-Micali -Generator wurde im Jahr 1984 von seinen Namensgebern Manuel
Blum und Silvio Micali vorgestellt und gilt als kryptographisch sicherer Pseudozufalls-
generator [8]. Bevor dieser These auf den Grund gegangen wird, muss das Konzept des
Generators beleuchtet werden.

5.1 Konzept
Dazu wird der Pseudocode des Generators betrachtet.
Pseudocode 6 : Blum-Micali-Generator - Aufbau [16]

1 Choose a random k−b i t prime p and a p r i m i t i v e r o o t g mod p .
2 Choose x ∈R Z∗p .
3 Let x1 = x and xi = g xi−1 mod p , f o r i = 2 t o l(k) .
4 Let bi = most(xi ) .
5 Output t h e s e q u e n c e bl(k) , bl(k)−1 , ..., b2 , b1 .

Zunächst werden die Parameter für den Algorithmus gewählt (Zeile 1 und 2). Es gibt
drei Parameter:

   • Eine echt zufällige Primzahl p mit einer Länge von k Bits.

   • Eine zu p zugehörige Primitivwurzel g mod p.

   • Ein echt zufälliger Seed x.

Eine Zahl a ∈ Z ist eine Primitivwurzel mod m, wenn sich alle Elemente der primen
Restklassengruppe mod m als Potenzen ai mit 1 ≤ i < a darstellen lassen [9].

Beispiel 5.1 Die 3 ist eine Primitivwurzel mod 5, da jedes Element x mit 1 ≤ x < 5
der Restklassengruppe mod 5 als Potenz 3i mit 1 ≤ i < 5 zu erzeugen ist.

                              31 ≡ 3      mod 5            32 ≡ 1   mod 5
                              33 ≡ 4      mod 5            34 ≡ 2   mod 5

                             Tabelle 5.1: Restklassengruppe mod 5.

                                                     17
Nun wird die Berechnung der Pseudozufallszahl b mit einer Länge von l(k) ≥ k Bits
betrachtet:

  1. Für jedes i in 2 ≤ i ≤ l(k)...
       a) ...wird xi = g xi−1 mod p berechnet, wobei zuvor x1 := x definiert wird
          (Zeile 3).
       b) ...ist das Bit bi = most(xi ) unter Anwendung des Hardcore-Prädikats most
          zu berechnen (Zeile 4).

  2. Die Bits werden dann im umgekehrter Reihenfolge ausgegeben (Zeile 5).

Kern des Algorithmus
Das zentrale Element des Blum-Micali -Generators ist die diskrete Exponentialfunktion

                           dexp(p, g, x) = (p, g, g x mod p).                    (5.1)

Die Umkehrfunktion zur diskreten Exponentialfunktion mod p ist der diskrete Loga-
rithmus mod p. Da es keinen deterministischen Algorithmus gibt, der den diskreten
Logarithmus mod p in Polynomialzeit berechnet, gilt die dexp-Funktion als Einweg-
funktion. Als zugehöriges Hardcore-Prädikat wird die Berechnung des höchstwertigen
Bits verwendet, um ein einzelnes Bit der Pseudozufallszahl zu bestimmen [16].
                                    
                                    0, if x < (p − 1)/2,
                          most(x) =                                              (5.2)
                                    1, sonst.

Die Bedeutung dieser beiden Funktionen für die Produktion von Pseudozufall wurde in
Kapitel 2.2 bereits aufgeführt. In der Theorie gilt die Kombination aus Einwegfunktion
und Hardcore-Prädikat als sicher gegenüber jedem Prädiktor. In letzter Instanz hängt
die Sicherheit aber noch von den Parametern ab.
Um die Ausgabe dieses Pseudozufallsgenerators bezüglich der Parameter zu untersuchen,
gegebenenfalls Pattern festzustellen und somit die Schwächen zu bestimmen, ist eine
Implementierung des Generators notwendig. Aus diesem Grund werden fortführend
die Bestandteile des Algorithmus vorgestellt und Unterschiede zwischen dem bereits
präsentierten Pseudocode und der reellen Implementierung aufgezeigt.
Sämtliche Implementierungen werden mittels Python vorgenommen. Da die Effizienz eine
wichtige Anforderung an Pseudozufallsgeneratoren ist, wird eine Laufzeitabschätzung
von jedem Algorithmus durchgeführt.

                                          18
5.2 Implementierung
5.2.1 Diskrete Exponentialfunktion
Zunächst wird kurz die diskrete Exponentialfunktion betrachtet. Diese Funktion ist ein
Zweizeiler, wobei die Laufzeit von x abhängt. Zur Berechnung von g x wird die Funktion
pow(g, x) verwendet.
Algorithmus 7 : diskrete Exponentialfunktion

 1 def dexp ( p , g , x ) :
 2       return pow( g , x ) % p

Die pow(g, x)-Funktion ließe sich auch ohne Verwendung der Standardbibliothek
umsetzen:
     return pow( g , x ) \% p             →              g_x = g
                                                         f o r _ in range ( 1 , x ) :
                                                              g_x = g_x ∗ g
                                                         return g_x % p

Durch Betrachtung der Variante mit der for-Schleife wird die Laufzeit des Algorithmus
klar. Das x als Zählervariable gibt die Laufzeit an, welche offenbar mit steigendem x
linear ansteigt. Die restlichen Operationen sind mathematischer Natur mit konstanter
Laufzeit und beeinflussen die Laufzeit somit nicht wesentlich. Da der lineare Anstieg
durch x der steilste ist, ist der Algorithmus der Laufzeitklasse O(x) zuzuordnen.

Definition 5.1 [14] Sind f (n) und g(n) Funktionen N → R≥0 , so sagt man:
f (n) ist O(g(n)) oder f (n) ∈ O(g(n)) oder „f (n) wächst höchstens in der Größen-
ordnung von g(n)” genau dann, wenn es Konstanten c > 0 und n0 ≥ 0 gibt, so dass
f (n) ≤ c ∗ g(n) für alle n ≥ n0 gilt.

5.2.2 Hardcore-Prädikat
Das Hardcore-Prädikat ist der zweite wichtige Baustein des Blum-Micali-Generators,
aber ebenso kurz, wie die Einwegfunktion.
Algorithmus 8 : Hardcore-Prädikat

 1 def most ( x , p ) :
 2       return 0 i f x < ( p − 1 ) / 2 e l s e 1

Zurückgegeben wird 0 oder 1, je nachdem, ob die Bedingung x < (p − 1)/2 für die
Ausgabe von 0 zutrifft oder nicht. Die Laufzeit für das Prüfen dieser Bedingung verhält
sich unabhängig von den Übergabeparametern x und p, was auf eine konstante Laufzeit

                                          19
schließen lässt. Damit ist dieser Algorithmus der Klasse O(1) zuzuordnen. Die einzige
Besonderheit des Algorithmus ist, dass dieser zusätzlich zu x auch die Primzahl p
übergeben bekommt. Dies wird der Funktion in der Definition als bekannt vorausgesetzt.
In der Implementierung ist das nicht der Fall.

5.2.3 Der Generator
Die Implementierung des Blum-Micali -Generators selbst unterscheidet sich leicht von
dem gegebenen Pseudocode.
Algorithmus 9 : Blum-Micali-Generator

1 def blum_micali_generator ( p , g , random , l k ) :
2        r e s u l t = ""
3        for i in range ( 1 , l k ) :
4              r e s u l t = s t r ( u t i l s . most ( random , p ) ) + r e s u l t
5              random = u t i l s . dexp ( p , g , random )
6        r e s u l t = s t r ( u t i l s . most ( random , p ) ) + r e s u l t
7        return r e s u l t

Anstatt die Wahl der Parameter p, g und des Seeds random, der x aus dem Pseudocode
entspricht, innerhalb des Generators vorzunehmen, werden diese übergeben. Damit ist
der Generator keine Blackbox mehr und es besteht ein erhöhtes Risiko, dass ein Angreifer
die Daten zur Generierung der Pseudozufallszahl abfangen und die Berechnungen auch
selbst vornehmen kann. Beim Einsatz in der Kryptographie ist das eine kritische Sicher-
heitslücke. In diesem Falle wird es vernachlässigt, da es zu experimentellen Zwecken
dient, die Parameter selbst bestimmen zu können.
Die Ausdrücke in der Schleife (Zeile 4 und 5) sind verglichen mit dem Pseudocode in
umgekehrter Reihenfolge. Zuerst wird die Funktion most(random,p) aufgerufen und das
Ergebnis vor den bisherigen result-String vorangestellt. Anschließend wird die Berech-
nung von dexp(p,g,random) vorgenommen. Hintergrund ist, dass im Pseudocode auch
von dem Seed x most(x) berechnet werden soll. Das muss geschehen, bevor x, also im im-
plementierten Python-Algorithmus random, mit dem Ergebnis von dexp(p,g,random)
überschrieben wird. Entsprechend muss vor Abschluss des Algorithmus für das letzte
Ergebnis der Exponentialfunktion most(random,p) aufgerufen werden (Zeile 6). In den
Algorithmen wird mit Stringrepräsentationen der Bitsequenzen gearbeitet.
Die Laufzeit des Generators als Ganzes wird hauptsächlich von random und von der
erwünschten Länge lk der Ausgabe bestimmt. Wird der Aufruf von dexp(p,g,random)
außer Acht gelassen, ergibt sich eine in Abhängigkeit von lk lineare Laufzeit. Die Lauf-
zeit von dexp(p,g,random) hängt von random ab, also von einem Wert, der sich nach

                                                 20
jedem Durchlauf der Schleife verändert. Wie groß dieser Wert werden kann, ist wiederum
abhängig von p, aufgrund der Modulo-Funktion innerhalb von dexp(p,g,random). Das
erschwert eine Laufzeitberechnung. Da jedoch der Exponent random der Exponential-
funktion durch die Modulo-Operation gedeckelt wird, bleibt es für dexp(p,g,random)
über alle Durchgänge bei einer linearen Laufzeit.
Durch diese Kombination aus Algorithmen mit linearen Laufzeiten ist zu schließen, dass
der Generator in Polynomialzeit läuft.

5.3 Hilfsfunktionen
Zur Berechnung der möglichen Primitivwurzeln zu einer Primzahl werden weitere
Hilfsfunktionen benötigt. Die Funktion zur Prüfung, ob zwei Zahlen teilerfremd sind,
wird benötigt, um die Liste der Primitivwurzeln zu einer Primzahl zu bestimmen.

5.3.1 Teilerfremdheit
Zwei Zahlen a, b ∈ N heißen teilerfremd, wenn es kein x ∈ N mit x > 1 gibt, sodass gilt:

                                      a mod x = b mod x = 0.                       (5.3)

Gesucht wird also der größte gemeinsame Teiler (ggT) beider Zahlen. ggT (a, b) gibt die
größte natürliche Zahl x an, der a, b ∈ N restlos teilt.
Algorithmus 10 : Prüfen auf Teilerfremdheit

 1       def c o p r i m e _ i n t e g e r s ( a , b ) :
 2              i f a == b :
 3                     return F a l s e
 4              lower = a i f a < b else b
 5              f o r i in range ( 2 , l o w e r +1):
 6                     i f a % i == 0 and b % i == 0 :
 7                            return F a l s e
 8              return True

Der Algorithmus prüft zunächst, ob a und b identisch sind und bricht die Berechnung
infolgedessen ab (Zeile 2 und 3), da die beiden Zahlen in diesem Fall nicht teilerfremd
sein können. Anschließend wird der kleinere der beiden Werte ausgemacht (Zeile 4),
weil dieser Wert die Obergrenze für einen größten gemeinsamen Teiler ist. Für jeden
Wert zwischen zwei und dem niedrigeren der beiden Zahlen wird überprüft, ob dieser
Wert beide Zahlen restlos teilt (Zeile 5 und 6). Ist dies der Fall wird abgebrochen. Wird
kein gemeinsamer Teiler gefunden, wird True zurückgegeben, womit die beiden Zahlen

                                                      21
teilerfremd sind.
Mit einer Schleife, deren Laufzeit linear zur Größe des kleinsten Wertes ist und weiteren
Operationen in konstanter Laufzeit, wächst die Laufzeit des ganzen Algorithmus in
linearer Größenordnung bezüglich a und b.

5.3.2 Primitivwurzeln
Nun wird die Berechnung aller Primitivwurzeln mod p zu einer Primzahl p betrachtet.
Algorithmus 11 : Primitivwurzeln bestimmen

 1 def g e t _ p r i m i t i v e _ r o o t ( p ) :
 2          coprimes = [ ]
 3          for i in range ( 1 , p ) :
 4                 i f coprime_ints ( i , p ) :
 5                        c o p r i m e s . append ( i )
 6          k = 0
 7          while k < len ( c o p r i m e s ) :
 8                 list = []
 9                 f o r i in range ( 1 , p ) :
10                        c a l c = pow( c o p r i m e s [ k ] , i ) % p
11                        i f c a l c not in l i s t :
12                               l i s t . append ( c a l c )
13                        else :
14                               c o p r i m e s . remove ( c o p r i m e s [ k ] )
15                               k = k − 1
16                               break
17                 k = k + 1
18          return c o p r i m e s

Dazu wird zunächst für alle Zahlen 1 ≤ i < p überprüft, ob diese teilerfremd zu p ist.
Jedes i, dass diese Bedingung erfüllt, wird in der Liste coprimes gespeichert (Zeile 2
bis 5).
Über diese Liste coprimes wird iteriert und für jeden Wert k geprüft, ob sich alle
Elemente der primen Restklassengruppe mod p als Potenz k i mit 1 ≤ i < p darstel-
len lassen (Zeile 9 und 10). Die Potenzen zu jedem Wert werden in der Liste list
gespeichert (Zeile 10 bis 12). Wiederholt sich ein Wert in list bevor alle Elemente
der Restklassengruppe gefunden wurden, dann ist k keine Primitivwurzel mod p, wird
aus list entfernt und es wird mit dem nächsten Element von coprimes fortgefahren
(Zeile 13 bis 16). Die verbliebene Liste coprimes entspricht der Menge der Primitiv-
wurzeln mod p.

                                                         22
Diese Brute-Force-Methode hat eine polynomielle Laufzeit. Die Größenordnung dieser
Laufzeit ergibt sich durch die Verschachtelung aus der while-Schleife, die über die Liste
der zu p teilerfremden Elemente iteriert (Zeile 7) und der for-Schleife, die für jedes
Element dieser Liste prüft, ob sich alle Werte der Restklassengruppe mod p als Potenz
berechnen lassen (Zeile 9). Die pow-Funktion innerhalb dieser Verschachtelung ermittelt
die Potenzen (Zeile 10) und erhöht die Laufzeit pro Durchgang der for-Schleife noch
einmal um den Faktor i. Durch diese Verschachtelung ergibt sich eine polynomielle
Laufzeit in Abhängigkeit von p.

5.4 Untersuchung
Nachfolgend werden Statistiken gezeigt, die verdeutlichen, welche Bedingungen für
die Parameter gelten müssen, damit die resultierende Pseudozufallszahl echtem Zufall
möglichst nahe kommt. Die p-W erte der vorgestellten Statistikfunktionen dienen als
Richtwert für die Auswertung. Dazu werden jeweils Bitsequenzen mit einer Länge
von 128 Bits verwendet. Aus der Betrachtung der beiden fundamentalen Bestandteile
des Blum-Micali -Generators, der diskreten Exponentialfunktion und dessen Hardcore-
Prädikat, lassen sich bereits einige Hypothesen ableiten.

5.4.1 Patternerzeugung in Abhängigkeit der Primzahl p
Es ist schnell festzustellen, dass eine gute Wahl des Parameters p von großer Bedeutung
ist. Denn mit p wird durch die Verwendung des Modulo ein Maximalwert für das
Ergebnis der diskreten Exponentialfunktion festgelegt. Abhängig von der Größe von p
wiederholen sich damit auch die generierten Bits.
Die Periode kann dabei eine Maximallänge von p erreichen, ist jedoch häufig kürzer. Für
die Nutzung dieses Generators in der Kryptographie bedeutet das, dass p vorzugsweise
einen höheren Wert als die Länge l(k) der benötigten Bitsequenz haben sollte. Wenn ein
Prädiktor P bei einer Periodenlänge von m Bits Kenntnis über alle Bits einer Periode
hat, dann kann dieser alle folgenden Bits berechnen, sofern das Pattern erkannt wird.
Besonders gut sind diese Pattern unter Betrachtung einer Auswertung des Cumulative
Sums Test zu erkennen, wie sich in der folgenden Grafik zeigt. Exemplarisch ist für
die grün dargestellte Sequenz die Entwicklung einer Periode durch ein rotes Rechteck
markiert. Jeder Punkt gibt die Entwicklung der kumulativen Summen wieder. Für
die grüne Sequenz ergibt sich ein Bitpattern mit einer Periodenlänge m = 22. Da ein
ansteigender Trend vorliegt, besteht diese Sequenz zur Mehrheit aus Einsen. An dem
durchgehenden Gefälle am Ende jeder Periode ist zu erkennen, dass die Sequenz aber
auch längere Teilfolgen von Nullen enthält.

                                           23
Abbildung 5.1: Mustererkennung am Beispiel der kumulativen Summen mit p = 23,
               x = 10 und g ∈ {17; 19; 20}.

5.4.2 Der Seed x gibt den Startwert des Patterns vor
Es wird eine Reihe unterschiedlicher Bitsequenzen mit konstanten Parametern p und
g und mit 1 ≤ x ≤ 200, so ist auch zwischen den Sequenzen ein repetitives Muster so
erkennen. Für die Bitsequenzen wird eine Länge von 32 Bits gewählt.

   Abbildung 5.2: Anteil an Nullen bei p = 23, g = 5 und x ∈ [1, 100] pro Sequenz.

Der prozentuale Anteil der Nullen (Frequency Test) ist aufgetragen über x ∈ [1, 100]
und zeigt, dass sich für ein p und ein g mit 100 unterschiedlichen Werten für x 100
Bitsequenzen erzeugen lassen, wobei sich innerhalb eines bestimmten Intervalls von x
der Anteil an Nullen in den Sequenzen wiederholt.
Werden diese Bitsequenzen geprüft, ist zu erkennen, dass es sich bei den generierten

                                         24
Pseudozufallszahlen mit etwa dem gleichen Anteil an Nullen, um annähernd dieselben
Bitfolgen handelt. Der entscheidende Unterschied ist, dass diese Sequenzen ungleich
anfangen, jedoch in den gleichen Pattern münden. Seien u und v zwei mit diesem
Generator generierte Bitsequenzen, bei denen die Ergebnisse der Funktion dexp(p, g, x)
zur Berechnung der Bits von u und v periodisch sind und dem gleichen Pattern
entsprechen, dann lässt sich v als Rotation von u darstellen und umgekehrt.
Eine Rotation ist eine Verschiebung der Bits einer Sequenz um n Stellen, sodass bei
einer Rotation nach links die n höchstwertigen Bits die n niederwertigsten Stellen
einnehmen. Bei einer Rechtsrotation gilt dies entsprechend umgekehrt.
Diese Phänomen wird nachfolgend am Beispiel zweier Sequenzen u und v gezeigt. Dafür
wird mit p = 17 ein niedriger Wert gewählt, damit sich möglichst früh eine Wiederholung
des Patterns zeigt, dass durch die Ergebnisse von dexp(p, g, x) zustande kommt. Auch
g = 6 ist fest für beide Sequenzen fest. Der Seed für u ist mit x0 = 5 und für v mit
x0 = 11 bestimmt.
          Durchlauf                  u mit x0 = 5             v mit x0 = 11
              i        dexp(17, 6, xi ) most(xi ) dexp(17, 6, xi ) most(xi )
              0                      5      0                  11      1
              1                     7       0                   5      0
              2                    14       1                  7       0
              3                     9       1                 14       1
              4                    11       1                  9       1
              5                     5       0                 11       1
              6                      7      0                  5       0
              7                     14      1                   7      0
             ...                   ...                        ...

             Tabelle 5.2: Patternentstehung bei festen p = 17 und g = 5.

Es ist zu beachten, dass der Blum-Micali -Generator die Bits in umgekehrter Reihenfolge
ausgibt. Die Bitsequenzen lauten also:
                                 u = ...10 01110 0
                                 v = ...0 01110 01
Nach fünf Durchläufen wiederholen sich somit die Werte von dexp(17, 6, xi ) für u und v.
Das heißt, das Pattern hat eine Periodenlänge von m = 5. Wenn p und g den oben
angegebenen Werten entsprechen, werden immer Bitsequenzen mit dem Pattern 01110
erzeugt, wenn Wert für x als Seed aus der Menge {7; 14; 9; 11; 5} gewählt wird.

5.4.3 Die Menge möglicher Pattern ist durch g gegeben
Auch die Primitivwurzel g mod p hängt mit der Patternerzeugung zusammen. Das ist
durch folgendes Experiment feststellbar.

                                          25
Es werden verschiedene Mengen M von Bitsequenzen erstellt. Es wird eine feste Primzahl
p gewählt, mit der alle Bitsequenzen über alle Mengen generiert werden. Für jede dieser
Mengen Mi wird eine feste Primitivwurzel g mod p bestimmt, mit der alle Sequenzen
dieser Menge berechnet werden, jedoch für jede Menge Mi eine andere Primitivwurzel.
Jede dieser Mengen Mi besteht aus 100 Bitsequenzen, mit x ∈ [1, 100].
Wie in Abbildung 5.2 zu erkennen war, zeigt sich an dem Anteil der Nullen in den
Sequenzen, welche Werte der Seed x haben muss, damit sich die gleichen Pattern
erzeugt werden. Wenn für unterschiedliche Primitivwurzeln g mod p die gleichen
Pattern generiert werden würden, dann sähen auch die Graphen für die Frequenz der
Nullen in den Sequenzen über x ∈ [1, 100] gleich aus oder wiesen höchstens eine vertikale
Verschiebung um ein bestimmtes x auf.
Durchgeführt wird dieses Experiment mit den Mengen Mi mit 1 ≤ i ≤ 4, deren je 100
Bitsequenzen mit folgenden Parametern generiert werden:

                            M1 : p = 23, g = 7, x ∈ [1, 100]
                            M2 : p = 23, g = 10, x ∈ [1, 100]
                            M3 : p = 23, g = 11, x ∈ [1, 100]
                            M4 : p = 23, g = 14, x ∈ [1, 100]

In den nächsten Grafiken ist für jede Menge Mi die Frequenz der Nullen über
x aufgetragen. Dabei steht hinter jedem x eine Sequenz, die mit x als Seed ge-
neriert wurde, bei gleich bleibenden Werten für p und g, wie oben angegeben.

Abbildung 5.3: Anteil an Nullen über            Abbildung 5.4: Anteil an Nullen über
               x für M1 .                                      x für M2 .

                                           26
Abbildung 5.5: Anteil an Nullen über           Abbildung 5.6: Anteil an Nullen über
               x für M3 .                                     x für M4 .
Alle generierten Sequenzen haben eine Länge von 32 Bits. Dadurch, dass p gering be-
stimmt ist, kann ein schnell wiederkehrendes Muster erkannt werden. Dass die Graphen
gänzlich unterschiedlich sind, ist eine hinreichende Bedingung dafür, dass durch die
Wahl von g bei festem p unterschiedliche Mengen von Pattern vorgegeben werden.
Durch die Wahl von x wird dann aus dieser Menge von Pattern eines ausgewählt.
Zu beachten ist, dass andersherum die Gleichheit der Muster der Graphen jedoch nicht
hinreichend wäre, um zu beweisen, dass mit unterschiedlichen Primitivwurzeln g mod p
die gleichen Pattern erzeugt werden können. Das ist wichtig, da verschiedene Sequenzen
den gleichen Anteil an Nullen haben können, ohne aus denselben, wiederkehrenden
Pattern zu bestehen. Somit ist es möglich, dass sich zwei Graphen mit dem Anteil
der Nullen über x ähneln, obwohl die Sequenzen, die hinter jedem x stehen, gänzlich
unterschiedlich sind.

5.4.4 Niedrige Seeds x fallen aus dem Muster
Unter Betrachtung der Graphen fallen noch weitere Eigenschaften in den Mengen M auf.
Bisher wurde zum einen gezeigt, dass innerhalb der Bitsequenzen Pattern festgestellt
werden können. Zum anderen wurde aufgeführt, dass diese Pattern nicht nur innerhalb
der Sequenzen zu finden sind, sondern auch über mehrere Sequenzen hinweg, wenn
feste p und g für alle Sequenzen gewählt werden. Bestehen zwei Sequenzen u und v
aus dem gleichen Pattern, ist die eine Sequenz als Rotation der Anderen darzustellen.
Ferner erweist aber auch, dass u = v mit xu als Seed von u und xv als Seed von v für
eine bestimmte Differenz |xv − xu | gilt. Es werden somit in immer gleichen Abständen
|xv − xu | die exakt gleichen Sequenzen genieriert. Für die Parameter der Mengen Mi
mit 1 ≤ i ≤ 4 zeigt sich, dass diese Differenz |xv − xu | = p − 1 in Abhängigkeit von p
steht.
Hintergrund ist die Eigenschaft von Primitivwurzeln g mod p, dass das Ergebnis jeder

                                          27
Sie können auch lesen