示例#1
0
static void numer_plus(giant x1, giant x2, giant res, curveParams *par)
/* Numerator algebra.
   res = (x1 x2 + a)(x1 + x2) + 2(c x1 x2 + b).
 */
{
    giant t1;
    giant t2;

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

    gtog(x1, t1); mulg(x2, t1); feemod(par, t1);
    gtog(x2, t2); addg(x1, t2); feemod(par, t2);
    gtog(t1, res);
    if(!isZero(par->a))
    	addg(par->a, res);
    mulg(t2, res); feemod(par, res);
    if(par->curveType == FCT_Weierstrass) {	// i.e., isZero(par->c)
    	int_to_giant(0, t1);
    }
    else {
        mulg(par->c, t1); feemod(par, t1);
    }
    if(!isZero(par->b))
    	addg(par->b, t1);
    gshiftleft(1, t1);
    addg(t1, res); feemod(par, res);

    returnGiant(t1);
    returnGiant(t2);
    PROF_END(numerPlusTime);
}
示例#2
0
/*
 * Completely rewritten in CryptKit-18, 13 Jan 1997, for new IEEE-style
 * curveParameters.
 */
int which_curve(giant x, curveParams *par)
 /* Returns (+-1) depending on whether x is on curve
   (+-)y^2 = x^3 + c x^2 + a x + b.
 */
{
    giant t1;
    giant t2;
    giant t3;
    int result;
    PROF_START;

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

   /* First, set t2:= x^3 + c x^2 + a x + b. */
    gtog(x, t2); addg(par->c, t2);
    mulg(x, t2); addg(par->a, t2);  /* t2 := x^2 + c x + a. */
    feemod(par, t2);
    mulg(x, t2); addg(par->b, t2);
    feemod(par, t2);
    /* Next, test whether t2 is a square. */
    gtog(t2, t1);
    make_base(par, t3); iaddg(1, t3); gshiftright(1, t3); /* t3 = (p+1)/2. */
    feepowermodg(par, t1, t3); 		      /* t1 := t2^((p+1)/2) (mod p). */
    if(gcompg(t1, t2) == 0)
            result = CURVE_PLUS;
    else
            result = CURVE_MINUS;
    returnGiant(t1);
    returnGiant(t2);
    returnGiant(t3);
    PROF_END(whichCurveTime);
    return result;
}
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);
}
示例#4
0
int signature_compare(giant p0x, giant p1x, giant p2x, curveParams *par)
/* Returns non-zero iff p0x cannot be the x-coordinate of the sum of two points whose respective x-coordinates are p1x, p2x. */
{
        int ret = 0;
        giant t1;
	giant t2;
        giant t3;
        giant t4;
        giant t5;

	PROF_START;

        t1 = borrowGiant(par->maxDigits);
	t2 = borrowGiant(par->maxDigits);
        t3 = borrowGiant(par->maxDigits);
        t4 = borrowGiant(par->maxDigits);
        t5 = borrowGiant(par->maxDigits);

        if(gcompg(p1x, p2x) == 0) {
		int_to_giant(1, t1);
		numer_double(p1x, t1, t2, par);
		denom_double(p1x, t1, t3, par);
		mulg(p0x, t3); subg(t3, t2);
		feemod(par, t2);
        } else {
		numer_plus(p1x, p2x, t1, par);
		gshiftleft(1, t1); feemod(par, t1);
		int_to_giant(1, t3);
		numer_times(p1x, t3, p2x, t3, t2, par);
		int_to_giant(1, t4); int_to_giant(1, t5);
		denom_times(p1x, t4 , p2x, t5, t3, par);
		/* Now we require t3 x0^2 - t1 x0 + t2 == 0. */
		mulg(p0x, t3); feemod(par, t3);
		subg(t1, t3); mulg(p0x, t3);
		feemod(par, t3);
		addg(t3, t2);
		feemod(par, t2);
        }

	if(!isZero(t2)) ret = SIGNATURE_INVALID;
        returnGiant(t1);
        returnGiant(t2);
        returnGiant(t3);
        returnGiant(t4);
        returnGiant(t5);
	PROF_END(sigCompTime);
	return(ret);
}
示例#5
0
static void
powermodg(
	giant		x,
	giant		n,
	curveParams	*cp
)
/* x becomes x^n (mod basePrime). */
{
	int 		len, pos;
	giant		scratch2 = borrowGiant(cp->maxDigits);

	gtog(x, scratch2);
	int_to_giant(1, x);
	len = bitlen(n);
	pos = 0;
	while (1)
	{
		if (bitval(n, pos++))
		{
			mulg(scratch2, x);
			feemod(cp, x);
		}
		if (pos>=len)
			break;
		gsquare(scratch2);
		feemod(cp, scratch2);
	}
	returnGiant(scratch2);
}
示例#6
0
/*
 * New, 13 Jan 1997.
 */
static void feepowermodg(curveParams *par, giant x, giant n)
/* Power ladder.
   x := x^n  (mod 2^q-k)
 */
{
    int len, pos;
    giant t1;

    PROF_START;
    t1 = borrowGiant(par->maxDigits);
    gtog(x, t1);
    int_to_giant(1, x);
    len = bitlen(n);
    pos = 0;
    while(1) {
	if(bitval(n, pos++)) {
	    mulg(t1, x);
	    feemod(par, x);
	}
	if(pos>=len) break;
	gsquare(t1);
	feemod(par, t1);
    }
    returnGiant(t1);
    PROF_END(powerModTime);
}
/*
 * g *= (int n)
 *
 * FIXME - we can improve this...
 */
