chiark / gitweb /
83d1f721f94248b83f353b239780f9f1bd7996dd
[catacomb-perl] / ec.xs
1 # ---?---
2 #
3 # $Id$
4 #
5 # Elliptic curves
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::EC::Point PREFIX = ec_
29
30 ec *
31 new(me, x = 0, y = 0, z = 0)
32         SV *me
33         mp *x
34         mp *y
35         mp *z
36         CODE:
37         RETVAL = CREATE(ec);
38         EC_CREATE(RETVAL);
39         if (x && y) {
40           RETVAL->x = MP_COPY(x);
41           RETVAL->y = MP_COPY(y);
42           if (z)
43             RETVAL->z = MP_COPY(z);
44         }
45         OUTPUT: 
46         RETVAL
47
48 bool
49 atinfp(p)
50         ec *p
51         CODE:
52         RETVAL = EC_ATINF(p);
53         OUTPUT:
54         RETVAL
55
56 mp *
57 x(p)
58         ec *p
59         CODE:
60         RETVAL = p->x ? MP_COPY(p->x) : 0;
61         OUTPUT:
62         RETVAL
63         
64 mp *
65 y(p)
66         ec *p
67         CODE:
68         RETVAL = p->y ? MP_COPY(p->y) : 0;
69         OUTPUT:
70         RETVAL
71         
72 mp *
73 z(p)
74         ec *p
75         CODE:
76         RETVAL = p->z ? MP_COPY(p->z) : 0;
77         OUTPUT:
78         RETVAL
79
80 bool
81 ec_eq(p, q)
82         ec *p
83         ec *q
84
85 SV *
86 DESTROY(p)
87         ec *p
88         CODE:
89         EC_DESTROY(p);
90         DESTROY(p);
91         XSRETURN_YES;
92
93 SV *
94 put(p)
95         ec *p
96         PREINIT:
97         buf b;
98         size_t n = EC_ATINF(p) ? 2 : 4 + mp_octets(p->x) + mp_octets(p->y);
99         CODE:
100         RETVAL = NEWSV(0, n);
101         buf_init(&b, SvPVX(RETVAL), n);
102         if (buf_putec(&b, p))
103           croak("unexpected failure in Catacomb::EC::Point::put");
104         SvCUR_set(RETVAL, BLEN(&b));
105         OUTPUT:
106         RETVAL
107
108 void
109 get(s)
110         SV *s
111         PREINIT:
112         ec *p;
113         buf b;
114         char *q;
115         STRLEN n;
116         CODE:
117         q = SvPV(s, n);
118         buf_init(&b, q, n);
119         p = CREATE(ec);
120         EC_CREATE(p);
121         if (buf_getec(&b, p))
122           DESTROY(p);
123         else {
124           XPUSHs(RET(p, "Catacomb::EC::Point"));
125           if (GIMME_V == G_ARRAY)
126             XPUSHs(sv_2mortal(newSVpvn(BCUR(&b), BLEFT(&b))));
127         }
128
129 MODULE = Catacomb PACKAGE = Catacomb::EC::Curve PREFIX = ec_
130
131 EC_Curve *
132 prime(me, f, a, b)
133         SV *me
134         Field *f
135         mp *a
136         mp *b
137         CODE:
138         RETVAL = ec_prime(f, a, b);
139         OUTPUT:
140         RETVAL
141
142 EC_Curve *
143 primeproj(me, f, a, b)
144         SV *me
145         Field *f
146         mp *a
147         mp *b
148         CODE:
149         RETVAL = ec_primeproj(f, a, b);
150         OUTPUT:
151         RETVAL
152
153 EC_Curve *
154 bin(me, f, a, b)
155         SV *me
156         Field *f
157         gf *a
158         gf *b
159         CODE:
160         RETVAL = ec_bin(f, a, b);
161         OUTPUT:
162         RETVAL
163
164 EC_Curve *
165 binproj(me, f, a, b)
166         SV *me
167         Field *f
168         gf *a
169         gf *b
170         CODE:
171         RETVAL = ec_binproj(f, a, b);
172         OUTPUT:
173         RETVAL
174
175 char *
176 name(c)
177         EC_Curve *c
178         CODE:
179         RETVAL = (char *)EC_NAME(c);
180         OUTPUT: 
181         RETVAL
182
183 mp *
184 _a(c)
185         EC_Curve *c
186         CODE:
187         RETVAL = F_OUT(c->f, MP_NEW, c->a);
188         OUTPUT:
189         RETVAL
190
191 mp *
192 _b(c)
193         EC_Curve *c
194         CODE:
195         RETVAL = F_OUT(c->f, MP_NEW, c->a);
196         OUTPUT:
197         RETVAL
198
199 Field *
200 field(c)
201         EC_Curve *c
202         CODE:
203         RETVAL = copy_field(c->f);
204         OUTPUT:
205         RETVAL
206
207 SV *
208 get(c)
209         EC_Curve *c
210         CODE:
211         RETVAL = info_curve(c);
212         OUTPUT:
213         RETVAL
214
215 bool
216 ec_samep(me, c)
217         EC_Curve *me
218         EC_Curve *c
219
220 SV *
221 putraw(c, p)
222         EC_Curve *c
223         ec *p
224         PREINIT:
225         buf b;
226         size_t n = c->f->noctets * 2 + 1;
227         CODE:
228         RETVAL = NEWSV(0, n);
229         buf_init(&b, SvPVX(RETVAL), n);
230         if (ec_putraw(c, &b, p))
231           croak("unexpected failure in Catacomb::EC::Curve::putraw");
232         SvCUR_set(RETVAL, BLEN(&b));
233         OUTPUT:
234         RETVAL
235
236 void
237 _getraw(c, s)
238         EC_Curve *c
239         SV *s
240         PREINIT:
241         ec *p;
242         buf b;
243         char *q;
244         STRLEN n;
245         CODE:
246         q = SvPV(s, n);
247         buf_init(&b, q, n);
248         p = CREATE(ec);
249         EC_CREATE(p);
250         if (ec_getraw(c, &b, &p))
251           DESTROY(p);
252         else {
253           XPUSHs(RET(p, "Catacomb::EC::Point"));
254           if (GIMME_V == G_ARRAY)
255             XPUSHs(sv_2mortal(newSVpvn(BCUR(&b), BLEFT(&b))));
256         }
257
258 ec *
259 _find(c, x)
260         EC_Curve *c
261         fe *x
262         CODE:
263         RETVAL = CREATE(ec);
264         EC_CREATE(RETVAL);
265         if (!ec_find(c, RETVAL, x)) {
266           DESTROY(RETVAL);
267           RETVAL = 0;
268         }
269         OUTPUT:
270         RETVAL
271
272 ec *
273 _rand(c, r = &rand_global)
274         EC_Curve *c
275         grand *r
276         CODE:
277         RETVAL = CREATE(ec);
278         EC_CREATE(RETVAL);
279         ec_rand(c, RETVAL, r);
280         OUTPUT:
281         RETVAL
282
283 ec *
284 neg(c, p)
285         EC_Curve *c
286         ec *p
287         CODE:
288         RETVAL = CREATE(ec);
289         EC_CREATE(RETVAL);
290         ec_neg(c, RETVAL, p);
291         OUTPUT:
292         RETVAL
293
294 ec *
295 add(c, p, q)
296         EC_Curve *c
297         ec *p
298         ec *q
299         CODE:
300         RETVAL = CREATE(ec);
301         EC_CREATE(RETVAL);
302         ec_add(c, RETVAL, p, q);
303         OUTPUT:
304         RETVAL
305
306 ec *
307 sub(c, p, q)
308         EC_Curve *c
309         ec *p
310         ec *q
311         CODE:
312         RETVAL = CREATE(ec);
313         EC_CREATE(RETVAL);
314         ec_sub(c, RETVAL, p, q);
315         OUTPUT:
316         RETVAL
317
318 ec *
319 dbl(c, p)
320         EC_Curve *c
321         ec *p
322         CODE:
323         RETVAL = CREATE(ec);
324         EC_CREATE(RETVAL);
325         ec_dbl(c, RETVAL, p);
326         OUTPUT:
327         RETVAL
328
329 SV *
330 check(c, p)
331         EC_Curve *c
332         ec *p
333         CODE:
334         if (ec_check(c, p))
335           XSRETURN_UNDEF;
336         XSRETURN_YES;
337
338 ec *
339 mul(c, p, x)
340         EC_Curve *c
341         ec *p
342         mp *x
343         CODE:
344         RETVAL = CREATE(ec);
345         EC_CREATE(RETVAL);
346         ec_mul(c, RETVAL, p, x);
347         OUTPUT:
348         RETVAL
349
350 ec *
351 in(c, p)
352         EC_Curve *c
353         ec *p
354         CODE:
355         RETVAL = CREATE(ec);
356         EC_CREATE(RETVAL);
357         EC_IN(c, RETVAL, p);
358         OUTPUT:
359         RETVAL
360
361 ec *
362 out(c, p)
363         EC_Curve *c
364         ec *p
365         CODE:
366         RETVAL = CREATE(ec);
367         EC_CREATE(RETVAL);
368         EC_OUT(c, RETVAL, p);
369         OUTPUT:
370         RETVAL
371
372 ec *
373 fix(c, p)
374         EC_Curve *c
375         ec *p
376         CODE:
377         RETVAL = CREATE(ec);
378         EC_CREATE(RETVAL);
379         EC_FIX(c, RETVAL, p);
380         OUTPUT:
381         RETVAL
382
383 ec *
384 ifind(c, x)
385         EC_Curve *c
386         mp *x
387         CODE:
388         RETVAL = CREATE(ec);
389         if (!EC_FIND(c, RETVAL, x)) {
390           DESTROY(RETVAL);
391           RETVAL = 0;
392         }
393         OUTPUT:
394         RETVAL
395
396 ec *
397 ineg(c, p)
398         EC_Curve *c
399         ec *p
400         CODE:
401         RETVAL = CREATE(ec);
402         EC_CREATE(RETVAL);
403         EC_NEG(c, RETVAL, p);
404         OUTPUT:
405         RETVAL
406
407 ec *
408 iadd(c, p, q)
409         EC_Curve *c
410         ec *p
411         ec *q
412         CODE:
413         RETVAL = CREATE(ec);
414         EC_CREATE(RETVAL);
415         EC_ADD(c, RETVAL, p, q);
416         OUTPUT:
417         RETVAL
418
419 ec *
420 isub(c, p, q)
421         EC_Curve *c
422         ec *p
423         ec *q
424         CODE:
425         RETVAL = CREATE(ec);
426         EC_CREATE(RETVAL);
427         EC_SUB(c, RETVAL, p, q);
428         OUTPUT:
429         RETVAL
430
431 ec *
432 idbl(c, p)
433         EC_Curve *c
434         ec *p
435         CODE:
436         RETVAL = CREATE(ec);
437         EC_CREATE(RETVAL);
438         EC_DBL(c, RETVAL, p);
439         OUTPUT:
440         RETVAL
441
442 bool
443 icheck(c, p)
444         EC_Curve *c
445         ec *p
446         CODE:
447         RETVAL = EC_CHECK(c, p);
448         OUTPUT:
449         RETVAL
450
451 ec *
452 imul(c, p, x)
453         EC_Curve *c
454         ec *p
455         mp *x
456         CODE:
457         RETVAL = CREATE(ec);
458         EC_CREATE(RETVAL);
459         ec_imul(c, RETVAL, p, x);
460         OUTPUT:
461         RETVAL
462
463 ec *
464 immul(c, ...)
465         EC_Curve *c
466         PREINIT:
467         ec_mulfactor *v;
468         size_t i, j, n;
469         CODE:
470         if (items < 3 || !(items & 1)) {
471           croak("Usage: Catacomb::EC::Curve::immul"
472                 "(c, p_0, x_0, p_1, x_1, ...");
473         }
474         n = (items - 1)/2;
475         v = xmalloc(n * sizeof(mp_expfactor));
476         for (i = 1, j = 0; i < items; i += 2, j++) {
477           v[j].base = *ecpt(ST(i), "p_i");
478           v[j].exp = mp_fromsv(ST(i + 1), "x_i", 0, 0);
479         }
480         RETVAL = CREATE(RETVAL);
481         EC_CREATE(RETVAL);
482         ec_mmul(c, RETVAL, v, n);
483         xfree(v);
484         OUTPUT:
485         RETVAL
486
487 void
488 _getinfo(me, p)
489         SV *me
490         char *p
491         PREINIT:
492         ec_info i;
493         const char *e;
494         ec *pt;
495         PPCODE:
496         if ((e = ec_getinfo(&i, p)) != 0)
497           croak("bad curve spec: %s", e);
498         pt = CREATE(ec);
499         *pt = i.g;
500         XPUSHs(RET(i.c, "Catacomb::EC::Curve"));
501         XPUSHs(RET(pt, "Catacomb::EC::Point"));
502         XPUSHs(RET(i.r, "Catacomb::MP"));
503         XPUSHs(RET(i.h, "Catacomb::MP"));
504
505 const char *
506 checkinfo(c, g, r, h, rng = &rand_global)
507         EC_Curve *c
508         ec *g
509         mp *r
510         mp *h
511         grand *rng
512         PREINIT:
513         ec_info ei;
514         CODE:
515         ei.c = c;
516         ei.g = *g;
517         ei.r = r;
518         ei.h = h;
519         RETVAL = ec_checkinfo(&ei, rng);
520         OUTPUT:
521         RETVAL