コード例 #1
0
int binvaux(giant p, giant x)
/* Binary inverse method.
   Returns zero if no inverse exists, in which case x becomes
   GCD(x,p). */
{
    giant scratch7;
    giant u0;
    giant u1;
    giant v0;
    giant v1;
    int result = 1;
    int giantSize;
    PROF_START;

    if(isone(x)) return(result);
    giantSize = 4 * abs(p->sign);
    scratch7 = borrowGiant(giantSize);
    u0 = borrowGiant(giantSize);
    u1 = borrowGiant(giantSize);
    v0 = borrowGiant(giantSize);
    v1 = borrowGiant(giantSize);
    int_to_giant(1, v0); gtog(x, v1);
    int_to_giant(0,x); gtog(p, u1);
    while(!isZero(v1)) {
        gtog(u1, u0); bdivg(v1, u0);
        gtog(x, scratch7);
        gtog(v0, x);
        mulg(u0, v0);
        subg(v0,scratch7);
        gtog(scratch7, v0);

        gtog(u1, scratch7);
        gtog(v1, u1);
        mulg(u0, v1);
        subg(v1,scratch7);
        gtog(scratch7, v1);
    }
    if (!isone(u1)) {
        gtog(u1,x);
        if(x->sign<0) addg(p, x);
        result = 0;
        goto done;
    }
    if (x->sign<0) addg(p, x);
  done:
    returnGiant(scratch7);
    returnGiant(u0);
    returnGiant(u1);
    returnGiant(v0);
    returnGiant(v1);
    PROF_END(binvauxTime);
    return(result);
}
コード例 #2
0
/*
 * Simple projective multiply.
 *
 * pt := pt * k, result normalized.
 */
void ellMulProjSimple(pointProj pt0, giant k, curveParams *cp)
{
	pointProjStruct pt1;	// local, giants borrowed

	CKASSERT(isone(pt0->z));
	CKASSERT(cp->curveType == FCT_Weierstrass);

	/* ellMulProj assumes constant pt0, can't pass as src and dst */
	pt1.x = borrowGiant(cp->maxDigits);
	pt1.y = borrowGiant(cp->maxDigits);
	pt1.z = borrowGiant(cp->maxDigits);
	ellMulProj(pt0, &pt1, k, cp);
	normalizeProj(&pt1, cp);
	CKASSERT(isone(pt1.z));

	ptopProj(&pt1, pt0);
	returnGiant(pt1.x);
	returnGiant(pt1.y);
	returnGiant(pt1.z);
}
コード例 #3
0
ファイル: ap.c プロジェクト: KoyoA/patterns
T AP_pow(T x, T y, T p) {
    T z;
    assert(x);
    assert(y);
    assert(y->sign == 1);
    assert( (!p) || (p->sign==1 && !iszero(p) && !isone(p)));
    if (iszero(x))
        return AP_new(0);
    if (iszero(y))
        return AP_new(1);
    if (isone(x))
        return AP_new((((y)->digits[0]&1) == 0) ? 1 : x->sign);
    if (p)
        if (isone(y))
            z = AP_mod(x, p);
        else {
            T y2 = AP_rshift(y, 1), t = AP_pow(x, y2, p);
            z = mulmod(t, t, p);
            AP_free(&y2);
            AP_free(&t);
            if (!(((y)->digits[0]&1) == 0)) {
                z = mulmod(y2 = AP_mod(x, p), t = z, p);
                AP_free(&y2);
                AP_free(&t);
            }
        }
    else if (isone(y))
        z = AP_addi(x, 0);
    else {
        T y2 = AP_rshift(y, 1), t = AP_pow(x, y2, NULL);
        z = AP_mul(t, t);
        AP_free(&y2);
        AP_free(&t);
        if (!(((y)->digits[0]&1) == 0)) {
            z = AP_mul(x, t = z);
            AP_free(&t);
        }
    }
    return z;
}
コード例 #4
0
ファイル: io.c プロジェクト: lattera/openbsd
/*
 * infrom:
 *	reads a card, supposedly in hand, accepting unambiguous brief
 *	input, returns the index of the card found...
 */
