X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/8823192f6413bed15cfa884ed3a3cbbb97885657..bc985cefafea2e1b02095a2ff2a9982c4c647d17:/ec-prime.c diff --git a/ec-prime.c b/ec-prime.c index 14e4c16..5c6297f 100644 --- a/ec-prime.c +++ b/ec-prime.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: ec-prime.c,v 1.3.4.2 2004/03/20 00:13:31 mdw Exp $ + * $Id: ec-prime.c,v 1.6 2004/03/23 15:19:32 mdw Exp $ * * Elliptic curves over prime fields * @@ -30,6 +30,20 @@ /*----- Revision history --------------------------------------------------* * * $Log: ec-prime.c,v $ + * Revision 1.6 2004/03/23 15:19:32 mdw + * Test elliptic curves more thoroughly. + * + * Revision 1.5 2004/03/22 02:19:10 mdw + * Rationalise the sliding-window threshold. Drop guarantee that right + * arguments to EC @add@ are canonical, and fix up projective implementations + * to cope. + * + * Revision 1.4 2004/03/21 22:52:06 mdw + * Merge and close elliptic curve branch. + * + * Revision 1.3.4.3 2004/03/21 22:39:46 mdw + * Elliptic curves on binary fields work. + * * Revision 1.3.4.2 2004/03/20 00:13:31 mdw * Projective coordinates for prime curves * @@ -67,7 +81,8 @@ static const ec_ops ec_primeops, ec_primeprojops, ec_primeprojxops; static ec *ecneg(ec_curve *c, ec *d, const ec *p) { EC_COPY(d, p); - d->y = F_NEG(c->f, d->y, d->y); + if (d->y) + d->y = F_NEG(c->f, d->y, d->y); return (d); } @@ -254,8 +269,7 @@ static ec *ecadd(ec_curve *c, ec *d, const ec *a, const ec *b) dx = F_SUB(f, dx, dx, b->x); /* %$x' = \lambda^2 - x_0 - x_1$% */ dy = F_SUB(f, dy, b->x, dx); /* %$x_1 - x'$% */ dy = F_MUL(f, dy, lambda, dy); /* %$\lambda (x_1 - x')$% */ - dy = F_SUB(f, dy, dy, b->y); - /* %$y' = \lambda (x_1 - x') - y_1$% */ + dy = F_SUB(f, dy, dy, b->y); /* %$y' = \lambda (x_1 - x') - y_1$% */ EC_DESTROY(d); d->x = dx; @@ -276,37 +290,42 @@ static ec *ecprojadd(ec_curve *c, ec *d, const ec *a, const ec *b) EC_COPY(d, a); else { field *f = c->f; - mp *p, *q, *r, *w, *u, *s, *dx, *dy, *dz; + mp *p, *q, *r, *w, *u, *uu, *s, *ss, *dx, *dy, *dz; q = F_SQR(f, MP_NEW, a->z); /* %$z_0^2$% */ u = F_MUL(f, MP_NEW, q, b->x); /* %$u = x_1 z_0^2$% */ p = F_MUL(f, MP_NEW, q, b->y); /* %$y_1 z_0^2$% */ s = F_MUL(f, q, p, a->z); /* %$s = y_1 z_0^3$% */ - w = F_SUB(f, p, a->x, u); /* %$w = x_0 - u$% */ - r = F_SUB(f, MP_NEW, a->y, s); /* %$r = y_0 - s$% */ + q = F_SQR(f, MP_NEW, b->z); /* %$z_1^2$% */ + uu = F_MUL(f, MP_NEW, q, a->x); /* %$uu = x_0 z_1^2$%*/ + p = F_MUL(f, p, q, a->y); /* %$y_0 z_1^2$% */ + ss = F_MUL(f, q, p, b->z); /* %$ss = y_0 z_1^3$% */ + + w = F_SUB(f, p, uu, u); /* %$w = uu - u$% */ + r = F_SUB(f, MP_NEW, ss, s); /* %$r = ss - s$% */ if (F_ZEROP(f, w)) { + MP_DROP(w); + MP_DROP(u); + MP_DROP(s); + MP_DROP(uu); + MP_DROP(ss); if (F_ZEROP(f, r)) { - MP_DROP(w); MP_DROP(r); - MP_DROP(u); - MP_DROP(s); return (c->ops->dbl(c, d, a)); } else { - MP_DROP(w); MP_DROP(r); - MP_DROP(u); - MP_DROP(s); EC_SETINF(d); return (d); } } - u = F_ADD(f, u, u, a->x); /* %$t = x_0 + u$% */ - s = F_ADD(f, s, s, a->y); /* %$m = y_0 + r$% */ + u = F_ADD(f, u, u, uu); /* %$t = uu + u$% */ + s = F_ADD(f, s, s, ss); /* %$m = ss + r$% */ - dz = F_MUL(f, MP_NEW, a->z, w); /* %$z' = z_0 w$% */ + uu = F_MUL(f, uu, a->z, w); /* %$z_0 w$% */ + dz = F_MUL(f, ss, uu, b->z); /* %$z' = z_0 z_1 w$% */ - p = F_SQR(f, MP_NEW, w); /* %$w^2$% */ + p = F_SQR(f, uu, w); /* %$w^2$% */ q = F_MUL(f, MP_NEW, p, u); /* %$t w^2$% */ u = F_MUL(f, u, p, w); /* %$w^3$% */ p = F_MUL(f, p, u, s); /* %$m w^3$% */ @@ -411,17 +430,17 @@ extern ec_curve *ec_primeproj(field *f, mp *a, mp *b) static const ec_ops ec_primeops = { ecdestroy, ec_idin, ec_idout, ec_idfix, - 0, ecneg, ecadd, ec_stdsub, ecdbl, eccheck + ecfind, ecneg, ecadd, ec_stdsub, ecdbl, eccheck }; static const ec_ops ec_primeprojops = { ecdestroy, ec_projin, ec_projout, ec_projfix, - 0, ecneg, ecprojadd, ec_stdsub, ecprojdbl, ecprojcheck + ecfind, ecneg, ecprojadd, ec_stdsub, ecprojdbl, ecprojcheck }; static const ec_ops ec_primeprojxops = { ecdestroy, ec_projin, ec_projout, ec_projfix, - 0, ecneg, ecprojadd, ec_stdsub, ecprojxdbl, ecprojcheck + ecfind, ecneg, ecprojadd, ec_stdsub, ecprojxdbl, ecprojcheck }; /*----- Test rig ----------------------------------------------------------*/ @@ -430,12 +449,13 @@ static const ec_ops ec_primeprojxops = { #define MP(x) mp_readstring(MP_NEW, #x, 0, 0) -int main(void) +int main(int argc, char *argv[]) { field *f; ec_curve *c; ec g = EC_INIT, d = EC_INIT; mp *p, *a, *b, *r; + int i, n = argc == 1 ? 1 : atoi(argv[1]); printf("ec-prime: "); fflush(stdout); @@ -445,25 +465,26 @@ int main(void) r = MP(6277101735386680763835789423176059013767194773182842284080); f = field_prime(p); - c = ec_prime(f, a, b); + c = ec_primeproj(f, a, b); g.x = MP(0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012); g.y = MP(0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811); - ec_mul(c, &d, &g, r); - if (EC_ATINF(&d)) { - fprintf(stderr, "zero too early\n"); - return (1); - } - ec_add(c, &d, &d, &g); - if (!EC_ATINF(&d)) { - fprintf(stderr, "didn't reach zero\n"); - MP_EPRINT("d.x", d.x); - MP_EPRINT("d.y", d.y); - return (1); + for (i = 0; i < n; i++) { + ec_mul(c, &d, &g, r); + if (EC_ATINF(&d)) { + fprintf(stderr, "zero too early\n"); + return (1); + } + ec_add(c, &d, &d, &g); + if (!EC_ATINF(&d)) { + fprintf(stderr, "didn't reach zero\n"); + MP_EPRINT("d.x", d.x); + MP_EPRINT("d.y", d.y); + return (1); + } + ec_destroy(&d); } - - ec_destroy(&d); ec_destroy(&g); ec_destroycurve(c); F_DESTROY(f);