X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-perl/blobdiff_plain/a24b5cfdde0be71a5bb2b85d94be3b93c7719e2a..f9952aec1cf6c64a5681308eea817b6113a37433:/utils.c diff --git a/utils.c b/utils.c index 1e72294..e5b49f0 100644 --- a/utils.c +++ b/utils.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: utils.c,v 1.2 2004/04/08 01:36:21 mdw Exp $ + * $Id$ * * Utilities for Catacomb/Perl * @@ -29,6 +29,9 @@ /*----- Header files ------------------------------------------------------*/ #include "catacomb-perl.h" +#include +#include +#include /*----- Main code ---------------------------------------------------------*/ @@ -45,4 +48,94 @@ U32 findconst(const struct consttab *cc, const char *pkg, const char *name) croak("unknown %s constant `%s'", pkg, name); } +void ptrtosv(SV **sv, void *p, const char *type) +{ + if (p) + sv_setref_pv(*sv, type, (void *)p); + else + *sv = &PL_sv_undef; +} + +void *ptrfromsv(SV *sv, const char *type, const char *what, ...) +{ + if (!sv_derived_from(sv, type)) { + va_list ap; + SV *t = sv_newmortal(); + va_start(ap, what); + sv_vsetpvfn(t, what, strlen(what), &ap, 0, 0, 0); + croak("%s is not of type %s", SvPVX(t), type); + } + return (void *)SvIV((SV *)SvRV(sv)); +} + +/*----- Reconstructing various objects ------------------------------------*/ + +/* --- Somewhat unpleasant, really --- */ + +field *copy_field(field *f) +{ + if (strcmp(F_NAME(f), "prime") == 0) + f = field_prime(f->m); + else if (strcmp(F_NAME(f), "niceprime") == 0) + f = field_niceprime(f->m); + else if (strcmp(F_NAME(f), "binpoly") == 0) + f = field_binpoly(f->m); + else if (strcmp(F_NAME(f), "binnorm") == 0) { + fctx_binnorm *fc = (fctx_binnorm *)f; + f = field_binnorm(f->m, fc->ntop.r[fc->ntop.n - 1]); + } else + f = 0; + return (f); +} + +ec_curve *copy_curve(ec_curve *c) +{ + field *f; + mp *a, *b; + + if ((f = copy_field(c->f)) == 0) + return (0); + a = F_OUT(f, MP_NEW, c->a); + b = F_OUT(f, MP_NEW, c->b); + if (strcmp(EC_NAME(c), "prime") == 0) + c = ec_prime(f, a, b); + else if (strcmp(EC_NAME(c), "primeproj") == 0) + c = ec_primeproj(f, a, b); + if (strcmp(EC_NAME(c), "bin") == 0) + c = ec_bin(f, a, b); + else if (strcmp(EC_NAME(c), "binproj") == 0) + c = ec_binproj(f, a, b); + else + c = 0; + MP_DROP(a); + MP_DROP(b); + if (!c) F_DESTROY(f); + return (c); +} + +group *copy_group(group *g) +{ + if (strcmp(G_NAME(g), "prime") == 0) { + gctx_prime *gc = (gctx_prime *)g; + gprime_param gp; + gp.g = G_TOINT(g, MP_NEW, g->g); + gp.p = gc->mm.m; + gp.q = gc->g.r; + g = group_prime(&gp); + MP_DROP(gp.g); + } else if (strcmp(G_NAME(g), "ec") == 0) { + gctx_ec *gc = (gctx_ec *)g; + ec_info ei; + if ((ei.c = copy_curve(gc->ei.c)) == 0) + return (0); + EC_CREATE(&ei.g); + EC_COPY(&ei.g, &gc->ei.g); + ei.r = MP_COPY(gc->ei.r); + ei.h = MP_COPY(gc->ei.h); + g = group_ec(&ei); + } else + g = 0; + return (g); +} + /*----- That's all, folks -------------------------------------------------*/