int mpz_millerrabin (mpz_srcptr n, int reps) { int r; mpz_t nm1, nm3, x, y, q; unsigned long int k; gmp_randstate_t rstate; int is_prime; TMP_DECL; TMP_MARK; MPZ_TMP_INIT (nm1, SIZ (n) + 1); mpz_sub_ui (nm1, n, 1L); MPZ_TMP_INIT (x, SIZ (n) + 1); MPZ_TMP_INIT (y, 2 * SIZ (n)); /* mpz_powm_ui needs excessive memory!!! */ /* Perform a Fermat test. */ mpz_set_ui (x, 210L); mpz_powm (y, x, nm1, n); if (mpz_cmp_ui (y, 1L) != 0) { TMP_FREE; return 0; } MPZ_TMP_INIT (q, SIZ (n)); /* Find q and k, where q is odd and n = 1 + 2**k * q. */ k = mpz_scan1 (nm1, 0L); mpz_tdiv_q_2exp (q, nm1, k); /* n-3 */ MPZ_TMP_INIT (nm3, SIZ (n) + 1); mpz_sub_ui (nm3, n, 3L); ASSERT (mpz_cmp_ui (nm3, 1L) >= 0); gmp_randinit_default (rstate); is_prime = 1; for (r = 0; r < reps && is_prime; r++) { /* 2 to n-2 inclusive, don't want 1, 0 or -1 */ mpz_urandomm (x, rstate, nm3); mpz_add_ui (x, x, 2L); is_prime = millerrabin (n, nm1, x, y, q, k); } gmp_randclear (rstate); TMP_FREE; return is_prime; }
int main() { unsigned long long n,i=1; for(n=2;n<SMALL;n++) if(isprime((int)n)) printf("%llu %d\n",i++,intsqrt(n)); if(n%2==0) n++; for(;n<(1ULL<<32);n+=2) { if(millerrabin((unsigned int)n)) printf("%llu %d\n",i++,intsqrt(n)); } for(;n<(1ULL<<63);n+=2) { if(ullmillerrabin(n)) printf("%llu %d\n",i++,intsqrt(n)); } return 0; }
/* it seems the routine breaks down if n>=2^63 */ int ullmillerrabin(unsigned long long n) { if(n<4294967296ULL) return millerrabin(n); if(!(n&1)) return 0; if(n<4759123141ULL) return ullwitness(n,2) && ullwitness(n,7) && ullwitness(n,61); if(n<2152302898747ULL) return ullwitness(n,2) && ullwitness(n,3) && ullwitness(n,5) && ullwitness(n,7) && ullwitness(n,11); if(n<3474749660383ULL) return ullwitness(n,2) && ullwitness(n,3) && ullwitness(n,5) && ullwitness(n,7) && ullwitness(n,11) && ullwitness(n,13); if(n<341550071728321ULL) return ullwitness(n,2) && ullwitness(n,3) && ullwitness(n,5) && ullwitness(n,7) && ullwitness(n,11) && ullwitness(n,13) && ullwitness(n,17); return ullwitness(n,2) && ullwitness(n,325) && ullwitness(n,9375) && ullwitness(n,28178) && ullwitness(n,450775) && ullwitness(n,9780504) && ullwitness(n,1795265022); }
// Generate a numbits-bit probable prime using the Random-Search algorithm void rndsearch(int numbits, int maxitr, FILE* primesfile, FILE* rndfile) { bool found_prime = false; int count = 1; int num_bytes = ceil(numbits/8.0); BIGNUM* num_orig = BN_new(); char* num_trimmed = (char*)calloc(1, num_bytes); // Iterate through potential numbers in RandomFile while(!found_prime) { printf("RANDOM-SEARCH: iteration %d\n", count); // Generate random odd numbit-long integer RndOddNum(numbits, num_orig, rndfile); num_trimmed = BN_bn2dec(num_orig); // Test with trial division printf(" n = %s\n", num_trimmed); printf(" "); if(trialdiv(num_trimmed, primesfile)) { // Passed trial division, check Miller-Rabin if(millerrabin(num_trimmed, maxitr, primesfile, " ")) { found_prime = true; } } count++; } BN_free(num_orig); free(num_trimmed); // PSEUDO-CODE // - Generate a random numbit-bit number // - Read ceil(numbit/8) bytes from the random file // - Set bits 0 and numbit-1 to 1 // - Set bits numbit to ceil(numbit/8)*8 to 0 // - Run the Trial Division test // - If it passes, run the Miller-Rabin test // - If it passes that too, return that prime number // - If it fails either test, return to the beginning and try a new number }
/* * rndsearch function to generate numbits-bit probable prime * @param: k numbits, maxitr, FILE pointer to primesfile, FILE pointer to rndfile * @output: Print out rndsearch process and generate a probable prime */ void rndsearch(int k, int maxitr, FILE *fp, FILE *fp_rndfile) { int byte = 0; int x_byte = ceil_func((double)k/8, (int)k/8); char *temp = malloc(x_byte); //read in x_byte from rndfile int itr_count = 1; while((byte = fread(temp, 1, x_byte, fp_rndfile)) > 0) { BIGNUM *bn_n = RndOddNum(k, temp, x_byte); if(bn_n == NULL) { free(temp); return; //ERROR has happened in RndOddNum() function call } else { //Print itr fprintf(stdout, "RANDOM-SEARCH: iteration %d\n", itr_count); itr_count += 1; fprintf(stdout, " n = %s\n", BN_bn2dec(bn_n)); //Use trial division function to check if n passes trial division test int trialdiv_returnCode = trialdiv(bn_n, fp, 2); //reset fp pointer to beginning of primesfile for next time use rewind(fp); if(trialdiv_returnCode == -1) { //error has happened in trialdiv function. Terminate this function free(temp); BN_free(bn_n); //free from RndOddNum() function call return; } else if(trialdiv_returnCode == 0) { BN_free(bn_n); continue; //bn_n does not pass trial division test. Continue to generate next number } int millerrabin_returnCode = millerrabin(bn_n, maxitr, fp, 2); //reset fp pointer to beginning of primesfile for next time use rewind(fp); if(millerrabin_returnCode == -1) { //error has happened in millerrabin function. Terminate this function free(temp); BN_free(bn_n); //free from RndOddNum() function call return; } else if(millerrabin_returnCode == 1) { free(temp); BN_free(bn_n); //free from RndOddNum() function call return; //Prove n to be a prime number. End function } else { //continue generate the next probable prime BN_free(bn_n); } } } //Free in case we have never generated a bn_n that passes both tests free(temp); fprintf(stderr, "Run out of bytes in rndfile and we have not successfully generated a prime number\n"); }
int main(int argc, char *argv[]) { int i; char *trialNum = NULL; char *rndFile = NULL; char *inFile = NULL; int maxVal; int maxIterations; int numBits; if (argc <= 2) { usage(); return 0; } // Variable parsing for tablecheck if (strncmp(argv[1], "primes", 6) == 0) { if (argc != 3) { usage(); return 0; } for (i = 1; i < argc; i++) { if (argc == 3) { if (strncmp(argv[i], "-n=", 3) == 0) { maxVal = atoi(argv[i] + 3); } if (!argv[i]) { usage(); return 0; } } else { usage(); return 0; } } if (maxVal < 1) { usage(); return 0; } else { // Call tablecheck function primes(maxVal); } } else if (strncmp(argv[1], "trialdiv", 8) == 0) { if (argc != 4) { usage(); return 0; } for (i = 1; i < argc; i++) { if (argc == 4) { if (strncmp(argv[i], "-n=", 3) == 0) { trialNum = argv[i] + 3; } if (strncmp(argv[i], "-p=", 3) == 0) { inFile = argv[i] + 3; } if (!argv[i]) { usage(); return 0; } } else { usage(); return 0; } } if (trialNum == NULL || inFile == NULL) { usage(); return 0; } else { // Call keyExpand function trialdiv(trialNum, inFile); } } else if (strncmp(argv[1], "millerrabin", 11) == 0) { if (argc != 5) { usage(); return 0; } for (i = 1; i < argc; i++) { if (argc == 5) { if (strncmp(argv[i], "-n=", 3) == 0) { trialNum = argv[i] + 3; } if (strncmp(argv[i], "-t=", 3) == 0) { maxIterations = atoi(argv[i] + 3); } if (strncmp(argv[i], "-p=", 3) == 0) { inFile = argv[i] + 3; } if (!argv[i]) { usage(); return 0; } } else { usage(); return 0; } } if (trialNum == NULL || maxIterations < 1 || inFile == NULL) { usage(); return 0; } else { // Call keyExpand function millerrabin(trialNum, maxIterations, inFile, 0); } } else if (strncmp(argv[1], "rndsearch", 9) == 0) { if (argc != 6) { usage(); return 0; } for (i = 1; i < argc; i++) { if (argc == 6) { if (strncmp(argv[i], "-k=", 3) == 0) { numBits = atoi(argv[i] + 3); } if (strncmp(argv[i], "-t=", 3) == 0) { maxIterations = atoi(argv[i] + 3); } if (strncmp(argv[i], "-p=", 3) == 0) { inFile = argv[i] + 3; } if (strncmp(argv[i], "-r=", 3) == 0) { rndFile = argv[i] + 3; } if (!argv[i]) { usage(); return 0; } } else { usage(); return 0; } } if (numBits < 1 || maxIterations < 1 || inFile == NULL || rndFile == NULL) { usage(); return 0; } else { // Call rndsearch function rndsearch(numBits, maxIterations, inFile, rndFile); } } else if (strncmp(argv[1], "maurer", 6) == 0) { if (argc != 5) { usage(); return 0; } for (i = 1; i < argc; i++) { if (argc == 5) { if (strncmp(argv[i], "-k=", 3) == 0) { numBits = atoi(argv[i] + 3); } if (strncmp(argv[i], "-p=", 3) == 0) { inFile = argv[i] + 3; } if (strncmp(argv[i], "-r=", 3) == 0) { rndFile = argv[i] + 3; } if (!argv[i]) { usage(); return 0; } } else { usage(); return 0; } } if (numBits < 1 || inFile == NULL || rndFile == NULL) { usage(); return 0; } else { // Call rndsearch function maurer(numBits, inFile, rndFile); } } // If these conditions are not met, then print usage and quit. else { usage(); return 0; } return 0; }