void imulg(unsigned n, giant g)
{
	giant tmp = borrowGiant(abs(g->sign) + sizeof(int));

	int_to_giant(n, tmp);
	mulg(tmp, g);
	returnGiant(tmp);
}
示例#8
0
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);
}
示例#9
0
void make_recip(giant d, giant r)
/* r becomes the steady-state reciprocal
* 2^(2b)/d, where b = bit-length of d-1. */
{
	int		b;
	giant 	tmp, tmp2;

	if (isZero(d) || (d->sign < 0))
	{
		exit(SIGN);
	}
	tmp = popg();
	tmp2 = popg();
	itog(1, r);
	subg(r, d);
	b = bitlen(d);
	addg(r, d);
	gshiftleft(b, r);
	gtog(r, tmp2);
	while (1)
	{
		gtog(r, tmp);
		squareg(tmp);
		gshiftright(b, tmp);
		mulg(d, tmp);
		gshiftright(b, tmp);
		addg(r, r);
		subg(tmp, r);
		if (gcompg(r, tmp2) <= 0)
			break;
		gtog(r, tmp2);
	}
	itog(1, tmp);
	gshiftleft(2 * b, tmp);
	gtog(r, tmp2);
	mulg(d, tmp2);
	subg(tmp2, tmp);
	itog(1, tmp2);
	while (tmp->sign < 0)
	{
		subg(tmp2, r);
		addg(d, tmp);
	}
	pushg(2);
}
示例#10
0
static void denom_times(giant x1, giant z1, giant x2, giant z2, giant res,
	curveParams *par)
/* Denominator algebra.
    res := (x1 z2 - x2 z1)^2
 */
{
    giant t1;

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

    gtog(x1, res); mulg(z2, res); feemod(par, res);
    gtog(z1, t1); mulg(x2, t1); feemod(par, t1);
    subg(t1, res); gsquare(res); feemod(par, res);

    returnGiant(t1);
    PROF_END(denomTimesTime);
}
示例#11
0
void ellDoubleProj(pointProj pt, curveParams *cp)
/* pt := 2 pt on the curve. */
{
	giant x = pt->x, y = pt->y, z = pt->z;
	giant t1;
	giant t2;
	giant t3;

	if(isZero(y) || isZero(z)) {
		int_to_giant(1,x); int_to_giant(1,y); int_to_giant(0,z);
		return;
	}
	t1 = borrowGiant(cp->maxDigits);
	t2 = borrowGiant(cp->maxDigits);
	t3 = borrowGiant(cp->maxDigits);

	if((cp->a->sign >= 0) || (cp->a->n[0] != 3)) { /* Path prior to Apr2001. */
		gtog(z,t1); gsquare(t1); feemod(cp, t1);
		gsquare(t1); feemod(cp, t1);
		mulg(cp->a, t1); feemod(cp, t1);			/* t1 := a z^4. */
		gtog(x, t2); gsquare(t2); feemod(cp, t2);
			smulg(3, t2);                           /* t2 := 3x^2. */
		addg(t2, t1); feemod(cp, t1);	 			/* t1 := slope m. */
	} else { /* New optimization for a = -3 (post Apr 2001). */
		gtog(z, t1); gsquare(t1); feemod(cp, t1);   /* t1 := z^2. */
		gtog(x, t2); subg(t1, t2);                  /* t2 := x-z^2. */
		addg(x, t1); smulg(3, t1);                  /* t1 := 3(x+z^2). */
		mulg(t2, t1); feemod(cp, t1);               /* t1 := slope m. */
	}
	mulg(y, z); addg(z,z); feemod(cp, z);	  	/* z := 2 y z. */
	gtog(y, t2); gsquare(t2); feemod(cp, t2); 	/* t2 := y^2. */
	gtog(t2, t3); gsquare(t3); feemod(cp, t3);	/* t3 := y^4. */
	gshiftleft(3, t3);  				/* t3 := 8 y^4. */
	mulg(x, t2); gshiftleft(2, t2); feemod(cp, t2);	/* t2 := 4xy^2. */
	gtog(t1, x); gsquare(x); feemod(cp, x);
	subg(t2, x); subg(t2, x); feemod(cp, x);	/* x done. */
	gtog(t1, y); subg(x, t2); mulg(t2, y); subg(t3, y);
	feemod(cp, y);
	returnGiant(t1);
	returnGiant(t2);
	returnGiant(t3);
}
示例#12
0
void normalizeProj(pointProj pt, curveParams *cp)
/* Obtain actual x,y coords via normalization:
   {x,y,z} := {x/z^2, y/z^3, 1}.
 */

{	giant x = pt->x, y = pt->y, z = pt->z;
	giant t1;

	CKASSERT(cp->curveType == FCT_Weierstrass);
	if(isZero(z)) {
		int_to_giant(1,x); int_to_giant(1,y);
		return;
	}
	t1 = borrowGiant(cp->maxDigits);
	binvg_cp(cp, z);		// was binvaux(p, z);
		gtog(z, t1);
	gsquare(z); feemod(cp, z);
	mulg(z, x); feemod(cp, x);
	mulg(t1, z); mulg(z, y); feemod(cp, y);
	int_to_giant(1, z);
	returnGiant(t1);
}
示例#13
0
void modg_via_recip(giant d, giant r, giant n)
/* This is the fastest mod of the present collection.
* n := n % d, where r is the precalculated
* steady-state reciprocal of d. */
{
	int		s = (bitlen(r) - 1), sign = n->sign;
	giant 	tmp, tmp2;

	if (isZero(d) || (d->sign < 0))
	{
		exit(SIGN);
	}

	tmp = popg();
	tmp2 = popg();

	n->sign = abs(n->sign);
	while (1)
	{
		gtog(n, tmp); gshiftright(s - 1, tmp);
		mulg(r, tmp);
		gshiftright(s + 1, tmp);
		mulg(d, tmp);
		subg(tmp, n);
		if (gcompg(n, d) >= 0)
			subg(d, n);
		if (gcompg(n, d) < 0)
			break;
	}
	if (sign >= 0)
		goto done;
	if (isZero(n))
		goto done;
	negg(n);
	addg(d, n);
done:
	pushg(2);
	return;
}
示例#14
0
static void numer_times(giant x1, giant z1, giant x2, giant z2, giant res,
	curveParams *par)
