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;
58 RETVAL = mp_loadb(MP_NEW, p, len);
71 RETVAL = mp_loadl(MP_NEW, p, len);
84 RETVAL = mp_loadb2c(MP_NEW, p, len);
97 RETVAL = mp_loadl2c(MP_NEW, p, len);
106 XSINTERFACE_FUNC_SETMP
124 RETVAL = NEWSV(0, sz ? sz : 1);
125 mp_storeb(m, SvPVX(RETVAL), sz);
126 SvCUR_set(RETVAL, sz);
138 sz = (i < 0) ? mp_octets(m) : i;
139 RETVAL = NEWSV(0, sz ? sz : 1);
140 mp_storel(m, SvPVX(RETVAL), sz);
141 SvCUR_set(RETVAL, sz);
153 sz = (i < 0) ? mp_octets2c(m) : i;
154 RETVAL = NEWSV(0, sz ? sz : 1);
155 mp_storeb(m, SvPVX(RETVAL), sz);
156 SvCUR_set(RETVAL, sz);
168 sz = (i < 0) ? mp_octets2c(m) : i;
169 RETVAL = NEWSV(0, sz ? sz : 1);
170 mp_storel(m, SvPVX(RETVAL), sz);
171 SvCUR_set(RETVAL, sz);
177 tostring(m, radix = 10)
181 RETVAL = NEWSV(0, 0);
182 mp_writesv(m, RETVAL, radix);
187 fromstring(me, s, radix = 10)
196 ms.buf = SvPV(s, len);
197 ms.lim = ms.buf + len;
198 x = mp_read(MP_NEW, radix, &mptext_stringops, &ms);
201 if (GIMME_V == G_ARRAY)
202 XPUSHs(sv_2mortal(newSVpvn(ms.buf, ms.lim - ms.buf)));
209 RETVAL = newSViv(mp_toiv(m));
227 XSINTERFACE_FUNC_SETMP
236 RETVAL = mp_split(a);
237 if (RETVAL->v < RETVAL->vl)
257 XSINTERFACE_FUNC_SETMP
259 add sub mul and2c or2c nand2c nor2c xor2c and or nand nor xor exp
269 XSINTERFACE_FUNC_SETMP
279 XSINTERFACE_FUNC_SETMP
291 XSINTERFACE_FUNC_SETMP
293 setbit clearbit setbit2c clearbit2c
310 if (!MP_LEN(n) || !(n->v[0] & 1))
311 croak("n must be odd in Catacomb::MP::jacobi");
312 RETVAL = mp_jacobi(a, n);
321 if (!MP_POSP(p) || !MP_ODDP(p))
322 croak("p is not positive and odd");
323 if (mp_jacobi(x, p) != 1)
324 croak("x not a quadratic residue mod p");
333 mp *q = MP_NEW, *r = MP_NEW;
335 if (MP_EQ(b, MP_ZERO))
336 croak("Divide by zero in Catacomb::MP::div");
341 mp_div(&q, &r, a, b);
360 mp *g = MP_NEW, *x = MP_NEW, *y = MP_NEW;
364 mp_gcd(&g, &x, &y, a, b);
373 mp_gcd(&g, 0, 0, a, b);
386 t = mp_odd(MP_NEW, m, &s);
388 PUSHs(sv_2mortal(newSViv(s)));
391 MODULE = Catacomb PACKAGE = Catacomb::MP PREFIX = pgen_
394 pgen_primep(x, r = &rand_global)
398 MODULE = Catacomb PACKAGE = Catacomb::MP PREFIX = pfilt_
404 MODULE = Catacomb PACKAGE = Catacomb::MP::Mont PREFIX = mpmont_
411 RETVAL = CREATE(MP_Mont);
412 if (mpmont_create(RETVAL, x)) {
448 mp_div(0, &RETVAL, x, mm->m);
449 RETVAL = mpmont_mul(mm, RETVAL, RETVAL, mm->r2);
454 mpmont_expr(mm, g, x)
470 mpmont_mexpr(mm, ...)
476 if (items < 3 || !(items & 1)) {
477 croak("Usage: Catacomb::MP::Mont::mexpr"
478 "(mm, g_0, x_0, g_1, x_1, ...");
481 v = xmalloc(n * sizeof(mp_expfactor));
482 for (i = 1, j = 0; i < items; i += 2, j++) {
483 v[j].base = mp_fromsv(ST(i), "g_i", 0, 0);
484 v[j].exp = mp_fromsv(ST(i + 1), "x_i", 0, 0);
486 RETVAL = mpmont_mexpr(mm, MP_NEW, v, n);
498 if (items < 3 || !(items & 1)) {
499 croak("Usage: Catacomb::MP::Mont::mexp"
500 "(mm, g_0, x_0, g_1, x_1, ...");
503 v = xmalloc(n * sizeof(mp_expfactor));
504 for (i = 1, j = 0; i < items; i += 2, j++) {
505 v[j].base = mp_fromsv(ST(i), "g_%lu", 0, 0, (unsigned long)i);
506 v[j].exp = mp_fromsv(ST(i + 1), "x_%lu", 0, 0, (unsigned long)i);
508 RETVAL = mpmont_mexp(mm, MP_NEW, v, n);
517 RETVAL = MP_COPY(mm->r);
525 RETVAL = MP_COPY(mm->r2);
533 RETVAL = MP_COPY(mm->m);
537 MODULE = Catacomb PACKAGE = Catacomb::MP::Barrett PREFIX = mpbarrett_
544 RETVAL = CREATE(mpbarrett);
545 if (mpbarrett_create(RETVAL, x)) {
556 mpbarrett_destroy(mb);
561 mpbarrett_reduce(mb, x)
568 mpbarrett_exp(mb, g, x)
579 RETVAL = MP_COPY(mb->m);
583 MODULE = Catacomb PACKAGE = Catacomb::MP::Reduce PREFIX = mpreduce_
590 RETVAL = CREATE(MP_Reduce);
591 if (mpreduce_create(RETVAL, x)) {
611 RETVAL = mpreduce_do(r, MP_NEW, x);
616 mpreduce_exp(r, x, y)
627 RETVAL = MP_COPY(r->p);
631 MODULE = Catacomb PACKAGE = Catacomb::MP::CRT
641 croak("Usage: Catacomb::MP::CRT::new(me, n_0, n_1, ...)");
643 v = xmalloc(n * sizeof(mpcrt_mod));
644 for (i = 0; i < n; i++) {
645 v[i].m = mp_copy(mp_fromsv(ST(i + 1), "n_%lu",
646 0, 0, (unsigned long)i));
647 v[i].n = v[i].ni = v[i].nni = 0;
649 RETVAL = CREATE(MP_CRT);
650 mpcrt_create(RETVAL, v, n, 0);
658 RETVAL = MP_COPY(mc->mb.m);
669 if (GIMME_V == G_SCALAR)
670 XPUSHs(sv_2mortal(newSViv(n)));
671 else for (i = 0; i < n; i++)
672 XPUSHs(RET_MP(MP_COPY(mc->v[i].m)));
692 croak("Wrong number of residues for this CRT context");
693 v = xmalloc(n * sizeof(mp *));
694 for (i = 0; i < n; i++)
695 v[i] = mp_fromsv(ST(i + 1), "r_%lu", 0, 0, (unsigned long)i);
696 RETVAL = mpcrt_solve(mc, MP_NEW, v);
701 #----- That's all, folks ----------------------------------------------------