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 and2c or2c nand2c nor2c xor2c and or nand nor xor
189 XSINTERFACE_FUNC_SETMP
199 XSINTERFACE_FUNC_SETMP
211 XSINTERFACE_FUNC_SETMP
213 setbit clearbit setbit2c clearbit2c
230 if (!MP_LEN(n) || !(n->v[0] & 1))
231 croak("n must be odd in Catacomb::MP::jacobi");
232 RETVAL = mp_jacobi(a, n);
248 mp *q = MP_NEW, *r = MP_NEW;
250 if (MP_EQ(b, MP_ZERO))
251 croak("Divide by zero in Catacomb::MP::div");
256 mp_div(&q, &r, a, b);
264 mp_div(&q, &r, a, b);
275 mp *g = MP_NEW, *x = MP_NEW, *y = MP_NEW;
279 mp_gcd(&g, &x, &y, a, b);
288 mp_gcd(&g, 0, 0, a, b);
301 t = mp_odd(MP_NEW, m, &s);
304 PUSHs(sv_2mortal(newSViv(s)));
310 RETVAL = pfilt_smallfactor(x);
319 croak("Argument to Catacomb::MP::makereduce must be positive");
320 RETVAL = CREATE(MP_Reduce);
321 mpreduce_create(RETVAL, x);
330 croak("Argument to Catacomb::MP::mont must be positive");
332 croak("Argument to Catacomb::MP::mont must be odd");
333 RETVAL = CREATE(MP_Mont);
334 mpmont_create(RETVAL, x);
343 croak("Argument to Catacomb::MP::barrett must be positive");
344 RETVAL = CREATE(mpbarrett);
345 mpbarrett_create(RETVAL, x);
354 croak("Argument to Catacomb::MP::rabin must be positive");
356 croak("Argument to Catacomb::MP::rabin must be odd");
357 RETVAL = CREATE(MP_Prime_Rabin);
358 rabin_create(RETVAL, x);
362 MODULE = Catacomb PACKAGE = Catacomb::MP::Mont PREFIX = mpmont_
370 croak("Argument to Catacomb::MP::Mont::new must be positive");
372 croak("Argument to Catacomb::MP::Mont::new must be odd");
373 RETVAL = CREATE(MP_Mont);
374 mpmont_create(RETVAL, x);
402 mpmont_expr(mm, g, x)
418 mpmont_mexpr(mm, ...)
424 if (items < 3 || !(items & 1)) {
425 croak("Usage: Catacomb::MP::Mont::mexpr"
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_i", "Catacomb::MP", 0, 0);
432 v[j].exp = mp_fromsv(ST(i + 1), "x_i", "Catacomb::MP", 0, 0);
434 RETVAL = mpmont_mexpr(mm, MP_NEW, v, n);
446 if (items < 3 || !(items & 1)) {
447 croak("Usage: Catacomb::MP::Mont::mexp"
448 "(mm, g_0, x_0, g_1, x_1, ...");
451 v = xmalloc(n * sizeof(mp_expfactor));
452 for (i = 1, j = 0; i < items; i += 2, j++) {
453 v[j].base = mp_fromsv(ST(i), "g_%lu",
454 "Catacomb::MP", 0, 0, (unsigned long)i);
455 v[j].exp = mp_fromsv(ST(i + 1), "x_%lu",
456 "Catacomb::MP", 0, 0, (unsigned long)i);
458 RETVAL = mpmont_mexp(mm, MP_NEW, v, n);
467 RETVAL = MP_COPY(mm->r);
475 RETVAL = MP_COPY(mm->r2);
483 RETVAL = MP_COPY(mm->m);
487 MODULE = Catacomb PACKAGE = Catacomb::MP::Barrett PREFIX = mpbarrett_
495 croak("Argument to Catacomb::MP::Barrett::new must be positive");
496 RETVAL = CREATE(mpbarrett);
497 mpbarrett_create(RETVAL, x);
505 mpbarrett_destroy(mb);
510 mpbarrett_reduce(mb, x)
517 mpbarrett_exp(mb, g, x)
528 RETVAL = MP_COPY(mb->m);
532 MODULE = Catacomb PACKAGE = Catacomb::MP::Reduce PREFIX = mpreduce_
540 croak("Argument to Catacomb::MP::Reduce::new must be positive");
541 RETVAL = CREATE(mpreduce);
542 mpreduce_create(RETVAL, x);
559 RETVAL = mpreduce_do(r, MP_NEW, x);
564 mpreduce_exp(r, x, y)
575 RETVAL = MP_COPY(r->p);
579 MODULE = Catacomb PACKAGE = Catacomb::MP::CRT
589 croak("Usage: Catacomb::MP::CRT::new(me, n_0, n_1, ...)");
591 v = xmalloc(n * sizeof(mpcrt_mod));
592 for (i = 0; i < n; i++) {
593 v[i].m = mp_copy(mp_fromsv(ST(i + 1), "n_%lu",
594 "Catacomb::MP", 0, 0,
597 RETVAL = CREATE(MP_CRT);
598 mpcrt_create(RETVAL, v, n, 0);
620 croak("Wrong number of residues for this CRT context");
621 for (i = 0; i < n; i++) {
622 v[i] = mp_fromsv(ST(i + 1), "r_%lu", "Catacomb::MP",
623 0, 0, (unsigned long)i);
625 RETVAL = mpcrt_solve(mc, MP_NEW, v);
630 #----- That's all, folks ----------------------------------------------------