public class Rsa {
static int bits=20;
private long p;
private long q;
private long phi;
private long e, u, v;
private long d;
private long n;
TextArea out;
public Rsa(){
p=randomPrime(bits);
q=randomPrime(bits);
n=p*q;
phi=(p-1)*(q-1);
e=randomPrime(bits/2);
}
public Rsa(TextArea out){
this.out=out;
p=randomPrime(bits);
q=randomPrime(bits);
n=p*q;
phi=(p-1)*(q-1);
e=randomPrime(bits/2);
}
public void setP(long x){
p=x;
n=p*q;
phi=newPhi(p,q);
}
public void setQ(long x){
q=x;
n=p*q;
phi=newPhi(p,q);
}
public void setE(long x){
e=x;
}
public long getP(){
return p;
}
public long getQ(){
return q;
}
public long getN(){
return n;
}
public long getPhi(){
return phi;
}
public long getE(){
return e;
}
public long newP(){
p= randomPrime(bits);
return p;
}
public long newQ(){
q= randomPrime(bits);
return q;
}
public long newE(){
e= randomPrime(bits/2);
return e;
}
public long newPhi(long p, long q){
phi= (p-1)*(q-1);
return phi;
}
public long newN(long p, long q){
n=(p)*(q);
return n;
}
private long erweiterterEuklid(long a, long b) {
long g ;
if (b==0) {
g=a;
u=1;
v=0;
}
else {
g = erweiterterEuklid(b, a%b);
long t=u-a/b*v;
u=v;
v=t;
}
return g;
}
public long newD(long phi, long e){
long d=0;
long ggt = erweiterterEuklid( phi, e);
ausgabeln("d suchen....");
ausgabeln( "ggt = " + ggt);
if( ggt != 1 ) {
ausgabe( "e="+e+" und (p-1)*(q-1)="+ phi );
ausgabeln( " sind nicht teilerfremd!");
}
ausgabeln( "u,v: " + u + " " + v);
d = v;
if( d < 0 ) d += (p-1)*(q-1); // negative Werte korrigieren return d;
ausgabeln(d+"");
return d;
}
public long newD(long e){
long d=0, dRest, x;
phi=newPhi(p,q);
dRest = 1;
for (x=1; (dRest>0); x++) {
d = (x*phi+1)/e;
dRest = (x*phi+1)%e;
//ausgabeln("x:"+x+" e:"+e+" d:"+d+" dRest:"+dRest);
}
return d;
}
//zufällige Primzahl
public long randomPrime(int bits){
BigInteger pr= new BigInteger(bits,10000,new Random());
return pr.longValue();
}
public long modulFunktion(long a, long b, long p){
// Berechnet a^b mod p
long i= b/2; long r= b%2;
long mod=1;
for (long j=0;j<i;j++){
mod=(mod*(a*a))%p;
}
if (r!=0) mod=(mod*(r*a))%p;
return mod;
}
public String intToString(int i, int laenge, String c) {
String s=" ";
s=s.valueOf(i);
if (laenge > 0)
while (s.length()<laenge)
s=c+s;
return s;
}
public byte[] rsaEncode(String klar, String e, String n){
ausgabeln("encodieren....");
int Laufvariable=0; String z, zz;
boolean ende=false;
String GesamtStr="", neuStr="";
BigInteger bigOriginal, bigChiffriert=BigInteger.ZERO;
BigInteger eBig=new BigInteger(e);
BigInteger nBig=new BigInteger(n);
for (int i=0; i < klar.length(); i++ ) // Original ausgeben
ausgabe(klar.charAt(i)+""); // reine Kontrolle!
ausgabeln("\n");
while (!ende) {
zz="";
int ByteLaenge=4; // Blockgroesse (Zeichen pro Zeile)
String szahl="";
int zeichen;
for (long i=0; ((i<ByteLaenge)&&(!ende));i++) {
ausgabe(klar.charAt(Laufvariable)+" "); // Original ASCII-Zeichen
z=intToString((int)klar.charAt(Laufvariable),3,"0");
zz+=z+" ";
szahl=szahl+z;
Laufvariable++;
if (Laufvariable==klar.length()) ende=true;
}
while (szahl.length()<(ByteLaenge*3))
szahl="0"+szahl; // mit Nullen auffüllen (reine Optik)
ausgabe(": --> "+zz); // zur Kontrolle ausgeben
bigOriginal= new BigInteger(szahl);
bigChiffriert=bigOriginal.modPow(eBig,nBig);
neuStr=bigIntToString(bigChiffriert,n.length(),"0");
ausgabeln(" --> kodiert: "+neuStr);
GesamtStr=GesamtStr+neuStr;
}
byte [] b=new byte[GesamtStr.length()];
for (int i=0;i<GesamtStr.length();i++) b[i]=(byte)GesamtStr.charAt(i);
return b;
}
public String rsaDecode (byte[] code, String d, String n) {
ausgabeln("decodieren....");
String original, GesamtText="";
int Lauf; char ASCII;
int LaufVariable=0; boolean ende=false;
BigInteger dBig=new BigInteger(d); BigInteger nBig=new BigInteger(n);
BigInteger bigOriginal, bigChiffriert;
for (int i = 0; i < code.length; i++ ) // Chiffre ausgeben
ausgabe(code[i]+"");
ausgabeln("\n");
while (!ende) {
String szahl="";
for (int i=0; (i<n.length()); i++) {
szahl=szahl+(char)code[LaufVariable];
LaufVariable++;
if (LaufVariable>=code.length) ende=true;
}
ausgabe("Zahl: "+szahl+" ->");
bigChiffriert=new BigInteger(szahl);
ausgabe(bigChiffriert+"--> \t");
original=bigChiffriert.modPow(dBig,nBig).toString();
ausgabe(original+"---> \t");
while ((original.length()%3)>0) // Fuehrende Nullen erzeugen
original="0"+original;
ausgabe(original+"----> !");
Lauf = 0; // erstes Zeichen aus "original" bestimmen
while (Lauf<original.length()) {
ASCII=(char)Integer.parseInt(original.substring(Lauf,Lauf+3));
GesamtText=GesamtText+ASCII;
ausgabe(ASCII+" ");
Lauf+=3;
}
ausgabeln(" !");
}
return GesamtText;
}
static public String bigIntToString(BigInteger i, int laenge, String c) {
String s=" ";
s=s.valueOf(i);
while (s.length()<laenge)
s=c+s;
return s;
}
static public String bigIntToString(BigInteger i, int laenge) {
String s=" ";
s=s.valueOf(i);
if (laenge>0)
while (s.length()<laenge) s=" "+s;
return s;
}
static public String bigIntToString(BigInteger i) {
String s=" ";
s=s.valueOf(i);
return s;
}
void ausgabe(String s){
if (out==null) System.out.print(s);
else out.append(s);
}
void ausgabeln(String s){
if (out==null) System.out.println(s);
else out.append(s+"\n");
}
}