import java.util.* ;
import java.sql.*;
import java.io.*;
import java.security.*;

class SignGen
{
	   public static long getCurrentTime() {
                java.util.Date date=Calendar.getInstance().getTime();
          Timestamp a=new Timestamp(date.getTime());
          long currentTime=Calendar.getInstance().getTimeInMillis();
           //     System.out.println("Time: "+currentTime);
                                                                                                                             
                return currentTime;
        }
                                                                                                                             

	public static void main(String args[]) {
		if(args.length!=1){
			System.out.println("Usage: SignGen <name_of_file_to_sign>");
			System.exit(0);
		}
		try{

			/************************* BEGIN Generate a key pair ***************************/
			KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA","SUN");
			SecureRandom random = SecureRandom.getInstance("SHA1PRNG","SUN");
			KeyPairGenerator rsaKeygen = KeyPairGenerator.getInstance("RSA");
			rsaKeygen.initialize(1024,random);
			keygen.initialize(1024,random);
			KeyPair rsaKeypair = rsaKeygen.generateKeyPair();
			KeyPair keypair = keygen.generateKeyPair();
			
			PrivateKey rsaPrivatekey = rsaKeypair.getPrivate();
                        PublicKey rsaPublickey = rsaKeypair.getPublic();
			PrivateKey privatekey = keypair.getPrivate();
			PublicKey publickey = keypair.getPublic();
			
			
			/************************* END Generate a key pair ***************************/

			/************* Create a Signature object and initialize it with private key **************/
			Signature dsa = Signature.getInstance("SHA1withDSA","SUN");
			dsa.initSign(privatekey);
			Signature rsa= Signature.getInstance("SHA1withRSA");
                        rsa.initSign(rsaPrivatekey);


			/************************* Update and Sign the data ***************************/
			FileInputStream fis = new FileInputStream(args[0]);
			BufferedInputStream bis = new BufferedInputStream(fis);
		 	StringBuffer sb=new  StringBuffer("");

			byte buffer[] = new byte[1024];
			int length;
			while(bis.available() != 0){
				length = bis.read(buffer);
				dsa.update(buffer,0,length);
				 rsa.update(buffer,0,length);
				 sb.append(new String(buffer));
			}
			bis.close();
			
			/*
			 * Now, that all the data t obe signed is read in,
			 * and hash generated ( using update method )
			 * generate a signature for it
			 */
			byte[] realsign = dsa.sign();
			byte [] rsaSign=rsa.sign();
			String data=new String(sb);
			/*********** Save signature in a file *************/
			FileOutputStream sigfos = new FileOutputStream(args[0]+".dsa_sign");
			sigfos.write(realsign);
			sigfos.close();
			sigfos = new FileOutputStream(args[0]+".rsa_sign");
                        sigfos.write(rsaSign);
                        sigfos.close();

			/*********** Save Public key in a file ************/
			FileOutputStream pubkeyfos = new FileOutputStream(args[0]+".dsa_sign_public_key");
			pubkeyfos.write(publickey.getEncoded());
			pubkeyfos.close();
			
			pubkeyfos = new FileOutputStream(args[0]+".rsa_sign_public_key");
                        pubkeyfos.write(rsaPublickey.getEncoded());
                        pubkeyfos.close();

			/*********** Save Private key in a file ************/
			FileOutputStream prikeyfos = new FileOutputStream(args[0]+".dsa_sign_private_key");
			prikeyfos.write(privatekey.getEncoded());
			prikeyfos.close();
			
			prikeyfos = new FileOutputStream(args[0]+".rsa_sign_private_key");
                        prikeyfos.write(rsaPrivatekey.getEncoded());
                        prikeyfos.close();
			
			/*********Verification****************************/
			Signature dsa1 = Signature.getInstance("SHA1withDSA","SUN");
                        //dsa.initSign(privatekey);
                        Signature rsa1= Signature.getInstance("SHA1withRSA");

			rsa1.initVerify(rsaPublickey);
			dsa1.initVerify(publickey);
			System.out.print("\n"+data);
			fis = new FileInputStream(args[0]);
                        bis = new BufferedInputStream(fis);
                                                                                                                                                   
                        //byte buffer[] = new byte[1024];
                        //int length;
                        while(bis.available() != 0){
                                length = bis.read(buffer);
                                dsa1.update(buffer,0,length);
                                 rsa1.update(buffer,0,length);
                                 //sb.append(new String(buffer));
                        }
                        bis.close();
			//rsa1.update(data.getBytes());
			//dsa1.update(data.getBytes());
			if(rsa1.verify(rsaSign)) {
				System.out.println("RSA sign verified");
			}
			else {
				System.out.println("RSA sign verification failed");
                        }
			if(dsa1.verify(realsign)) {
                                System.out.println("DSA sign verified");
                        }
                        else {
                                System.out.println("DSA sign verification failed");
                        }
			
			/********Time ****************/
			System.out.println( "Key_Size  MSg_Size   RSA_SIgning   DSA_signing     RSA_vrify    DSA_Verify" ) ;
			String msg="Kanwal Rekhi School of Information Technology, IIT Bombay";
			long start,end;
        		for(int primeSize=512;primeSize<=2048;primeSize*=2) {
			 	System.out.print(""+primeSize);
				System.out.print("       "+msg.length());
				rsaKeygen.initialize(primeSize,random);
	                        keygen.initialize(primeSize,random);
                     	 	rsaKeypair = rsaKeygen.generateKeyPair();
                        	keypair = keygen.generateKeyPair();                                                                                                                      
                       		rsaPrivatekey = rsaKeypair.getPrivate();
                       		rsaPublickey = rsaKeypair.getPublic();
                       		privatekey = keypair.getPrivate();
                        	publickey = keypair.getPublic();
				dsa.initSign(privatekey);
                        	rsa.initSign(rsaPrivatekey);
				rsa.update(msg.getBytes());
				dsa.update(msg.getBytes());
				start=getCurrentTime();
				rsa.sign();
				end=getCurrentTime();

				System.out.print("      "+(end-start));	
				start=getCurrentTime();
				dsa.sign();
				end=getCurrentTime();
				System.out.print("    "+(end-start));
				rsa.initVerify(rsaPublickey);
	                        dsa.initVerify(publickey);
		         	rsa.update(msg.getBytes());
			 	start=getCurrentTime();
				rsa.verify(rsaSign); 
				end=getCurrentTime();
				System.out.print("         "+(end-start));
				dsa.update(msg.getBytes());
                                start=getCurrentTime();
                                dsa.verify(realsign);
                                end=getCurrentTime();
                                System.out.println("        "+(end-start));


				if(primeSize==512) {
 					int i,m=0;
        	                	StringBuffer ptext=new StringBuffer(4096);
	                	        StringBuffer ts=new StringBuffer(128);
		                        ts.append("RAMA");
        	                	while(ts.length()<128)//making a message of 128B length
                	        	{
	                                	ts.append(ts.toString());
                        		}
	                        	for(int mSize=0;mSize<=4096;) {
        	                       		System.out.print( ""+primeSize+"    " ) ;
                	        		System.out.print( ""+mSize+"      " ) ;
        	                             	dsa.initSign(privatekey);
		                                rsa.initSign(rsaPrivatekey);
        		                       	msg=new String(ptext);
						rsa.update(msg.getBytes());
                        		        dsa.update(msg.getBytes());
		                                start=getCurrentTime();
                		                rsa.sign();
                                		end=getCurrentTime();
		                                System.out.print(""+(end-start));
                		                start=getCurrentTime();
                                		dsa.sign();
		                                end=getCurrentTime();
                		                System.out.print("       "+(end-start));
                                		rsa.initVerify(rsaPublickey);
			                        dsa.initVerify(publickey);
                        		        rsa.update(msg.getBytes());
		                                start=getCurrentTime();
                		                rsa.verify(rsaSign);
                                		end=getCurrentTime();
		                                System.out.print("        "+(end-start));
                		                dsa.update(msg.getBytes());
                                		start=getCurrentTime();
		                                dsa.verify(realsign);
                                		end=getCurrentTime();
                		                System.out.println("     "+(end-start));
						ptext.append(ts);
	                                        mSize=ptext.length();
        		                }//for msize
				}//if prime
			}//for prime
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}
