# RSA



## Sduni (18. Nov 2009)

Hi,

also wir müssen eine RSA Klasse schreiben.
Habe soweit alles fertig, aber ist das normal, dass der nach dem Ausführen nichts anzeigt? Müsste doch true oder false anzeigen? Gibts vlt. irgendwo nen Fehler, wo eine Schleife vlt. nicht endet? Ich find den Fehler nicht.

lg




```
/*
 * RSA.java
 *
 */

import java.math.BigInteger;
import java.util.Random;

/**
 *
 */
public class RSA {

    private BigInteger decryptionExponent;
    private BigInteger encryptionExponent;
    private BigInteger primeA;
    private BigInteger primeB;
    private BigInteger rsaModulus;
    private BigInteger totient;

    public RSA(BigInteger primeA, BigInteger primeB) {
        this.primeA = primeA;
        this.primeB = primeB;
        rsaModulus = calculateRSAModulus(primeA, primeB);
        totient = calculateTotient(primeA, primeB);
        encryptionExponent = chooseEncryptionExponent(totient);
        decryptionExponent = calculateDecryptionExponent(encryptionExponent, totient);
    }
    
    	public static void main(String[] args) {
        boolean correct = true;
        for (int i = 0; i < 10000; i++) {
            BigInteger plainText = BigInteger.valueOf(Math.abs(new Random().nextInt()));
            RSA rsa = new RSA(BigInteger.valueOf(597853), BigInteger.valueOf(611953));
            BigInteger cipherText = rsa.encrypt(plainText);
            BigInteger newPlainText = rsa.decrypt(cipherText);
            if (plainText.equals(newPlainText)) {
            } else {
                correct = false;
            }
        }
        System.out.println("Korrekt: " + correct);
    }
    
    private BigInteger calculateRSAModulus(BigInteger primeA, BigInteger primeB){
    	this.primeA = primeA;
		this.primeB = primeB;
    	return primeA.multiply(primeB);
    }
    
	private BigInteger calculateTotient(BigInteger primeA, BigInteger primeB){
		this.primeA = primeA;
		this.primeB = primeB;
		BigInteger n = primeA.subtract(new BigInteger("1")).multiply(primeB.subtract(new BigInteger("1")));
   		return n;
	}

	
	private BigInteger chooseEncryptionExponent(BigInteger totient){
		this.totient = totient;
		Random zufall;
        zufall = new Random();
        BigInteger e = BigInteger.valueOf(zufall.nextInt(totient.intValue() - 1) + 1);
        BigInteger b = new BigInteger("1");
        while (e.compareTo(b) == -1 || e.compareTo(totient) == 1 || totient.mod(e).intValue() == 0 
/**|| e.compareTo(new BigInteger("10")) == 1**/){  
// überprüfen ob randomize, also der exponent e, kleiner gleich 1 oder größer gleich phi(totient) ist 
// und ob bei der teilung von totient durch e ein rest übrig bleibt; schleife wird solange ausgeführt bis e
// halt größer 1 oder kleiner totient ist und der totient nicht teilbar durch e ist
           e = BigInteger.valueOf(zufall.nextInt(totient.intValue() - 1) + 1);
        }return e;
	}
	
	private BigInteger calculateDecryptionExponent(BigInteger encryptionExponent, BigInteger totient){
		this.encryptionExponent = encryptionExponent;
		this.totient = totient;
		BigInteger d = new BigInteger("1");
		while (encryptionExponent.multiply(d).mod(totient).equals(new BigInteger("1")) == false){
			d = d.add(new BigInteger("1"));
		}
   		return d;
	}
	
	private BigInteger encrypt(BigInteger plainText){
		this.encryptionExponent = encryptionExponent;
		this.rsaModulus = rsaModulus;
		BigInteger b = new BigInteger("0");
		BigInteger m;
		if (plainText.compareTo(totient) == -1){
			m = plainText.modPow(encryptionExponent, rsaModulus);
		}
		if ( plainText.compareTo(b) == 1){
			m = plainText.modPow(encryptionExponent, rsaModulus);
		}else{
			m = new BigInteger("0");
		}
		return m;
	}
	
	private BigInteger decrypt(BigInteger cipherText){
		this.decryptionExponent = decryptionExponent;
		this.rsaModulus = rsaModulus;
		BigInteger c;
		c = cipherText.modPow(decryptionExponent, rsaModulus);

		return c;
	}
}
```


