RSA Selbstgeschrieben

Status
Nicht offen für weitere Antworten.

bazz-dee

Aktives Mitglied
Jo moin leuz .... ich wollt mir grad ne eigene RSA Verschlüsselungsklasse schreiben, aber irgendwas haut da nicht hin.


Also hier mein Primzahltest:
Code:
 private boolean isPrim(int x){
        boolean isP = true;
        double p = Math.pow(2, (x - 1)) % x;
        if (p==1){
            isP = true;
        }
        else{
            isP = false;
        }
        return isP;
    }


Zum finden des ggT nutze ich den erweiterten euklid:
Code:
private int ggT(int a, int b){      
        if (a==b||b==0){
            return a;
        }
        else {
            return ggT(b,a%b);
        }
    }



Das berechnen der Schlüssel:
Code:
    private void init(){
        n =  p * q;
        phi = (p-1)*(q-1);
        e = 50;
        while (ggT(e , phi) != 1){
            e++;
        }      
        int x = 1;
        while(true){
            int de = (x * e) - 1;
            if ((de % phi) == 0){
                break;
            }
            x++;
        }
        d = x;
    }

p und q können nach belieben an den konstruktor übergeben werden, der testet dann obs primzahlen sind, oder man nutzt den standard konstruktor der sich zufalls primzahlen erstellt.


Das Verschlüsseln/Entschlüsseln in vereinfachter Form, d.h. ich geb nur einen Integer über der verschlüsselt werden soll. Sollte ja zu Testzwecken genügen bevor ich anfange nen String zu zerlegen.


Code:
private int encode(int text){
        return (int)(Math.pow(text, e)%n); 
    }
    
    private int decode(int text){
        return (int)(Math.pow(text, d)%n);
    }




Naja nun meine Frage ... wo ist der Fehler, denn das funzt so nicht.



Beispiel Ausgabe:
Code:
p = 79
q = 43
n = 3397
phi = 3276
e = 53
d = 989

Ausgang: 123
Codiert: 2714
Decodiert: 0
 

0xdeadbeef

Top Contributor
Hm, also Dein Algorithmus zur Bestimmung von Primzahlen ist schon mal falsch.

Zum einen liefert er für den Sonderfall 2 eine false, weil 2^1%2 = 0 ist.

Zum anderen deklariert er eine ganze Menge von Zahlen zu Primzahlen, die keine sind:

341
561
645
1105
1387
1729
1905
2047
2465
2701
2821
3277
4033
4369
4371
4681
5461
6601
7957
8321
8481
8911
10261
10585
11305
12801
13741
13747
13981
14491
15709
15841
...

Um nur mal die ersten paar zu nennen...

Ich fürchte, mit diesem Ansatz liefert zwar für Primzahlen (bis auf die 2) anscheinend immer (?) einen Teilungsrest von 1, aber halt leider auch für eine Reihe von Nicht-Primzahlen.
Wäre auch zu schön, denn wenn der Algorithmus korrekt wäre, könnte man für jede beliebige Zahl mit ein paar einfachen Operationen herausfinden, ob sie prim ist.
 

bazz-dee

Aktives Mitglied
2 kontrolliere ich auch nie ... deswegen hab ich da keine abfrage drin für ... aber die anderen kann ich mir nicht erklären, müsste eigentlichfunktionieren, zumindest stand des als einfachster algorithmus irgendwo in meinen unterlagen
 
S

stev.glasow

Gast
0xdeadbeef hat gesagt.:
Hm, also Dein Algorithmus zur Bestimmung von Primzahlen ist schon mal falsch.

Zum einen liefert er für den Sonderfall 2 eine false, weil 2^1%2 = 0 ist.

Zum anderen deklariert er eine ganze Menge von Zahlen zu Primzahlen, die keine sind:

.....

Um nur mal die ersten paar zu nennen...
Ich habe mal ein paar der Zahlen mit
Math.pow(2, x - 1) % x == 1;
geprüft. Er hat bei jeder false zurückgeliefert.
 

Bleiglanz

Gesperrter Benutzer
p = 79
q = 43
n = 3397
phi = 3276
e = 53
d = 989

da wirst du um Biginteger nicht herumkommen...
 

thE_29

Top Contributor
<ot>OMG ;)

Ich hatte den Algorithmus zur Matura (Abitur) und der Lehrer hat uns irgendeine Zahl falsch gegeben und natürlich kam totaler Blödsinn raus (hatte ein Wort kodiert)

Ich sagte ihm es seie falsch, er drauf, nein ich hab falsch gerechnet, 1 1/2 stunden später (mathe hat glaub ich 4 stunden gedauert), kam er rein und sagte: Ooo, die Zahlen sind doch falsch....</ot>
 

Bleiglanz

Gesperrter Benutzer
wenn int überläuft muss das programm falsch werden...

private int encode(int text){
return (int)(Math.pow(text, e)%n);
}

mal schauen:

e ist 53
text ist 123

die zahl 123^53 wird wohl kaum in ein int passen, und du machst zuerst pow und dann modulo

du musst das - wenn überhaupt - so machen, dass du pow selber schreibst (da gibts einen schnellen algorithmus dafür) und bei JEDER operation modulo rechnest

nimm BigInteger, mit int bist du da verloren!!
 

bazz-dee

Aktives Mitglied
ok das werd ich nachher mal machen, mal sehen was bei raus kommt ....


hmm das potenzieren selber schreiben .... ich glaub ich hab irgendwo noch was fertiges zum bitweisem multiplizieren
 

0xdeadbeef

Top Contributor
stevg hat gesagt.:
Ich habe mal ein paar der Zahlen mit
Math.pow(2, x - 1) % x == 1;
geprüft. Er hat bei jeder false zurückgeliefert.

Naja, zugegeben: durch die Ungenauigkeit von double kommt dabei 0 raus.
Aber wenn man korrekt rechnet, ergibt sich z.b. für die erste Zahl (341):

a = 2**(341-1) = 2239744742177804210557442280568444278121645497234649534899989100963791871180160945380877493271607115776

b = trunc(a/341)*341 = 2239744742177804210557442280568444278121645497234649534899989100963791871180160945380877493271607115775

Und daraus:

a - b = 1

oder

2**(341-1)%341 = 1

Wie ja sky80 schon angedeutet hat, liefert der Primzahltest nach Fermat nicht nur für Primzahlen das Ergebnis "wahr", sondern auch für Pseudoprimzahlen. Genauer gesagt liefert er außer echten Primzahlen auch eulersche Pseudoprimzahlen und die Carmichael-Zahlen.

Hier findet sich eine schöne Tabelle, die so ziemlich genau den von mir ermittelten Zahlen entspricht:
http://de.wikipedia.org/wiki/Eulersche_Pseudoprimzahl

Nebenbei: die BigInteger-Klasse bietet (wohl nicht grundlos) die Methoden:
isProbablePrime(int certainty) - mit der Betonung auf "probable"
gcd(BigInteger val) - "greatest common divider", also ggT

Es sollte einem zu Denken geben, daß es keine Methode "isPrime" gibt. Wäre die Entscheindung, ob prim oder nicht so einfach möglich, gäbe es kaum einen Grund, ein probalistisches Verfahren zu benutzen.
 
Status
Nicht offen für weitere Antworten.

Oben