/* Numerator algebra.
    res := (x1 x2 - a z1 z2)^2 -
  	          4 b(x1 z2 + x2 z1 + c z1 z2) z1 z2
 */
{
    giant t1;
    giant t2;
    giant t3;
    giant t4;

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

    gtog(x1, t1); mulg(x2, t1); feemod(par, t1);
    gtog(z1, t2); mulg(z2, t2); feemod(par, t2);
    gtog(t1, res);
    if(!isZero(par->a)) {
	gtog(par->a, t3);
      	mulg(t2, t3); feemod(par, t3);
      	subg(t3, res);
    }
    gsquare(res); feemod(par, res);
    if(isZero(par->b))
        goto done;
    if(par->curveType != FCT_Weierstrass) {	// i.e., !isZero(par->c)
        gtog(par->c, t3);
    	mulg(t2, t3); feemod(par, t3);
    } else int_to_giant(0, t3);
    gtog(z1, t4); mulg(x2, t4); feemod(par, t4);
    addg(t4, t3);
    gtog(x1, t4); mulg(z2, t4); feemod(par, t4);
    addg(t4, t3); mulg(par->b, t3); feemod(par, t3);
    mulg(t2, t3); gshiftleft(2, t3); feemod(par, t3);
    subg(t3, res);
    feemod(par, res);

done:
    returnGiant(t1);
    returnGiant(t2);
    returnGiant(t3);
    returnGiant(t4);
    PROF_END(numerTimesTime);
}
示例#15
0
/*
 * Elliptic multiply: x := n * {x, 1}
 */
void elliptic_simple(giant x, giant n, curveParams *par) {
    giant ztmp = borrowGiant(par->maxDigits);
    giant cur_n = borrowGiant(par->maxDigits);

    START_ELL_MEASURE(n);
    int_to_giant(1, ztmp);
    elliptic(x, ztmp, n, par);
    binvg_cp(par, ztmp);
    mulg(ztmp, x);
    feemod(par, x);
    END_ELL_MEASURE;

    returnGiant(cur_n);
    returnGiant(ztmp);
}
示例#16
0
static int mulgTest(unsigned loops, 
	giant *g1, 
	giant *g2)
{
	int loop;
	PLAT_TIME startTime;
	PLAT_TIME endTime;
	
	PLAT_GET_TIME(startTime);
	for(loop=0; loop<loops; loop++) {
		mulg(*g1++, *g2++);
	}
	PLAT_GET_TIME(endTime);
	return PLAT_GET_NS(startTime, endTime);
}
示例#17
0
static void
powFp2(giant a, giant b, giant w2, giant n, curveParams *cp)
/* Perform powering in the field F_p^2:
   a + b w := (a + b w)^n (mod p), where parameter w2 is a quadratic
   nonresidue (formally equal to w^2).
 */
{
	int j;
	giant t6;
	giant t7;
	giant t8;
	giant t9;

	if(isZero(n)) {
		int_to_giant(1,a);
		int_to_giant(0,b);
		return;
	}
    	t6 = borrowGiant(cp->maxDigits);
    	t7 = borrowGiant(cp->maxDigits);
    	t8 = borrowGiant(cp->maxDigits);
    	t9 = borrowGiant(cp->maxDigits);
	gtog(a, t8); gtog(b, t9);
	for(j = bitlen(n)-2; j >= 0; j--) {
		gtog(b, t6);
		mulg(a, b); addg(b,b); feemod(cp, b);  /* b := 2 a b. */
		gsquare(t6); feemod(cp, t6);
		mulg(w2, t6); feemod(cp, t6);
		gsquare(a); addg(t6, a); feemod(cp, a);
						/* a := a^2 + b^2 w2. */
		if(bitval(n, j)) {
			gtog(b, t6); mulg(t8, b); feemod(cp, b);
			gtog(a, t7); mulg(t9, a); addg(a, b); feemod(cp, b);
			mulg(t9, t6); feemod(cp, t6);
			mulg(w2, t6); feemod(cp, t6);
			mulg(t8, a); addg(t6, a); feemod(cp, a);
		}
	}
	returnGiant(t6);
	returnGiant(t7);
	returnGiant(t8);
	returnGiant(t9);
	return;
}
示例#18
0
void findPointProj(pointProj pt, giant seed, curveParams *cp)
/* Starting with seed, finds a random (projective) point {x,y,1} on curve.
 */
{
	giant x = pt->x, y = pt->y, z = pt->z;

	CKASSERT(cp->curveType == FCT_Weierstrass);
	feemod(cp, seed);
    	while(1) {
		gtog(seed, x);
		gsquare(x); feemod(cp, x);	// x := seed^2
		addg(cp->a, x);			// x := seed^2 + a
		mulg(seed,x); 			// x := seed^3 + a*seed
		addg(cp->b, x);
		feemod(cp, x);			// x := seed^3 + a seed + b.
		/* test cubic form for having root. */
		if(sqrtmod(x, cp)) break;
		iaddg(1, seed);
	}
	gtog(x, y);
    	gtog(seed,x);
	int_to_giant(1, z);
}
示例#19
0
void powermodg(giant x, giant n, giant g)
/* x becomes x^n (mod g). */
{
	int 		len, pos;
	giant		scratch2 = popg();

	gtog(x, scratch2);
	itog(1, x);
	len = bitlen(n);
	pos = 0;
	while (1)
	{
		if (bitval(n, pos++))
		{
			mulg(scratch2, x);
			modg(g, x);
		}
		if (pos >= len)
			break;
		squareg(scratch2);
		modg(g, scratch2);
	}
	pushg(1);
}
示例#20
0
static void denom_double(giant x, giant z, giant res, curveParams *par)
/* Denominator algebra.
    res = 4 z (x^3 + c x^2 z + a x z^2 + b z^3). */
{
    giant t1;
    giant t2;

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

    gtog(x, res); gtog(z, t1);
    if(par->curveType != FCT_Weierstrass) {	// i.e., !isZero(par->c)
	gtog(par->c, t2); mulg(t1, t2); feemod(par, t2);
	addg(t2, res);
    }
    mulg(x, res); feemod(par, res);
    gsquare(t1); feemod(par, t1);
    if(!isZero(par->a)) {
	gtog(t1, t2);
    	mulg(par->a, t2); feemod(par, t2);
    	addg(t2, res);
    }
    mulg(x, res); feemod(par, res);
    if(!isZero(par->b)) {
	mulg(z, t1); feemod(par, t1);
    	mulg(par->b, t1); feemod(par, t1);
    	addg(t1, res);
    }
    mulg(z, res); gshiftleft(2, res);
    feemod(par, res);

    returnGiant(t1);
    returnGiant(t2);
    PROF_END(denomDoubleTime);
}
示例#21
0
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");
}
示例#22
0
/*
 * Completely rewritten in CryptKit-18, 13 Jan 1997, for new IEEE-style
 * curveParameters.
 */
