Advertisement
Guest User

RSA

a guest
Jul 16th, 2014
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.49 KB | None | 0 0
  1. package rsa;
  2.  
  3. import java.math.BigInteger;
  4. import java.util.ArrayList;
  5. import java.util.Random;
  6. import java.util.concurrent.atomic.AtomicLong;
  7. import java.util.logging.Level;
  8. import java.util.logging.Logger;
  9.  
  10. public class RSA {
  11.  
  12.     private final Random random;
  13.  
  14.     private BigInteger privateKey;
  15.     private BigInteger publicKey;
  16.     private BigInteger modulo;
  17.  
  18.     public static void main(String[] args) {
  19.         RSA rsa = new RSA();
  20.         rsa.generateNewKeypair(1024);
  21.         BigInteger message = BigInteger.valueOf(1234);
  22.         BigInteger encrypted = RSA.translate(message, rsa.getPublicKey(), rsa.getModulo());
  23.         BigInteger decrypted = RSA.translate(encrypted, rsa.getPrivateKey(), rsa.getModulo());
  24.         System.out.println("Encrypted: " + encrypted);
  25.         System.out.println("Decrypted: " + decrypted);
  26.     }
  27.  
  28.     public RSA() {
  29.         random = new IntelRandom();
  30.     }
  31.  
  32.     public static BigInteger translate(BigInteger message, BigInteger key, BigInteger module) {
  33.         return message.modPow(key, module);
  34.     }
  35.  
  36.     public BigInteger encode(BigInteger message) {
  37.         return message.modPow(publicKey, modulo);
  38.     }
  39.  
  40.     public BigInteger decode(BigInteger message) {
  41.         return message.modPow(privateKey, modulo);
  42.     }
  43.  
  44.     public BigInteger getModulo() {
  45.         return modulo;
  46.     }
  47.  
  48.     public BigInteger getPrivateKey() {
  49.         return privateKey;
  50.     }
  51.  
  52.     public BigInteger getPublicKey() {
  53.         return publicKey;
  54.     }
  55.  
  56.     public void generateNewKeypair(int bit) {
  57.         BigInteger[] primes = generatePrimes(2, bit / 2);
  58.         BigInteger p = primes[0];
  59.         BigInteger q = primes[1];
  60.         modulo = q.multiply(p);
  61.         BigInteger pN = (q.subtract(BigInteger.valueOf(1))).multiply(p.subtract(BigInteger.valueOf(1)));
  62.         publicKey = BigInteger.ZERO;
  63.         while (publicKey.equals(BigInteger.ZERO)) {
  64.             BigInteger rnd = new BigInteger(pN.bitLength(), random);
  65.             if (rnd.compareTo(pN) <= 0 && rnd.gcd(pN).equals(BigInteger.ONE)) {
  66.                 publicKey = rnd;
  67.             }
  68.         }
  69.         privateKey = publicKey.modInverse(modulo);
  70.     }
  71.  
  72.     private BigInteger[] generatePrimes(int amount, int length) {
  73.         final ModifiableFinal<Integer> mAmount = new ModifiableFinal<>(amount);
  74.         final ArrayList<PrimeThread> threads = new ArrayList<>();
  75.         int threadAmount = Runtime.getRuntime().availableProcessors();
  76.         if (threadAmount < mAmount.getValue()) {
  77.             threadAmount = mAmount.getValue();
  78.         }
  79.         final BigInteger[] primes = new BigInteger[mAmount.getValue()];
  80.         for (int i = 0; i < threadAmount; i++) {
  81.             final PrimeThread pt = new PrimeThread(length, random) {
  82.                 @Override
  83.                 public void onDone() {
  84.                     if (mAmount.getValue() != 0) {
  85.                         primes[primes.length - mAmount.getValue()] = this.getPrime();
  86.                         mAmount.setValue(mAmount.getValue() - 1);
  87.                         if (mAmount.getValue() == 0) {
  88.                             new Thread() {
  89.                                 @Override
  90.                                 public void run() {
  91.                                     for (Thread t : threads) {
  92.                                         t.stop();
  93.                                     }
  94.                                 }
  95.                             }.start();
  96.                         }
  97.                     }
  98.                 }
  99.             };
  100.             pt.start();
  101.             threads.add(pt);
  102.         }
  103.         for (Thread thread : threads) {
  104.             try {
  105.                 thread.join();
  106.             } catch (InterruptedException ex) {
  107.                 Logger.getLogger(RSA.class.getName()).log(Level.SEVERE, null, ex);
  108.             }
  109.         }
  110.         return primes;
  111.     }
  112.  
  113.     private static class PrimeThread extends Thread {
  114.  
  115.         private BigInteger prime = null;
  116.         private final int length;
  117.         private final Random random;
  118.  
  119.         public PrimeThread(int length, Random random) {
  120.             this.length = length;
  121.             this.random = random;
  122.         }
  123.  
  124.         @Override
  125.         public void run() {
  126.             prime = BigInteger.probablePrime(length, random);
  127.             onDone();
  128.         }
  129.  
  130.         public BigInteger getPrime() {
  131.             return prime;
  132.         }
  133.  
  134.         public void onDone() {
  135.             //Override this
  136.         }
  137.     }
  138.  
  139.     public static class IntelRandom extends Random {
  140.  
  141.         private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L);
  142.         private static final long mask = (1L << 48) - 1;
  143.         private static final long multiplier = 0x5DEECE66DL;
  144.         private final AtomicLong seed;
  145.  
  146.         public IntelRandom() {
  147.             seed = new AtomicLong(initialScramble(seedUniquifier() ^ System.nanoTime()));
  148.         }
  149.  
  150.         private static long initialScramble(long seed) {
  151.             return (seed ^ multiplier) & mask;
  152.         }
  153.  
  154.         private static long seedUniquifier() {
  155.             for (;;) {
  156.                 long current = seedUniquifier.get();
  157.                 long next = current * 181783497276652981L;
  158.                 if (seedUniquifier.compareAndSet(current, next)) {
  159.                     return next;
  160.                 }
  161.             }
  162.         }
  163.  
  164.         @Override
  165.         public void nextBytes(byte[] bytes) {
  166.             for (int i = 0, len = bytes.length; i < len;) {
  167.                 for (int rnd = nextInt(),
  168.                         n = Math.min(len - i, Integer.SIZE / Byte.SIZE);
  169.                         n-- > 0; rnd >>= Byte.SIZE) {
  170.                     bytes[i++] = (byte) rnd;
  171.                 }
  172.             }
  173.         }
  174.  
  175.         @Override
  176.         public int nextInt() {
  177.             return next(seed, 32);
  178.         }
  179.  
  180.         private static int next(AtomicLong seed, int nbits) {
  181.             long x = seed.get();
  182.             x ^= (x << 21);
  183.             x ^= (x >>> 35);
  184.             x ^= (x << 4);
  185.             seed.set(x);
  186.             x &= ((1L << nbits) - 1);
  187.             return (int) x;
  188.         }
  189.     }
  190.    
  191.     public class ModifiableFinal<T> {
  192.  
  193.         private T value;
  194.  
  195.         public ModifiableFinal() {
  196.         }
  197.  
  198.         public ModifiableFinal(T initialValue) {
  199.             this.value = initialValue;
  200.         }
  201.  
  202.         public void setValue(T newValue) {
  203.             this.value = newValue;
  204.         }
  205.  
  206.         public T getValue() {
  207.             return this.value;
  208.         }
  209.     }
  210. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement