Ruhr-Universität Bochum Lehrstuhl für Kryptologie und IT-Sicherheit Prof. Dr. Alexander May Mathias Herrmann, Alexander Meurer Lösungsblatt zur Vorlesung Kryptanalyse WS 2009/2010 Blatt 6 / 23. Dezember 2009 / Abgabe bis spätestens 20. Januar 2010, 10 Uhr (vor der Übung) AUFGABE 1 (4 Punkte): Sei k = (p, α, β = α a ) ein öffentlicher ElGamal Schlüssel mit geheimem Schlüssel a. Sei e k (m) = (α r, mβ r ) ein ElGamal-Chiffretext. Weiterhin sei l = log p + log log p. Sei A ein Algorithmus, der für beliebiges b bei Eingabe α a+b, α r und mβ r die obersten l Bits von m (α r ) b berechnet. Zeigen Sie, dass es dann einen polynomiellen Algorithmus zur Berechnung von m gibt, d.h. dass ElGamal in polynomieller Zeit gebrochen werden kann. Hinweis: Konstruieren Sie eine Instanz des Hidden Number Problems. Lösungsvorschlag: Es sei e k (m) = (α r mod p, m β r mod p) mit r R Z p 1 die Verschlüsselung von m und sei (p, α, β = α a ) der öffentliche Schüssel. Wir wenden nun den Algorithmus A für i = 1,..., 2 log p mit Eingabe (βα i, α r, m β r ) an. Dieser liefert uns dann jeweils die l obersten Bits von mα ir. Ferner berechnen wir für obige i jeweils die Werte t i := (α r ) i = α ir mod p Aus den l obersten Bits von mα ir, welche uns A geliefert hat, können wir dann eine Approximation mt i von mt i berechnen 1 mit Güte mt i mod p mt i p 2 l 1 Das gilt ganz allgemein, wenn wir für ein x Z p die l obersten Bits von x kennen. Sei hierzu k = log x +1 die Bitlänge von x (d.h insbesondere gilt 2 k p) und sei x = x (l) 2 k l + r (d.h. x (l) sind die l obersten Bits von x und r der Rest). Wir können dann die Approximation x := x (l) 2 k l + 2 k l 1 bilden. Für diese gilt, dass x x = r 2 k l 1. Wir untersuchen also die beiden Extremfälle r = 0 bzw. r = 2 k l 1, welche maximale Abweichung von x ermöglichen. Für r = 0 erhalten wir x x 2 k l 1, für r = 2 k l 1 gilt x x = 2 k l 1 2 k l 1 = 2 k l 1 (2 1) 1 2 k l 1. Insgesamt haben wir also x x 2 k l 1 = 2k 1 2 l p 2 l
d.h. wir erhalten so eine Instanz des Hidden-Number-Problems mit d = 2 log p und l = log p + log log p, welche nach Fakt 75 aus der Vorlesung in polynomieller Zeit (heuristisch) gelöst werden kann und uns die Lösung m liefert. Anzumerken ist, dass alle nötigen Operationen (modulares Potenzieren, Invertieren) mit den Algorithmen aus der Vorlesung effizient durchführbar sind. AUFGABE 2 (6 Punkte): Sei M N mit unbekanntem Teiler b M 1 2 und f(x) = x + a. (a) Geben Sie die komplette Basismatrix B des Gitters L aus Satz 66 für die Parameterwahl m = 3 an. Bestimmen Sie dim(l) und det(l). Lösungsvorschlag: Für m = 3 und β = 1 2 berechnen wir folgende Kollektion von Polynomen f 0 (x) = M 3 f 1 (x) = M 2 f(x) = M 2 x + M 2 a f 2 (x) = Mf 2 (x) = Mx 2 + 2aM + Ma 2 f 3 (x) = f 3 (x) = x 3 + 3ax 2 + 3a 2 x + a 3 f 4 (x) = xf 3 (x) = x 4 + 3ax 3 + 3a 2 x 2 + a 3 x f 5 (x) = x 2 d 3 (x) = x 5 + 3ax 4 + 3a 2 x 3 + a 3 x 2 woraus wir leicht die Koeffizientenvektoren der Polynome f i (xx) bestimmen können, was zu folgender Basismatrix führt M 3 0... 0 M 2 a M 2 X 0... 0 B = Ma 2 2aMX MX 2 0 0 0 a 3 3a 2 X 3aX 2 X 3 0 0 0 a 3 X 3a 2 X 2 3aX 3 X 4 0 0 0 a 3 X 2 3a 2 X 3 3aX 4 X 5 B ist eine untere Dreiecksmatrix und wir erhalten sowie dim(l) = 6. det(l) = M 6 X 15 (b) Sei N = pq ein RSA Modul mit 512-Bit Primzahlen p, q, wobei p > q. Gegeben ist eine Approximation p von p mit p p N 0.225. Implementieren Sie einen Gitterangriff für dieses Szenario. Welchen Wert von m müssen Sie wählen, um den Modul faktorisieren zu können? Die Parameter N und p stehen auf der Webseite zum Download bereit.
Lösungsvorschlag: Das folgende sage Skript findet das korrekte p für die Parameterwahl m 6: from sage.libs.fplll.fplll import FP_LLL def fillbasis(b,g,row): coeffs=g.coeffs(); for pos in range(len(coeffs)): B[row,pos]=coeffs[pos]; return; def getpol(v,x): thepol=0; for i in range(len(v)): thepol = thepol + (v[i]/(x^i))*(x^i) return thepol; N=289284702823953245408697780864108836518475048797656161264983053848464669174718 03301255186315012884170094471946588020810537070264429899472619287547817072751027 43824613576022214301697370737119675473071965051178784807024335769065604280158146 56938250778423992053356769172404178025838971324951076247225099343793023 ptil=178534998342989234213656496540702147640622218510078159647469388128655062041 06551006895621956353222037418711259688355788999324788579270764296585545177366528 P,x=PolynomialRing(IntegerRing(),x).objgen() b=1/2 X=ceil(RDF(N^(0.225))) f=x+ptil dim=1/b*m B=matrix(dim,dim); thepositions=[]; #index ist position in der Basismatrix, denn wir fügen der Reihe anch hinzu counter=0; for i in range(m+1): pol=n^(m-i)*f^i; pol=pol.subs(x=x*x); thepositions=fillbasis(b,pol,counter); counter=counter+1; for i in range(m+1,1/b*m): pol=x^(i-m)*f^m; pol=pol.subs(x=x*x); thepositions=fillbasis(b,pol,counter); counter=counter+1;
F = FP_LLL(B) F.wrapper() red=f._sage_() root=getpol(red[0],x).roots()[0][0] testp=root+ptil if Integer(testp).divides(N): print "Found divisor p=", testp else: print "No divisor :-(" Die Ausgabe des Programms ist dann wie folgt: sage: m=4 sage: load "h6.sage" No divisor :-( sage: m=5 sage: load "h6.sage" No divisor :-( sage: m=6 sage: load "h6.sage" Found divisor p= 17853499834298923421365649654070214764062221851007815964746938812865506204106551 006896845094332296668294060981717582064439941024648813610860458430234931167
AUFGABE 3 (4 Punkte): Sei N = pq ein RSA-Modul mit p > q. Sei k N eine unbekannte Zahl, die kein Vielfaches von q ist. Weiterhin sei eine Approximation kp von kp gegeben mit kp kp N 1 4. Zeigen Sie, dass die Faktorisierung von N in Zeit polynomiell in log N berechnet werden kann. Lösungsvorschlag: Betrachte das Polynom f(x) = x + kp und x 0 = kp kp. Es gilt f(x 0 ) = kp 0 mod p, d.h. x 0 ist eine Nullstelle von f modulo p, welche nach Voraussetzung x 0 = kp kp N 1 4 erfüllt. Ferner gilt wegen p > q und N = pq, dass p > N 1 2. Wir wählen also β = 1 und 2 wenden Satz 67 an: Dieser besagt, dass wir in Zeit poly(log N) die Nullstelle x 0 berechnen können, sofern x 0 N β2 = N 1 4 gilt. Das ist wie oben erwähnt erfüllt. Hiermit können wir kp = kp + x 0 berechnen. Wir kennen k zwar nicht, aber wegen q k gilt ggt(n, x 0 + kp) = ggt(n, kp) = p und mit dem EEA können wir den ggt in O(log 2 N) berechnen, was die Anforderung Laufzeit polynomiell in log N nicht verletzt. AUFGABE 4 (6 Punkte): In dieser Aufgabe soll der Angriff von Nguyen auf das DSA Signaturverfahren implementiert werden. Dazu steht eine Liste von 30 Tupeln (N achricht, Signatur, teilweisebekanntezuf allswerte) auf der Webseite der Vorlesung zur Verfügung. Der Teil der Signatur besteht wiederum aus zwei Elementen γ, δ wie in der Vorlesung beschrieben. Die teilweise bekannten Zufallsbits sind gerade die niederwertigsten 11 Bits des für die jeweilige Signatur verwendeten r. (D.h. in der Notation des Skriptes : l = 11) Können Sie den geheimen Schlüssel a rekonstruieren?
Lösungsvorschlag: Angenommen die Parameter sind aus der Datei in eine Liste thelist eingelesen. Das folgende Codefragment erzeugt eine Basismatrix für das Hidden Number Problem wie im Skript beschrieben und führt die LLL Reduktion durch. Dabei wird die Technik der Einbettung eines CVP in ein SVP benutzt. Es wird einfach der Targetvektor als zusätzlicher Basisvektor eingeführt. Falls der Vektor v ein nächster Gittervektor zum Targetvektor ist, dann ist der Vektor v = t v in der neuen Basis ein kürzester Vektor. from sage.libs.fplll.fplll import FP_LLL l=12 ## bekannte untere Bits d=30 ## Anzahl Signaturen ##Berechne t_i liste_t_i = []; liste_at_i=[]; for i in thelist: liste_t_i.append(mod(i[1]*2^-l*i[2]^-1,q).lift()) liste_at_i.append(mod(2^-l*(i[3]-i[2]^-1*i[0]),q).lift()) ##Build Lattice B=matrix(ZZ,d+2,d+1); for i in range(d): B[i,i]=(2^l)*q; for i in range(d): B[d,i]=(2^l)*liste_t_i[i]; B[d,d]=1; for i in range(d): B[d+1,i]=(2^l)*liste_at_i[i]; B[d+1,d]=0 F = FP_LLL(B) F.wrapper() red=f._sage_() Die Lösung a = 126011428158121006071265978104940049671713011948 findet sich in einem der kurzen Vektoren der reduzierten Basis.