Extract Subversion ignore data.
[catacomb-perl] / ec.xs
CommitLineData
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
28MODULE = Catacomb PACKAGE = Catacomb::EC::Point PREFIX = ec_
29
fcd15e0b 30ec *
31new(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
48bool
49atinfp(p)
fcd15e0b 50 ec *p
a1a90aaf 51 CODE:
52 RETVAL = EC_ATINF(p);
53 OUTPUT:
54 RETVAL
55
56mp *
57x(p)
fcd15e0b 58 ec *p
a1a90aaf 59 CODE:
60 RETVAL = p->x ? MP_COPY(p->x) : 0;
61 OUTPUT:
62 RETVAL
63
64mp *
65y(p)
fcd15e0b 66 ec *p
a1a90aaf 67 CODE:
68 RETVAL = p->y ? MP_COPY(p->y) : 0;
69 OUTPUT:
70 RETVAL
71
72mp *
73z(p)
fcd15e0b 74 ec *p
a1a90aaf 75 CODE:
76 RETVAL = p->z ? MP_COPY(p->z) : 0;
77 OUTPUT:
78 RETVAL
79
f9952aec 80bool
81ec_eq(p, q)
fcd15e0b 82 ec *p
83 ec *q
f9952aec 84
a1a90aaf 85SV *
86DESTROY(p)
fcd15e0b 87 ec *p
a1a90aaf 88 CODE:
89 EC_DESTROY(p);
90 DESTROY(p);
91 XSRETURN_YES;
92
fcd15e0b 93SV *
94put(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
108void
109get(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 129MODULE = Catacomb PACKAGE = Catacomb::EC::Curve PREFIX = ec_
130
131EC_Curve *
fcd15e0b 132prime(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
142EC_Curve *
fcd15e0b 143primeproj(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
153EC_Curve *
fcd15e0b 154bin(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
164EC_Curve *
fcd15e0b 165binproj(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
175char *
176name(c)
177 EC_Curve *c
178 CODE:
179 RETVAL = (char *)EC_NAME(c);
180 OUTPUT:
181 RETVAL
182
fcd15e0b 183mp *
184_a(c)
185 EC_Curve *c
186 CODE:
187 RETVAL = F_OUT(c->f, MP_NEW, c->a);
188 OUTPUT:
189 RETVAL
190
191mp *
192_b(c)
193 EC_Curve *c
194 CODE:
195 RETVAL = F_OUT(c->f, MP_NEW, c->a);
196 OUTPUT:
197 RETVAL
198
199Field *
200field(c)
201 EC_Curve *c
202 CODE:
203 RETVAL = copy_field(c->f);
204 OUTPUT:
205 RETVAL
206
207SV *
208get(c)
209 EC_Curve *c
210 CODE:
211 RETVAL = info_curve(c);
212 OUTPUT:
213 RETVAL
214
a1a90aaf 215bool
216ec_samep(me, c)
217 EC_Curve *me
218 EC_Curve *c
219
fcd15e0b 220SV *
221putraw(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
236void
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
258ec *
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 272ec *
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 283ec *
a1a90aaf 284neg(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 294ec *
a1a90aaf 295add(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 306ec *
a1a90aaf 307sub(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 318ec *
a1a90aaf 319dbl(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 329SV *
330check(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 338ec *
a1a90aaf 339mul(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 350ec *
a1a90aaf 351in(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 361ec *
a1a90aaf 362out(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 372ec *
a1a90aaf 373fix(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 383ec *
a1a90aaf 384ifind(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 396ec *
a1a90aaf 397ineg(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 407ec *
a1a90aaf 408iadd(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 419ec *
a1a90aaf 420isub(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 431ec *
a1a90aaf 432idbl(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
442bool
443icheck(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 451ec *
a1a90aaf 452imul(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 463ec *
a1a90aaf 464immul(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
487void
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 505const char *
506checkinfo(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