// 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; }