int ecCalcY (ecPoint *p, int ybit) /* given the x coordinate of p, evaluate y such that y^2 + x*y = x^3 + EC_B */ { gfPoint a, b, t; b[0] = 1; b[1] = EC_B; if (p->x[0] == 0) { /* elliptic equation reduces to y^2 = EC_B: */ gfSquareRoot (p->y, EC_B); return 1; } /* evaluate alpha = x^3 + b = (x^2)*x + EC_B: */ gfSquare (t, p->x); /* keep t = x^2 for beta evaluation */ gfMultiply (a, t, p->x); gfAdd (a, a, b); /* now a == alpha */ if (a[0] == 0) { p->y[0] = 0; /* destroy potentially sensitive data: */ gfClear (a); gfClear (t); return 1; } /* evaluate beta = alpha/x^2 = x + EC_B/x^2 */ gfSmallDiv (t, EC_B); gfInvert (a, t); gfAdd (a, p->x, a); /* now a == beta */ /* check if a solution exists: */ if (gfTrace (a) != 0) { /* destroy potentially sensitive data: */ gfClear (a); gfClear (t); return 0; /* no solution */ } /* solve equation t^2 + t + beta = 0 so that gfYbit(t) == ybit: */ gfQuadSolve (t, a); if (gfYbit (t) != ybit) { t[1] ^= 1; } /* compute y = x*t: */ gfMultiply (p->y, p->x, t); /* destroy potentially sensitive data: */ gfClear (a); gfClear (t); return 1; } /* ecCalcY */
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 */