void elliptic_add(giant x1, giant x2, giant x3, curveParams *par, int s) {

 /* Addition algorithm for x3 = x1 + x2 on the curve, with sign ambiguity s.
    From theory, we know that if {x1,1} and {x2,1} are on a curve, then
    their elliptic sum (x1,1} + {x2,1} = {x3,1} must have x3 as one of two
    values:

       x3 = U/2 + s*Sqrt[U^2/4 - V]

    where sign s = +-1, and U,V are functions of x1,x2.  Tho present function
    is called a maximum of twice, to settle which of +- is s.  When a call
    is made, it is guaranteed already that x1, x2 both lie on the same curve
    (+- curve); i.e., which curve (+-) is not connected at all with sign s of
    the x3 relation.
  */

    giant cur_n;
    giant t1;
    giant t2;
    giant t3;
    giant t4;
    giant t5;

    PROF_START;
    cur_n = borrowGiant(par->maxDigits);
    t1 = borrowGiant(par->maxDigits);
    t2 = borrowGiant(par->maxDigits);
    t3 = borrowGiant(par->maxDigits);
    t4 = borrowGiant(par->maxDigits);
    t5 = borrowGiant(par->maxDigits);

    if(gcompg(x1, x2)==0) {
	int_to_giant(1, t1);
	numer_double(x1, t1, x3, par);
	denom_double(x1, t1, t2, par);
	binvg_cp(par, t2);
	mulg(t2, x3); feemod(par, x3);
	goto out;
    }
    numer_plus(x1, x2, t1, par);
    int_to_giant(1, t3);
    numer_times(x1, t3, x2, t3, t2, par);
    int_to_giant(1, t4); int_to_giant(1, t5);
    denom_times(x1, t4, x2, t5, t3, par);
    binvg_cp(par, t3);
    mulg(t3, t1); feemod(par, t1); /* t1 := U/2. */
    mulg(t3, t2); feemod(par, t2); /* t2 := V. */
    /* Now x3 will be t1 +- Sqrt[t1^2 - t2]. */
    gtog(t1, t4); gsquare(t4); feemod(par, t4);
    subg(t2, t4);
    make_base(par, cur_n); iaddg(1, cur_n); gshiftright(2, cur_n);
    	/* cur_n := (p+1)/4. */
    feepowermodg(par, t4, cur_n);      /* t4 := t2^((p+1)/4) (mod p). */
    gtog(t1, x3);
    if(s != SIGN_PLUS) negg(t4);
    addg(t4, x3);
    feemod(par, x3);

out:
    returnGiant(cur_n);
    returnGiant(t1);
    returnGiant(t2);
    returnGiant(t3);
    returnGiant(t4);
    returnGiant(t5);

    PROF_END(ellAddTime);
}
示例#23
0
static void ell_even(giant x1, giant z1, giant x2, giant z2, curveParams *par) {
    giant t1;
    giant t2;
    giant t3;

    EPROF_START;

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

    if(par->curveType == FCT_Montgomery) {
	/* Begin Montgomery OPT: 10 Jan 98 REC. */
	gtog(x1, t1); gsquare(t1); feemod(par, t1); /* t1 := x1^2. */
	gtog(z1, t2); gsquare(t2); feemod(par, t2); /* t2 := z1^2. */

	gtog(x1, t3); mulg(z1, t3); feemod(par, t3);
	gtog(t3, z2); mulg(par->c, z2); feemod(par, z2);
	addg(t1, z2); addg(t2, z2); mulg(t3, z2); gshiftleft(2, z2);
	feemod(par, z2);  /* z2 := 4 x1 z1 (x1^2 + c x1 z1 + z1^2). */
	gtog(t1, x2); subg(t2, x2); gsquare(x2); feemod(par, x2);
						/* x2 := (x1^2 - z1^2)^2. */
	/* End OPT: 10 Jan 98 REC. */
    }
    else if((par->curveType == FCT_Weierstrass) && isZero(par->a)) {
	/* Begin Atkin3 OPT: 9 Jan 98 REC. */
	gtog(x1, t1);
	gsquare(t1); feemod(par, t1);
	mulg(x1, t1); feemod(par, t1);   	/* t1 := x^3. */
	gtog(z1, t2);
	gsquare(t2); feemod(par, t2);
	mulg(z1, t2); feemod(par, t2);	/* t2 := z1^3 */
	mulg(par->b, t2); feemod(par, t2); 	/* t2 := b z1^3. */
	gtog(t1, t3); addg(t2, t3);		/* t3 := x^3 + b z1^3 */
	mulg(z1, t3); feemod(par, t3);	/* t3 *= z1
						*     = z1 ( x^3 + b z1^3 ) */
	gshiftleft(2, t3); feemod(par, t3);	/* t3 = 4 z1 (x1^3 + b z1^3) */

	gshiftleft(3, t2);			/* t2 = 8 b z1^3 */
	subg(t2, t1);			/* t1 = x^3 - 8 b z1^3 */
	mulg(x1, t1); feemod(par, t1);	/* t1 = x1 (x1^3 - 8 b z1^3) */

	gtog(t3, z2);
	gtog(t1, x2);
	/* End OPT: 9 Jan 98 REC. */
    }
    else {
	numer_double(x1, z1, t1, par);
	denom_double(x1, z1, t2, par);
	gtog(t1, x2); gtog(t2, z2);
    }
    returnGiant(t1);
    returnGiant(t2);
    returnGiant(t3);

    EPROF_END(ellEvenTime);
    EPROF_INCR(numEllEvens);

    /*
    printf("ell_even end\n");
    printf(" x1 : "); printGiant(x1);
    printf(" z1 : "); printGiant(z1);
    printf(" x2 : "); printGiant(x2);
    printf(" z2 : "); printGiant(z2);
    */
}
/*
 * Sign specified block of data (most likely a hash result) using
 * specified feePubKey.
 */
