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

class GenSig {
    public static long GetCurrentTime()
    {
	java.util.Date date=Calendar.getInstance().getTime();
	Timestamp a=new Timestamp(date.getTime()); 
	long currentTime=Calendar.getInstance().getTimeInMillis();
	return currentTime;
    }


    public static void main(String[] args) {
	int[] keySize={512, 1024, 2048};
	String[] type={"SHA1withRSA", "MD5withRSA", "SHA1withDSA"};
	String[] type1={"RSA", "DSA"};

	long start, end, diff;

        /* Generate a DSA signature */
        if (args.length != 1) {
            System.out.println("Usage: GenSig nameOfFileToSign");
	}
        else try{
            /* Generate a key pair */
	    for(int keyCount=0; keyCount<3; ++keyCount)
		{
		    for(int i=0; i<3; ++i)
			{
			    if (keyCount==2 && i==2)
				continue;

			    KeyPairGenerator keyGen = KeyPairGenerator.getInstance(type1[i/2]);
			    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
			    
			    keyGen.initialize(keySize[keyCount], random);
		    
			    KeyPair pair = keyGen.generateKeyPair();
			    PrivateKey priv = pair.getPrivate();
			    PublicKey pub = pair.getPublic();
			    
			    System.out.println("[Algorithm:  "+type[i]+ ", KeySize: "+keySize[keyCount]+"]");
			    System.out.print("Signing message ... ");
			    /* Create a Signature object and initialize it with the private key */
			    Signature dsa = Signature.getInstance(type[i]); 
		    
			    dsa.initSign(priv);
			    
			    /* Update and sign the data */
			    FileInputStream fis = new FileInputStream(args[0]);
			    BufferedInputStream bufin = new BufferedInputStream(fis);
			    byte[] buffer = new byte[1024];
			    int len=0;
			    while (bufin.available() != 0) {
				len = bufin.read(buffer);
				dsa.update(buffer, 0, len);
			    };
			    
			    bufin.close();

			    /* Now that all the data to be signed has been read in, generate a signature for it */
			    start= GetCurrentTime();
			    byte[] realSig = dsa.sign();
			    end= GetCurrentTime();
			    
			    System.out.println("Done. [time: "+(end-start)+" ]");
			    
			    /*Signing part is over
			      we have realSig <-- Signature
			      pub <-- public key
			    */
			    /*------------------------------------------------------------------------------------------------------*/
			    /*VERIFICATION OF SIGNATURE*/
			    {
				System.out.print("Verifying message signature... ");
				
				// Initializing dsa with public key to do verification
				dsa.initVerify(pub);
			
				// Regenerating hash value which i don't ehink require
				FileInputStream fis1 = new FileInputStream(args[0]);
				BufferedInputStream bufin1 = new BufferedInputStream(fis1);
				
				
				while (bufin1.available() != 0) {
				    len = bufin1.read(buffer);
				    dsa.update(buffer, 0, len);
				};
				
				bufin1.close();
			
				start= GetCurrentTime();
				boolean verifies = dsa.verify(realSig);
				end= GetCurrentTime();
			
				System.out.println(verifies+" Done.[time:"+(end-start)+" ]\n");
			    }
			}
		}
	} 
	catch (Exception e) {
            System.err.println("Caught exception " + e.toString());
        }
    };
}
