Much wider support for Catacomb in all its glory.
[catacomb-perl] / ec.xs
diff --git a/ec.xs b/ec.xs
index f546ab3..83d1f72 100644 (file)
--- a/ec.xs
+++ b/ec.xs
 
 MODULE = Catacomb PACKAGE = Catacomb::EC::Point PREFIX = ec_
 
-EC_Point *
-new(x = 0, y = 0, z = 0)
+ec *
+new(me, x = 0, y = 0, z = 0)
+       SV *me
        mp *x
        mp *y
        mp *z
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        if (x && y) {
          RETVAL->x = MP_COPY(x);
@@ -46,7 +47,7 @@ new(x = 0, y = 0, z = 0)
 
 bool
 atinfp(p)
-       EC_Point *p
+       ec *p
        CODE:
        RETVAL = EC_ATINF(p);
        OUTPUT:
@@ -54,7 +55,7 @@ atinfp(p)
 
 mp *
 x(p)
-       EC_Point *p
+       ec *p
        CODE:
        RETVAL = p->x ? MP_COPY(p->x) : 0;
        OUTPUT:
@@ -62,7 +63,7 @@ x(p)
        
 mp *
 y(p)
-       EC_Point *p
+       ec *p
        CODE:
        RETVAL = p->y ? MP_COPY(p->y) : 0;
        OUTPUT:
@@ -70,7 +71,7 @@ y(p)
        
 mp *
 z(p)
-       EC_Point *p
+       ec *p
        CODE:
        RETVAL = p->z ? MP_COPY(p->z) : 0;
        OUTPUT:
@@ -78,54 +79,98 @@ z(p)
 
 bool
 ec_eq(p, q)
-       EC_Point *p
-       EC_Point *q
+       ec *p
+       ec *q
 
 SV *
 DESTROY(p)
-       EC_Point *p
+       ec *p
        CODE:
        EC_DESTROY(p);
        DESTROY(p);
        XSRETURN_YES;
 
+SV *
+put(p)
+       ec *p
+       PREINIT:
+       buf b;
+       size_t n = EC_ATINF(p) ? 2 : 4 + mp_octets(p->x) + mp_octets(p->y);
+       CODE:
+       RETVAL = NEWSV(0, n);
+       buf_init(&b, SvPVX(RETVAL), n);
+       if (buf_putec(&b, p))
+         croak("unexpected failure in Catacomb::EC::Point::put");
+       SvCUR_set(RETVAL, BLEN(&b));
+       OUTPUT:
+       RETVAL
+
+void
+get(s)
+       SV *s
+       PREINIT:
+       ec *p;
+       buf b;
+       char *q;
+       STRLEN n;
+       CODE:
+       q = SvPV(s, n);
+       buf_init(&b, q, n);
+       p = CREATE(ec);
+       EC_CREATE(p);
+       if (buf_getec(&b, p))
+         DESTROY(p);
+       else {
+         XPUSHs(RET(p, "Catacomb::EC::Point"));
+         if (GIMME_V == G_ARRAY)
+           XPUSHs(sv_2mortal(newSVpvn(BCUR(&b), BLEFT(&b))));
+       }
+
 MODULE = Catacomb PACKAGE = Catacomb::EC::Curve PREFIX = ec_
 
 EC_Curve *
-ec_prime(me, f, a, b)
+prime(me, f, a, b)
        SV *me
        Field *f
        mp *a
        mp *b
-       C_ARGS:
-       f, a, b
+       CODE:
+       RETVAL = ec_prime(f, a, b);
+       OUTPUT:
+       RETVAL
 
 EC_Curve *
-ec_primeproj(me, f, a, b)
+primeproj(me, f, a, b)
        SV *me
        Field *f
        mp *a
        mp *b
-       C_ARGS:
-       f, a, b
+       CODE:
+       RETVAL = ec_primeproj(f, a, b);
+       OUTPUT:
+       RETVAL
 
 EC_Curve *
-ec_bin(me, f, a, b)
+bin(me, f, a, b)
        SV *me
        Field *f
        gf *a
        gf *b
-       C_ARGS:
-       f, a, b
+       CODE:
+       RETVAL = ec_bin(f, a, b);
+       OUTPUT:
+       RETVAL
 
 EC_Curve *
-ec_binproj(me, f, a, b)
+binproj(me, f, a, b)
        SV *me
        Field *f
        gf *a
        gf *b
-       C_ARGS:
-       f, a, b
+       CODE:
+       RETVAL = ec_binproj(f, a, b);
+       OUTPUT:
+       RETVAL
 
 char *
 name(c)
@@ -135,17 +180,88 @@ name(c)
        OUTPUT: 
        RETVAL
 
+mp *
+_a(c)
+       EC_Curve *c
+       CODE:
+       RETVAL = F_OUT(c->f, MP_NEW, c->a);
+       OUTPUT:
+       RETVAL
+
+mp *
+_b(c)
+       EC_Curve *c
+       CODE:
+       RETVAL = F_OUT(c->f, MP_NEW, c->a);
+       OUTPUT:
+       RETVAL
+
+Field *
+field(c)
+       EC_Curve *c
+       CODE:
+       RETVAL = copy_field(c->f);
+       OUTPUT:
+       RETVAL
+
+SV *
+get(c)
+       EC_Curve *c
+       CODE:
+       RETVAL = info_curve(c);
+       OUTPUT:
+       RETVAL
+
 bool
 ec_samep(me, c)
        EC_Curve *me
        EC_Curve *c
 
-EC_Point *
-find(c, x)
+SV *
+putraw(c, p)
        EC_Curve *c
-       mp *x
+       ec *p
+       PREINIT:
+       buf b;
+       size_t n = c->f->noctets * 2 + 1;
+       CODE:
+       RETVAL = NEWSV(0, n);
+       buf_init(&b, SvPVX(RETVAL), n);
+       if (ec_putraw(c, &b, p))
+         croak("unexpected failure in Catacomb::EC::Curve::putraw");
+       SvCUR_set(RETVAL, BLEN(&b));
+       OUTPUT:
+       RETVAL
+
+void
+_getraw(c, s)
+       EC_Curve *c
+       SV *s
+       PREINIT:
+       ec *p;
+       buf b;
+       char *q;
+       STRLEN n;
        CODE:
-       RETVAL = CREATE(EC_Point);
+       q = SvPV(s, n);
+       buf_init(&b, q, n);
+       p = CREATE(ec);
+       EC_CREATE(p);
+       if (ec_getraw(c, &b, &p))
+         DESTROY(p);
+       else {
+         XPUSHs(RET(p, "Catacomb::EC::Point"));
+         if (GIMME_V == G_ARRAY)
+           XPUSHs(sv_2mortal(newSVpvn(BCUR(&b), BLEFT(&b))));
+       }
+
+ec *
+_find(c, x)
+       EC_Curve *c
+       fe *x
+       CODE:
+       RETVAL = CREATE(ec);
+       EC_CREATE(RETVAL);
        if (!ec_find(c, RETVAL, x)) {
          DESTROY(RETVAL);
          RETVAL = 0;
@@ -153,142 +269,123 @@ find(c, x)
        OUTPUT:
        RETVAL
 
-EC_Point *
-rand(c, r = &rand_global)
+ec *
+_rand(c, r = &rand_global)
        EC_Curve *c
        grand *r
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
+       EC_CREATE(RETVAL);
        ec_rand(c, RETVAL, r);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 neg(c, p)
        EC_Curve *c
-       EC_Point *p
+       ec *p
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        ec_neg(c, RETVAL, p);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 add(c, p, q)
        EC_Curve *c
-       EC_Point *p
-       EC_Point *q
+       ec *p
+       ec *q
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        ec_add(c, RETVAL, p, q);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 sub(c, p, q)
        EC_Curve *c
-       EC_Point *p
-       EC_Point *q
+       ec *p
+       ec *q
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        ec_sub(c, RETVAL, p, q);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 dbl(c, p)
        EC_Curve *c
-       EC_Point *p
+       ec *p
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        ec_dbl(c, RETVAL, p);
        OUTPUT:
        RETVAL
 
-bool
-ec_check(c, p)
+SV *
+check(c, p)
        EC_Curve *c
-       EC_Point *p
+       ec *p
+       CODE:
+       if (ec_check(c, p))
+         XSRETURN_UNDEF;
+       XSRETURN_YES;
 
-EC_Point *
+ec *
 mul(c, p, x)
        EC_Curve *c
-       EC_Point *p
+       ec *p
        mp *x
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        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 *
+ec *
 in(c, p)
        EC_Curve *c
-       EC_Point *p
+       ec *p
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        EC_IN(c, RETVAL, p);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 out(c, p)
        EC_Curve *c
-       EC_Point *p
+       ec *p
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        EC_OUT(c, RETVAL, p);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 fix(c, p)
        EC_Curve *c
-       EC_Point *p
+       ec *p
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        EC_FIX(c, RETVAL, p);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 ifind(c, x)
        EC_Curve *c
        mp *x
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        if (!EC_FIND(c, RETVAL, x)) {
          DESTROY(RETVAL);
          RETVAL = 0;
@@ -296,47 +393,47 @@ ifind(c, x)
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 ineg(c, p)
        EC_Curve *c
-       EC_Point *p
+       ec *p
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        EC_NEG(c, RETVAL, p);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 iadd(c, p, q)
        EC_Curve *c
-       EC_Point *p
-       EC_Point *q
+       ec *p
+       ec *q
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        EC_ADD(c, RETVAL, p, q);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 isub(c, p, q)
        EC_Curve *c
-       EC_Point *p
-       EC_Point *q
+       ec *p
+       ec *q
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        EC_SUB(c, RETVAL, p, q);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 idbl(c, p)
        EC_Curve *c
-       EC_Point *p
+       ec *p
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        EC_DBL(c, RETVAL, p);
        OUTPUT:
@@ -345,25 +442,25 @@ idbl(c, p)
 bool
 icheck(c, p)
        EC_Curve *c
-       EC_Point *p
+       ec *p
        CODE:
        RETVAL = EC_CHECK(c, p);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 imul(c, p, x)
        EC_Curve *c
-       EC_Point *p
+       ec *p
        mp *x
        CODE:
-       RETVAL = CREATE(EC_Point);
+       RETVAL = CREATE(ec);
        EC_CREATE(RETVAL);
        ec_imul(c, RETVAL, p, x);
        OUTPUT:
        RETVAL
 
-EC_Point *
+ec *
 immul(c, ...)
        EC_Curve *c
        PREINIT:
@@ -377,8 +474,8 @@ immul(c, ...)
        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);
+         v[j].base = *ecpt(ST(i), "p_i");
+         v[j].exp = mp_fromsv(ST(i + 1), "x_i", 0, 0);
        }
        RETVAL = CREATE(RETVAL);
        EC_CREATE(RETVAL);
@@ -388,19 +485,37 @@ immul(c, ...)
        RETVAL
 
 void
-getinfo(me, p)
+_getinfo(me, p)
+       SV *me
        char *p
        PREINIT:
        ec_info i;
        const char *e;
-       EC_Point *pt;
+       ec *pt;
        PPCODE:
        if ((e = ec_getinfo(&i, p)) != 0)
          croak("bad curve spec: %s", e);
-       pt = CREATE(EC_Point);
+       pt = CREATE(ec);
        *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"));
 
+const char *
+checkinfo(c, g, r, h, rng = &rand_global)
+       EC_Curve *c
+       ec *g
+       mp *r
+       mp *h
+       grand *rng
+       PREINIT:
+       ec_info ei;
+       CODE:
+       ei.c = c;
+       ei.g = *g;
+       ei.r = r;
+       ei.h = h;
+       RETVAL = ec_checkinfo(&ei, rng);
+       OUTPUT:
+       RETVAL