Beispiel #1
0
void ecMultiply (ecPoint *p, const vlPoint k)
	/* sets p := k*p */
{
	vlPoint h;
	int z, hi, ki;
	word16 i;
	ecPoint r;

	gfCopy (r.x, p->x); p->x[0] = 0;
	gfCopy (r.y, p->y); p->y[0] = 0;
	vlShortMultiply (h, k, 3);
	z = vlNumBits (h) - 1; /* so vlTakeBit (h, z) == 1 */
	i = 1;
	for (;;) {
		hi = vlTakeBit (h, i);
		ki = vlTakeBit (k, i);
		if (hi == 1 && ki == 0) {
			ecAdd (p, &r);
		}
		if (hi == 0 && ki == 1) {
			ecSub (p, &r);
		}
		if (i >= z) {
			break;
		}
		i++;
		ecDouble (&r);
	}
} /* ecMultiply */
Beispiel #2
0
void ecAdd (ecPoint *p, const ecPoint *q)
	/* sets p := p + q */
{
	gfPoint lambda, t, tx, ty, x3;

	/* first check if there is indeed work to do (q != 0): */
	if (q->x[0] != 0 || q->y[0] != 0) {
		if (p->x[0] != 0 || p->y[0] != 0) {
			/* p != 0 and q != 0 */
			if (gfEqual (p->x, q->x)) {
				/* either p == q or p == -q: */
				if (gfEqual (p->y, q->y)) {
					/* points are equal; double p: */
					ecDouble (p);
				} else {
					/* must be inverse: result is zero */
					/* (should assert that q->y = p->x + p->y) */
					p->x[0] = p->y[0] = 0;
				}
			} else {
				/* p != 0, q != 0, p != q, p != -q */
				/* evaluate lambda = (y1 + y2)/(x1 + x2): */
				gfAdd (ty, p->y, q->y);
				gfAdd (tx, p->x, q->x);
				gfInvert (t, tx);
				gfMultiply (lambda, ty, t);
				/* evaluate x3 = lambda^2 + lambda + x1 + x2: */
				gfSquare (x3, lambda);
				gfAdd (x3, x3, lambda);
				gfAdd (x3, x3, tx);
				/* evaluate y3 = lambda*(x1 + x3) + x3 + y1: */
				gfAdd (tx, p->x, x3);
				gfMultiply (t, lambda, tx);
				gfAdd (t, t, x3);
				gfAdd (p->y, t, p->y);
				/* deposit the value of x3: */
				gfCopy (p->x, x3);
			}
		} else {
			/* just copy q into p: */
			gfCopy (p->x, q->x);
			gfCopy (p->y, q->y);
		}
	}
} /* ecAdd */
Beispiel #3
0
void ecSub (ecPoint *p, const ecPoint *r)
	/* sets p := p - r */
{
	ecPoint t;

	gfCopy (t.x, r->x);
	gfAdd  (t.y, r->x, r->y);
	ecAdd (p, &t);
} /* ecSub */
Beispiel #4
0
static int gfSlowTrace (const gfPoint p)
	/* slowly evaluates to the trace of p (or an error code) */
{
	int i;
	gfPoint t;

	assert (logt != NULL && expt != NULL);
	assert (p != NULL);
	gfCopy (t, p);
	for (i = 1; i < GF_M; i++) {
		gfSquare (t, t);
		gfAdd (t, t, p);
	}
	return t[0] != 0;
} /* gfSlowTrace */
Beispiel #5
0
void ecDouble (ecPoint *p)
	/* sets p := 2*p */
{
	gfPoint lambda, t1, t2;

	/* evaluate lambda = x + y/x: */
	gfInvert (t1, p->x);
	gfMultiply (lambda, p->y, t1);
	gfAdd (lambda, lambda, p->x);
	/* evaluate x3 = lambda^2 + lambda: */
	gfSquare (t1, lambda);
	gfAdd (t1, t1, lambda); /* now t1 = x3 */
	/* evaluate y3 = x^2 + lambda*x3 + x3: */
	gfSquare (p->y, p->x);
	gfMultiply (t2, lambda, t1);
	gfAdd (p->y, p->y, t2);
	gfAdd (p->y, p->y, t1);
	/* deposit the value of x3: */
	gfCopy (p->x, t1);
} /* ecDouble */
Beispiel #6
0
void gfSquareRoot (gfPoint p, lunit b)
	/* sets p := sqrt(b) = b^(2^(GF_M-1)) */
{
	int i;
	gfPoint q;

	assert (logt != NULL && expt != NULL);
	assert (p != NULL);
	q[0] = 1; q[1] = b;
	if ((GF_M - 1) & 1) {
		/* GF_M - 1 is odd */
		gfSquare (p, q);
		i = GF_M - 2;
	} else {
		/* GF_M - 1 is even */
		gfCopy (p, q);
		i = GF_M - 1;
	}
	while (i) {
		gfSquare (p, p);
		gfSquare (p, p);
		i -= 2;
	}
} /* gfSquareRoot */
Beispiel #7
0
int gfInvert (gfPoint b, const gfPoint a)
	/* sets b := a^(-1) mod (x^GF_K + x^GF_T + 1) */
	/* warning: a and b must not overlap! */
{
	gfPoint c, f, g;
	ltemp x, j, alpha;

	assert (logt != NULL && expt != NULL);
	assert (b != NULL);
	assert (a != NULL);
	assert (b != a); /* note that this test is not complete */
	if (a[0] == 0) {
		/* a is not invertible */
		return 1;
	}

	/* initialize b := 1; c := 0; f := p; g := x^GF_K + x^GF_T + 1: */
	b[0] = 1; b[1] = 1;
	c[0] = 0;
	gfCopy (f, a);
	gfClear (g);
	g[0] = GF_K + 1; g[1] = 1; g[GF_T + 1] = 1; g[GF_K + 1] = 1;

	for (;;) {
		if (f[0] == 1) {
			assert (f[1] != 0);
			gfSmallDiv (b, f[1]);
			/* destroy potentially sensitive data: */
			gfClear (c); gfClear (f); gfClear (g); x = j = alpha = 0;
			return 0;
		}
		if (f[0] < g[0]) {
			goto SWAP_FG;
		}
SWAP_GF:
		j = f[0] - g[0];
		x = logt[f[f[0]]] - logt[g[g[0]]] + TOGGLE;
		alpha = expt[x >= TOGGLE ? x - TOGGLE : x];
		gfAddMul (f, alpha, j, g);
		gfAddMul (b, alpha, j, c);
	}

	/* basically same code with b,c,f,g swapped */
	for (;;) {
		if (g[0] == 1) {
			assert (g[1] != 0);
			gfSmallDiv (c, g[1]);
			gfCopy (b, c);
			/* destroy potentially sensitive data: */
			gfClear (c); gfClear (f); gfClear (g); x = j = alpha = 0;
			return 0;
		}
		if (g[0] < f[0]) {
			goto SWAP_GF;
		}
SWAP_FG:
		j = g[0] - f[0];
		x = logt[g[g[0]]] - logt[f[f[0]]] + TOGGLE;
		alpha = expt[x >= TOGGLE ? x - TOGGLE : x];
		gfAddMul (g, alpha, j, f);
		gfAddMul (c, alpha, j, b);
	}
} /* gfInvert */
Beispiel #8
0
int ecSelfTest (int test_count)
	/* perform test_count self tests */
{
	int i, yb, nfail = 0, afail = 0, sfail = 0, cfail = 0, qfail = 0, pfail = 0, yfail = 0;
	ecPoint f, g, x, y;
	vlPoint m, n, p;
	clock_t elapsed = 0L;

	srand ((unsigned)(time(NULL) % 65521U));
	printf ("Executing %d curve self tests...", test_count);
	for (i = 0; i < test_count; i++) {
		ecRandom (&f);
		ecRandom (&g);
		vlRandom (m);
		vlRandom (n);

		/* negation test: -(-f) = f */
		ecCopy (&x, &f);
		ecNegate (&x);
		ecNegate (&x);
		if (!ecEqual (&x, &f)) {
			nfail++;
			/* printf ("Addition test #%d failed!\n", i); */
		}
		/* addition test: f+g = g+f */
		ecCopy (&x, &f); ecAdd (&x, &g);
		ecCopy (&y, &g); ecAdd (&y, &f);
		if (!ecEqual (&x, &y)) {
			afail++;
			/* printf ("Addition test #%d failed!\n", i); */
		}
		/* subtraction test: f-g = f+(-g) */
		ecCopy (&x, &f); ecSub (&x, &g);
		ecCopy (&y, &g); ecNegate (&y); ecAdd (&y, &f);
		if (!ecEqual (&x, &y)) {
			sfail++;
			/* printf ("Subtraction test #%d failed!\n", i); */
		}
		/* quadruplication test: 2*(2*f) = f + f + f + f */
		ecCopy (&x, &f); ecDouble (&x); ecDouble (&x);
		ecClear (&y); ecAdd (&y, &f); ecAdd (&y, &f); ecAdd (&y, &f); ecAdd (&y, &f);
		if (!ecEqual (&x, &y)) {
			qfail++;
			/* printf ("Quadruplication test #%d failed!\n", i); */
		}
		/* scalar multiplication commutativity test: m*(n*f) = n*(m*f) */
		ecCopy (&x, &f);
		ecCopy (&y, &f);
		elapsed -= clock ();
		ecMultiply (&x, n); ecMultiply (&x, m);
		ecMultiply (&y, m); ecMultiply (&y, n);
		elapsed += clock ();
		if (!ecEqual (&x, &y)) {
			cfail++;
			/* printf ("Commutativity test #%d failed!\n", i); */
		}
		/* y calculation test: */
		yb = ecYbit (&f);
		ecClear (&x);
		gfCopy (x.x, f.x);
		ecCalcY (&x, yb);
		if (!ecEqual (&f, &x)) {
			yfail++;
			/* printf ("Y calculation test #%d failed!\n", i); */
		}
		/* packing test: unpack (pack (f)) = f */
		ecPack (&f, p);
		ecUnpack (&x, p);
		if (!ecEqual (&f, &x)) {
			pfail++;
			/* printf ("Packing test #%d failed!\n", i); */
		}
	}
	printf (" done, scalar multiplication time: %.3f s/op.\n",
		(float)elapsed/CLOCKS_PER_SEC/(test_count?4*test_count:4));
	if (nfail) printf ("---> %d negations failed <---\n", nfail);
	if (afail) printf ("---> %d additions failed <---\n", afail);
	if (sfail) printf ("---> %d subtractions failed <---\n", sfail);
	if (qfail) printf ("---> %d quadruplications failed <---\n", qfail);
	if (cfail) printf ("---> %d commutativities failed <---\n", cfail);
	if (yfail) printf ("---> %d y calculations failed <---\n", yfail);
	if (pfail) printf ("---> %d packings failed <---\n", pfail);
	return nfail || afail || sfail || qfail || cfail || yfail || pfail;
} /* ecSelfTest */
Beispiel #9
0
void ecCopy (ecPoint *p, const ecPoint *q)
	/* sets p := q */
{
	gfCopy (p->x, q->x);
	gfCopy (p->y, q->y);
} /* ecCopy */