chiark / gitweb /
infra: Add a copy of the GPL.
[catacomb-perl] / group.xs
1 # ---?---
2 #
3 # $Id$
4 #
5 # Abstract groups
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 MODULE = Catacomb PACKAGE = Catacomb::Group PREFIX = group_
29
30 Group *
31 prime(me, p, g, q)
32         SV *me
33         mp *p
34         mp *g
35         mp *q
36         PREINIT:
37         gprime_param gp;
38         CODE:
39         gp.p = p;
40         gp.q = q;
41         gp.g = g;
42         RETVAL = group_prime(&gp);
43         OUTPUT:
44         RETVAL
45
46 Group *
47 binary(me, p, g, q)
48         SV *me
49         mp *p
50         mp *g
51         mp *q
52         PREINIT:
53         gbin_param gb;
54         CODE:
55         gb.p = p;
56         gb.q = q;
57         gb.g = g;
58         RETVAL = group_binary(&gb);
59         OUTPUT:
60         RETVAL
61
62 Group *
63 ec(me, c, g, r, h)
64         SV *me
65         EC_Curve *c
66         ec *g
67         mp *r
68         mp *h
69         PREINIT:
70         ec_info ei;
71         CODE:
72         ei.c = copy_curve(c);
73         EC_CREATE(&ei.g);
74         EC_COPY(&ei.g, g);
75         ei.r = MP_COPY(r);
76         ei.h = MP_COPY(h);
77         RETVAL = group_ec(&ei);
78         OUTPUT:
79         RETVAL
80
81 Group *
82 byname(me, n)
83         SV *me
84         char *n
85         PREINIT:
86         const char *e;
87         CODE:
88         if ((e = group_fromstring(n, &RETVAL)) != 0)
89           croak("bad group name: `%s'", e);
90         OUTPUT:
91         RETVAL
92
93 SV *
94 DESTROY(g)
95         Group *g
96         CODE:
97         G_DESTROYGROUP(g);
98         XSRETURN_YES;
99
100 ge *
101 _i(g)
102         Group *g
103         CODE:
104         RETVAL = G_CREATE(g);
105         G_COPY(g, RETVAL, g->i);
106         OUTPUT:
107         RETVAL
108
109 ge *
110 _g(g)
111         Group *g
112         CODE:
113         RETVAL = G_CREATE(g);
114         G_COPY(g, RETVAL, g->g);
115         OUTPUT:
116         RETVAL
117
118 mp *
119 r(g)
120         Group *g
121         CODE:
122         RETVAL = MP_COPY(g->r);
123         OUTPUT:
124         RETVAL
125
126 mp *
127 h(g)
128         Group *g
129         CODE:
130         RETVAL = MP_COPY(g->h);
131         OUTPUT:
132         RETVAL
133
134 bool
135 group_samep(g, h)
136         Group *g
137         Group *h
138
139 void
140 check(g, rng = &rand_global)
141         Group *g
142         grand *rng
143         PREINIT:
144         const char *e;
145         PPCODE:
146         e = G_CHECK(g, rng);
147         if (!e)
148           XSRETURN_YES;
149         XPUSHs(&PL_sv_undef);
150         if (GIMME_V == G_ARRAY)
151           XPUSHs(sv_2mortal(newSVpv(e, 0)));
152
153 SV *
154 _checkelt(g, x)
155         Group *g
156         ge *x
157         CODE:
158         if (group_check(g, x))
159           XSRETURN_UNDEF;
160         else 
161           XSRETURN_YES;   
162
163 SV *
164 _destroyelement(g, x)
165         Group *g
166         ge *x
167         CODE:
168         G_DESTROY(g, x);
169         XSRETURN_YES;
170
171 bool
172 _identp(g, x)
173         Group *g
174         ge *x
175         CODE:
176         RETVAL = G_IDENTP(g, x);
177         OUTPUT:
178         RETVAL
179
180 SV *
181 get(g)
182         Group *g
183         CODE:
184         RETVAL = info_group(g);
185         OUTPUT:
186         RETVAL
187
188 bool
189 _eq(g, x, y)
190         Group *g
191         ge *x
192         ge *y
193         CODE:
194         RETVAL = G_EQ(g, x, y);
195         OUTPUT:
196         RETVAL
197
198 ge *
199 _mul(g, x, y)
200         Group *g
201         ge *x
202         ge *y
203         CODE:
204         RETVAL = G_CREATE(g);
205         G_MUL(g, RETVAL, x, y);
206         OUTPUT:
207         RETVAL
208
209 ge *
210 _sqr(g, x)
211         Group *g
212         ge *x
213         CODE:
214         RETVAL = G_CREATE(g);
215         G_SQR(g, RETVAL, x);
216         OUTPUT:
217         RETVAL
218
219 ge *
220 _inv(g, x)
221         Group *g
222         ge *x
223         CODE:
224         RETVAL = G_CREATE(g);
225         G_INV(g, RETVAL, x);
226         OUTPUT:
227         RETVAL
228
229 ge *
230 _div(g, x, y)
231         Group *g
232         ge *x
233         ge *y
234         CODE:
235         RETVAL = G_CREATE(g);
236         G_DIV(g, RETVAL, x, y);
237         OUTPUT:
238         RETVAL
239
240 ge *
241 _exp(g, x, n)
242         Group *g
243         ge *x
244         mp *n
245         CODE:
246         RETVAL = G_CREATE(g);
247         G_EXP(g, RETVAL, x, n);
248         OUTPUT:
249         RETVAL
250
251 ge *
252 _mexp(g, ...)
253         Group *g
254         PREINIT:
255         group_expfactor *v;
256         size_t i, j, n;
257         CODE:
258         if (items < 3 || !(items & 1)) {
259           croak("Usage: Catacomb::Group::mexp"
260                 "(g, x_0, n_0, x_1, n_1, ...");
261         }
262         n = (items - 1)/2;
263         v = xmalloc(n * sizeof(group_expfactor));
264         for (i = 1, j = 0; i < items; i += 2, j++) {
265           v[j].base = ptrfromsv(ST(i), "Catacomb::Group::Element", "p_i");
266           v[j].exp = mp_fromsv(ST(i + 1), "x_i", 0, 0);
267         }
268         RETVAL = G_CREATE(g);
269         G_MEXP(g, RETVAL, v, n);
270         xfree(v);
271         OUTPUT:
272         RETVAL
273
274 mp *
275 _toint(g, x)
276         Group *g
277         ge *x
278         CODE:
279         RETVAL = G_TOINT(g, MP_NEW, x);
280         OUTPUT:
281         RETVAL
282
283 ge *
284 _fromint(g, x)
285         Group *g
286         mp *x
287         CODE:
288         RETVAL = G_CREATE(g);
289         if (G_FROMINT(g, RETVAL, x)) {
290           G_DESTROY(g, RETVAL);
291           RETVAL = 0;
292         }
293         OUTPUT:
294         RETVAL
295
296 ec *
297 _toec(g, x)
298         Group *g
299         ge *x
300         CODE:
301         RETVAL = CREATE(ec);
302         EC_CREATE(RETVAL);
303         if (G_TOEC(g, RETVAL, x)) {
304           DESTROY(RETVAL);
305           RETVAL = 0;
306         }
307         OUTPUT:
308         RETVAL
309
310 ge *
311 _fromec(g, x)
312         Group *g
313         ec *x
314         CODE:
315         RETVAL = G_CREATE(g);
316         if (G_FROMEC(g, RETVAL, x)) {
317           G_DESTROY(g, RETVAL);
318           RETVAL = 0;
319         }
320         OUTPUT:
321         RETVAL
322
323 SV *
324 _putbuf(g, x)
325         Group *g
326         ge *x
327         PREINIT:
328         buf b;
329         size_t n = g->noctets + 8; /* Guess */
330         CODE:
331         RETVAL = NEWSV(0, n);
332         buf_init(&b, SvPVX(RETVAL), n);
333         if (G_TOBUF(g, &b, x))
334           croak("unexpected failure in Catacomb::Group::putbuf");
335         SvCUR_set(RETVAL, BLEN(&b));
336         OUTPUT:
337         RETVAL
338
339 void
340 _getbuf(g, s)
341         Group *g
342         SV *s
343         PREINIT:
344         ge *x;
345         buf b;
346         char *q;
347         STRLEN n;
348         CODE:
349         q = SvPV(s, n);
350         buf_init(&b, q, n);
351         x = G_CREATE(g);
352         if (G_FROMBUF(g, &b, x))
353           G_DESTROY(g, x);
354         else {
355           XPUSHs(RET(x, "Catacomb::Group::Element"));
356           if (GIMME_V == G_ARRAY)
357             XPUSHs(sv_2mortal(newSVpvn((char *)BCUR(&b), BLEFT(&b))));
358         }
359
360 SV *
361 _putraw(g, x)
362         Group *g
363         ge *x
364         PREINIT:
365         buf b;
366         size_t n = g->noctets;
367         CODE:
368         RETVAL = NEWSV(0, n);
369         buf_init(&b, SvPVX(RETVAL), n);
370         if (G_TORAW(g, &b, x))
371           croak("unexpected failure in Catacomb::Group::putraw");
372         SvCUR_set(RETVAL, BLEN(&b));
373         OUTPUT:
374         RETVAL
375
376 void
377 _getraw(g, s)
378         Group *g
379         SV *s
380         PREINIT:
381         ge *x;
382         buf b;
383         char *q;
384         STRLEN n;
385         CODE:
386         q = SvPV(s, n);
387         buf_init(&b, q, n);
388         x = G_CREATE(g);
389         if (G_FROMRAW(g, &b, x))
390           G_DESTROY(g, x);
391         else {
392           XPUSHs(RET(x, "Catacomb::Group::Element"));
393           if (GIMME_V == G_ARRAY)
394             XPUSHs(sv_2mortal(newSVpvn((char *)BCUR(&b), BLEFT(&b))));
395         }
396
397 SV *
398 _tostring(g, x)
399         Group *g
400         ge *x
401         CODE:
402         RETVAL = NEWSV(0, 64);
403         if (group_writesv(g, x, RETVAL)) {
404           SvREFCNT_dec(RETVAL);
405           XSRETURN_UNDEF;
406         }
407         OUTPUT:
408         RETVAL  
409
410 void
411 _fromstring(g, s)
412         Group *g
413         SV *s
414         PREINIT:
415         mptext_stringctx ms;
416         STRLEN len;
417         ge *x;
418         PPCODE:
419         ms.buf = SvPV(s, len);
420         ms.lim = ms.buf + len;
421         x = G_CREATE(g);
422         if (G_READ(g, x, &mptext_stringops, &ms))
423           G_DESTROY(g, x);
424         else {
425           XPUSHs(RET(x, "Catacomb::Group::Element"));
426           if (GIMME_V == G_ARRAY)
427             XPUSHs(sv_2mortal(newSVpvn(ms.buf, ms.lim - ms.buf)));
428         }