@@ -0,0 +1,4 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="Encoding" addBOMForNewFiles="with NO BOM" /> | |||||
</project> |
@@ -0,0 +1,6 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK"> | |||||
<output url="file://$PROJECT_DIR$/out" /> | |||||
</component> | |||||
</project> |
@@ -0,0 +1,8 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="ProjectModuleManager"> | |||||
<modules> | |||||
<module fileurl="file://$PROJECT_DIR$/RSA.iml" filepath="$PROJECT_DIR$/RSA.iml" /> | |||||
</modules> | |||||
</component> | |||||
</project> |
@@ -0,0 +1,6 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<project version="4"> | |||||
<component name="VcsDirectoryMappings"> | |||||
<mapping directory="" vcs="Git" /> | |||||
</component> | |||||
</project> |
@@ -0,0 +1,11 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<module type="JAVA_MODULE" version="4"> | |||||
<component name="NewModuleRootManager" inherit-compiler-output="true"> | |||||
<exclude-output /> | |||||
<content url="file://$MODULE_DIR$"> | |||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" /> | |||||
</content> | |||||
<orderEntry type="inheritedJdk" /> | |||||
<orderEntry type="sourceFolder" forTests="false" /> | |||||
</component> | |||||
</module> |
@@ -0,0 +1,9 @@ | |||||
import java.math.BigInteger; | |||||
public class Main { | |||||
public static void main(String[] args) { | |||||
BigInteger prime = Prime.generate(32); | |||||
System.out.println("Finished - number is "+prime); | |||||
} | |||||
} |
@@ -0,0 +1,132 @@ | |||||
import java.math.BigInteger; | |||||
import java.util.LinkedList; | |||||
import java.util.List; | |||||
import java.util.Random; | |||||
public class Prime { | |||||
/** | |||||
* Calculates the integer square root of a number. | |||||
* Source: https://stackoverflow.com/questions/4407839/how-can-i-find-the-square-root-of-a-java-biginteger/13023513#13023513 | |||||
* | |||||
* @param x the number | |||||
* @return the square root | |||||
*/ | |||||
private static BigInteger sqrt(BigInteger x) { | |||||
BigInteger div = BigInteger.ZERO.setBit(x.bitLength()/2); | |||||
BigInteger div2 = div; | |||||
// Loop until we hit the same value twice in a row, or wind | |||||
// up alternating. | |||||
for(;;) { | |||||
BigInteger y = div.add(x.divide(div)).shiftRight(1); | |||||
if (y.equals(div) || y.equals(div2)) | |||||
return y; | |||||
div2 = div; | |||||
div = y; | |||||
} | |||||
} | |||||
/** | |||||
* Checks, whether a number is a prime or not. Uses naive implementation accelerated by multithreading. | |||||
* | |||||
* @param candidate the number to check | |||||
* @return the boolean | |||||
*/ | |||||
private static boolean isPrime(BigInteger candidate) { | |||||
// Check special candidate values 0, 1, 2 and even | |||||
if (candidate.compareTo(BigInteger.ZERO) == 0 // candidate == 0 | |||||
|| candidate.compareTo(BigInteger.ONE) == 0) { // candidate == 1) | |||||
return false; | |||||
} | |||||
if (candidate.compareTo(BigInteger.valueOf(2)) == 0) { // candidate == 2 | |||||
return true; | |||||
} else if (candidate.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) { // candidate is even | |||||
return false; | |||||
} | |||||
// Divide interval into segments, one for each cpu core | |||||
int cores = Runtime.getRuntime().availableProcessors(); | |||||
BigInteger max = sqrt(candidate).add(BigInteger.ONE); | |||||
BigInteger min = BigInteger.valueOf(3); | |||||
BigInteger step = max.subtract(min).divide(BigInteger.valueOf(cores)); | |||||
BigInteger remainder = max.subtract(min).mod(BigInteger.valueOf(cores)); | |||||
int i = 0; | |||||
List<Worker> workers = new LinkedList<>(); | |||||
while (i < cores) { | |||||
BigInteger num = step; | |||||
if (remainder.compareTo(BigInteger.ZERO) == 1) { // remainder > 0 | |||||
num = num.add(BigInteger.ONE); | |||||
remainder = remainder.subtract(BigInteger.ONE); | |||||
} | |||||
num = num.subtract(BigInteger.ONE); | |||||
if (num.compareTo(BigInteger.ZERO) >= 0) { | |||||
workers.add(new Worker(candidate, min, min.add(num), "Thread " + i)); | |||||
workers.get(i).start(); | |||||
min = min.add(num).add(BigInteger.ONE); | |||||
} | |||||
i++; | |||||
if (min.compareTo(max) > 0) { | |||||
break; | |||||
} | |||||
} | |||||
// Wait for workers to complete | |||||
boolean stop = false; | |||||
boolean isPrime = true; | |||||
while (!stop) { | |||||
i = 0; | |||||
while (i < workers.size()) { | |||||
Worker w = workers.get(i); | |||||
try { | |||||
w.join(500); | |||||
} catch (InterruptedException ex) { | |||||
ex.printStackTrace(); | |||||
} | |||||
if (w.hasFinished()) { | |||||
if (!w.isPrime()) { | |||||
isPrime = false; | |||||
stop = true; | |||||
break; | |||||
} else { | |||||
// This worker is done, remove it from the list | |||||
workers.remove(w); | |||||
if (workers.isEmpty()) { | |||||
stop = true; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
i++; | |||||
} | |||||
} | |||||
// Stop workers | |||||
for (Worker w: workers) { | |||||
w.interrupt(); | |||||
} | |||||
return isPrime; | |||||
} | |||||
/** | |||||
* Generates a guaranteed prime of the given length. | |||||
* | |||||
* @param bits binary length of the prime to generate | |||||
* @return prime number | |||||
*/ | |||||
public static BigInteger generate(int bits) { | |||||
Random rng = new Random(); | |||||
BigInteger candidate = new BigInteger(bits, rng); | |||||
int i = 0; | |||||
while (!isPrime(candidate)){ | |||||
//System.out.println("Not a prime: " + candidate); | |||||
candidate = new BigInteger(bits, rng); | |||||
i++; | |||||
} | |||||
//System.out.println("Found prime after " + i + " tries: " + candidate); | |||||
return candidate; | |||||
} | |||||
} |
@@ -0,0 +1,28 @@ | |||||
public class RSA { | |||||
// p = 5, q = 11 | |||||
// RSA-Modul N = p * q = 55 | |||||
// Phi(N) = Phi(p)*Phi(q) | weil eigenschaft eulersche phi funktion und p,q teilerfremd | |||||
// = (p-1)*(q-1) | p,q primzahlen, daher nur durch 1 und sich selbst teilbar und alle anderen teilerfremd | |||||
// = 4*10 = 40 | |||||
// e: 1 < e < Phi(N) und ggT(e, Phi(N)) = 1 | |||||
// e elem aus {3,..} => e = 3 | |||||
// (e,N) = (3, 55) public key | |||||
// ----- | |||||
// d: e*d kongr 1 mod Phi(N) => e*d mod Phi(N) = 1 | |||||
// 3*d mod 40 = 1 | |||||
// Durch probieren: d=27 => (27, 55) private key | |||||
// | |||||
// ---- | |||||
// Verschlüsseln | |||||
// 13 | |||||
// c = m^e (mod N) => 13^3 (mod 55) = 52 = c | |||||
// ---- | |||||
// Entschlüsseln | |||||
// m = c^d (mod N) => 52^27 (mod 55) = 13 = m | |||||
public RSA() { | |||||
} | |||||
} |
@@ -0,0 +1,58 @@ | |||||
import java.math.BigInteger; | |||||
/** | |||||
* Worker class used in multithreading to check, whether a given number is a prime. | |||||
*/ | |||||
public class Worker extends Thread { | |||||
private boolean isPrime; | |||||
private BigInteger minVal; | |||||
private BigInteger maxVal; | |||||
private BigInteger candidate; | |||||
private boolean finished = false; | |||||
private String threadName ; | |||||
public Worker(BigInteger candidate, BigInteger min, BigInteger max, String threadName) { | |||||
this.minVal = min; | |||||
this.maxVal = max; | |||||
this.candidate = candidate; | |||||
this.isPrime = true; | |||||
this.threadName = threadName; | |||||
//System.out.println("Created "+threadName+" for "+min+"-"+max+""); | |||||
} | |||||
/** | |||||
* Returns a flag, indicating whether the prime candidate has a divisor in the given interval. | |||||
* Since the thread might be still be running, it is important to check it first by using the | |||||
* hasFinished() method. | |||||
* | |||||
* @return flag indicating whether there is a divisor or not | |||||
*/ | |||||
public boolean isPrime() { | |||||
return this.isPrime; | |||||
} | |||||
/** | |||||
* Returns if the thread has finished checking the given interval. | |||||
* | |||||
* @return the boolean | |||||
*/ | |||||
public boolean hasFinished() { return this.finished; } | |||||
public void run() { | |||||
BigInteger divCandidate = minVal; | |||||
if (divCandidate.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)){ | |||||
divCandidate = divCandidate.add(BigInteger.ONE); | |||||
} | |||||
while (divCandidate.compareTo(maxVal) < 1){ //divCandidate <= maxVal | |||||
//System.out.println(this.threadName + " is testing "+divCandidate); | |||||
if (candidate.mod(divCandidate).equals(BigInteger.ZERO)) { | |||||
this.isPrime = false; | |||||
this.finished = true; | |||||
return; | |||||
} | |||||
divCandidate = divCandidate.add(BigInteger.ONE).add(BigInteger.ONE); | |||||
} | |||||
this.finished = true; | |||||
// No divisor found, we are done for this interval | |||||
} | |||||
} |