3 # $Id: mp.xs,v 1.2 2004/04/08 01:36:21 mdw Exp $
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", radix, 1) : MP_ZERO;
54 RETVAL = mp_loadb(MP_NEW, p, len);
67 RETVAL = mp_loadl(MP_NEW, p, len);
76 XSINTERFACE_FUNC_SETMP
87 sz = (i < 0) ? mp_octets(m) : i;
88 RETVAL = NEWSV(0, sz ? sz : 1);
89 mp_storeb(m, SvPVX(RETVAL), sz);
90 SvCUR_set(RETVAL, sz);
102 sz = (i < 0) ? mp_octets(m) : i;
103 RETVAL = NEWSV(0, sz ? sz : 1);
104 mp_storel(m, SvPVX(RETVAL), sz);
105 SvCUR_set(RETVAL, sz);
111 tostring(m, radix = 10)
115 RETVAL = NEWSV(0, 0);
116 mp_writesv(m, RETVAL, radix);
124 RETVAL = newSViv(mp_toiv(m));
142 XSINTERFACE_FUNC_SETMP
151 RETVAL = mp_split(a);
152 if (RETVAL->v < RETVAL->vl)
172 XSINTERFACE_FUNC_SETMP
174 add sub mul and or xor
184 XSINTERFACE_FUNC_SETMP
203 if (!MP_LEN(n) || !(n->v[0] & 1))
204 croak("n must be odd in Catacomb::MP::jacobi");
205 RETVAL = mp_jacobi(a, n);
221 mp *q = MP_NEW, *r = MP_NEW;
223 if (MP_EQ(b, MP_ZERO))
224 croak("Divide by zero in Catacomb::MP::div");
229 mp_div(&q, &r, a, b);
237 mp_div(&q, &r, a, b);
248 mp *g = MP_NEW, *x = MP_NEW, *y = MP_NEW;
252 mp_gcd(&g, &x, &y, a, b);
261 mp_gcd(&g, 0, 0, a, b);
274 t = mp_odd(MP_NEW, m, &s);
277 PUSHs(sv_2mortal(newSViv(s)));
283 RETVAL = pfilt_smallfactor(x);
292 croak("Argument to Catacomb::MP::mont must be positive");
293 if (x->v == x->vl || !(x->v[0] & 1u))
294 croak("Argument to Catacomb::MP::mont must be odd");
295 RETVAL = CREATE(MP_Mont);
296 mpmont_create(RETVAL, x);
305 croak("Argument to Catacomb::MP::barrett must be positive");
306 RETVAL = CREATE(mpbarrett);
307 mpbarrett_create(RETVAL, x);
316 croak("Argument to Catacomb::MP::rabin must be positive");
317 if (x->v == x->vl || !(x->v[0] & 1u))
318 croak("Argument to Catacomb::MP::rabin must be odd");
319 RETVAL = CREATE(MP_Prime_Rabin);
320 rabin_create(RETVAL, x);
324 MODULE = Catacomb PACKAGE = Catacomb::MP::Mont PREFIX = mpmont_
332 croak("Argument to Catacomb::MP::Mont::new must be positive");
333 if (x->v == x->vl || !(x->v[0] & 1u))
334 croak("Argument to Catacomb::MP::Mont::new must be odd");
335 RETVAL = CREATE(MP_Mont);
336 mpmont_create(RETVAL, x);
364 mpmont_expr(mm, g, x)
380 mpmont_mexpr(mm, ...)
386 if (items < 3 || !(items & 1)) {
387 croak("Usage: Catacomb::MP::Mont::mexpr"
388 "(mm, g_0, x_0, g_1, x_1, ...");
391 v = xmalloc(n * sizeof(mp_expfactor));
392 for (i = 1, j = 0; i < items; i += 2, j++) {
393 v[j].base = mp_fromsv(ST(i), "g_i", 0, 0);
394 v[j].exp = mp_fromsv(ST(i + 1), "x_i", 0, 0);
396 RETVAL = mpmont_mexpr(mm, MP_NEW, v, n);
408 if (items < 3 || !(items & 1)) {
409 croak("Usage: Catacomb::MP::Mont::mexp"
410 "(mm, g_0, x_0, g_1, x_1, ...");
413 v = xmalloc(n * sizeof(mp_expfactor));
414 for (i = 1, j = 0; i < items; i += 2, j++) {
415 v[j].base = mp_fromsv(ST(i), "g_%lu", 0, 0, (unsigned long)i);
416 v[j].exp = mp_fromsv(ST(i + 1), "x_%lu", 0, 0, (unsigned long)i);
418 RETVAL = mpmont_mexp(mm, MP_NEW, v, n);
427 RETVAL = mp_copy(mm->r);
435 RETVAL = mp_copy(mm->r2);
443 RETVAL = mp_copy(mm->m);
447 MODULE = Catacomb PACKAGE = Catacomb::MP::Barrett PREFIX = mpbarrett_
455 croak("Argument to Catacomb::MP::Barrett::new must be positive");
456 RETVAL = CREATE(mpbarrett);
457 mpbarrett_create(RETVAL, x);
465 mpbarrett_destroy(mb);
470 mpbarrett_reduce(mb, x)
477 mpbarrett_exp(mb, g, x)
488 RETVAL = mp_copy(mb->m);
492 MODULE = Catacomb PACKAGE = Catacomb::MP::CRT
502 croak("Usage: Catacomb::MP::CRT::new(me, n_0, n_1, ...)");
504 v = xmalloc(n * sizeof(mpcrt_mod));
505 for (i = 0; i < n; i++) {
506 v[i].m = mp_copy(mp_fromsv(ST(i + 1), "n_%lu", 0, 0,
509 RETVAL = CREATE(MP_CRT);
510 mpcrt_create(RETVAL, v, n, 0);
532 croak("Wrong number of residues for this CRT context");
533 for (i = 0; i < n; i++)
534 v[i] = mp_fromsv(ST(i + 1), "r_%lu", 0, 0, (unsigned long)i);
535 RETVAL = mpcrt_solve(mc, MP_NEW, v);
540 #----- That's all, folks ----------------------------------------------------