package rsa; import java.io.*; import java.lang.*; import java.util.*; import java.security.*; import java.security.interfaces.*; import java.math.*; /** * * @author John D'Ambrosio */ public class Main { // this is a very primitive encoding scheme... not really for efficiency public static BigInteger encode(String inputString) { BigInteger addend, result = BigInteger.valueOf(0), multiplier = BigInteger.valueOf(256); System.out.print("Encoding..."); for(int n=inputString.length()-1; n>=0; n--) { addend = BigInteger.valueOf(inputString.charAt(n)); result = result.add(addend); //System.out.println("\nCharacter " + n + ": " + inputString.charAt(n)); //System.out.println("Sum: " + result); if(n>0) result = result.multiply(multiplier); //System.out.println("Product: " + result); } System.out.println("done!"); return result; } public static String decode(BigInteger inputBigInt) { String result = new String(); BigInteger quotientAndRemainder[], divisor = BigInteger.valueOf(256); System.out.print("Decoding..."); while(inputBigInt.compareTo(BigInteger.ZERO) != 0) { quotientAndRemainder = inputBigInt.divideAndRemainder(divisor); inputBigInt = quotientAndRemainder[0]; result = result.concat(String.valueOf((char)(quotientAndRemainder[1].byteValue()))); //System.out.println("\nQuotient: " + quotientAndRemainder[0]); //System.out.println("Remainder: " + quotientAndRemainder[1]); //System.out.println("Result: " + result); } System.out.println("done!"); return result; } /** Creates a new instance of Main */ public Main() { } /** * @param args the command line arguments */ public static void main(String args[]) { try { Random rand = new Random(); BigInteger d, e, p, q, m, n, in, msg, out; p = BigInteger.probablePrime(24, rand); q = BigInteger.probablePrime(24, rand); m = p.multiply(q); n = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE)); e = BigInteger.probablePrime(16, rand); d = e.modInverse(n); in = encode("RSA"); msg = in.modPow(e,m); out = msg.modPow(d,m); System.out.println("\nInput: RSA"); System.out.println("\nChoose two random primes of the same magnitude:" + "\np = " + p.toString(16) + "\nq = " + q.toString(16)); System.out.println("\nNow determine the:" + "\nModulus of reduction, p * q, m = " + m.toString(16) + "\nEuler-Phi of m, (p-1)*(q-1), n = " + n.toString(16) + "\nGCD(m,n) = " + (m.gcd(n)).toString(16)); System.out.println("\nChoose an encryption exponent, e = " + e.toString(16) + "\nGCD(e,n) = " + (e.gcd(n)).toString(16)); System.out.println("\nNow, using the Extended Euclidean Algorithm to find inverse(e)," + "\nCalculate the decryption exponent, d = " + d.toString(16) + "\ne * d = " + ((e.multiply(d)).mod(n)).toString(16) + " mod(n)"); System.out.println("\nMake the following public:" + "\nm = " + m.toString(16) + ", e = " + e.toString(16)); System.out.println("\nForm the encrypted message, in^e mod(m) = " + "\n" + in + "^" + e + " mod(" + m.toString(16) + ") = msg = " + msg.toString(16)); System.out.println("\nFinally, decrypt the message, msg^d mod(m) =" + "\n" + msg.toString(16) + "^" + d.toString(16) + " mod(" + m.toString(16) + ") = out = " + out.toString(16)); System.out.println("\nOutput: " + decode(out)); } catch (Exception e) { System.err.println("Caught exception " + e.toString()); } } }