feeReturn feeSigSign(feeSig sig,
	const unsigned char *data,   		// data to be signed
	unsigned dataLen,			// in bytes
	feePubKey pubKey)
{
	sigInst 		*sinst = (sigInst*) sig;
	giant 			messageGiant = NULL;
	unsigned 		maxlen;
	giant 			privGiant;
	unsigned		privGiantBytes;
	feeReturn 		frtn = FR_Success;
	unsigned		randBytesLen;
	unsigned		uDigits;	// alloc'd digits in sinst->u
	curveParams		*cp;

	if(pubKey == NULL) {
		return FR_BadPubKey;
	}
	cp = feePubKeyCurveParams(pubKey);
	if(cp == NULL) {
		return FR_BadPubKey;
	}
	
	privGiant = feePubKeyPrivData(pubKey);
	if(privGiant == NULL) {
		dbgLog(("Attempt to Sign without private data\n"));
		frtn = FR_IllegalArg;
		goto abort;
	}
	privGiantBytes = abs(privGiant->sign) * GIANT_BYTES_PER_DIGIT;

	/*
	 * Note PmX = m 'o' P1.
	 * Get message/digest as giant. May be significantly different
	 * in size from pubKey's basePrime.
	 */
	messageGiant = giant_with_data(data, dataLen);	    // M(text)
	randBytesLen = feePubKeyBitsize(pubKey) / 8;
	maxlen = max(randBytesLen, dataLen);

	/* leave plenty of room.... */
	uDigits = (3 * (privGiantBytes + maxlen)) / GIANT_BYTES_PER_DIGIT;
	sinst->u = newGiant(uDigits);
	gtog(privGiant, sinst->u);			    // u := ourPri
	mulg(messageGiant, sinst->u);			    // u *= M(text)
	addg(sinst->randGiant, sinst->u);		    // u += m

	/*
	 * Paranoia: we're using the curveParams from the caller's pubKey;
	 * this cp will have a valid x1OrderPlusRecip if pubKey is the same
	 * as the one passed to feeSigNewWithKey() (since feeSigNewWithKey
	 * called x1OrderPlusJustify()). But the caller could conceivably be
	 * using a different instance of their pubKey, in which case
	 * the key's cp->x1OrderPlusRecip may not be valid.
	 */
	calcX1OrderPlusRecip(cp);

	/* u := u mod x1OrderPlus */
	#if	SIG_DEBUG
	if(sigDebug) {
		printf("sigSign:\n");
		printf("u pre-modg  : ");
		printGiant(sinst->u);
	}
	#endif
	modg_via_recip(cp->x1OrderPlus, cp->x1OrderPlusRecip, sinst->u);

	#if	SIG_DEBUG
	if(sigDebug) {
		printf("privGiant   : ");
		printGiant(privGiant);
		printf("u           : ");
		printGiant(sinst->u);
		printf("messageGiant: ");
		printGiant(messageGiant);
		printf("curveParams :\n");
		printCurveParams(cp);
	}
	#endif	// SIG_DEBUG
abort:
	if(messageGiant) {
		freeGiant(messageGiant);
	}
	return frtn;
}
示例#25
0
static void ell_odd(giant x1, giant z1, giant x2, giant z2, giant xxor,
	giant zor, curveParams *par)
{

    giant t1;
    giant t2;

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

    if(par->curveType == FCT_Montgomery) {
	/* Begin Montgomery OPT: 10 Jan 98 REC. */
	giant t3 = borrowGiant(par->maxDigits);
	giant t4 = borrowGiant(par->maxDigits);

	gtog(x1, t1); addg(z1, t1);  	/* t1 := x1 + z1. */
	gtog(x2, t2); subg(z2, t2);  	/* t2 := x2 - z2. */
	gtog(x1, t3); subg(z1, t3);  	/* t3 := x1 - z1. */
	gtog(x2, t4); addg(z2, t4);  	/* t4 := x2 + z2. */
	mulg(t2, t1); feemod(par, t1);      /* t1 := (x1 + z1)(x2 - z2) */
	mulg(t4, t3); feemod(par, t3);      /* t4 := (x2 + z2)(x1 - z1) */
	gtog(t1, z2); subg(t3, z2); 	/*???gshiftright(1, z2);*/
			    /* z2 := ((x1 + z1)(x2 - z2) - x2)/2 */
	gsquare(z2); feemod(par,  z2);
	mulg(xxor, z2); feemod(par, z2);
	gtog(t1, x2); addg(t3, x2); 	/*????gshiftright(1, x2);*/
	gsquare(x2); feemod(par, x2);
	mulg(zor, x2); feemod(par, x2);

	returnGiant(t3);
	returnGiant(t4);
    }
    else if((par->curveType == FCT_Weierstrass) && isZero(par->a)) {
	/* Begin Atkin3 OPT: 9 Jan 98 REC. */

	giant t3 = borrowGiant(par->maxDigits);
	giant t4 = borrowGiant(par->maxDigits);

	gtog(x1, t1); mulg(x2, t1);  feemod(par, t1);  /* t1 := x1 x2. */
	gtog(z1, t2); mulg(z2, t2);  feemod(par, t2);  /* t2 := z1 z2. */
	gtog(x1, t3); mulg(z2, t3);  feemod(par, t3);  /* t3 := x1 z2. */
	gtog(z1, t4); mulg(x2, t4);  feemod(par, t4);  /* t4 := x2 z1. */
	gtog(t3, z2); subg(t4, z2); gsquare(z2); feemod(par, z2);
	mulg(xxor, z2); feemod(par, z2);
	gtog(t1, x2); gsquare(x2); feemod(par, x2);
	addg(t4, t3); mulg(t2, t3); feemod(par, t3);
	mulg(par->b, t3); feemod(par, t3);
	addg(t3, t3); addg(t3, t3);
	subg(t3, x2); mulg(zor, x2); feemod(par, x2);

	returnGiant(t3);
	returnGiant(t4);
	/* End OPT: 9 Jan 98 REC. */
    }
    else {
	numer_times(x1, z1, x2, z2, t1, par);
	mulg(zor, t1); feemod(par, t1);
	denom_times(x1, z1, x2, z2, t2, par);
	mulg(xxor, t2); feemod(par, t2);

	gtog(t1, x2); gtog(t2, z2);
    }

    returnGiant(t1);
    returnGiant(t2);

    EPROF_END(ellOddTime);
    EPROF_INCR(numEllOdds);

    /*
    printf("ell_odd end\n");
    printf(" x2 : "); printGiant(x2);
    printf(" z2 : "); printGiant(z2);
    */
}
示例#26
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;
}
示例#27
0
feeReturn feeECDSASign(
    feePubKey pubKey,
    feeSigFormat  format,             // Signature format DER 9.62 / RAW
	const unsigned char *data,   		// data to be signed
	unsigned dataLen,					// in bytes
	feeRandFcn randFcn,					// optional
	void *randRef,						// optional 
	unsigned char **sigData,			// malloc'd and RETURNED
	unsigned *sigDataLen)				// RETURNED
{
	curveParams 		*cp;

	/* giant integers per IEEE P1363 notation */

	giant 			c;		// both 1363 'c' and 'i'
						// i.e., x-coord of u's pub key
	giant 			d;
	giant 			u;		// random private key
	giant			s;		// private key as giant
	giant			f;		// data (message) as giant

	feeReturn 		frtn = FR_Success;
	feeRand 		frand;
	unsigned char 	*randBytes;
	unsigned		randBytesLen;
    unsigned        groupBytesLen;
	giant			privGiant;
	#if	ECDSA_SIGN_USE_PROJ
	pointProjStruct	pt;		// pt->x = c
	giant			pty;		// pt->y
	giant			ptz;		// pt->z
	#endif	// ECDSA_SIGN_USE_PROJ

	if(pubKey == NULL) {
		return FR_BadPubKey;
	}
	cp = feePubKeyCurveParams(pubKey);
	if(cp == NULL) {
		return FR_BadPubKey;
	}
	if(cp->curveType != FCT_Weierstrass) {
		return FR_IllegalCurve;
	}

	CKASSERT(!isZero(cp->x1OrderPlus));

	/*
	 * Private key and message to be signed as giants
	 */
	privGiant = feePubKeyPrivData(pubKey);
	if(privGiant == NULL) {
		dbgLog(("Attempt to Sign without private data\n"));
		return FR_IllegalArg;
	}
	s = borrowGiant(cp->maxDigits);
	gtog(privGiant, s);
	if(dataLen > (cp->maxDigits * GIANT_BYTES_PER_DIGIT)) {
	    f = borrowGiant(BYTES_TO_GIANT_DIGITS(dataLen));
	}
	else {
	    f = borrowGiant(cp->maxDigits);
	}
	deserializeGiant(data, f, dataLen);

	/* 
	 * Certicom SEC1 states that if the digest is larger than the modulus, 
	 * use the left q bits of the digest. 
	 */
	unsigned hashBits = dataLen * 8;
	if(hashBits > cp->q) {
		gshiftright(hashBits - cp->q, f);
	}

	sigDbg(("ECDSA sign:\n"));
	sigLogGiant("  s        : ", s);
	sigLogGiant("  f        : ", f);

	c = borrowGiant(cp->maxDigits);
	d = borrowGiant(cp->maxDigits);
	u = borrowGiant(cp->maxDigits);
	if(randFcn == NULL) {
		frand = feeRandAlloc();
	}
	else {
		frand = NULL;
	}
	
	/*
	 * Random size is just larger than base prime
	 */
	groupBytesLen = ((feePubKeyBitsize(pubKey)+7) / 8);
    randBytesLen = groupBytesLen+8;  // +8bytes (64bits)  to reduce the biais when with reduction mod prime. Per FIPS186-4 - "Using Extra Random Bits"
	randBytes = (unsigned char*) fmalloc(randBytesLen);

	#if	ECDSA_SIGN_USE_PROJ
	/* quick temp pointProj */
	pty = borrowGiant(cp->maxDigits);
	ptz = borrowGiant(cp->maxDigits);
	pt.x = c;
	pt.y = pty;
	pt.z = ptz;
	#endif	// ECDSA_SIGN_USE_PROJ

	while(1) {
		/* Repeat this loop until we have a non-zero c and d */

		/*
		 * 1) Obtain random u in [2, x1OrderPlus-2]
		 */
		SIGPROF_START;
		if(randFcn) {
			randFcn(randRef, randBytes, randBytesLen);
		}
		else {
			feeRandBytes(frand, randBytes, randBytesLen);
		}
		deserializeGiant(randBytes, u, randBytesLen);
        sigLogGiant("  raw u        : ", u);
        sigLogGiant("  order        : ", cp->x1OrderPlus);
        x1OrderPlusJustify(u, cp);
		SIGPROF_END(signStep1);
		sigLogGiant("  in range u        : ", u);

    		/*
		 * note 'o' indicates elliptic multiply, * is integer mult.
		 *
    		 * 2) Compute x coordinate, call it c, of u 'o' G
		 * 3) Reduce: c := c mod x1OrderPlus;
   		 * 4) If c == 0, goto (1);
		 */
		SIGPROF_START;
		gtog(cp->x1Plus, c);

		#if	ECDSA_SIGN_USE_PROJ

		/* projective coordinates */
		gtog(cp->y1Plus, pty);
		int_to_giant(1, ptz);
		ellMulProjSimple(&pt, u, cp);

		#else	/* ECDSA_SIGN_USE_PROJ */

		/* the FEE way */
		elliptic_simple(c, u, cp);

		#endif	/* ECDSA_SIGN_USE_PROJ */

		SIGPROF_END(signStep2);
		SIGPROF_START;
		x1OrderPlusMod(c, cp);
		SIGPROF_END(signStep34);
		if(isZero(c)) {
			dbgLog(("feeECDSASign: zero modulo (1)\n"));
			continue;
		}

		/*
		 * 5) Compute u^(-1) mod x1OrderPlus;
		 */
		SIGPROF_START;
		gtog(u, d);
		binvg_x1OrderPlus(cp, d);
		SIGPROF_END(signStep5);
		sigLogGiant("  u^(-1)   : ", d);

		/*
		 * 6) Compute signature d as:
	 	 *    d = [u^(-1) (f + s*c)] (mod x1OrderPlus)
		 */
		SIGPROF_START;
		mulg(c, s);	     	// s *= c
		x1OrderPlusMod(s, cp);
		addg(f, s);   		// s := f + (s * c)
		x1OrderPlusMod(s, cp);
		mulg(s, d);	     	// d := u^(-1) (f + (s * c))
		x1OrderPlusMod(d, cp);
		SIGPROF_END(signStep67);

		/*
		 * 7) If d = 0, goto (1);
		 */
		if(isZero(d)) {
			dbgLog(("feeECDSASign: zero modulo (2)\n"));
			continue;
		}
		sigLogGiant("  c        : ", c);
		sigLogGiant("  d        : ", d);
		break;			// normal successful exit
	}

	/*
	 * 8) signature is now the integer pair (c, d).
	 */

	/*
	 * Cook up raw data representing the signature.
	 */
	SIGPROF_START;
	ECDSA_encode(format,groupBytesLen, c, d, sigData, sigDataLen);
	SIGPROF_END(signStep8);

	if(frand != NULL) {
		feeRandFree(frand);
	}
	ffree(randBytes);
	returnGiant(u);
	returnGiant(d);
	returnGiant(c);
	returnGiant(f);
	returnGiant(s);
	#if	ECDSA_SIGN_USE_PROJ
	returnGiant(pty);
	returnGiant(ptz);
	#endif	/* ECDSA_SIGN_USE_PROJ */
	return frtn;
}
示例#28
0
feeReturn feeECDSAVerify(const unsigned char *sigData,
	size_t sigDataLen,
	const unsigned char *data,
	unsigned dataLen,
	feePubKey pubKey,
    feeSigFormat  format)
{
	/* giant integers per IEEE P1363 notation */
	giant 		h;			// s^(-1)
	giant		h1;			// f h
	giant		h2;			// c times h
	giant		littleC;		// newGiant from ECDSA_decode
	giant 		littleD;		// ditto
	giant		c;			// borrowed, full size
	giant		d;			// ditto
	giant		cPrime = NULL;		// i mod r
	pointProj	h1G = NULL;		// h1 'o' G
	pointProj	h2W = NULL;		// h2 'o' W
	key		W;			// i.e., their public key

	unsigned	version;
	feeReturn	frtn;
	curveParams	*cp = feePubKeyCurveParams(pubKey);
    unsigned    groupBytesLen = ((feePubKeyBitsize(pubKey)+7) / 8);
    int		result;

	if(cp == NULL) {
		return FR_BadPubKey;
	}

	/*
	 * First decode the byteRep string.
	 */
	frtn = ECDSA_decode(
        format,
        groupBytesLen,
        sigData,
		sigDataLen,
		&littleC,
		&littleD,
		&version);
	if(frtn) {
		return frtn;
	}

	/*
	 * littleC and littleD have capacity = abs(sign), probably
	 * not big enough....
	 */
	c = borrowGiant(cp->maxDigits);
	d = borrowGiant(cp->maxDigits);
	gtog(littleC, c);
	gtog(littleD, d);
	freeGiant(littleC);
	freeGiant(littleD);

	sigDbg(("ECDSA verify:\n"));

    /*
     * Verify that c and d are within [1,group_order-1]
     */
    if((gcompg(cp->cOrderPlus, c) != 1) || (gcompg(cp->cOrderPlus, d) != 1) ||
       isZero(c) || isZero(d))
    {
        returnGiant(c);
        returnGiant(d);
        return FR_InvalidSignature;
    }

	/*
	 * W = signer's public key
	 */
	W = feePubKeyPlusCurve(pubKey);

	/*
	 * 1) Compute h = d^(-1) (mod x1OrderPlus);
	 */
	SIGPROF_START;
	h = borrowGiant(cp->maxDigits);
	gtog(d, h);
	binvg_x1OrderPlus(cp, h);
	SIGPROF_END(vfyStep1);

	/*
	 * 2) h1 = digest as giant (skips assigning to 'f' in P1363)
	 */
	if(dataLen > (cp->maxDigits * GIANT_BYTES_PER_DIGIT)) {
	    h1 = borrowGiant(BYTES_TO_GIANT_DIGITS(dataLen));
	}
	else {
	    h1 = borrowGiant(cp->maxDigits);
	}
	deserializeGiant(data, h1, dataLen);

	/* 
	 * Certicom SEC1 states that if the digest is larger than the modulus, 
	 * use the left q bits of the digest. 
	 */
	unsigned hashBits = dataLen * 8;
	if(hashBits > cp->q) {
		gshiftright(hashBits - cp->q, h1);
	}
	
	sigLogGiant("  Wx       : ", W->x);
	sigLogGiant("  f        : ", h1);
	sigLogGiant("  c        : ", c);
	sigLogGiant("  d        : ", d);
	sigLogGiant("  s^(-1)   : ", h);

	/*
	 * 3) Compute h1 = f * h mod x1OrderPlus;
	 */
	SIGPROF_START;
	mulg(h, h1);					// h1 := f * h
	x1OrderPlusMod(h1, cp);
	SIGPROF_END(vfyStep3);

	/*
	 * 4) Compute h2 = c * h (mod x1OrderPlus);
	 */
	SIGPROF_START;
	h2 = borrowGiant(cp->maxDigits);
	gtog(c, h2);
	mulg(h, h2);					// h2 := c * h
	x1OrderPlusMod(h2, cp);
	SIGPROF_END(vfyStep4);

     	/*
	 * 5) Compute h2W = h2 'o' W  (W = theirPub)
	 */
	CKASSERT((W->y != NULL) && !isZero(W->y));
	h2W = newPointProj(cp->maxDigits);
	gtog(W->x, h2W->x);
	gtog(W->y, h2W->y);
	int_to_giant(1, h2W->z);
	ellMulProjSimple(h2W, h2, cp);

	/*
	 * 6) Compute h1G = h1 'o' G   (G = {x1Plus, y1Plus, 1} )
	 */
	CKASSERT((cp->y1Plus != NULL) && !isZero(cp->y1Plus));
	h1G = newPointProj(cp->maxDigits);
	gtog(cp->x1Plus, h1G->x);
	gtog(cp->y1Plus, h1G->y);
	int_to_giant(1,  h1G->z);
	ellMulProjSimple(h1G, h1, cp);

	/*
	 * 7) h1G := (h1 'o' G) + (h2  'o' W)
	 */
	ellAddProj(h1G, h2W, cp);

	/*
	 * 8) If elliptic sum is point at infinity, signature is bad; stop.
	 */
	if(isZero(h1G->z)) {
		dbgLog(("feeECDSAVerify: h1 * G = point at infinity\n"));
		result = 1;
		goto vfyDone;
	}
	normalizeProj(h1G, cp);

	/*
	 * 9) cPrime = x coordinate of elliptic sum, mod x1OrderPlus
	 */
	cPrime = borrowGiant(cp->maxDigits);
	gtog(h1G->x, cPrime);
	x1OrderPlusMod(cPrime, cp);

	/*
	 * 10) Good sig iff cPrime == c
	 */
	result = gcompg(c, cPrime);

vfyDone:
	if(result) {
		frtn = FR_InvalidSignature;
		#if	LOG_BAD_SIG
		printf("***yup, bad sig***\n");
		#endif	// LOG_BAD_SIG
	}
	else {
		frtn = FR_Success;
	}

	returnGiant(c);
	returnGiant(d);
	returnGiant(h);
	returnGiant(h1);
	returnGiant(h2);
	if(h1G != NULL) {
		freePointProj(h1G);
	}
	if(h2W != NULL) {
		freePointProj(h2W);
	}
	if(cPrime != NULL) {
		returnGiant(cPrime);
	}
	return frtn;
}
示例#29
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);
}