Beispiel #1
0
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));
}
Beispiel #2
0
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;
}