3 # $Id: mp.xs,v 1.1 2004/04/02 18:04:01 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 #----- Revision history -----------------------------------------------------
32 # Revision 1.1 2004/04/02 18:04:01 mdw
36 MODULE = Catacomb PACKAGE = Catacomb::MP PREFIX = mp_
39 new(me, sv = 0, radix = 0)
44 RETVAL = sv ? mp_fromsv(sv, "sv", radix, 1) : MP_ZERO;
61 RETVAL = mp_loadb(MP_NEW, p, len);
74 RETVAL = mp_loadl(MP_NEW, p, len);
83 XSINTERFACE_FUNC_SETMP
94 sz = (i < 0) ? mp_octets(m) : i;
95 RETVAL = NEWSV(0, sz ? sz : 1);
96 mp_storeb(m, SvPVX(RETVAL), sz);
97 SvCUR_set(RETVAL, sz);
109 sz = (i < 0) ? mp_octets(m) : i;
110 RETVAL = NEWSV(0, sz ? sz : 1);
111 mp_storel(m, SvPVX(RETVAL), sz);
112 SvCUR_set(RETVAL, sz);
118 tostring(m, radix = 10)
122 RETVAL = NEWSV(0, 0);
123 mp_writesv(m, RETVAL, radix);
131 RETVAL = newSViv(mp_toiv(m));
149 XSINTERFACE_FUNC_SETMP
158 RETVAL = mp_split(a);
159 if (RETVAL->v < RETVAL->vl)
179 XSINTERFACE_FUNC_SETMP
181 add sub mul and or xor
191 XSINTERFACE_FUNC_SETMP
210 if (!MP_LEN(n) || !(n->v[0] & 1))
211 croak("n must be odd in Catacomb::MP::jacobi");
212 RETVAL = mp_jacobi(a, n);
228 mp *q = MP_NEW, *r = MP_NEW;
230 if (MP_EQ(b, MP_ZERO))
231 croak("Divide by zero in Catacomb::MP::div");
236 mp_div(&q, &r, a, b);
244 mp_div(&q, &r, a, b);
255 mp *g = MP_NEW, *x = MP_NEW, *y = MP_NEW;
259 mp_gcd(&g, &x, &y, a, b);
268 mp_gcd(&g, 0, 0, a, b);
281 t = mp_odd(MP_NEW, m, &s);
284 PUSHs(sv_2mortal(newSViv(s)));
290 RETVAL = pfilt_smallfactor(x);
299 croak("Argument to Catacomb::MP::mont must be positive");
300 if (x->v == x->vl || !(x->v[0] & 1u))
301 croak("Argument to Catacomb::MP::mont must be odd");
302 RETVAL = CREATE(MP_Mont);
303 mpmont_create(RETVAL, x);
312 croak("Argument to Catacomb::MP::barrett must be positive");
313 RETVAL = CREATE(mpbarrett);
314 mpbarrett_create(RETVAL, x);
323 croak("Argument to Catacomb::MP::rabin must be positive");
324 if (x->v == x->vl || !(x->v[0] & 1u))
325 croak("Argument to Catacomb::MP::rabin must be odd");
326 RETVAL = CREATE(MP_Prime_Rabin);
327 rabin_create(RETVAL, x);
331 MODULE = Catacomb PACKAGE = Catacomb::MP::Mont PREFIX = mpmont_
339 croak("Argument to Catacomb::MP::Mont::new must be positive");
340 if (x->v == x->vl || !(x->v[0] & 1u))
341 croak("Argument to Catacomb::MP::Mont::new must be odd");
342 RETVAL = CREATE(MP_Mont);
343 mpmont_create(RETVAL, x);
371 mpmont_expr(mm, g, x)
387 mpmont_mexpr(mm, ...)
393 if (items < 3 || !(items & 1)) {
394 croak("Usage: Catacomb::MP::Mont::mexpr"
395 "(mm, g_0, x_0, g_1, x_1, ...");
398 v = xmalloc(n * sizeof(mp_expfactor));
399 for (i = 1, j = 0; i < items; i += 2, j++) {
400 v[j].base = mp_fromsv(ST(i), "g_i", 0, 0);
401 v[j].exp = mp_fromsv(ST(i + 1), "x_i", 0, 0);
403 RETVAL = mpmont_mexpr(mm, MP_NEW, v, n);
415 if (items < 3 || !(items & 1)) {
416 croak("Usage: Catacomb::MP::Mont::mexp"
417 "(mm, g_0, x_0, g_1, x_1, ...");
420 v = xmalloc(n * sizeof(mp_expfactor));
421 for (i = 1, j = 0; i < items; i += 2, j++) {
422 v[j].base = mp_fromsv(ST(i), "g_%lu", 0, 0, (unsigned long)i);
423 v[j].exp = mp_fromsv(ST(i + 1), "x_%lu", 0, 0, (unsigned long)i);
425 RETVAL = mpmont_mexp(mm, MP_NEW, v, n);
434 RETVAL = mp_copy(mm->r);
442 RETVAL = mp_copy(mm->r2);
450 RETVAL = mp_copy(mm->m);
454 MODULE = Catacomb PACKAGE = Catacomb::MP::Barrett PREFIX = mpbarrett_
462 croak("Argument to Catacomb::MP::Barrett::new must be positive");
463 RETVAL = CREATE(mpbarrett);
464 mpbarrett_create(RETVAL, x);
472 mpbarrett_destroy(mb);
477 mpbarrett_reduce(mb, x)
484 mpbarrett_exp(mb, g, x)
495 RETVAL = mp_copy(mb->m);
499 MODULE = Catacomb PACKAGE = Catacomb::MP::CRT
509 croak("Usage: Catacomb::MP::CRT::new(me, n_0, n_1, ...)");
511 v = xmalloc(n * sizeof(mpcrt_mod));
512 for (i = 0; i < n; i++) {
513 v[i].m = mp_copy(mp_fromsv(ST(i + 1), "n_%lu", 0, 0,
516 RETVAL = CREATE(MP_CRT);
517 mpcrt_create(RETVAL, v, n, 0);
539 croak("Wrong number of residues for this CRT context");
540 for (i = 0; i < n; i++)
541 v[i] = mp_fromsv(ST(i + 1), "r_%lu", 0, 0, (unsigned long)i);
542 RETVAL = mpcrt_solve(mc, MP_NEW, v);
547 #----- That's all, folks ----------------------------------------------------