----------



## Noctarius (18. Nov 2009)

Ich würde vermuten eine von beiden while-Schleifen wird einen Fehler in der Bedingung haben. Ich würd sagen: Debugger oder System.out-println-Meldungen reinpacken und schauen wo er hängen bleibt.


----------



## Sduni (18. Nov 2009)

hab sie auch schon:


```
private BigInteger calculateDecryptionExponent(BigInteger encryptionExponent, BigInteger totient){
		this.encryptionExponent = encryptionExponent;
		this.totient = totient;
		BigInteger d = new BigInteger("1");
		while (encryptionExponent.multiply(d).mod(totient).equals(new BigInteger("1")) == false){
			System.out.println("aaa");
			d = d.add(new BigInteger("1"));
		}
   		return d;
	}
```

ind der Bedingung müsste stehen:

encryptionExponent · d ≡ 1 mod (totient) .... wie kann ich das sonst als Algo in JAVA darstellen. ≡ heißt doch kongruenz oder? 

vlt.

```
while (encryptionExponent.mod(totient).equals(new BigInteger("1")) == false 
&& d.mod(totient).equals(new BigInteger("1")) == false)
```


----------



## SlaterB (18. Nov 2009)

man kann auch Code/ Postings editieren, so dass nicht alles super-breit im Forum dargestellt wird,

--------

statt
if (x == false)
kann man auch
if (!x)
schreiben

-----

new BigInteger("1")
muss doch auf die Dauer nerven, von den unnötig erzeugten Objekten ganz zu schweigen, 
definiere dir eine statisch Variable ONE


----------



## Noctarius (18. Nov 2009)

SlaterB hat gesagt.:


> definiere dir eine statisch Variable ONE



Die gibt es schon


----------



## Sduni (18. Nov 2009)

Das Problem liegt hier:


```
private BigInteger chooseEncryptionExponent(){
		this.totient = totient;
		this.bigIntOne = bigIntOne;
		Random zufall;
        zufall = new Random();
        BigInteger e = BigInteger.valueOf(zufall.nextInt(totient.intValue())+1);
       	while (totient.gcd(e) != bigIntOne){
           	e = BigInteger.valueOf(zufall.nextInt(totient.intValue())+1);
        }
        System.out.println("VExponent: " + e.toString());
        return e;
	}
```

bigIntOne is globale BigInteger("1")


----------



## Noctarius (18. Nov 2009)

BigInteger (Java 2 Platform SE 5.0)
BigInteger (Java 2 Platform SE 5.0)
...


----------



## Sduni (18. Nov 2009)

darum gehts doch nicht... natürlich kann ich auch einfach BigInteger.ONE für bigIntOne schreiben... relativ

nur die Methode funktioniert nicht 

enthält zufall.nextInt(12)+1 alle werte von 1-11? oder nur einzelne Zahlen wie 4,8,6?


----------



## SlaterB (18. Nov 2009)

> while (totient.gcd(e) != bigIntOne){

BigInteger vergleicht man wie Strings besser mit equals, sie müssen nie == sein,

überhaupt bringt es wenig, nur Code zu posten,
baue doch Logmeldungen ein, prüfe, was wann warum ausgerechnet wird, 
und welche Bedingungen und Folgeaktionen wann wo warum ausgelöst werden

> enthält zufall.nextInt(12)+1 alle werte von 1-11? oder nur einzelne Zahlen wie 4,8,6? 

ausprobieren?


----------



## Sduni (18. Nov 2009)

danke! das sind wirklich dinge die man wissen muss und die ich leider noch nichts weiß...

das mit den logmeldungen, hab ich so in dem dreh schon gemacht... ich hab mir halt immer System.out.println für jede operation gemacht.

dadurch wußte ich ja, dass das problem bei der eg. bei der while bedingung liegen muss  hatte auch eine system.out nur für die random. zeigte eg. jede zahl an... nur leider wusste ich nicht, dass ich equal nehmen muss... recht herzlichen dank nochmal


----------

