chiark / gitweb /
e5b49f07a114229f413144e46468f7d9dd0841bc
[catacomb-perl] / utils.c
1 /* -*-c-*-
2  *
3  * $Id$
4  *
5  * Utilities for Catacomb/Perl
6  *
7  * (c) 2001 Straylight/Edgeware
8  */
9
10 /*----- Licensing notice --------------------------------------------------* 
11  *
12  * This file is part of the Perl interface to Catacomb.
13  *
14  * Catacomb/Perl is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 2 of the License, or
17  * (at your option) any later version.
18  * 
19  * Catacomb/Perl is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with Catacomb/Perl; if not, write to the Free Software Foundation,
26  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27  */
28
29 /*----- Header files ------------------------------------------------------*/
30
31 #include "catacomb-perl.h"
32 #include <catacomb/ec-guts.h>
33 #include <catacomb/group-guts.h>
34 #include <catacomb/field-guts.h>
35
36 /*----- Main code ---------------------------------------------------------*/
37
38 U32 findconst(const struct consttab *cc, const char *pkg, const char *name)
39 {
40   const char *p;
41   if ((p = strrchr(name, ':')) != 0)
42     name = p + 1;
43   while (cc->name) {
44     if (strcmp(cc->name, name) == 0)
45       return (cc->val);
46     cc++;
47   }
48   croak("unknown %s constant `%s'", pkg, name);
49 }
50
51 void ptrtosv(SV **sv, void *p, const char *type)
52 {
53   if (p)
54     sv_setref_pv(*sv, type, (void *)p);
55   else
56     *sv = &PL_sv_undef;
57 }
58
59 void *ptrfromsv(SV *sv, const char *type, const char *what, ...)
60 {
61   if (!sv_derived_from(sv, type)) {
62     va_list ap;
63     SV *t = sv_newmortal();
64     va_start(ap, what);
65     sv_vsetpvfn(t, what, strlen(what), &ap, 0, 0, 0);      
66     croak("%s is not of type %s", SvPVX(t), type);
67   }
68   return (void *)SvIV((SV *)SvRV(sv));
69 }
70
71 /*----- Reconstructing various objects ------------------------------------*/
72
73 /* --- Somewhat unpleasant, really --- */
74
75 field *copy_field(field *f)
76 {
77   if (strcmp(F_NAME(f), "prime") == 0)
78     f = field_prime(f->m);
79   else if (strcmp(F_NAME(f), "niceprime") == 0)
80     f = field_niceprime(f->m);
81   else if (strcmp(F_NAME(f), "binpoly") == 0)
82     f = field_binpoly(f->m);
83   else if (strcmp(F_NAME(f), "binnorm") == 0) {
84     fctx_binnorm *fc = (fctx_binnorm *)f;
85     f = field_binnorm(f->m, fc->ntop.r[fc->ntop.n - 1]);
86   } else
87     f = 0;
88   return (f);
89 }
90
91 ec_curve *copy_curve(ec_curve *c)
92 {
93   field *f;
94   mp *a, *b;
95
96   if ((f = copy_field(c->f)) == 0)
97     return (0);
98   a = F_OUT(f, MP_NEW, c->a);
99   b = F_OUT(f, MP_NEW, c->b);
100   if (strcmp(EC_NAME(c), "prime") == 0)
101     c = ec_prime(f, a, b);
102   else if (strcmp(EC_NAME(c), "primeproj") == 0)
103     c = ec_primeproj(f, a, b);
104   if (strcmp(EC_NAME(c), "bin") == 0)
105     c = ec_bin(f, a, b);
106   else if (strcmp(EC_NAME(c), "binproj") == 0)
107     c = ec_binproj(f, a, b);
108   else
109     c = 0;
110   MP_DROP(a);
111   MP_DROP(b);
112   if (!c) F_DESTROY(f);
113   return (c);
114 }
115
116 group *copy_group(group *g)
117 {
118   if (strcmp(G_NAME(g), "prime") == 0) {
119     gctx_prime *gc = (gctx_prime *)g;
120     gprime_param gp;
121     gp.g = G_TOINT(g, MP_NEW, g->g);
122     gp.p = gc->mm.m;
123     gp.q = gc->g.r;
124     g = group_prime(&gp);
125     MP_DROP(gp.g);
126   } else if (strcmp(G_NAME(g), "ec") == 0) {
127     gctx_ec *gc = (gctx_ec *)g;
128     ec_info ei;
129     if ((ei.c = copy_curve(gc->ei.c)) == 0)
130       return (0);
131     EC_CREATE(&ei.g);
132     EC_COPY(&ei.g, &gc->ei.g);
133     ei.r = MP_COPY(gc->ei.r);
134     ei.h = MP_COPY(gc->ei.h);
135     g = group_ec(&ei);
136   } else
137     g = 0;
138   return (g);
139 }
140
141 /*----- That's all, folks -------------------------------------------------*/