package mkgray.security.dh;

import java.math.*;
import java.util.*;
import java.io.*;

public class Util {
  static BigInteger modulus;
  static BigInteger exp;

  public static void main (String args[]){
    findModulus(Integer.parseInt(args[0]));
    System.out.println("Modulus "+modulus);
    System.out.println("Exp "+exp);
  }

  public static String hexify(byte data[]) {
    char tohex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    			   'a', 'b', 'c', 'd', 'e', 'f'};
    char hexout[] = new char[data.length*2];

    for(int ct=0;ct<data.length;ct++){
      int val;
      if(data[ct] < 0)
	val = 256+((int)data[ct]);
      else
	val = (int) data[ct];
      hexout[ct*2] = tohex[val/16];
      hexout[(ct*2)+1] = tohex[val%16];
    }
    return new String(hexout);
  }

  public static byte[] dehexify(String s){
    int fromhex[] = new int[103];
    fromhex[48] = 0;
    fromhex[49] = 1;
    fromhex[50] = 2;
    fromhex[51] = 3;
    fromhex[52] = 4;
    fromhex[53] = 5;
    fromhex[54] = 6;
    fromhex[55] = 7;
    fromhex[56] = 8;
    fromhex[57] = 9;
    fromhex[97] = 10;
    fromhex[98] = 11;
    fromhex[99] = 12;
    fromhex[100] = 13;
    fromhex[101] = 14;
    fromhex[102] = 15;
    byte hexstr[] = s.getBytes();
    byte data[] = new byte[hexstr.length/2];
    for(int ct=0;(ct+1)<hexstr.length;ct+=2){
      int val1, val2;
      if(hexstr[ct] < 0)
	val1 = 256-hexstr[ct];
      else
	val1 = hexstr[ct];

      if(hexstr[ct+1] < 0)
	val2 = 256-hexstr[ct+1];
      else
	val2 = hexstr[ct+1];

      data[ct/2] = 
	((byte) (fromhex[val1]*16 + 
		 fromhex[val2]));
    }
    return data;
  }

  public static void findModulus(int nbits) {
    BigInteger candidate, other;
    while(true) {
      candidate = new BigInteger(nbits, 12, new Random());
      System.out.println("Trying a new candidate "+candidate);
      other = (candidate.subtract(new BigInteger("1"))).divide(new BigInteger("2"));
      if(other.isProbablePrime(12)){
	System.out.println("Candidate passes phase 1");
	for(int g=2;g<25;g++){
	  if(!((new BigInteger(new String(""+g))).modPow(other, candidate)).equals(new BigInteger("1"))){
	    System.out.println("Candidate passes phase 2");
	    if(!((new BigInteger(new String(""+g))).modPow(new BigInteger("2"), candidate)).equals(new BigInteger("1")) ){
	      exp = new BigInteger(new String(""+g));
	      modulus = candidate;
	      return;
	    }
	  }
	}
      }
    }
  }
}