int
infrom(CARD hand[], int n, char *prompt)
{
	int i, j;
	CARD crd;

	if (n < 1) {
		bye();
		printf("\nINFROM: %d = n < 1!!\n", n);
		exit(74);
	}
	for (;;) {
		msg("%s", prompt);
		if (incard(&crd)) {	/* if card is full card */
			if (!isone(crd, hand, n))
				msg("That's not in your hand");
			else {
				for (i = 0; i < n; i++)
					if (hand[i].rank == crd.rank &&
					    hand[i].suit == crd.suit)
						break;
				if (i >= n) {
					bye();
			printf("\nINFROM: isone or something messed up\n");
					exit(77);
				}
				return (i);
			}
		} else			/* if not full card... */
			if (crd.rank != EMPTY) {
				for (i = 0; i < n; i++)
					if (hand[i].rank == crd.rank)
						break;
				if (i >= n)
					msg("No such rank in your hand");
				else {
					for (j = i + 1; j < n; j++)
						if (hand[j].rank == crd.rank)
							break;
					if (j < n)
						msg("Ambiguous rank");
					else
						return (i);
				}
			} else
				msg("Sorry, I missed that");
	}
	/* NOTREACHED */
}
コード例 #5
0
ファイル: elliptic.c プロジェクト: Apple-FOSS-Mirror/Security
static void numer_double(giant x, giant z, giant res, curveParams *par)
/* Numerator algebra.
   res := (x^2 - a z^2)^2 - 4 b (2 x + c z) z^3.
 */
{
    giant t1;
    giant t2;

    PROF_START;
    t1 = borrowGiant(par->maxDigits);
    t2 = borrowGiant(par->maxDigits);

    gtog(x, t1); gsquare(t1); feemod(par, t1);
    gtog(z, res); gsquare(res); feemod(par, res);
    gtog(res, t2);
    if(!isZero(par->a) ) {
        if(!isone(par->a)) { /* Speedup - REC 17 Jan 1997. */
	    mulg(par->a, res); feemod(par, res);
        }
        subg(res, t1); feemod(par, t1);
    }
    gsquare(t1); feemod(par, t1);
    /* t1 := (x^2 - a z^2)^2. */
    if(isZero(par->b))  {   /* Speedup - REC 17 Jan 1997. */
	gtog(t1, res);
        goto done;
    }
    if(par->curveType != FCT_Weierstrass) {	// i.e., !isZero(par->c)
    						// Speedup - REC 17 Jan 1997.
	gtog(z, res); mulg(par->c, res); feemod(par, res);
    } else {
        int_to_giant(0, res);
    }
    addg(x, res); addg(x, res); mulg(par->b, res);
    feemod(par, res);
    gshiftleft(2, res); mulg(z, res); feemod(par, res);
    mulg(t2, res); feemod(par, res);
    negg(res); addg(t1, res);
    feemod(par, res);

done:
    returnGiant(t1);
    returnGiant(t2);
    PROF_END(numerDoubleTime);
}
コード例 #6
0
ファイル: elliptic.c プロジェクト: Apple-FOSS-Mirror/Security
/*
 * New optimzation of curveOrderJustify using known reciprocal, 11 June 1997.
 * g is set to be within [2, curveOrder-2].
 */
