X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-perl/blobdiff_plain/f9952aec1cf6c64a5681308eea817b6113a37433..fcd15e0b7a3d0f0ca2f30953573f8d1f6b8e8bd2:/group.xs diff --git a/group.xs b/group.xs new file mode 100644 index 0000000..51af11c --- /dev/null +++ b/group.xs @@ -0,0 +1,428 @@ +# ---?--- +# +# $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))); + }