/* -*-c-*-
*
- * $Id: ec.c,v 1.2 2001/05/07 17:29:44 mdw Exp $
+ * $Id: ec.c,v 1.3 2002/01/13 13:48:44 mdw Exp $
*
* Elliptic curve definitions
*
/*----- Revision history --------------------------------------------------*
*
* $Log: ec.c,v $
+ * Revision 1.3 2002/01/13 13:48:44 mdw
+ * Further progress.
+ *
* Revision 1.2 2001/05/07 17:29:44 mdw
* Treat projective coordinates as an internal representation. Various
* minor interface changes.
/*----- Header files ------------------------------------------------------*/
#include "ec.h"
+#include "ec-exp.h"
/*----- Trivial wrappers --------------------------------------------------*/
return (d);
}
+/* --- @ec_stdsub@ --- *
+ *
+ * Arguments: @ec_curve *c@ = pointer to an elliptic curve
+ * @ec *d@ = pointer to the destination
+ * @const ec *a, *b@ = the operand points
+ *
+ * Returns: The destination @d@.
+ *
+ * Use: Standard point subtraction operation, in terms of negation
+ * and addition. This isn't as efficient as a ready-made
+ * subtraction operator.
+ */
+
+ec *ec_stdsub(ec_curve *c, ec *d, const ec *a, const ec *b)
+{
+ ec t = EC_INIT;
+ EC_NEG(c, &t, b);
+ EC_SUB(c, d, a, &t);
+ EC_DESTROY(&t);
+ return (d);
+}
+
/*----- Real arithmetic ---------------------------------------------------*/
/* --- @ec_find@ --- *
return (EC_OUT(c, d, d));
}
-/* --- @ec_mul@ --- *
+/* --- @ec_imul@, @ec_mul@ --- *
*
* Arguments: @ec_curve *c@ = pointer to an elliptic curve
* @ec *d@ = pointer to the destination point
* @const ec *p@ = pointer to the generator point
* @mp *n@ = integer multiplier
*
- * Returns: ---
+ * Returns: The destination @d@.
*
- * Use: Multiplies a point by a scalar, returning %$n p$%.
+ * Use: Multiplies a point by a scalar, returning %$n p$%. The
+ * @imul@ variant uses internal representations for argument
+ * and result.
*/
-ec *ec_mul(ec_curve *c, ec *d, const ec *p, mp *n)
+ec *ec_imul(ec_curve *c, ec *d, const ec *p, mp *n)
{
- mpscan sc;
- ec g = EC_INIT;
- unsigned sq = 0;
+ ec t = EC_INIT;
+ EC_COPY(&t, p);
+ if (t.x && (n->f & MP_BURN))
+ t.x->f |= MP_BURN;
+ MP_SHRINK(n);
EC_SETINF(d);
- if (EC_ATINF(p))
- return;
-
- mp_rscan(&sc, n);
- if (!MP_RSTEP(&sc))
- goto exit;
- while (!MP_RBIT(&sc))
- MP_RSTEP(&sc);
-
- EC_IN(c, &g, p);
- if ((n->f & MP_BURN) && !(g.x->f & MP_BURN))
- MP_DEST(g.x, 0, MP_BURN);
- if ((n->f & MP_BURN) && !(g.y->f & MP_BURN))
- MP_DEST(g.y, 0, MP_BURN);
-
- for (;;) {
- EC_ADD(c, d, d, &g);
- sq = 0;
- for (;;) {
- if (!MP_RSTEP(&sc))
- goto done;
- if (MP_RBIT(&sc))
- break;
- sq++;
- }
- sq++;
- while (sq) {
- EC_DBL(c, d, d);
- sq--;
- }
- }
-
-done:
- while (sq) {
- EC_DBL(c, d, d);
- sq--;
- }
+ if (MP_LEN(n) == 0)
+ ;
+ else if (MP_LEN(n) < EXP_THRESH)
+ EXP_SIMPLE(&d, t, n);
+ else
+ EXP_WINDOW(&d, t, n);
+ return (d);
+}
- EC_DESTROY(&g);
-exit:
+ec *ec_mul(ec_curve *c, ec *d, const ec *p, mp *n)
+{
+ EC_IN(c, d, p);
+ ec_imul(c, d, d, n);
return (EC_OUT(c, d, d));
}