static void curveOrderJustifyWithRecip(giant g, giant curveOrder, giant recip)
{
    giant tmp;

    CKASSERT(!isZero(curveOrder));

    modg_via_recip(curveOrder, recip, g);	// g now in [0, curveOrder-1]

    if(isZero(g)) {
    	/*
	 * First degenerate case - (g == 0) : set g := 2
	 */
	dbgLog(("curveOrderJustify: case 1\n"));
   	int_to_giant(2, g);
	return;
    }
    if(isone(g)) {
    	/*
	 * Second case - (g == 1) : set g := 2
	 */
 	dbgLog(("curveOrderJustify: case 2\n"));
   	int_to_giant(2, g);
	return;
    }
    tmp = borrowGiant(g->capacity);
    gtog(g, tmp);
    iaddg(1, tmp);
    if(gcompg(tmp, curveOrder) == 0) {
    	/*
	 * Third degenerate case - (g == (curveOrder-1)) : set g -= 1
	 */
	dbgLog(("curveOrderJustify: case 3\n"));
	int_to_giant(1, tmp);
	subg(tmp, g);
    }
    returnGiant(tmp);
    return;
}
コード例 #7
0
static int
jacobi_symbol(giant a, curveParams *cp)
/* Standard Jacobi symbol (a/cp->basePrime).
  basePrime must be odd, positive. */
{
	int t = 1, u;
	giant t5 = borrowGiant(cp->maxDigits);
	giant t6 = borrowGiant(cp->maxDigits);
	giant t7 = borrowGiant(cp->maxDigits);
	int rtn;

	gtog(a, t5); feemod(cp, t5);
	gtog(cp->basePrime, t6);
	while(!isZero(t5)) {
	    u = (t6->n[0]) & 7;
		while((t5->n[0] & 1) == 0) {
			gshiftright(1, t5);
			if((u==3) || (u==5)) t = -t;
		}
		gtog(t5, t7); gtog(t6, t5); gtog(t7, t6);
		u = (t6->n[0]) & 3;
		if(((t5->n[0] & 3) == 3) && ((u & 3) == 3)) t = -t;
		modg(t6, t5);
	}
	if(isone(t6)) {
		rtn = t;
	}
	else {
		rtn = 0;
	}
	returnGiant(t5);
	returnGiant(t6);
	returnGiant(t7);

	return rtn;
}
コード例 #8
0
ファイル: tutor.c プロジェクト: dhruvstar10/projectEuler
void
main(
	void
)
{
	giant 		x = newgiant(INFINITY), y = newgiant(INFINITY),
				p = newgiant(INFINITY), r = newgiant(100);
	int 		j;

   	printf("Give two integers x, y on separate lines:\n");
   	gin(x); 
   	gin(y); 

   	gtog(y, p);  /* p := y */
   	mulg(x, p);
   	printf("y * x = "); 
   	gout(p);

  	gtog(y, p);
   	subg(x, p);
   	printf("y - x = "); 
   	gout(p);

   	gtog(y, p);
   	addg(x, p);
   	printf("y + x = "); 
   	gout(p);

   	gtog(y, p);
   	divg(x, p);
   	printf("y div x = "); 
   	gout(p);

   	gtog(y, p);
   	modg(x, p);
   	printf("y mod x = "); 
   	gout(p);

   	gtog(y, p);
   	gcdg(x, p);
   	printf("GCD(x, y) = "); 
   	gout(p);
 
	/* Next, test which of x, y is greater. */
   	if (gcompg(x, y) < 0 ) 
   		printf("y is greater\n");
	else if (gcompg(x,y) == 0) 
		printf("x, y equal\n");
	else 
		printf("x is greater\n");

	/* Next, we see how a giant struct is comprised.
   	 * We make a random, bipolar number of about 100 
   	 * digits in base 65536. 
   	 */
	for (j=0; j < 100; j++) 
	{  /* Fill 100 digits randomly. */
		r->n[j] = (unsigned short)rand();
   	}
   	r->sign = 100 * (1 - 2*(rand()%2));

	/* Next, don't forget to check for leading zero digits,
     * even though such are unlikely. 
     */
   	j = abs(r->sign) - 1;
   	while ((r->n[j] == 0) && (j > 0)) 
   	{
   		--j;
   	}
   	r->sign = (j+1) * ((r->sign > 0) ? 1: -1);
   	printf("The random number: "); gout(r);

	/* Next, compare a large-FFT multiply with a standard,
     * grammar-school multiply. 
     */
   	itog(1, x); 
   	gshiftleft(65536, x); 
   	iaddg(1, x);
   	itog(5, y); 
   	gshiftleft(30000, y); 
   	itog(1, p); 
   	subg(p, y); 
	/* Now we multiply (2^65536 + 1)*(5*(2^30000) - 1). */
   	gtog(y, p);
   	mulg(x, p);  /* Actually invokes FFT method because
					bit lengths of x, y are sufficiently large. */
   	printf("High digit of (2^65536 + 1)*(5*(2^30000) - 1) via FFT mul: %d\n", (int) p->n[abs(p->sign)-1]);
   	fflush(stdout);
   	gtog(y, p);
   	grammarmulg(x, p);  /* Grammar-school method. */
   	printf("High digit via grammar-school mul: %d\n", (int) p->n[abs(p->sign)-1]);
   	fflush(stdout);

	/* Next, perform Fermat test for pseudoprimality. */
   	printf("Give prime candidate p:\n");
   	gin(p); 
   	gtog(p, y);
   	itog(1, x); subg(x, y);
   	itog(2, x);
   	powermodg(x, y, p);
   	if (isone(x)) 
   		printf("p is probably prime.\n");
	else 
		printf("p is composite.\n");
}
コード例 #9
0
BOOL isone(const Poly2Mod& m)      {return isone(m.p);}
コード例 #10
0
static int sqrtmod(giant x, curveParams *cp)
/* If Sqrt[x] (mod p) exists, function returns 1, else 0.
   In either case x is modified, but if 1 is returned,
   x:= Sqrt[x] (mod p).
 */
{
	int rtn;
	giant t0 = borrowGiant(cp->maxDigits);
	giant t1 = borrowGiant(cp->maxDigits);
	giant t2 = borrowGiant(cp->maxDigits);
	giant t3 = borrowGiant(cp->maxDigits);
	giant t4 = borrowGiant(cp->maxDigits);

	giant p = cp->basePrime;

    	feemod(cp, x);			/* Justify the argument. */
    	gtog(x, t0);  /* Store x for eventual validity check on square root. */
    	if((p->n[0] & 3) == 3) {  /* The case p = 3 (mod 4). */
		gtog(p, t1);
		iaddg(1, t1); gshiftright(2, t1);
		powermodg(x, t1, cp);
		goto resolve;
    	}
	/* Next, handle case p = 5 (mod 8). */
    	if((p->n[0] & 7) == 5) {
		gtog(p, t1); int_to_giant(1, t2);
		subg(t2, t1); gshiftright(2, t1);
		gtog(x, t2);
		powermodg(t2, t1, cp);  /* t2 := x^((p-1)/4) % p. */
		iaddg(1, t1);
		gshiftright(1, t1); /* t1 := (p+3)/8. */
		if(isone(t2)) {
			powermodg(x, t1, cp);  /* x^((p+3)/8) is root. */
			goto resolve;
		} else {
			int_to_giant(1, t2); subg(t2, t1);
				/* t1 := (p-5)/8. */
			gshiftleft(2,x);
			powermodg(x, t1, cp);
			mulg(t0, x); addg(x, x); feemod(cp, x);
				/* 2x (4x)^((p-5)/8. */
			goto resolve;
		}
	}

	/* Next, handle tougher case: p = 1 (mod 8). */
	int_to_giant(2, t1);
	while(1) {  /* Find appropriate nonresidue. */
		gtog(t1, t2);
		gsquare(t2); subg(x, t2); feemod(cp, t2);
		if(jacobi_symbol(t2, cp) == -1) break;
		iaddg(1, t1);
	}  /* t2 is now w^2 in F_p^2. */
   	int_to_giant(1, t3);
   	gtog(p, t4); iaddg(1, t4); gshiftright(1, t4);
	powFp2(t1, t3, t2, t4, cp);
	gtog(t1, x);

resolve:
   	gtog(x,t1); gsquare(t1); feemod(cp, t1);
    	if(gcompg(t0, t1) == 0) {
		rtn = 1; 	/* Success. */
	}
	else {
		rtn = 0;	/* no square root */
	}
	returnGiant(t0);
	returnGiant(t1);
	returnGiant(t2);
	returnGiant(t3);
	returnGiant(t4);
	return rtn;
}
コード例 #11
0
void ellAddProj(pointProj pt0, pointProj pt1, curveParams *cp)
/* pt0 := pt0 + pt1 on the curve. */
{
	giant x0 = pt0->x, y0 = pt0->y, z0 = pt0->z,
		  x1 = pt1->x, y1 = pt1->y, z1 = pt1->z;
	giant t1;
	giant t2;
	giant t3;
	giant t4;
	giant t5;
	giant t6;
	giant t7;

	if(isZero(z0)) {
		gtog(x1,x0); gtog(y1,y0); gtog(z1,z0);
		return;
	}
	if(isZero(z1)) return;

	t1 = borrowGiant(cp->maxDigits);
	t2 = borrowGiant(cp->maxDigits);
	t3 = borrowGiant(cp->maxDigits);
	t4 = borrowGiant(cp->maxDigits);
	t5 = borrowGiant(cp->maxDigits);
	t6 = borrowGiant(cp->maxDigits);
	t7 = borrowGiant(cp->maxDigits);

	gtog(x0, t1); gtog(y0,t2); gtog(z0, t3);
	gtog(x1, t4); gtog(y1, t5);
	if(!isone(z1)) {
		gtog(z1, t6);
		gtog(t6, t7); gsquare(t7); feemod(cp, t7);
		mulg(t7, t1); feemod(cp, t1);
		mulg(t6, t7); feemod(cp, t7);
		mulg(t7, t2); feemod(cp, t2);
	}
	gtog(t3, t7); gsquare(t7); feemod(cp, t7);
	mulg(t7, t4); feemod(cp, t4);
	mulg(t3, t7); feemod(cp, t7);
	mulg(t7, t5); feemod(cp, t5);
	negg(t4); addg(t1, t4); feemod(cp, t4);
	negg(t5); addg(t2, t5); feemod(cp, t5);
	if(isZero(t4)) {
		if(isZero(t5)) {
			ellDoubleProj(pt0, cp);
	    	} else {
			int_to_giant(1, x0); int_to_giant(1, y0);
			int_to_giant(0, z0);
		}
		goto out;
	}
	addg(t1, t1); subg(t4, t1); feemod(cp, t1);
	addg(t2, t2); subg(t5, t2); feemod(cp, t2);
	if(!isone(z1)) {
		mulg(t6, t3); feemod(cp, t3);
	}
	mulg(t4, t3); feemod(cp, t3);
	gtog(t4, t7); gsquare(t7); feemod(cp, t7);
	mulg(t7, t4); feemod(cp, t4);
	mulg(t1, t7); feemod(cp, t7);
	gtog(t5, t1); gsquare(t1); feemod(cp, t1);
	subg(t7, t1); feemod(cp, t1);
	subg(t1, t7); subg(t1, t7); feemod(cp, t7);
	mulg(t7, t5); feemod(cp, t5);
	mulg(t2, t4); feemod(cp, t4);
	gtog(t5, t2); subg(t4,t2); feemod(cp, t2);
	if(t2->n[0] & 1) { /* Test if t2 is odd. */
		addg(cp->basePrime, t2);
	}
	gshiftright(1, t2);
	gtog(t1, x0); gtog(t2, y0); gtog(t3, z0);
out:
	returnGiant(t1);
	returnGiant(t2);
	returnGiant(t3);
	returnGiant(t4);
	returnGiant(t5);
	returnGiant(t6);
	returnGiant(t7);
}