Last active
January 2, 2016 04:48
-
-
Save stephnr/8252475 to your computer and use it in GitHub Desktop.
RSA key generator written in Java. Implements the eratosthenes sieve for computing prime numbers. Keys are based from a selection of 5000 prime numbers. Estimated run time efficiency: [ Roughly ~ 0.8 seconds ]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Random; | |
import java.util.ArrayList; | |
import java.util.StringTokenizer; | |
import java.math.BigInteger; | |
class RSA { | |
private int[] public_Key = new int[2]; | |
private int[] privat_Key = new int[2]; | |
public static void main(String[] args) { | |
RSA keys = new RSA(); | |
int[] pubK = keys.getPublicKey(); | |
int[] privK = keys.getPrivateKey(); | |
for(int i : pubK) { | |
System.out.println("Public Key: " + i); | |
} | |
for(int i : privK) { | |
System.out.println("Private Key: " + i); | |
} | |
} | |
public RSA() { | |
generate_Keys(5000); | |
} | |
public int[] getPublicKey() { | |
return this.public_Key; | |
} | |
public int[] getPrivateKey() { | |
return this.privat_Key; | |
} | |
private void generate_Keys(int complexity) { | |
ArrayList<Integer> primeTable = eratosthenes_Sieve(complexity); | |
Random rn = new Random(); | |
int prime1 = primeTable.get(rn.nextInt(primeTable.size())); | |
int prime2 = primeTable.get(rn.nextInt(primeTable.size())); | |
//System.out.println("Primes: " + prime1 + " " + prime2); | |
int n = prime1 * prime2; | |
//System.out.println("N: " + n); | |
int prodP = (prime1 - 1) * (prime2 - 1); | |
//System.out.println("prodP: " + prodP); | |
ArrayList<Integer> coprimes = new ArrayList<>(); | |
for(int i = 0; i < primeTable.size(); i++) { | |
if(primeTable.get(i) >= prodP) break; | |
if(gcd(primeTable.get(i),prodP) == 1 && primeTable.get(i)%2 == 1) coprimes.add(primeTable.get(i)); | |
} | |
int e = coprimes.get(rn.nextInt(coprimes.size())); | |
int[] pk = new int[4]; | |
public_Key[0] = n; | |
public_Key[1] = e; | |
int[] result = extended_GCD(e, prodP); | |
int d = prodP + result[0]; | |
privat_Key[0] = n; | |
privat_Key[1] = d; | |
} | |
private ArrayList<Integer> eratosthenes_Sieve(int num_Of_Primes) { | |
int limit = num_Of_Primes; | |
num_Of_Primes *= 4.5; | |
int[] primeTable = new int[num_Of_Primes]; | |
primeTable[0] = 1; | |
for( int i = 4; i < num_Of_Primes; i += 2) primeTable[i] = 1; | |
for( int i = 6; i < num_Of_Primes; i += 3) primeTable[i] = 1; | |
for( int i = 10; i < num_Of_Primes; i += 5) primeTable[i] = 1; | |
for( int i = 14; i < num_Of_Primes; i += 7) primeTable[i] = 1; | |
ArrayList<Integer> primes = new ArrayList<Integer>(); | |
for(int i = 1; i < num_Of_Primes; i++) { | |
if(primeTable[i] == 0) primes.add(i); | |
if(primes.size() == limit) break; | |
} | |
return primes; | |
} | |
private int gcd(int a, int b) { | |
if(a == 0 || b == 0) return a + b; | |
return gcd(b, a%b); | |
} | |
private int[] extended_GCD(int a, int b) { | |
int[] result = {1,0}; | |
if(b == 0) return result; | |
else { | |
int q = a/b; | |
int r = a - b*q; | |
result = extended_GCD(b,r); | |
int temp = result[0]; | |
result[0] = result[1]; | |
result[1] = temp - q * result[0]; | |
return result; | |
} | |
} | |
// Given a string, returns an encrypted line | |
public String encrypt_Line(String text, int[] public_Key) { | |
String result = ""; | |
for(int i = 0; i < text.length(); i++) { | |
int m = (int) text.charAt(i); | |
BigInteger encrypt = BigInteger.valueOf(m); | |
m = encrypt.pow(public_Key[1]).mod(BigInteger.valueOf(public_Key[0])).intValue(); | |
result += String.valueOf(m) + " "; | |
} | |
return result; | |
} | |
// Given an encrypted string, returns the original string | |
public String decrypt_Line(String code, int[] privat_Key) { | |
String result = ""; | |
StringTokenizer st = new StringTokenizer(code); | |
while(st.hasMoreTokens()) { | |
BigInteger base = BigInteger.valueOf(Integer.parseInt(st.nextToken())); | |
int temp = base.pow(privat_Key[1]).mod(BigInteger.valueOf(privat_Key[0])).intValue(); | |
char ch = (char) temp; | |
result += ch; | |
} | |
return result; | |
} | |
// Performs encryption on an entire array of strings | |
public ArrayList<String> encrypt_Text(ArrayList<String> text, int[] public_Key) { | |
for(int i = 0; i < text.size(); i++) text.set(i, encrypt_Line(text.get(i).toString(), public_Key)); | |
return text; | |
} | |
// Performs decryption on an entire array of encrypted strings | |
public ArrayList<String> decrypt_Text(ArrayList<String> text, int[] privat_Key) { | |
for(int i = 0; i < text.size(); i++) text.set(i, decrypt_Line(text.get(i).toString(), privat_Key)); | |
return text; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment