//KEY GENERATION ALGORITHM IN DIFFIE-HELLMAN KEY EXCHANGE PROTOCOL
void KeyGeneration(long int *q, long int *alpha, long int *private_key, long int *public_key)
{
	
        long int p;
	if(print_flag1)
		printf("\n selecting q->\n\r");

	
        
	while(1)
	{
               srand((unsigned int) time(NULL));
               p = random() % LARGE;
	       if( p <= 10000) continue;
               /* test for even number */
               if ( (p & 0x01) == 0 ) continue;

               /* Trivial divisibility test by primes 3, 5, 7, 11, 13, 17, 19 */
               if ( (p % 3 == 0 ) || (p % 5 == 0) || (p % 7 == 0) || (p % 11 == 0 )
                    || (p % 13 == 0) || ( p % 17 == 0) || ( p% 19 == 0) )
               continue;

               if( MillerRobinTest(p, MAX_ITERATION) )
		break;
		
	}

    *q = p;
    if (verify_prime(p) )
      printf( "q = %ld is prime\n", *q);
     else {
      printf("q = %ld is composite\n", *q);
      exit(0);
     }
     
     /* Select a primitive root of q */
     *alpha = primitive_root( p );
          
     /* Select a private key  < q  randomly */
     *private_key = rand() % p;

    /* Compute the public key */
    *public_key = ModPower(*alpha, *private_key, *q);

} 
//KEY GENERATION ALGORITHM IN RSA CRYPTOSYSTEM.
void KeyGeneration(key *pub_key, key *pvt_key)
{
long int p,q;
long int n;
long int phi_n;
long int e;
// Select p and q which are primes and p<q.
if(print_flag1)
printf("\n selecting p->\n\r");
while(1)
{
 srand((unsigned int) time(NULL));
 p = random() % LARGE;
 /* test for even number */
 if ( p & 0x01 == 0 ) continue;
 if(MillerRobinTest(p, MAX_ITERATION))
break;
}
if(print_flag1)
printf("\n selecting q->\n\r");

while(1)
{
 srand((unsigned int) time(NULL));
 q=random() % LARGE;
if( q == p)
{
 srand((unsigned int) time(NULL));
q = random() % LARGE;
continue;
}
if(MillerRobinTest(q, MAX_ITERATION))
break;

}
 // Compute n.
 if (verify_prime(p) && verify_prime(q) )
 printf("p = %ld, q = %ld are primes\n", p, q);
 else {
 //exit(0);

 return recall_key(pub_key, pvt_key);

 }
 printf("p = %ld, q = %ld\n", p, q);
 n = p * q;
 // Compute Euler's phi(totient) function
 phi_n = (p-1)*(q-1);
 // Compute e such that gcd(e,phi_n(n))=1.
 if(print_flag1)
 printf("\n selcting e->\n\r");
 while(1)
 {
 e = random()%phi_n;
 if(gcd(e, phi_n)==1)
 break;
 }
// Compute d such that ed=1(mod phi_n(n)).
 if(print_flag1)
 printf("\n selceting d->\n\r");
 extended_euclid(1, 0, phi_n, 0, 1, e);
 if(mul_inverse <0) {
 mul_inverse = - mul_inverse;
 mul_inverse = ((phi_n - 1 ) * mul_inverse) mod phi_n;
 }
 if(print_flag1)
 printf("\n phi_n= %ld\n\n",phi_n);
// Put Public Key and Private Key.
 pub_key->public_key.n = n;
 pub_key->public_key.e = e;
 pvt_key->private_key.n = n;
 pvt_key->private_key.d = mul_inverse;
} // end of KeyGeneraion()