# ---?--- # # $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 * new(me, x = 0, y = 0, z = 0) SV *me mp *x mp *y mp *z CODE: RETVAL = CREATE(ec); 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 *p CODE: RETVAL = EC_ATINF(p); OUTPUT: RETVAL mp * x(p) ec *p CODE: RETVAL = p->x ? MP_COPY(p->x) : 0; OUTPUT: RETVAL mp * y(p) ec *p CODE: RETVAL = p->y ? MP_COPY(p->y) : 0; OUTPUT: RETVAL mp * z(p) ec *p CODE: RETVAL = p->z ? MP_COPY(p->z) : 0; OUTPUT: RETVAL bool ec_eq(p, q) ec *p ec *q SV * DESTROY(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((char *)BCUR(&b), BLEFT(&b)))); } MODULE = Catacomb PACKAGE = Catacomb::EC::Curve PREFIX = ec_ EC_Curve * prime(me, f, a, b) SV *me Field *f mp *a mp *b CODE: RETVAL = ec_prime(f, a, b); OUTPUT: RETVAL EC_Curve * primeproj(me, f, a, b) SV *me Field *f mp *a mp *b CODE: RETVAL = ec_primeproj(f, a, b); OUTPUT: RETVAL EC_Curve * bin(me, f, a, b) SV *me Field *f gf *a gf *b CODE: RETVAL = ec_bin(f, a, b); OUTPUT: RETVAL EC_Curve * binproj(me, f, a, b) SV *me Field *f gf *a gf *b CODE: RETVAL = ec_binproj(f, a, b); OUTPUT: RETVAL char * name(c) EC_Curve *c CODE: RETVAL = (char *)EC_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 SV * putraw(c, p) EC_Curve *c 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: 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((char *)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; } OUTPUT: RETVAL ec * _rand(c, r = &rand_global) EC_Curve *c grand *r CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); ec_rand(c, RETVAL, r); OUTPUT: RETVAL ec * neg(c, p) EC_Curve *c ec *p CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); ec_neg(c, RETVAL, p); OUTPUT: RETVAL ec * add(c, p, q) EC_Curve *c ec *p ec *q CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); ec_add(c, RETVAL, p, q); OUTPUT: RETVAL ec * sub(c, p, q) EC_Curve *c ec *p ec *q CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); ec_sub(c, RETVAL, p, q); OUTPUT: RETVAL ec * dbl(c, p) EC_Curve *c ec *p CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); ec_dbl(c, RETVAL, p); OUTPUT: RETVAL SV * check(c, p) EC_Curve *c ec *p CODE: if (ec_check(c, p)) XSRETURN_UNDEF; XSRETURN_YES; ec * mul(c, p, x) EC_Curve *c ec *p mp *x CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); ec_mul(c, RETVAL, p, x); OUTPUT: RETVAL ec * in(c, p) EC_Curve *c ec *p CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); EC_IN(c, RETVAL, p); OUTPUT: RETVAL ec * out(c, p) EC_Curve *c ec *p CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); EC_OUT(c, RETVAL, p); OUTPUT: RETVAL ec * fix(c, p) EC_Curve *c ec *p CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); EC_FIX(c, RETVAL, p); OUTPUT: RETVAL ec * ifind(c, x) EC_Curve *c mp *x CODE: RETVAL = CREATE(ec); if (!EC_FIND(c, RETVAL, x)) { DESTROY(RETVAL); RETVAL = 0; } OUTPUT: RETVAL ec * ineg(c, p) EC_Curve *c ec *p CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); EC_NEG(c, RETVAL, p); OUTPUT: RETVAL ec * iadd(c, p, q) EC_Curve *c ec *p ec *q CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); EC_ADD(c, RETVAL, p, q); OUTPUT: RETVAL ec * isub(c, p, q) EC_Curve *c ec *p ec *q CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); EC_SUB(c, RETVAL, p, q); OUTPUT: RETVAL ec * idbl(c, p) EC_Curve *c ec *p CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); EC_DBL(c, RETVAL, p); OUTPUT: RETVAL bool icheck(c, p) EC_Curve *c ec *p CODE: RETVAL = EC_CHECK(c, p); OUTPUT: RETVAL ec * imul(c, p, x) EC_Curve *c ec *p mp *x CODE: RETVAL = CREATE(ec); EC_CREATE(RETVAL); ec_imul(c, RETVAL, p, x); OUTPUT: RETVAL ec * 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 = *ecpt(ST(i), "p_i"); v[j].exp = mp_fromsv(ST(i + 1), "x_i", 0, 0); } RETVAL = CREATE(RETVAL); EC_CREATE(RETVAL); ec_mmul(c, RETVAL, v, n); xfree(v); OUTPUT: RETVAL void _getinfo(me, p) SV *me char *p PREINIT: ec_info i; const char *e; ec *pt; PPCODE: if ((e = ec_getinfo(&i, p)) != 0) croak("bad curve spec: %s", e); 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