Key mangling, and elliptic curves.
[catacomb-perl] / ec.xs
diff --git a/ec.xs b/ec.xs
new file mode 100644 (file)
index 0000000..66314ce
--- /dev/null
+++ b/ec.xs
@@ -0,0 +1,401 @@
+# ---?---
+#
+# $Id$
+#
+# Elliptic curves
+#
+# (c) 2001 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Perl interface to Catacomb.
+#
+# Catacomb/Perl is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# Catacomb/Perl 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 General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Catacomb/Perl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+MODULE = Catacomb PACKAGE = Catacomb::EC::Point PREFIX = ec_
+
+EC_Point *
+new(x = 0, y = 0, z = 0)
+       mp *x
+       mp *y
+       mp *z
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       if (x && y) {
+         RETVAL->x = MP_COPY(x);
+         RETVAL->y = MP_COPY(y);
+         if (z)
+           RETVAL->z = MP_COPY(z);
+       }
+       OUTPUT: 
+       RETVAL
+
+bool
+atinfp(p)
+       EC_Point *p
+       CODE:
+       RETVAL = EC_ATINF(p);
+       OUTPUT:
+       RETVAL
+
+mp *
+x(p)
+       EC_Point *p
+       CODE:
+       RETVAL = p->x ? MP_COPY(p->x) : 0;
+       OUTPUT:
+       RETVAL
+       
+mp *
+y(p)
+       EC_Point *p
+       CODE:
+       RETVAL = p->y ? MP_COPY(p->y) : 0;
+       OUTPUT:
+       RETVAL
+       
+mp *
+z(p)
+       EC_Point *p
+       CODE:
+       RETVAL = p->z ? MP_COPY(p->z) : 0;
+       OUTPUT:
+       RETVAL
+
+SV *
+DESTROY(p)
+       EC_Point *p
+       CODE:
+       EC_DESTROY(p);
+       DESTROY(p);
+       XSRETURN_YES;
+
+MODULE = Catacomb PACKAGE = Catacomb::EC::Curve PREFIX = ec_
+
+EC_Curve *
+ec_prime(me, f, a, b)
+       SV *me
+       Field *f
+       mp *a
+       mp *b
+       C_ARGS:
+       f, a, b
+
+EC_Curve *
+ec_primeproj(me, f, a, b)
+       SV *me
+       Field *f
+       mp *a
+       mp *b
+       C_ARGS:
+       f, a, b
+
+EC_Curve *
+ec_bin(me, f, a, b)
+       SV *me
+       Field *f
+       gf *a
+       gf *b
+       C_ARGS:
+       f, a, b
+
+EC_Curve *
+ec_binproj(me, f, a, b)
+       SV *me
+       Field *f
+       gf *a
+       gf *b
+       C_ARGS:
+       f, a, b
+
+char *
+name(c)
+       EC_Curve *c
+       CODE:
+       RETVAL = (char *)EC_NAME(c);
+       OUTPUT: 
+       RETVAL
+
+bool
+ec_samep(me, c)
+       EC_Curve *me
+       EC_Curve *c
+
+EC_Point *
+find(c, x)
+       EC_Curve *c
+       mp *x
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       if (!ec_find(c, RETVAL, x)) {
+         DESTROY(RETVAL);
+         RETVAL = 0;
+       }
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+rand(c, r = &rand_global)
+       EC_Curve *c
+       grand *r
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       ec_rand(c, RETVAL, r);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+neg(c, p)
+       EC_Curve *c
+       EC_Point *p
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       ec_neg(c, RETVAL, p);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+add(c, p, q)
+       EC_Curve *c
+       EC_Point *p
+       EC_Point *q
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       ec_add(c, RETVAL, p, q);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+sub(c, p, q)
+       EC_Curve *c
+       EC_Point *p
+       EC_Point *q
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       ec_sub(c, RETVAL, p, q);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+dbl(c, p)
+       EC_Curve *c
+       EC_Point *p
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       ec_dbl(c, RETVAL, p);
+       OUTPUT:
+       RETVAL
+
+bool
+ec_check(c, p)
+       EC_Curve *c
+       EC_Point *p
+
+EC_Point *
+mul(c, p, x)
+       EC_Curve *c
+       EC_Point *p
+       mp *x
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       ec_mul(c, RETVAL, p, x);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+mmul(c, ...)
+       EC_Curve *c
+       PREINIT:
+       ec_mulfactor *v;
+       size_t i, j, n;
+       CODE:
+       if (items < 3 || !(items & 1)) {
+         croak("Usage: Catacomb::EC::Curve::mmul"
+               "(c, p_0, x_0, p_1, x_1, ...");
+       }
+       n = (items - 1)/2;
+       v = xmalloc(n * sizeof(mp_expfactor));
+       for (i = 1, j = 0; i < items; i += 2, j++) {
+         v[j].base = *(ec *)ptrfromsv(ST(i), "Catacomb::EC::Point", "p_i");
+         v[j].exp = mp_fromsv(ST(i + 1), "x_i", "Catacomb::MP", 0, 0);
+       }
+       RETVAL = CREATE(RETVAL);
+       EC_CREATE(RETVAL);
+       ec_mmul(c, RETVAL, v, n);
+       xfree(v);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+in(c, p)
+       EC_Curve *c
+       EC_Point *p
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       EC_IN(c, RETVAL, p);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+out(c, p)
+       EC_Curve *c
+       EC_Point *p
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       EC_OUT(c, RETVAL, p);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+fix(c, p)
+       EC_Curve *c
+       EC_Point *p
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       EC_FIX(c, RETVAL, p);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+ifind(c, x)
+       EC_Curve *c
+       mp *x
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       if (!EC_FIND(c, RETVAL, x)) {
+         DESTROY(RETVAL);
+         RETVAL = 0;
+       }
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+ineg(c, p)
+       EC_Curve *c
+       EC_Point *p
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       EC_NEG(c, RETVAL, p);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+iadd(c, p, q)
+       EC_Curve *c
+       EC_Point *p
+       EC_Point *q
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       EC_ADD(c, RETVAL, p, q);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+isub(c, p, q)
+       EC_Curve *c
+       EC_Point *p
+       EC_Point *q
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       EC_SUB(c, RETVAL, p, q);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+idbl(c, p)
+       EC_Curve *c
+       EC_Point *p
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       EC_DBL(c, RETVAL, p);
+       OUTPUT:
+       RETVAL
+
+bool
+icheck(c, p)
+       EC_Curve *c
+       EC_Point *p
+       CODE:
+       RETVAL = EC_CHECK(c, p);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+imul(c, p, x)
+       EC_Curve *c
+       EC_Point *p
+       mp *x
+       CODE:
+       RETVAL = CREATE(EC_Point);
+       EC_CREATE(RETVAL);
+       ec_imul(c, RETVAL, p, x);
+       OUTPUT:
+       RETVAL
+
+EC_Point *
+immul(c, ...)
+       EC_Curve *c
+       PREINIT:
+       ec_mulfactor *v;
+       size_t i, j, n;
+       CODE:
+       if (items < 3 || !(items & 1)) {
+         croak("Usage: Catacomb::EC::Curve::immul"
+               "(c, p_0, x_0, p_1, x_1, ...");
+       }
+       n = (items - 1)/2;
+       v = xmalloc(n * sizeof(mp_expfactor));
+       for (i = 1, j = 0; i < items; i += 2, j++) {
+         v[j].base = *(ec *)ptrfromsv(ST(i), "Catacomb::EC::Point", "p_i");
+         v[j].exp = mp_fromsv(ST(i + 1), "x_i", "Catacomb::MP", 0, 0);
+       }
+       RETVAL = CREATE(RETVAL);
+       EC_CREATE(RETVAL);
+       ec_mmul(c, RETVAL, v, n);
+       xfree(v);
+       OUTPUT:
+       RETVAL
+
+void
+getinfo(me, p)
+       char *p
+       PREINIT:
+       ec_info i;
+       const char *e;
+       EC_Point *pt;
+       PPCODE:
+       if ((e = ec_getinfo(&i, p)) != 0)
+         croak("bad curve spec: %s", e);
+       pt = CREATE(EC_Point);
+       *pt = i.g;
+       XPUSHs(RET(i.c, "Catacomb::EC::Curve"));
+       XPUSHs(RET(pt, "Catacomb::EC::Point"));
+       XPUSHs(RET(i.r, "Catacomb::MP"));
+       XPUSHs(RET(i.h, "Catacomb::MP"));
+