def gcd(m,n):
"""Der ggT der ganzen Zahlen m und n."""
if n==0:
return abs(m) else:
return gcd(n, m % n)
def sgn(m):
"""Vorzeichen der ganzen Zahl m."""
if m == 0: return 0
elif m < 0: return -1
elif m > 0: return 1
def xgcd(m,n):
"""Ganze Zahlen d,x,y, sodaß d = ggT(x,y) = m*x + n*y."""
if n==0:
return abs(m),sgn(m),0 else:
q = m / n r = m % n d,x,y = xgcd(n,r)
return d, y, x - y*q
def invmod(e,m):
"""Das multiplikative Inverse von e modulo m."""
d,x,y = xgcd(e,m)
if d==1: return x % m
def powermod(x,e,m):
""" x^e mod m """
if e == 0:
return 1
elif e < 0: return invmod(powermod(x,-e,m),m)
else: b = 2 q = e / b
r = e % b
return ( powermod(x,q,m)**b * x**r ) % m
p = 341
print "Ist",p,"eine Primzahl?"
for b in [2,3]:
print "Basis %d sagt:"% b, powermod(b,p-1,p)==1
print "\n\nRSA-Beispiel\n"
p = 11
q = 23
m = p*q
phi = (p-1)*(q-1)
print "m = %d = %d * %d, phi = %d" % (m,p,q,phi)
print "\nSuche passendes e:"
for e in [25,17]:
print "e = %d, ggt(e,phi) = %d, geeignet:" %(e, gcd(e,phi)), gcd(e,phi)==1
e=17
d=invmod(e,phi)
print "e = %d; d = %d" % (e,d)
print "e * d = %d * %d = %d = %d (mod %d)" % (e,d,e*d, e*d % phi,phi)
print "\nGeheime Nachricht an Alice"
for x in [47,118]:
print "x =", x
y = powermod(x,e,m)
print "Verschluesselung: y = x^e = %d^%d = %d (mod %d)" % (x,e,y,m)
print "Entschluesselung: y^d = %d^%d = %d (mod %d)" % (y,d,powermod(y,d,m),m)
print "\nGeheime Nachricht an Bob"
m_ = 323
e_ = 5
print "Bobs oeffentlicher Schluessel: m' = %d, e' = %d" % (m_,e_)
x = 16
print "x =", x
y = powermod(x,e_,m_)
print "Verschluesselung: y = x^e' = %d^%d = %d (mod %d)" % (x,e_,powermod(x,e_,m_),m_)
print "\nAlice signiert"
x_ = powermod(x,d,m)
print "Signatur: x' = x^d = %d^%d = %d (mod %d)" % (x,d,x_,m)
y_ = powermod(x_,e_,m_)
print "Verschlüsselung: y' = x'^e' = %d^%d = %d (mod %d)" % (x_,e_,powermod(x_,e_,m_),m_)
print "\nBob's Schluessel knacken:"
print "Wir suchen die Faktoren von m' =",m_
p_ = 17 q_ = 19 print "m' = %d = %d * %d = p'*q'" % (p_*q_,p_,q_)
phi_ = (p_-1)*(q_-1)
d_ = invmod(e_,phi_)
print "phi' = %d, d' = %d" % (phi_,d_)
print "\nNachricht fälschen:"
z = 66
print "z =",z
z_ = powermod (z,d_,m_)
print "Signieren: z' = z^d' = %d^%d = %d (mod %d)" % (z,d_,z_,m_)
print "Carol erhält die Nachricht %d." % z_
print "und liest: z'^e' = %d^%d = %d (mod %d)" % (z_,e_,powermod(z_,e_,m_),m_)
print "Sie glaubt daher sicher sein zu koennen, dass sie von Bob stammt"
print "...und ist ganz traurig."
print "\n\nGroße Zahlen:\n"
import random random.seed(5345345)
def isprime (p,iter=1):
"""Test, ob p eine Primzahl ist (einfacher Fermat-Test)"""
if p==2: return True
if p < 2: return False
for i in [2,3,5,7,11,13,17,19]: if i<p and p % i == 0: return False
for i in range(iter):
b = random.randint(2,p-1) if not (powermod(b,p-1,p) == 1): return False
return True
for p in [17,18,341,42347889747234892347492346746474788484834939394834893]:
print "Ist %d eine Primzahl?" % p, isprime(p)
def getprime(n,b=10):
"""Suche eine n-stellige (Basis b) Primzahl"""
p = random.randint(b**(n-1),b**n - 1)
if isprime(p):
return p
else:
return getprime(n,b)
def nextprime(p):
"""Bestimme kleinste Primzahl groesser gleich p"""
if isprime(p):
return p
else:
return nextprime(p+1)
for p in [11,24,341,464634893939474589409]:
print "%d ist groesser gleich %d und prim." % (nextprime(p),p)
for n in [1,2,3,10,50]:
print "%d ist eine %d-stellige Primzahl" % (getprime(n),n)
def getpublic (phi):
"""Waehle ein e relativ prim zu phi"""
e = random.randint(5,phi-1)
if gcd(e,phi)==1:
return e
else:
return getpublic (phi)
def getkey(p,q):
"""Liefere ein Schluesselpaar fuer m = p*q. Resultat als (m,e,d)."""
m = p*q
phi = (p-1)*(q-1)
e = getpublic(phi)
d = invmod(e,phi)
return m,e,d
def generateRSA(n,b=10):
"""Erzeue einen RSA-Schluessel mit n-stelligen Primzahlen"""
p = getprime(n)
q = getprime(n)
if p==q:
return generateRSA(n,b) return getkey(p,q)
print "\n\nRSA Verfahren:"
for n in [2,10,50]: print "\nmit %d-stelligen Primzahlen" % n
m,e,d = generateRSA(n)
print "Modul: m =",m
print "Oeffentlicher Schluesel: e =", e
print "Geheimer Schluessel: d =", d
for i in range(2):
x = random.randint(2,m-1)
print "\nNachricht: x =",x
y = powermod(x,e,m)
print "Verschluesselt: y = x^d = %d ^ %d = %d (mod %d)" % (x,e,y,m)
print "Test: y^d =",powermod(y,d,m)
z = powermod(x,d,m)
print "Signiert: z = x^d =", z
print "Test: z^e =",powermod(z,e,m)
print generateRSA(2)