5 # Multiprecision interface
7 # (c) 2000 Straylight/Edgeware
10 #----- Licensing notice -----------------------------------------------------
12 # This file is part of the Perl interface to Catacomb.
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.
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.
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.
29 MODULE = Catacomb PACKAGE = Catacomb::MP PREFIX = mp_
32 new(me, sv = 0, radix = 0)
37 RETVAL = sv ? mp_fromsv(sv, "sv",
38 "Catacomb::MP", radix, 1) : MP_ZERO;
59 RETVAL = mp_loadb(MP_NEW, p, len);
72 RETVAL = mp_loadl(MP_NEW, p, len);
81 XSINTERFACE_FUNC_SETMP
92 sz = (i < 0) ? mp_octets(m) : i;
93 RETVAL = NEWSV(0, sz ? sz : 1);
94 mp_storeb(m, SvPVX(RETVAL), sz);
95 SvCUR_set(RETVAL, sz);
107 sz = (i < 0) ? mp_octets(m) : i;
108 RETVAL = NEWSV(0, sz ? sz : 1);
109 mp_storel(m, SvPVX(RETVAL), sz);
110 SvCUR_set(RETVAL, sz);
116 tostring(m, radix = 10)
120 RETVAL = NEWSV(0, 0);
121 mp_writesv(m, RETVAL, radix);
129 RETVAL = newSViv(mp_toiv(m));
147 XSINTERFACE_FUNC_SETMP
156 RETVAL = mp_split(a);
157 if (RETVAL->v < RETVAL->vl)
177 XSINTERFACE_FUNC_SETMP
179 add sub mul and or xor
189 XSINTERFACE_FUNC_SETMP
208 if (!MP_LEN(n) || !(n->v[0] & 1))
209 croak("n must be odd in Catacomb::MP::jacobi");
210 RETVAL = mp_jacobi(a, n);
226 mp *q = MP_NEW, *r = MP_NEW;
228 if (MP_EQ(b, MP_ZERO))
229 croak("Divide by zero in Catacomb::MP::div");
234 mp_div(&q, &r, a, b);
242 mp_div(&q, &r, a, b);
253 mp *g = MP_NEW, *x = MP_NEW, *y = MP_NEW;
257 mp_gcd(&g, &x, &y, a, b);
266 mp_gcd(&g, 0, 0, a, b);
279 t = mp_odd(MP_NEW, m, &s);
282 PUSHs(sv_2mortal(newSViv(s)));
288 RETVAL = pfilt_smallfactor(x);
297 croak("Argument to Catacomb::MP::makereduce must be positive");
298 RETVAL = CREATE(MP_Reduce);
299 mpreduce_create(RETVAL, x);
308 croak("Argument to Catacomb::MP::mont must be positive");
310 croak("Argument to Catacomb::MP::mont must be odd");
311 RETVAL = CREATE(MP_Mont);
312 mpmont_create(RETVAL, x);
321 croak("Argument to Catacomb::MP::barrett must be positive");
322 RETVAL = CREATE(mpbarrett);
323 mpbarrett_create(RETVAL, x);
332 croak("Argument to Catacomb::MP::rabin must be positive");
334 croak("Argument to Catacomb::MP::rabin must be odd");
335 RETVAL = CREATE(MP_Prime_Rabin);
336 rabin_create(RETVAL, x);
340 MODULE = Catacomb PACKAGE = Catacomb::MP::Mont PREFIX = mpmont_
348 croak("Argument to Catacomb::MP::Mont::new must be positive");
350 croak("Argument to Catacomb::MP::Mont::new must be odd");
351 RETVAL = CREATE(MP_Mont);
352 mpmont_create(RETVAL, x);
380 mpmont_expr(mm, g, x)
396 mpmont_mexpr(mm, ...)
402 if (items < 3 || !(items & 1)) {
403 croak("Usage: Catacomb::MP::Mont::mexpr"
404 "(mm, g_0, x_0, g_1, x_1, ...");
407 v = xmalloc(n * sizeof(mp_expfactor));
408 for (i = 1, j = 0; i < items; i += 2, j++) {
409 v[j].base = mp_fromsv(ST(i), "g_i", "Catacomb::MP", 0, 0);
410 v[j].exp = mp_fromsv(ST(i + 1), "x_i", "Catacomb::MP", 0, 0);
412 RETVAL = mpmont_mexpr(mm, MP_NEW, v, n);
424 if (items < 3 || !(items & 1)) {
425 croak("Usage: Catacomb::MP::Mont::mexp"
426 "(mm, g_0, x_0, g_1, x_1, ...");
429 v = xmalloc(n * sizeof(mp_expfactor));
430 for (i = 1, j = 0; i < items; i += 2, j++) {
431 v[j].base = mp_fromsv(ST(i), "g_%lu",
432 "Catacomb::MP", 0, 0, (unsigned long)i);
433 v[j].exp = mp_fromsv(ST(i + 1), "x_%lu",
434 "Catacomb::MP", 0, 0, (unsigned long)i);
436 RETVAL = mpmont_mexp(mm, MP_NEW, v, n);
445 RETVAL = MP_COPY(mm->r);
453 RETVAL = MP_COPY(mm->r2);
461 RETVAL = MP_COPY(mm->m);
465 MODULE = Catacomb PACKAGE = Catacomb::MP::Barrett PREFIX = mpbarrett_
473 croak("Argument to Catacomb::MP::Barrett::new must be positive");
474 RETVAL = CREATE(mpbarrett);
475 mpbarrett_create(RETVAL, x);
483 mpbarrett_destroy(mb);
488 mpbarrett_reduce(mb, x)
495 mpbarrett_exp(mb, g, x)
506 RETVAL = MP_COPY(mb->m);
510 MODULE = Catacomb PACKAGE = Catacomb::MP::Reduce PREFIX = mpreduce_
518 croak("Argument to Catacomb::MP::Reduce::new must be positive");
519 RETVAL = CREATE(mpreduce);
520 mpreduce_create(RETVAL, x);
537 RETVAL = mpreduce_do(r, MP_NEW, x);
542 mpreduce_exp(r, x, y)
553 RETVAL = MP_COPY(r->p);
557 MODULE = Catacomb PACKAGE = Catacomb::MP::CRT
567 croak("Usage: Catacomb::MP::CRT::new(me, n_0, n_1, ...)");
569 v = xmalloc(n * sizeof(mpcrt_mod));
570 for (i = 0; i < n; i++) {
571 v[i].m = mp_copy(mp_fromsv(ST(i + 1), "n_%lu",
572 "Catacomb::MP", 0, 0,
575 RETVAL = CREATE(MP_CRT);
576 mpcrt_create(RETVAL, v, n, 0);
598 croak("Wrong number of residues for this CRT context");
599 for (i = 0; i < n; i++) {
600 v[i] = mp_fromsv(ST(i + 1), "r_%lu", "Catacomb::MP",
601 0, 0, (unsigned long)i);
603 RETVAL = mpcrt_solve(mc, MP_NEW, v);
608 #----- That's all, folks ----------------------------------------------------