--- /dev/null
+# ---?---
+#
+# $Id$
+#
+# Abstract groups
+#
+# (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::Group PREFIX = group_
+
+Group *
+prime(me, p, g, q)
+ SV *me
+ mp *p
+ mp *g
+ mp *q
+ PREINIT:
+ gprime_param gp;
+ CODE:
+ gp.p = p;
+ gp.q = q;
+ gp.g = g;
+ RETVAL = group_prime(&gp);
+ OUTPUT:
+ RETVAL
+
+Group *
+binary(me, p, g, q)
+ SV *me
+ mp *p
+ mp *g
+ mp *q
+ PREINIT:
+ gbin_param gb;
+ CODE:
+ gb.p = p;
+ gb.q = q;
+ gb.g = g;
+ RETVAL = group_binary(&gb);
+ OUTPUT:
+ RETVAL
+
+Group *
+ec(me, c, g, r, h)
+ SV *me
+ EC_Curve *c
+ ec *g
+ mp *r
+ mp *h
+ PREINIT:
+ ec_info ei;
+ CODE:
+ ei.c = copy_curve(c);
+ EC_CREATE(&ei.g);
+ EC_COPY(&ei.g, g);
+ ei.r = MP_COPY(r);
+ ei.h = MP_COPY(h);
+ RETVAL = group_ec(&ei);
+ OUTPUT:
+ RETVAL
+
+Group *
+byname(me, n)
+ SV *me
+ char *n
+ PREINIT:
+ const char *e;
+ CODE:
+ if ((e = group_fromstring(n, &RETVAL)) != 0)
+ croak("bad group name: `%s'", e);
+ OUTPUT:
+ RETVAL
+
+SV *
+DESTROY(g)
+ Group *g
+ CODE:
+ G_DESTROYGROUP(g);
+ XSRETURN_YES;
+
+ge *
+_i(g)
+ Group *g
+ CODE:
+ RETVAL = G_CREATE(g);
+ G_COPY(g, RETVAL, g->i);
+ OUTPUT:
+ RETVAL
+
+ge *
+_g(g)
+ Group *g
+ CODE:
+ RETVAL = G_CREATE(g);
+ G_COPY(g, RETVAL, g->g);
+ OUTPUT:
+ RETVAL
+
+mp *
+r(g)
+ Group *g
+ CODE:
+ RETVAL = MP_COPY(g->r);
+ OUTPUT:
+ RETVAL
+
+mp *
+h(g)
+ Group *g
+ CODE:
+ RETVAL = MP_COPY(g->h);
+ OUTPUT:
+ RETVAL
+
+bool
+group_samep(g, h)
+ Group *g
+ Group *h
+
+void
+check(g, rng = &rand_global)
+ Group *g
+ grand *rng
+ PREINIT:
+ const char *e;
+ PPCODE:
+ e = G_CHECK(g, rng);
+ if (!e)
+ XSRETURN_YES;
+ XPUSHs(&PL_sv_undef);
+ if (GIMME_V == G_ARRAY)
+ XPUSHs(sv_2mortal(newSVpv(e, 0)));
+
+SV *
+_checkelt(g, x)
+ Group *g
+ ge *x
+ CODE:
+ if (group_check(g, x))
+ XSRETURN_UNDEF;
+ else
+ XSRETURN_YES;
+
+SV *
+_destroyelement(g, x)
+ Group *g
+ ge *x
+ CODE:
+ G_DESTROY(g, x);
+ XSRETURN_YES;
+
+bool
+_identp(g, x)
+ Group *g
+ ge *x
+ CODE:
+ RETVAL = G_IDENTP(g, x);
+ OUTPUT:
+ RETVAL
+
+SV *
+get(g)
+ Group *g
+ CODE:
+ RETVAL = info_group(g);
+ OUTPUT:
+ RETVAL
+
+bool
+_eq(g, x, y)
+ Group *g
+ ge *x
+ ge *y
+ CODE:
+ RETVAL = G_EQ(g, x, y);
+ OUTPUT:
+ RETVAL
+
+ge *
+_mul(g, x, y)
+ Group *g
+ ge *x
+ ge *y
+ CODE:
+ RETVAL = G_CREATE(g);
+ G_MUL(g, RETVAL, x, y);
+ OUTPUT:
+ RETVAL
+
+ge *
+_sqr(g, x)
+ Group *g
+ ge *x
+ CODE:
+ RETVAL = G_CREATE(g);
+ G_SQR(g, RETVAL, x);
+ OUTPUT:
+ RETVAL
+
+ge *
+_inv(g, x)
+ Group *g
+ ge *x
+ CODE:
+ RETVAL = G_CREATE(g);
+ G_INV(g, RETVAL, x);
+ OUTPUT:
+ RETVAL
+
+ge *
+_div(g, x, y)
+ Group *g
+ ge *x
+ ge *y
+ CODE:
+ RETVAL = G_CREATE(g);
+ G_DIV(g, RETVAL, x, y);
+ OUTPUT:
+ RETVAL
+
+ge *
+_exp(g, x, n)
+ Group *g
+ ge *x
+ mp *n
+ CODE:
+ RETVAL = G_CREATE(g);
+ G_EXP(g, RETVAL, x, n);
+ OUTPUT:
+ RETVAL
+
+ge *
+_mexp(g, ...)
+ Group *g
+ PREINIT:
+ group_expfactor *v;
+ size_t i, j, n;
+ CODE:
+ if (items < 3 || !(items & 1)) {
+ croak("Usage: Catacomb::Group::mexp"
+ "(g, x_0, n_0, x_1, n_1, ...");
+ }
+ n = (items - 1)/2;
+ v = xmalloc(n * sizeof(group_expfactor));
+ for (i = 1, j = 0; i < items; i += 2, j++) {
+ v[j].base = ptrfromsv(ST(i), "Catacomb::Group::Element", "p_i");
+ v[j].exp = mp_fromsv(ST(i + 1), "x_i", 0, 0);
+ }
+ RETVAL = G_CREATE(g);
+ G_MEXP(g, RETVAL, v, n);
+ xfree(v);
+ OUTPUT:
+ RETVAL
+
+mp *
+_toint(g, x)
+ Group *g
+ ge *x
+ CODE:
+ RETVAL = G_TOINT(g, MP_NEW, x);
+ OUTPUT:
+ RETVAL
+
+ge *
+_fromint(g, x)
+ Group *g
+ mp *x
+ CODE:
+ RETVAL = G_CREATE(g);
+ if (G_FROMINT(g, RETVAL, x)) {
+ G_DESTROY(g, RETVAL);
+ RETVAL = 0;
+ }
+ OUTPUT:
+ RETVAL
+
+ec *
+_toec(g, x)
+ Group *g
+ ge *x
+ CODE:
+ RETVAL = CREATE(ec);
+ EC_CREATE(RETVAL);
+ if (G_TOEC(g, RETVAL, x)) {
+ DESTROY(RETVAL);
+ RETVAL = 0;
+ }
+ OUTPUT:
+ RETVAL
+
+ge *
+_fromec(g, x)
+ Group *g
+ ec *x
+ CODE:
+ RETVAL = G_CREATE(g);
+ if (G_FROMEC(g, RETVAL, x)) {
+ G_DESTROY(g, RETVAL);
+ RETVAL = 0;
+ }
+ OUTPUT:
+ RETVAL
+
+SV *
+_putbuf(g, x)
+ Group *g
+ ge *x
+ PREINIT:
+ buf b;
+ size_t n = g->noctets + 8; /* Guess */
+ CODE:
+ RETVAL = NEWSV(0, n);
+ buf_init(&b, SvPVX(RETVAL), n);
+ if (G_TOBUF(g, &b, x))
+ croak("unexpected failure in Catacomb::Group::putbuf");
+ SvCUR_set(RETVAL, BLEN(&b));
+ OUTPUT:
+ RETVAL
+
+void
+_getbuf(g, s)
+ Group *g
+ SV *s
+ PREINIT:
+ ge *x;
+ buf b;
+ char *q;
+ STRLEN n;
+ CODE:
+ q = SvPV(s, n);
+ buf_init(&b, q, n);
+ x = G_CREATE(g);
+ if (G_FROMBUF(g, &b, x))
+ G_DESTROY(g, x);
+ else {
+ XPUSHs(RET(x, "Catacomb::Group::Element"));
+ if (GIMME_V == G_ARRAY)
+ XPUSHs(sv_2mortal(newSVpvn(BCUR(&b), BLEFT(&b))));
+ }
+
+SV *
+_putraw(g, x)
+ Group *g
+ ge *x
+ PREINIT:
+ buf b;
+ size_t n = g->noctets;
+ CODE:
+ RETVAL = NEWSV(0, n);
+ buf_init(&b, SvPVX(RETVAL), n);
+ if (G_TORAW(g, &b, x))
+ croak("unexpected failure in Catacomb::Group::putraw");
+ SvCUR_set(RETVAL, BLEN(&b));
+ OUTPUT:
+ RETVAL
+
+void
+_getraw(g, s)
+ Group *g
+ SV *s
+ PREINIT:
+ ge *x;
+ buf b;
+ char *q;
+ STRLEN n;
+ CODE:
+ q = SvPV(s, n);
+ buf_init(&b, q, n);
+ x = G_CREATE(g);
+ if (G_FROMRAW(g, &b, x))
+ G_DESTROY(g, x);
+ else {
+ XPUSHs(RET(x, "Catacomb::Group::Element"));
+ if (GIMME_V == G_ARRAY)
+ XPUSHs(sv_2mortal(newSVpvn(BCUR(&b), BLEFT(&b))));
+ }
+
+SV *
+_tostring(g, x)
+ Group *g
+ ge *x
+ CODE:
+ RETVAL = NEWSV(0, 64);
+ if (group_writesv(g, x, RETVAL)) {
+ SvREFCNT_dec(RETVAL);
+ XSRETURN_UNDEF;
+ }
+ OUTPUT:
+ RETVAL
+
+void
+_fromstring(g, s)
+ Group *g
+ SV *s
+ PREINIT:
+ mptext_stringctx ms;
+ STRLEN len;
+ ge *x;
+ PPCODE:
+ ms.buf = SvPV(s, len);
+ ms.lim = ms.buf + len;
+ x = G_CREATE(g);
+ if (G_READ(g, x, &mptext_stringops, &ms))
+ G_DESTROY(g, x);
+ else {
+ XPUSHs(RET(x, "Catacomb::Group::Element"));
+ if (GIMME_V == G_ARRAY)
+ XPUSHs(sv_2mortal(newSVpvn(ms.buf, ms.lim - ms.buf)));
+ }