chiark / gitweb /
infra: Add a copy of the GPL.
[catacomb-perl] / pgen.xs
1 # -*-fundamental-*-
2 #
3 # $Id$
4 #
5 # Prime generation gubbins
6 #
7 # (c) 2001 Straylight/Edgeware
8 #
9
10 #----- Licensing notice -----------------------------------------------------
11 #
12 # This file is part of the Perl interface to Catacomb.
13 #
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.
18
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.
23
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.
27
28 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Filter
29
30 MP_Prime_Filter *
31 new(me, x)
32         SV *me
33         mp *x
34         CODE:
35         RETVAL = CREATE(MP_Prime_Filter);
36         RETVAL->rc = pfilt_create(&RETVAL->pf, x);
37         OUTPUT:
38         RETVAL
39
40 SV *
41 DESTROY(pf)
42         MP_Prime_Filter *pf
43         CODE:
44         pfilt_destroy(&pf->pf);
45         DESTROY(pf);
46         XSRETURN_UNDEF;
47
48 int
49 status(pf)
50         MP_Prime_Filter *pf
51         CODE:
52         RETVAL = pf->rc;
53         OUTPUT:
54         RETVAL
55
56 MP_Prime_Filter *
57 muladd(pf, m, a)
58         MP_Prime_Filter *pf
59         U32 m
60         U32 a
61         CODE:
62         if (m > MPW_MAX)
63           croak("multiplier too large");
64         if (a > MPW_MAX)
65           croak("step too large");
66         RETVAL = CREATE(MP_Prime_Filter);
67         RETVAL->rc = pfilt_muladd(&RETVAL->pf, &pf->pf, m, a);
68         OUTPUT:
69         RETVAL
70
71 int
72 step(pf, n)
73         MP_Prime_Filter *pf
74         U32 n
75         CODE:
76         if (n > MPW_MAX)
77           croak("step too large");
78         RETVAL = pf->rc = pfilt_step(&pf->pf, n);
79         OUTPUT:
80         RETVAL
81
82 int
83 jump(pf, j)
84         MP_Prime_Filter *pf
85         MP_Prime_Filter *j
86         CODE:
87         RETVAL = pf->rc = pfilt_jump(&pf->pf, &j->pf);
88         OUTPUT:
89         RETVAL
90
91 mp *
92 m(pf)
93         MP_Prime_Filter *pf
94         CODE:
95         RETVAL = mp_copy(pf->pf.m);
96         OUTPUT:
97         RETVAL
98
99 MP_Prime_Gen_FilterStepper *
100 stepper(me, step)
101         SV *me
102         unsigned step
103         CODE:
104         RETVAL = CREATE(MP_Prime_Gen_FilterStepper);
105         RETVAL->f.step = step;
106         RETVAL->mg.p = pgen_filter;
107         RETVAL->mg.ctx = &RETVAL->f;
108         OUTPUT:
109         RETVAL
110
111 MP_Prime_Gen_JumpStepper *
112 jumper(me, j)
113         SV *me
114         mp *j
115         CODE:
116         RETVAL = CREATE(MP_Prime_Gen_JumpStepper);
117         pfilt_create(&RETVAL->pf, j);
118         RETVAL->j.j = &RETVAL->pf;
119         RETVAL->mg.p = pgen_jump;
120         RETVAL->mg.ctx = &RETVAL->j;
121         OUTPUT:
122         RETVAL
123
124 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Rabin PREFIX = rabin_
125
126 MP_Prime_Rabin *
127 new(me, x)
128         SV *me
129         mp *x
130         CODE:
131         RETVAL = CREATE(MP_Prime_Rabin);
132         if (rabin_create(RETVAL, x)) {
133           DESTROY(RETVAL);
134           RETVAL = 0;
135         }
136         OUTPUT:
137         RETVAL
138
139 SV *
140 DESTROY(r)
141         MP_Prime_Rabin *r
142         CODE:
143         rabin_destroy(r);
144         DESTROY(r);
145         XSRETURN_UNDEF;
146
147 int
148 rabin_test(r, g)
149         MP_Prime_Rabin *r
150         mp *g
151
152 mp *
153 m(r)
154         MP_Prime_Rabin *r
155         CODE:
156         RETVAL = MP_COPY(r->mm.m);
157         OUTPUT:
158         RETVAL
159
160 int
161 rabin_iters(r)
162         MP_Prime_Rabin *r
163         C_ARGS:
164         mp_bits(r->mm.m)
165
166 int
167 ntests(me, bits)
168         SV *me
169         int bits
170         CODE:
171         RETVAL = rabin_iters(bits);
172         OUTPUT:
173         RETVAL
174
175 MP_Prime_Gen_RabinTester *
176 tester(me)
177         SV *me
178         CODE:
179         RETVAL = CREATE(MP_Prime_Gen_RabinTester);
180         RETVAL->mg.p = pgen_test;
181         RETVAL->mg.ctx = &RETVAL->r;
182         OUTPUT:
183         RETVAL
184
185 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::MagicProc
186
187 SV *
188 DESTROY(proc)
189         MP_Prime_Gen_MagicProc *proc
190         CODE:
191         DESTROY(proc);
192         XSRETURN_UNDEF;
193
194 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::FilterStepper
195
196 SV *
197 DESTROY(s)
198         MP_Prime_Gen_FilterStepper *s
199         CODE:
200         DESTROY(s);
201         XSRETURN_UNDEF;
202
203 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::JumpStepper
204
205 SV *
206 DESTROY(s)
207         MP_Prime_Gen_JumpStepper *s
208         CODE:
209         pfilt_destroy(&s->pf);
210         DESTROY(s);
211         XSRETURN_UNDEF;
212
213 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::RabinTester
214
215 SV *
216 DESTROY(t)
217         MP_Prime_Gen_RabinTester *t
218         CODE:
219         DESTROY(t);
220         XSRETURN_UNDEF;
221
222 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::Proc
223
224 MP_Prime_Gen_MagicProc *
225 ev(me)
226         SV *me
227         CODE:
228         RETVAL = CREATE(MP_Prime_Gen_MagicProc);
229         RETVAL->p = pgen_ev;
230         RETVAL->ctx = 0;
231         OUTPUT:
232         RETVAL
233
234 MP_Prime_Gen_MagicProc *
235 evspin(me)
236         SV *me
237         CODE:
238         RETVAL = CREATE(MP_Prime_Gen_MagicProc);
239         RETVAL->p = pgen_evspin;
240         RETVAL->ctx = 0;
241         OUTPUT:
242         RETVAL
243
244 MP_Prime_Gen_MagicProc *
245 subev(me)
246         SV *me
247         CODE:
248         RETVAL = CREATE(MP_Prime_Gen_MagicProc);
249         RETVAL->p = pgen_subev;
250         RETVAL->ctx = 0;
251         OUTPUT:
252         RETVAL
253
254 int
255 PG_BEGIN(me, ev)
256         SV *me
257         MP_Prime_Gen_Event *ev
258         ALIAS:
259         PG_TRY = 0
260         PG_PASS = 1
261         PG_FAIL = 2
262         PG_ABORT = 3
263         PG_DONE = 4
264         CODE:
265         RETVAL = 0;
266         OUTPUT:
267         RETVAL
268
269 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime
270
271 mp *
272 gen(me, name, m, steps, stepper, tests, tester, events = &PL_sv_undef)
273         SV *me
274         char *name
275         mp *m
276         MP_Prime_Gen_NullProc *events
277         unsigned steps
278         MP_Prime_Gen_Proc *stepper
279         unsigned tests
280         MP_Prime_Gen_Proc *tester
281         PREINIT:
282         pgen_proc *ev, *step, *test;
283         void *ectx, *sctx, *tctx;
284         CODE:
285         pgproc_get(events, &ev, &ectx);
286         pgproc_get(stepper, &step, &sctx);
287         pgproc_get(tester, &test, &tctx);
288         RETVAL = pgen(name, MP_NEW, m, ev, ectx,
289                       steps, step, sctx, tests, test, tctx);
290         OUTPUT:
291         RETVAL
292
293 void
294 strongprime_setup(me, name, bits, r = &rand_global, n = 0, events = &PL_sv_undef)
295         SV *me
296         char *name
297         unsigned bits
298         grand *r
299         unsigned n
300         MP_Prime_Gen_NullProc *events
301         PREINIT:
302         pgen_proc *ev;
303         void *ectx;
304         mp *d;
305         MP_Prime_Gen_JumpStepper *j;
306         PPCODE:
307         pgproc_get(events, &ev, &ectx);
308         j = CREATE(MP_Prime_Gen_JumpStepper);
309         d = strongprime_setup(name, MP_NEW, &j->pf, bits, r, n, ev, ectx);
310         EXTEND(SP, 2);
311         if (!d)
312           DESTROY(j);
313         else {
314           j->j.j = &j->pf;
315           j->mg.p = pgen_jump;
316           j->mg.ctx = &j->j;
317           PUSHs(RET_MP(d));
318           PUSHs(RET(j, "Catacomb::MP::Prime::Gen::JumpStepper"));
319         }
320
321 void
322 limlee(me, name, qbits, pbits, r = &rand_global, on = 0, oevents = &PL_sv_undef, ievents = &PL_sv_undef)
323         SV *me
324         char *name
325         unsigned qbits
326         unsigned pbits
327         grand *r
328         unsigned on
329         MP_Prime_Gen_NullProc *oevents
330         MP_Prime_Gen_NullProc *ievents
331         PREINIT:
332         pgen_proc *oev, *iev;
333         void *oec, *iec;
334         mp **f;
335         size_t nf, i;
336         mp *x;
337         PPCODE:
338         pgproc_get(oevents, &oev, &oec);
339         pgproc_get(ievents, &iev, &iec);
340         if (GIMME_V == G_SCALAR) {
341           x = limlee(name, MP_NEW, MP_NEW, qbits, pbits, r, on,
342                      oev, oec, iev, iec, 0, 0);
343           if (!x) return;
344           EXTEND(SP, 1);
345           PUSHs(RET_MP(x));
346         } else {
347           x = limlee(name, MP_NEW, MP_NEW, qbits, pbits, r, on,
348                      oev, oec, iev, iec, &nf, &f);
349           if (!x) return;
350           EXTEND(SP, 1 + nf);
351           PUSHs(RET_MP(x));
352           for (i = 0; i < nf; i++)
353             PUSHs(RET_MP(f[i]));
354           xfree(f);
355         }
356
357 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::Event
358
359 char *
360 name(ev)
361         MP_Prime_Gen_Event *ev
362         CODE:
363         RETVAL = (char *)ev->name;
364         OUTPUT:
365         RETVAL
366
367 mp *
368 m(ev, x = &PL_sv_undef)
369         MP_Prime_Gen_Event *ev
370         SV *x
371         PREINIT:
372         mp *y;
373         CODE:
374         RETVAL = mp_copy(ev->m);
375         if (SvOK(x)) {
376           if ((y = mp_fromsv(x, "x", 0, 1)) == 0)
377             croak("bad integer");
378           mp_drop(ev->m);
379           ev->m = y;
380         }
381         OUTPUT:
382         RETVAL
383
384 int
385 steps(ev)
386         MP_Prime_Gen_Event *ev
387         CODE:
388         RETVAL = ev->steps;
389         OUTPUT:
390         RETVAL
391
392 int
393 tests(ev)
394         MP_Prime_Gen_Event *ev
395         CODE:
396         RETVAL = ev->tests;
397         OUTPUT:
398         RETVAL
399
400 SV *
401 rand(ev)
402         MP_Prime_Gen_Event *ev
403         CODE:
404         RETVAL = MAKE(ev->r, "Catacomb::Rand::Magic");
405         OUTPUT:
406         RETVAL
407
408 #----- That's all, folks ----------------------------------------------------