/* -*-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
*
/*----- 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.
*
/*----- 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 -------------------------------------------------*/