/* * keygen.cpp * * */ #include "keygen.h" #include "miller_rabin.h" #ifndef DEBUG #define DEBUG #endif /* forward declaration of variables from keygen_args.h */ extern char *pubkey; extern char *prikey; extern long prime_p; extern long prime_q; extern int random_f; unsigned long gcd(unsigned long x, unsigned long y) { while (x != y) { if (x > y) x -= y; else y -= x; } return x; } unsigned short gen_prime(void) { unsigned short prime_gen = rand(); /* tips from http://www.di-mgt.com.au/rsa_alg.html */ prime_gen |= LOW_BIT_ON; prime_gen |= FIRST_TWO_BITS_ON; while (!miller_rabin_16(prime_gen)) prime_gen += 2; return prime_gen; } int main(int argc, char **argv) { /* seed rand() */ srand((unsigned int ) time(NULL)); if (keygen_args(argc, argv) == 0) cout << "read arguments successfully" << endl; if (random_f) { printf("generating random primes...\n"); prime_p = gen_prime(); printf("generated p: %hu\n", (unsigned short) prime_p); prime_q = gen_prime(); printf("generated q: %hu\n", (unsigned short) prime_q); } /* n = p * q */ unsigned long n = prime_p * prime_q; if (n <= 127) { fprintf(stderr, "p * q needs to be bigger than 127\n"); exit(EXIT_FAILURE); } /* phi = (p-1)(q-1) */ unsigned long phi = (prime_p-1) * (prime_q-1); unsigned long fermat_primes[4] = { 3l, 17l, 19l, 31l }; unsigned long e; /* find e, 1 < e < phi, such that gcd(e, phi) = 1 */ int i; printf("computing e... "); for (i = 0; i < 4; i++) { e = fermat_primes[i]; if (gcd(e, phi) == 1) break; } if (i == 4) { fprintf(stderr, "error, could not find e\n"); exit(EXIT_FAILURE); } printf("done\n"); /* find d */ printf("computing d... (might take a while) "); fflush(stdout); unsigned long d = 1; while (1) { if ( ((e*d) % phi) == 1 ) break; d++; } printf("done\n"); #ifdef DEBUG printf("debug: pubkey = \"%s\"\n" " prikey = \"%s\"\n" " p = \"%ld\"\n" " q = \"%ld\"\n" " n = \"%lu\"\n" " phi = \"%lu\"\n" " e = \"%lu\"\n" " d = \"%lu\"\n", pubkey, prikey, prime_p, prime_q, n, phi, e, d); #endif /* save to xml files */ FILE *public_key = fopen(pubkey, "w"); FILE *private_key = fopen(prikey, "w"); if (public_key == NULL || private_key == NULL) { perror("fopen"); exit(EXIT_FAILURE); } fprintf(public_key, "\n"); fprintf(public_key, "\t%lu\n", e); fprintf(public_key, "\t%lu\n", n); fprintf(public_key, "\n"); printf("wrote \"%s\" file\n", pubkey); fprintf(private_key, "\n"); fprintf(private_key, "\t%lu\n", d); fprintf(private_key, "\t%lu\n", n); fprintf(private_key, "\n"); printf("wrote \"%s\" file\n", prikey); fclose(public_key); fclose(private_key); return 0; }