X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/1ba83484ee5bb486da9aa958576de4bc29ef0c1d..34e4f738bcba58e6d8c4cabbb0b3232a65b42a9d:/ec-exp.c?ds=sidebyside diff --git a/ec-exp.c b/ec-exp.c new file mode 100644 index 0000000..26953e7 --- /dev/null +++ b/ec-exp.c @@ -0,0 +1,155 @@ +/* -*-c-*- + * + * $Id: ec-exp.c,v 1.1 2004/04/01 12:50:09 mdw Exp $ + * + * Point multiplication for elliptic curves + * + * (c) 2004 Straylight/Edgeware + */ + +/*----- Licensing notice --------------------------------------------------* + * + * This file is part of Catacomb. + * + * Catacomb is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * Catacomb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with Catacomb; if not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + * MA 02111-1307, USA. + */ + +/*----- Revision history --------------------------------------------------* + * + * $Log: ec-exp.c,v $ + * Revision 1.1 2004/04/01 12:50:09 mdw + * Add cyclic group abstraction, with test code. Separate off exponentation + * functions for better static linking. Fix a buttload of bugs on the way. + * Generally ensure that negative exponents do inversion correctly. Add + * table of standard prime-field subgroups. (Binary field subgroups are + * currently unimplemented but easy to add if anyone ever finds a good one.) + * + */ + +/*----- Header files ------------------------------------------------------*/ + +#include "ec.h" +#include "ec-exp.h" + +/*----- Main code ---------------------------------------------------------*/ + +/* --- @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: The destination @d@. + * + * Use: Multiplies a point by a scalar, returning %$n p$%. The + * @imul@ variant uses internal representations for argument + * and result. + */ + +ec *ec_imul(ec_curve *c, ec *d, const ec *p, mp *n) +{ + 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 (MP_LEN(n) == 0) + ; + else { + if (n->f & MP_NEG) + EC_NEG(c, &t, &t); + if (MP_LEN(n) < EXP_THRESH) + EXP_SIMPLE(*d, t, n); + else + EXP_WINDOW(*d, t, n); + } + EC_DESTROY(&t); + return (d); +} + +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)); +} + +/* --- @ec_mmul@, @ec_immul@ --- * + * + * Arguments: @ec_curve *c@ = pointer to an elliptic curve + * @ec *d@ = pointer to the destination point + * @const ec_mulfactor *f@ = pointer to vector of factors + * @size_t n@ = number of factors + * + * Returns: The destination @d@. + * + * Use: Does simultaneous point multiplication. The @immul@ variant + * uses internal representations for arguments and result. + */ + +#undef EXP_WINSZ +#define EXP_WINSZ 3 + +static ec *immul(ec_curve *c, ec *d, ec_mulfactor *f, size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) { + MP_SHRINK(f[i].exp); + if (f[i].exp->f & MP_NEG) + EC_NEG(c, &f[i].base, &f[i].base); + if (f[i].base.x && f[i].exp->f & MP_BURN) + f[i].base.x->f |= MP_BURN; + } + EC_SETINF(d); + EXP_SIMUL(*d, f, n); + for (i = 0; i < n; i++) + EC_DESTROY(&f[i].base); + xfree(f); + return (d); +} + +ec *ec_immul(ec_curve *c, ec *d, const ec_mulfactor *f, size_t n) +{ + ec_mulfactor *ff = xmalloc(n * sizeof(ec_mulfactor)); + size_t i; + + for (i = 0; i < n; i++) { + EC_CREATE(&ff[i].base); + EC_COPY(&ff[i].base, &f[i].base); + ff[i].exp = f[i].exp; + } + return (immul(c, d, ff, n)); +} + +ec *ec_mmul(ec_curve *c, ec *d, const ec_mulfactor *f, size_t n) +{ + ec_mulfactor *ff = xmalloc(n * sizeof(ec_mulfactor)); + size_t i; + + for (i = 0; i < n; i++) { + EC_CREATE(&ff[i].base); + EC_IN(c, &ff[i].base, &f[i].base); + ff[i].exp = f[i].exp; + } + immul(c, d, ff, n); + return (EC_OUT(c, d, d)); +} + +/*----- That's all, folks -------------------------------------------------*/