Diszkre t matematika 10. elo ada s MA RTON Gyo ngyve r mgyongyi@ms.sapientia.ro Sapientia Egyetem, Matematika-Informatika Tansze k Marosva sa rhely, Roma nia 2018, o szi fe le v MA RTON Gyo ngyve r 2018, Diszkre t matematika
Miről volt szó az elmúlt előadáson? a prímszámtétel prímszámok, tulajdonságok, sejtések maradékosztályok, maradékrendszerek moduláris hatványozás a kis Fermat-tétel a kis-fermat tételen alapuló prímteszt az Euler függvény, az Euler-tétel az Euler függvényhez kapcsolódó összefüggések a Miller-Rabin prímteszt hatványok és generátor elemek
Miről lesz szó? az eukleidészi algoritmus és változatai lineáris kongruenciák moduláris inverz, algoritmusok a brute-force algoritmus a kiterjesztett Eukleidészi algoritmus a kis Fermat tételen alapuló algoritmus hatványok és generátor elemek a diszkrét logaritmus (DL) probléma a Diffie-Hellman kulcscsere
Az eukleidészi algoritmus Az a és b egész számok legnagyobb közös osztója, az a legnagyobb szám amely osztja az a-t és b-t is. Jelölése: lnko(a, b), (a, b), vagy gcd(a, b) Az a és b egész számok legnagyobb közös osztója az a d legkisebb egész szám, amely egyenlő az a és b lineáris kombinációjával: d = x a + y b, ahol x, y egész számok. Eukleidész algoritmusa: meghatározza a legnagyobb közös osztót Eukleidész kiterjesztett algoritmusa: meghatározza a d, x, y egész számokat Az a és b egész számok relatív prímek, ha lnko(a, b) = 1. Az a 1, a 2,..., a n kölcsönösen relatív prímek, ha lnko(a 1, a 2,..., a n) = 1. Az a 1, a 2,..., a n páronként relatív prímek, ha lnko(a i, a j ) = 1, bármely i, j {1, 2,..., n}.
Az eukleidészi algoritmus 1. feladat Az eukleidészi algoritmus iteratív és rekurzív változatával határozzuk meg két szám legnagyobb közös osztóját. Iteratív változat: def euclid (a, b): while True: r = a % b if r == 0: break a = b b = r return b Rekurzív változat: def euclidr(a, b): r = a % b if r == 0: return b return euclidr(b, r)
Az eukleidészi algoritmus Megjegyzések: 1. tétel hány osztást végez az algoritmus? Lamé tétele: Az eukleidészi algoritmus során végzett osztások száma nem lesz nagyobb, mint ötször a kisebbik szám számjegyeinek száma határozzuk meg két egymásutáni Fibonacci szám legnagyobb közös osztóját? Ekkor hány osztást végez az algoritmus? létezik-e más algoritmus?
Az eukleidészi algoritmus és változatai Eukleidész kiterjesztett algoritmusa: legyenek a, b pozitív egész számok, akkor feĺırható a következő összefüggés: lnko(a, b) = x n a + y n b, n {0, 1, 2,... }, ahol x n és y n a következő rekurzív számítási sorozat n-ik tagjai: x 0 = 1, y 0 = 0 x 1 = 0, y 1 = 1 x j = x j 2 q j 1 x j 1 y j = y j 2 q j 1 y j 1, ahol q j a megfelelő hányados, amelyet az eukleidészi algoritmus során számolunk ki.
A kiterjesztett eukleidészi algoritmus, példa Határozzuk meg 84 és 35 legnagyobb közös osztóját, majd azokat az x és y egész számokat, melyekre fennáll a következő összefüggés: 84 x + 35 y = d, ahol d = lnko(84, 35). a b r q x 0 x 1 y 0 y 1 1 0 0 1 84 35 14 2 0 1 1 2 35 14 7 2 1 2 2 5 14 7 0 2 Tehát a megoldás: d = 7, x = 2, y = 5, és fennáll a következő összefüggés: 84 ( 2) + 35 5 = 7.
A kiterjesztett eukleidészi algoritmus, példa Határozzuk meg 45 és 31 legnagyobb közös osztóját, majd azokat az x és y egész számokat, melyekre fennáll a következő összefüggés: 45 x + 31 y = d, ahol d = lnko(45, 31). a b r q x 0 x 1 y 0 y 1 1 0 0 1 45 31 14 1 0 1 1 1 31 14 3 2 1 2 1 3 14 3 2 4 2 9 3 13 3 2 1 1 9 11 13 16 2 1 0 2 Tehát a megoldás: d = 1, x = 11, y = 29, és fennáll a következő összefüggés: 45 ( 11) + 31 16 = 1.
A kiterjesztett eukleidészi algoritmus 2. feladat Eukleidész kiterjesztett algoritmusával határozzuk meg azokat a d, x, y egész számokat amelyek teljesítik: d = x a + y b. def exteuclid (a, b): x0, x1, y0, y1 = 1, 0, 0, 1 while True: q = a // b r = a - q * b if r == 0: return (b, x1, y1) a = b b = r x = x0 - q * x1 y = y0 - q * y1 x0, x1, y0, y1 = x1, x, y1, y
Lineáris kongruenciák Az a x b (mod m) típusú egyenletet lineáris kongruenciának hívjuk, ahol x ismeretlen. ha x 0 megoldása a fenti kongruenciának és x 1 x 0 (mod m), akkor x 1 is megoldás 2. tétel Legyenek a, b, m egész számok, ahol m > 0 és lnko(a, m) = d. Ha d b, akkor az a x b (mod m) kongruenciának nincs megoldása. Ha d b, akkor az a x b (mod m) kongruenciának d inkongruens megoldása van (mod m) szerint. Az a x b (mod m) kongruencia ekvivalens az a x m y = b egyenlettel. kiterjesztett Eukleidészi algoritmussal meghatározzuk a ˆx, ŷ-t, úgy hogy teljesüljön: a ˆx + m ŷ = d. A kongruencia első megoldása x 0 = ˆx (b/d) lesz. A kongruencia többi megoldásait az n = 1, 2,..., d 1 lehetséges értékek alapján, a következőképpen számoljuk ki: x i = x 0 + n (m/d).
Példák Határozzuk meg a 9 x 12 (mod 15) kongruencia megoldásait. lnko(9, 15) = 3 és 3 12 a kongruenciának 3 inkongruens megoldása van (mod 15) szerint. Kiterjesztett eukleidészi algoritmussal kapjuk: 9 2 + 15 ( 1) = 3, azaz ˆx = 2, ŷ = 1. A kongruencia első megoldása: x 0 = 2 (12/3) = 8. A többi megoldás: fennáll: x 1 = x 0 + 1 (15/3) = 8 + 5 = 13 (mod 15), x 2 = x 0 + 2 (15/3) = 8 + 10 = 18 3 (mod 15). 9 8 = 72 = 12 (mod 15), 9 13 = 117 = 12 (mod 15), 9 3 = 27 = 12 (mod 15),
Moduláris inverz meghatározása 1. értelmezés Az a x 1 (mod m) kongruenciának a megoldását, ahol lnko(a, m) = 1 az a szám moduláris inverzének hívjuk (mod m) szerint. Megjegyzés Példák: a fenti egyenlet egy sajátos esete az a x b (mod m) egyenletnek: b = 1. Mennyi lesz 4 inverze hogy 1-et kapjunk? Válasz: 2-vel, mert 4 2 = 1 (mod 7). Mennyi lesz 7 inverze hogy 1-et kapjunk? Válasz: 9-cel, mert 7 9 = 1 (mod 31). (mod 7) szerint? Mivel kell megszorozni 4-et, (mod 31) szerint? Mivel kell megszorozni 7-et,
Moduláris inverz meghatározása Megjegyzések: Ha meghatározzuk a egy inverzét (mod m) szerint, akkor megtudjuk határozni az a x b (mod m) kongruencia megoldásait is. Ha lnko(a, m) = 1, akkor az a x b (mod m) kongruenciának egy megoldása van (mod m) szerint. Az Euler tétel segítségével hogyan tudjuk meghatározni egy szám moduláris inverzét? x = a φ(m) 1 (mod m) ha m prímszám, akkor x = a m 2 (mod m) Határozzuk meg a 7 x 22 (mod 31) kongruencia egy megoldását. lnko(7, 31) = 1 a kongruenciának egy megoldása van (mod 31) szerint. Tudva, hogy 7 9 1 (mod 31), azaz 7 inverze 9, megszorozzuk az egyenletet 22-vel: 7 9 22 22 (mod 31) ezért a megoldás x = 9 22 = 198 12 (mod 31) lesz.
Moduláris inverz meghatározása 3. feladat A Eukleidész kiterjesztett algoritmusával határozzuk meg a inverzét (mod m) szerint. def inverz(a, m): d, x, y = exteuclid(a, m) if d!= 1: print ( nincs inverz ) return -1 return x % m Megjegyzések: A kiterjesztett Eukleidészi algoritmus az x és y értékekben negatív számot is meghatározhat. azt szeretnénk hogy a moduláris inverz, ha létezik, akkor az mindig pozitív érték legyen a Python % operátora a legkisebb pozitív maradékot határozza meg: >>> -5 % 7 2
Feladatok Határozzuk meg a következő számok inverzét (mod 17) szerint: 4, 7, 5, 16. Határozzuk meg a következő számok inverzét 734342, 499999, 1000001. Oldjuk meg az alábbi egyenleteket: (mod 153331) szerint: 3 x 6 (mod 9) 19 x 30 (mod 40) 980 x 1500 (mod 1600) 6789783 x 2474010 (mod 288927591)
A moduláris inverz 4. feladat Határozzuk meg a moduláris inverz értékét brute force illetve a kis Fermat tétel segítségével. def inverzbf(a, m): for i in range(1, m): if (a*i) % m == 1: return i def inverzfermat(a, m): res = pow(a, m-2, m) if (res * a) % m!= 1: print m, nem primszam! return -1 return res
A moduláris inverz 5. feladat Hasonĺıtsuk össze a három moduláris inverzet számoló algoritmus futási idejét def main1(a, m): st = time.time() res = inverzbf(a, m) fs = time.time() print fs - st print inverz:, res st = time.time() res = inverzfermat(a, m) fs = time.time() print fs - st print inverz:, res >>> main1(2, 4221109) 0.440999984741 inverz: 2110555 0.0 inverz: 2110555 0.0 inverz: 2110555 st = time.time() res = inverz(a, m) #a 9. eloadason megadott inverz fuggveny fs = time.time() print fs - st print inverz:, res
A moduláris inverz 6. feladat Hasonĺıtsuk össze az Eukleidészi algoritmuson alapuló, illetve a kis Fermat tételén alapuló moduláris inverzet számoló algoritmusok futási idejét, egy m 1024 bites prímszám esetében def main2(): a = 2 m = 1204328148337291603642924232769208462720078 78689251114536602300016710024726076936509435386 49083953166853517249346367715669274167793296290 86878213191274539205544604728549441021320463964 58538345025572719153741961623463125980738349016 07120494461215543243875002652798979907105247593 5039352681744845614576741318513 st = time.time() res = inverzfermat(a, m) fs = time.time() print fs - st print inverz:, res st = time.time() res = inverz(a, m) fs = time.time() print fs - st print inverz:, res >>> main2() 0.0490000247955 inverz: 60216407416864580182146211638460423 13600393934462555726830115000835501 23630384682547176932454197658342675 86246731838578346370838966481454343 91065956372696027723023642747205106 60231982292691725127863595768709808 11731562990369174508035602472306077 71621937501326399489953552623796751 9676340872422807288370659257 0.0 inverz: 60216407416864580182146211638460423... 967519676340872422807288370659257
Hatványok és generátor elemek a kis Fermat, illetve Euler tétel mellett, számos egyéb tulajdonság figyelhető meg az x n (mod m) értékek meghatározásakor Határozzuk meg x n n = 1, 2,... 10-re: (mod 11), értékeit x = 2, 3,... 10-re illetve 2 1 = 2 3 1 = 3 4 1 = 4 5 1 = 5 6 1 = 6 7 1 = 7 8 1 = 8 9 1 = 9 10 1 = 10 2 2 = 4 3 2 = 9 4 2 = 5 5 2 = 3 6 2 = 3 7 2 = 5 8 2 = 9 9 2 = 4 10 2 = 1 2 3 = 8 3 3 = 5 4 3 = 9 5 3 = 4 6 3 = 7 7 3 = 2 8 3 = 6 9 3 = 3 10 3 = 10 2 4 = 5 3 4 = 4 4 4 = 3 5 4 = 9 6 4 = 9 7 4 = 3 8 4 = 4 9 4 = 5 10 4 = 1 2 5 = 10 3 5 = 1 4 5 = 1 5 5 = 1 6 5 = 10 7 5 = 10 8 5 = 10 9 5 = 1 10 5 = 10 2 6 = 9 3 6 = 3 4 6 = 4 5 6 = 5 6 6 = 5 7 6 = 4 8 6 = 3 9 6 = 9 10 6 = 1 2 7 = 7 3 7 = 9 4 7 = 5 5 7 = 3 6 7 = 8 7 7 = 6 8 7 = 2 9 7 = 4 10 7 = 10 2 8 = 3 3 8 = 5 4 8 = 9 5 8 = 4 6 8 = 4 7 8 = 9 8 8 = 5 9 8 = 3 10 8 = 1 2 9 = 6 3 9 = 4 4 9 = 3 5 9 = 9 6 9 = 2 7 9 = 8 8 9 = 7 9 9 = 5 10 9 = 10 2 10 = 1 3 10 = 1 4 10 = 1 5 10 = 1 6 10 = 1 7 10 = 1 8 10 = 1 9 10 = 1 10 10 = 1
Hatványok és generátor elemek kis Fermat tétel, kimondja, hogy ha p prím és lnko(x, p) = 1, akkor x p 1 = 1 (mod p). a fenti táblázat alapján kijelenthetjük, hogy lesznek olyan x számok, ahol x-nek kisebb hatványértékei is kongruensek lesznek 1-el. x rend-jén, (mod p) szerint, azt a legkisebb k kitevőt értjük, amelyre fennáll: x k 1 (mod p). Pl. (mod 11) szerint a 2-es szám rendje 10, a 3 szám rendje 5, míg a 10-es szám rendje 2. ha p egy prímszám, akkor mindig létezik gen {1, 2,..., p 1}, amelynek hatványértékei (mod p) szerint előálĺıtják az {1, 2,..., p 1} halmaz elemeit egy tetszőleges sorrendbe. ezeket a gen elemeket primitív gyököknek, vagy generátor elemeknek hívjuk. ezek azok az elemek lesznek, amelyeknek rendje p 1. a generátor elemek száma: φ(p 1). a fenti táblázatban 2, 6, 7, 8 generátor elemek, számuk φ(10) = 4.
Hatványok és generátor elemek Megjegyzések: fontos feladat, hogy egy adott prímszám esetében meghatározunk egy generátor elemet ha a p prímszám speciális alakú, azaz p = 2 q + 1, ahol q is prímszám, akkor a generátor elem kiválasztása nem számít nehéz feladatnak, biztonságos prímeknek (safe prime) hívjuk azokat a p prímszámokat, amelyek egyenlőek 2 q + 1-el, ahol q is prímszám egy biztonságos prím meghatározása azonban jóval időigényesebb, mint egy közönséges prím kiválasztása legyen p = 2 q + 1 biztonságos prím, ekkor ha a gen egész számra fennáll, hogy gen ±1 (mod p) és gen q 1 (mod p), akkor gen generátor elem (mod p) szerint ha p = 2 q + 1 biztonságos prím, akkor a generátor elemek száma φ(p 1) = φ(2) φ(q) = q 1
Hatványok és generátor elemek 7. feladat Írjunk Python függvényt, amely generál egy k bites biztonságos prímet és meghatározza a prím egy generátor elemét. import eload8, random def safeprime(k): q = random.getrandbits(k) if not (q & 1): q += 1 while True: p = 2 * q + 1 if miller_rabint(q, 10) and miller_rabint(p, 10): break q = random.getrandbits(k) if not (q & 1): q += 1 while True: gen = random.randint(2, p-2) temp = pow(gen, q, p) if temp!= 1: break return p, gen
A diszkrét logaritmus (DL) probléma Az egész számok Z p = {1, 2,..., p 1} véges halmaza esetében, ahol p prímszám a DL probléma a következő: az A, gen-alapú diszkrét logaritmusa (mod p) szerint azt jelenti, hogy megkeressük azt az a pozitív egész számot, melyre fennáll: gen a A (mod p), ahol gen generátor elem (primitív gyök), és gen, A Z p. Nagy számok esetében a DL probléma meghatározására nem ismert hatékony algoritmus. Számos kriptorendszer biztonsága alapszik a DL problémán.
A Diffie-Hellman kulcscsere 1976-ban publikálták a szerzők, biztonsága a DL problémán alapszik két távoli egység (számítógép, mobileszköz, stb.) kulcscsere mechanizmusára ad elsőként megoldást. megfigyelhető egy áttérés a (mod p) aritmetikáról az elliptikus görbékre, feltételezve, hogy a kommunikációban résztvevő két legális fél Alice és Bob, akkor a protokoll a következő: Alice és Bob egy központi szervertől lekéri a p, k-bites prímszámot, és a (mod p) szerinti gen generátor elemet, Alice a k, p, gen ismeretében meghatározza az a, A értékeket, ahol: a {2,..., p 2} véletlen szám, A = gen a (mod p), az a értékét titokban tartja, A-t pedig elküldi Bobnak.
Diffie-Hellman kulcscsere Bob a k, p, gen ismeretében meghatározza a b, B értékeket, ahol: b {2,..., p 2} véletlen szám, B = gen b (mod p), a b értékét titokban tartja, B-t pedig elküldi Alicenak. Alice a közös K kulcsot a kövekezőképpen határozza meg: K = B a (mod p). Bob a közös K kulcsot a kövekezőképpen határozza meg: Helyesség: K = A b (mod p). K = A b = B a = gen ab (mod p).
Diffie-Hellman kulcscsere, példa Legyen p = 47, gen = 13, ahol p = 2 23 + 1. Fennáll, hogy 13 23 46 1 (mod 47), azaz 13 generátor elem. Alice : választja a = 12-t A = gen a (mod p) = 9 (mod 47), elküldi Bobnak az A = 9 értéket. Bob: választja b = 34-t B = gen b (mod p) = 21 (mod 47), elküldi Alicenak a B = 21 értéket. Alice: K = B a (mod p) = 21 12 = 16 (mod 47), Bob: K = A b (mod p) = 9 34 = 16 (mod 47). a közös kulcs: K = 16. Laborfeladat: kliens szerver alkalmazás