# ---?--- # # $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((char *)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((char *)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))); }