X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/b0ab12e6a6cb035df2b6312df7ad1736af0a6128..75263f25a1ce8e7b38ad4bd61a9a893723ec1db3:/ec-prime.c diff --git a/ec-prime.c b/ec-prime.c index 5a806da..09733ce 100644 --- a/ec-prime.c +++ b/ec-prime.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: ec-prime.c,v 1.1 2001/04/29 18:12:33 mdw Exp $ + * $Id: ec-prime.c,v 1.2 2002/01/13 13:48:44 mdw Exp $ * * Elliptic curves over prime fields * @@ -30,6 +30,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: ec-prime.c,v $ + * Revision 1.2 2002/01/13 13:48:44 mdw + * Further progress. + * * Revision 1.1 2001/04/29 18:12:33 mdw * Prototype version. * @@ -48,25 +51,93 @@ typedef struct ecctx { /*----- Main code ---------------------------------------------------------*/ -static void ecadd(ec_curve *c, ec *d, const ec *a, const ec *b) +static ec *ecneg(ec_cuvrve *c, ec *d, const ec *p) +{ + EC_COPY(d, p); + d->y = F_NEG(c->f, d->y, d->y); + return (d); +} + +static ec *ecdbl(ec_curve *c, ec *d, const ec *a) { - /* --- Deal with the simple cases --- */ + if (EC_ATINF(a)) + EC_SETINF(d); + else if (!MP_LEN(a->y)) + EC_COPY(d, a); + else { + field *f = c->f; + ecctx *cc = (ecctx *)c; + mp *lambda; + mp *dy, *dx; + + dx = F_SQR(f, MP_NEW, a->x); + dy = F_DBL(f, MP_NEW, a->y); + dx = F_TPL(f, dx, dx); + dx = F_ADD(f, dx, dx, cc->a); + dy = F_INV(f, dy, dy); + lambda = F_MUL(d, MP_NEW, dx, dy); + + dx = F_SQR(f, dx, lambda); + dy = F_DBL(d, dy, a->x); + dx = F_SUB(f, dx, dx, dy); + dy = F_SUB(f, dy, a->x, dx); + dy = F_MUL(f, dy, lambda, dy); + dy = F_SUB(f, dy, dy, a->y); + EC_DESTROY(d); + d->x = dx; + d->y = dy; + d->z = 0; + MP_DROP(lambda); + } + return (d); +} + +static ec *ecadd(ec_curve *c, ec *d, const ec *a, const ec *b) +{ if (a == b) ecdbl(c, d, a); else if (EC_ATINF(a)) EC_COPY(d, b); else if (EC_ATINF(b)) EC_COPY(d, a); - else if (MP_EQ(a->x, b->x) && MP_EQ(a->z, b->z)) { - if ((a->y->f ^ b->y->f) & MP_NEG) + else { + field *f = c->f; + mp *lambda; + mp *dy, *dx; + + if (!MP_EQ(a->x, b->x)) { + dy = F_SUB(f, MP_NEW, a->y, b->y); + dx = F_SUB(f, MP_NEW, a->x, b->x); + dx = F_INV(f, dx, dx); + lambda = F_MUL(f, MP_NEW, dy, dx); + } else if (!MP_LEN(a->y) || !MP_EQ(a->y, b->y)) { EC_SETINF(d); - else - ecdbl(c, d, a); - } else { + return (d); + } else { + ecctx *cc = (ecctx *)c; + dx = F_SQR(f, MP_NEW, a->x); + dx = F_TPL(f, dx, dx); + dx = F_ADD(f, dx, dx, cc->a); + dy = F_DBL(f, MP_NEW, a->y); + dy = F_INV(f, dy, dy); + lambda = F_MUL(d, MP_NEW, dx, dy); + } + + dx = F_SQR(f, dx, lambda); + dx = F_SUB(f, dx, dx, a->x); + dx = F_SUB(f, dx, dx, b->x); + dy = F_SUB(f, dy, b->x, dx); + dy = F_MUL(f, dy, lambda, dy); + dy = F_SUB(f, dy, dy, b->y); - /* --- + EC_DESTROY(d); + d->x = dx; + d->y = dy; + d->z = 0; + MP_DROP(lambda); } + return (d); } /*----- That's all, folks -------------------------------------------------*/