int mmv_execute(mmv_t *mmv) { if (!(mmv->op & APPEND)) { check_collisions(mmv); } findorder(mmv); if (mmv->op & (COPY | LINK)) { nochains(mmv); } scandeletes(mmv, baddel); goonordie(mmv); if (!(mmv->op & APPEND) && mmv->delstyle == ASKDEL) { scandeletes(mmv, skipdel); } doreps(mmv); return (mmv->failed ? 2 : mmv->nreps == 0 && (mmv->paterr || mmv->badreps)); }
void Shor(SHORSTATS * results, unsigned int N, double epsilon, bool msg) { //Set up the random number generator seed struct timeval t; gettimeofday(&t, NULL); srand((unsigned) t.tv_usec); //Set up the default return values results->factor = 0; results->x = 0; results->r = 0; results->errorcode = 0; results->quantum = false; //Check if the number to be factored and epsilon are in the proper range if (N <= 2) {results->errorcode = 1; if (msg) {printf("The number is too small to be factored.\n");} return;} if (epsilon <= 0 || epsilon >= 1) {results->errorcode = 1; if (msg) {printf("The faulttolerance is invalid.\n");} return;} //Calculate the effective fault-tolerance double faulttolerance = 1.0/(2.0*(pow(2.0,ceil(log2(2.0 + 1.0/(2.0*epsilon)) - 1e-8)) - 2.0)); //Display the welcome message if (msg) { printf("Shor's algorithm initiated...\n"); printf(" - The number to be factored is %d.\n", N); printf(" - The fault-tolerance towards the order finding subroutine is %f.\n",faulttolerance); } //Check if the number to be factored is even if (N % 2 == 0) {results->factor = 2; if (msg) {printf("The number is even, so this case is trivial.\nA dividing factor of %d is 2.\n", N);} return;} //Check if N can be written as a^b with a >= 1 and b >= 2 double log2N = log2(N); for (unsigned int b = 2; b <= log2N; b++) { double a = pow(2,log2N/b); if ((0.5 - fabs(a - floor(a + 1e-8) - 0.5)) <= 1e-8) { results->factor = floor(a + 1e-8); if (msg) {printf("The number can be written as a power.\nA dividing factor of %d is %d.\n", N, results->factor);} return; } } //Randomly choose an x in the range between 2 and N-2. results->x = rand() % (N - 3) + 2; if (msg) {printf("The program guesses a number to find the order of. This number is %d.\n", results->x);} //Return gcd(x,N) if it is a non-trivial divisor of N unsigned int temp = gcd(N,results->x); if (temp > 1) { results->factor = temp; if (msg) {printf("The program got lucky and guessed a number that is not coprime to N.\nA dividing factor of %d is %d.\n", N, results->factor);} return; } //Calculate the order of x modulo N results->quantum = true; unsigned int r1 = findorder(N,epsilon,results->x); unsigned int r2 = findorder(N,epsilon,results->x); if (r1 == 0 && r2 == 0) { results->errorcode = 2; if (msg) {printf("The order finding subroutine failed.\n");} return; } if (r1 == 0) {results->r = r2;} else if (r2 == 0) {results->r = r1;} else {results->r = r1*r2/gcd(r1,r2);} //Check if the order is correct unsigned int y = 1; for (unsigned int a = 0; a < results->r; a++) { y = (y * results->x) % N; } if (y != 1) {results->errorcode = 3; if (msg) {printf("The order finding subroutine failed.\n");} return;} if (msg) {printf("The order is found to be %d.\n",results->r);} //Check if the order is even if (results->r % 2 != 0) {results->errorcode = 4; if (msg) {printf("The order is odd, so the algorithm fails.\n");} return;} //Check if there is any hope in finding a divisor if (remmod(results->x,results->r/2,0,N) == N - 1) {results->errorcode = 5; if (msg) {printf("x^(r/2) = -1 mod N, so the algorithm fails.\n");} return;} //Return one of the factors unsigned int candidate = gcd(remmod(results->x,results->r/2,N-1,N),N); if (candidate != 1) {results->factor = candidate; if (msg) {printf("A dividing factor of %d is %d.\n", N, results->factor);} return;} candidate = gcd(remmod(results->x,results->r/2,1,N),N); if (candidate != 1) {results->factor = candidate; if (msg) {printf("A dividing factor of %d is %d.\n", N, results->factor);} return;} results->errorcode = 6; if (msg) {printf("An unexpected error occured. Exiting.\n");} return; }