a1a90aaf |
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 | |
fcd15e0b |
30 | ec * |
31 | new(me, x = 0, y = 0, z = 0) |
32 | SV *me |
a1a90aaf |
33 | mp *x |
34 | mp *y |
35 | mp *z |
36 | CODE: |
fcd15e0b |
37 | RETVAL = CREATE(ec); |
a1a90aaf |
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) |
fcd15e0b |
50 | ec *p |
a1a90aaf |
51 | CODE: |
52 | RETVAL = EC_ATINF(p); |
53 | OUTPUT: |
54 | RETVAL |
55 | |
56 | mp * |
57 | x(p) |
fcd15e0b |
58 | ec *p |
a1a90aaf |
59 | CODE: |
60 | RETVAL = p->x ? MP_COPY(p->x) : 0; |
61 | OUTPUT: |
62 | RETVAL |
63 | |
64 | mp * |
65 | y(p) |
fcd15e0b |
66 | ec *p |
a1a90aaf |
67 | CODE: |
68 | RETVAL = p->y ? MP_COPY(p->y) : 0; |
69 | OUTPUT: |
70 | RETVAL |
71 | |
72 | mp * |
73 | z(p) |
fcd15e0b |
74 | ec *p |
a1a90aaf |
75 | CODE: |
76 | RETVAL = p->z ? MP_COPY(p->z) : 0; |
77 | OUTPUT: |
78 | RETVAL |
79 | |
f9952aec |
80 | bool |
81 | ec_eq(p, q) |
fcd15e0b |
82 | ec *p |
83 | ec *q |
f9952aec |
84 | |
a1a90aaf |
85 | SV * |
86 | DESTROY(p) |
fcd15e0b |
87 | ec *p |
a1a90aaf |
88 | CODE: |
89 | EC_DESTROY(p); |
90 | DESTROY(p); |
91 | XSRETURN_YES; |
92 | |
fcd15e0b |
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) |
bfdf19cb |
126 | XPUSHs(sv_2mortal(newSVpvn((char *)BCUR(&b), BLEFT(&b)))); |
fcd15e0b |
127 | } |
128 | |
a1a90aaf |
129 | MODULE = Catacomb PACKAGE = Catacomb::EC::Curve PREFIX = ec_ |
130 | |
131 | EC_Curve * |
fcd15e0b |
132 | prime(me, f, a, b) |
a1a90aaf |
133 | SV *me |
134 | Field *f |
135 | mp *a |
136 | mp *b |
fcd15e0b |
137 | CODE: |
138 | RETVAL = ec_prime(f, a, b); |
139 | OUTPUT: |
140 | RETVAL |
a1a90aaf |
141 | |
142 | EC_Curve * |
fcd15e0b |
143 | primeproj(me, f, a, b) |
a1a90aaf |
144 | SV *me |
145 | Field *f |
146 | mp *a |
147 | mp *b |
fcd15e0b |
148 | CODE: |
149 | RETVAL = ec_primeproj(f, a, b); |
150 | OUTPUT: |
151 | RETVAL |
a1a90aaf |
152 | |
153 | EC_Curve * |
fcd15e0b |
154 | bin(me, f, a, b) |
a1a90aaf |
155 | SV *me |
156 | Field *f |
157 | gf *a |
158 | gf *b |
fcd15e0b |
159 | CODE: |
160 | RETVAL = ec_bin(f, a, b); |
161 | OUTPUT: |
162 | RETVAL |
a1a90aaf |
163 | |
164 | EC_Curve * |
fcd15e0b |
165 | binproj(me, f, a, b) |
a1a90aaf |
166 | SV *me |
167 | Field *f |
168 | gf *a |
169 | gf *b |
fcd15e0b |
170 | CODE: |
171 | RETVAL = ec_binproj(f, a, b); |
172 | OUTPUT: |
173 | RETVAL |
a1a90aaf |
174 | |
175 | char * |
176 | name(c) |
177 | EC_Curve *c |
178 | CODE: |
179 | RETVAL = (char *)EC_NAME(c); |
180 | OUTPUT: |
181 | RETVAL |
182 | |
fcd15e0b |
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 | |
a1a90aaf |
215 | bool |
216 | ec_samep(me, c) |
217 | EC_Curve *me |
218 | EC_Curve *c |
219 | |
fcd15e0b |
220 | SV * |
221 | putraw(c, p) |
a1a90aaf |
222 | EC_Curve *c |
fcd15e0b |
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; |
a1a90aaf |
245 | CODE: |
fcd15e0b |
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) |
bfdf19cb |
255 | XPUSHs(sv_2mortal(newSVpvn((char *)BCUR(&b), BLEFT(&b)))); |
fcd15e0b |
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); |
a1a90aaf |
265 | if (!ec_find(c, RETVAL, x)) { |
266 | DESTROY(RETVAL); |
267 | RETVAL = 0; |
268 | } |
269 | OUTPUT: |
270 | RETVAL |
271 | |
fcd15e0b |
272 | ec * |
273 | _rand(c, r = &rand_global) |
a1a90aaf |
274 | EC_Curve *c |
275 | grand *r |
276 | CODE: |
fcd15e0b |
277 | RETVAL = CREATE(ec); |
278 | EC_CREATE(RETVAL); |
a1a90aaf |
279 | ec_rand(c, RETVAL, r); |
280 | OUTPUT: |
281 | RETVAL |
282 | |
fcd15e0b |
283 | ec * |
a1a90aaf |
284 | neg(c, p) |
285 | EC_Curve *c |
fcd15e0b |
286 | ec *p |
a1a90aaf |
287 | CODE: |
fcd15e0b |
288 | RETVAL = CREATE(ec); |
a1a90aaf |
289 | EC_CREATE(RETVAL); |
290 | ec_neg(c, RETVAL, p); |
291 | OUTPUT: |
292 | RETVAL |
293 | |
fcd15e0b |
294 | ec * |
a1a90aaf |
295 | add(c, p, q) |
296 | EC_Curve *c |
fcd15e0b |
297 | ec *p |
298 | ec *q |
a1a90aaf |
299 | CODE: |
fcd15e0b |
300 | RETVAL = CREATE(ec); |
a1a90aaf |
301 | EC_CREATE(RETVAL); |
302 | ec_add(c, RETVAL, p, q); |
303 | OUTPUT: |
304 | RETVAL |
305 | |
fcd15e0b |
306 | ec * |
a1a90aaf |
307 | sub(c, p, q) |
308 | EC_Curve *c |
fcd15e0b |
309 | ec *p |
310 | ec *q |
a1a90aaf |
311 | CODE: |
fcd15e0b |
312 | RETVAL = CREATE(ec); |
a1a90aaf |
313 | EC_CREATE(RETVAL); |
314 | ec_sub(c, RETVAL, p, q); |
315 | OUTPUT: |
316 | RETVAL |
317 | |
fcd15e0b |
318 | ec * |
a1a90aaf |
319 | dbl(c, p) |
320 | EC_Curve *c |
fcd15e0b |
321 | ec *p |
a1a90aaf |
322 | CODE: |
fcd15e0b |
323 | RETVAL = CREATE(ec); |
a1a90aaf |
324 | EC_CREATE(RETVAL); |
325 | ec_dbl(c, RETVAL, p); |
326 | OUTPUT: |
327 | RETVAL |
328 | |
fcd15e0b |
329 | SV * |
330 | check(c, p) |
a1a90aaf |
331 | EC_Curve *c |
fcd15e0b |
332 | ec *p |
333 | CODE: |
334 | if (ec_check(c, p)) |
335 | XSRETURN_UNDEF; |
336 | XSRETURN_YES; |
a1a90aaf |
337 | |
fcd15e0b |
338 | ec * |
a1a90aaf |
339 | mul(c, p, x) |
340 | EC_Curve *c |
fcd15e0b |
341 | ec *p |
a1a90aaf |
342 | mp *x |
343 | CODE: |
fcd15e0b |
344 | RETVAL = CREATE(ec); |
a1a90aaf |
345 | EC_CREATE(RETVAL); |
346 | ec_mul(c, RETVAL, p, x); |
347 | OUTPUT: |
348 | RETVAL |
349 | |
fcd15e0b |
350 | ec * |
a1a90aaf |
351 | in(c, p) |
352 | EC_Curve *c |
fcd15e0b |
353 | ec *p |
a1a90aaf |
354 | CODE: |
fcd15e0b |
355 | RETVAL = CREATE(ec); |
a1a90aaf |
356 | EC_CREATE(RETVAL); |
357 | EC_IN(c, RETVAL, p); |
358 | OUTPUT: |
359 | RETVAL |
360 | |
fcd15e0b |
361 | ec * |
a1a90aaf |
362 | out(c, p) |
363 | EC_Curve *c |
fcd15e0b |
364 | ec *p |
a1a90aaf |
365 | CODE: |
fcd15e0b |
366 | RETVAL = CREATE(ec); |
a1a90aaf |
367 | EC_CREATE(RETVAL); |
368 | EC_OUT(c, RETVAL, p); |
369 | OUTPUT: |
370 | RETVAL |
371 | |
fcd15e0b |
372 | ec * |
a1a90aaf |
373 | fix(c, p) |
374 | EC_Curve *c |
fcd15e0b |
375 | ec *p |
a1a90aaf |
376 | CODE: |
fcd15e0b |
377 | RETVAL = CREATE(ec); |
a1a90aaf |
378 | EC_CREATE(RETVAL); |
379 | EC_FIX(c, RETVAL, p); |
380 | OUTPUT: |
381 | RETVAL |
382 | |
fcd15e0b |
383 | ec * |
a1a90aaf |
384 | ifind(c, x) |
385 | EC_Curve *c |
386 | mp *x |
387 | CODE: |
fcd15e0b |
388 | RETVAL = CREATE(ec); |
a1a90aaf |
389 | if (!EC_FIND(c, RETVAL, x)) { |
390 | DESTROY(RETVAL); |
391 | RETVAL = 0; |
392 | } |
393 | OUTPUT: |
394 | RETVAL |
395 | |
fcd15e0b |
396 | ec * |
a1a90aaf |
397 | ineg(c, p) |
398 | EC_Curve *c |
fcd15e0b |
399 | ec *p |
a1a90aaf |
400 | CODE: |
fcd15e0b |
401 | RETVAL = CREATE(ec); |
a1a90aaf |
402 | EC_CREATE(RETVAL); |
403 | EC_NEG(c, RETVAL, p); |
404 | OUTPUT: |
405 | RETVAL |
406 | |
fcd15e0b |
407 | ec * |
a1a90aaf |
408 | iadd(c, p, q) |
409 | EC_Curve *c |
fcd15e0b |
410 | ec *p |
411 | ec *q |
a1a90aaf |
412 | CODE: |
fcd15e0b |
413 | RETVAL = CREATE(ec); |
a1a90aaf |
414 | EC_CREATE(RETVAL); |
415 | EC_ADD(c, RETVAL, p, q); |
416 | OUTPUT: |
417 | RETVAL |
418 | |
fcd15e0b |
419 | ec * |
a1a90aaf |
420 | isub(c, p, q) |
421 | EC_Curve *c |
fcd15e0b |
422 | ec *p |
423 | ec *q |
a1a90aaf |
424 | CODE: |
fcd15e0b |
425 | RETVAL = CREATE(ec); |
a1a90aaf |
426 | EC_CREATE(RETVAL); |
427 | EC_SUB(c, RETVAL, p, q); |
428 | OUTPUT: |
429 | RETVAL |
430 | |
fcd15e0b |
431 | ec * |
a1a90aaf |
432 | idbl(c, p) |
433 | EC_Curve *c |
fcd15e0b |
434 | ec *p |
a1a90aaf |
435 | CODE: |
fcd15e0b |
436 | RETVAL = CREATE(ec); |
a1a90aaf |
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 |
fcd15e0b |
445 | ec *p |
a1a90aaf |
446 | CODE: |
447 | RETVAL = EC_CHECK(c, p); |
448 | OUTPUT: |
449 | RETVAL |
450 | |
fcd15e0b |
451 | ec * |
a1a90aaf |
452 | imul(c, p, x) |
453 | EC_Curve *c |
fcd15e0b |
454 | ec *p |
a1a90aaf |
455 | mp *x |
456 | CODE: |
fcd15e0b |
457 | RETVAL = CREATE(ec); |
a1a90aaf |
458 | EC_CREATE(RETVAL); |
459 | ec_imul(c, RETVAL, p, x); |
460 | OUTPUT: |
461 | RETVAL |
462 | |
fcd15e0b |
463 | ec * |
a1a90aaf |
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++) { |
fcd15e0b |
477 | v[j].base = *ecpt(ST(i), "p_i"); |
478 | v[j].exp = mp_fromsv(ST(i + 1), "x_i", 0, 0); |
a1a90aaf |
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 |
fcd15e0b |
488 | _getinfo(me, p) |
489 | SV *me |
a1a90aaf |
490 | char *p |
491 | PREINIT: |
492 | ec_info i; |
493 | const char *e; |
fcd15e0b |
494 | ec *pt; |
a1a90aaf |
495 | PPCODE: |
496 | if ((e = ec_getinfo(&i, p)) != 0) |
497 | croak("bad curve spec: %s", e); |
fcd15e0b |
498 | pt = CREATE(ec); |
a1a90aaf |
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 | |
fcd15e0b |
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 |