Various changes. Kinda in the middle of it here, but it seems to work.
[catacomb-perl] / pgen.xs
1 # -*-fundamental-*-
2 #
3 # $Id: pgen.xs,v 1.2 2004/04/08 01:36:21 mdw Exp $
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 in Catacomb::MP::Prime::Filter::muladd");
64 if (a > MPW_MAX)
65 croak("step too large in Catacomb::MP::Prime::Filter::muladd");
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 in Catacomb::MP::Prime::Filter::step");
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 if (x->f & MP_NEG)
132 croak("Argument to Catacomb::MP::Prime::Rabin must be positive");
133 if (x->v == x->vl || !(x->v[0] & 1u))
134 croak("Argument to Catacomb::MP::Prime::Rabin must be odd");
135 RETVAL = CREATE(MP_Prime_Rabin);
136 rabin_create(RETVAL, x);
137 OUTPUT:
138 RETVAL
139
140 SV *
141 DESTROY(r)
142 MP_Prime_Rabin *r
143 CODE:
144 rabin_destroy(r);
145 DESTROY(r);
146 XSRETURN_UNDEF;
147
148 int
149 rabin_test(r, g)
150 MP_Prime_Rabin *r
151 mp *g
152
153 int
154 rabin_iters(r)
155 MP_Prime_Rabin *r
156 C_ARGS:
157 mp_bits(r->mm.m)
158
159 int
160 ntests(bits)
161 int bits
162 CODE:
163 RETVAL = rabin_iters(bits);
164 OUTPUT:
165 RETVAL
166
167 MP_Prime_Gen_RabinTester *
168 tester(me)
169 SV *me
170 CODE:
171 RETVAL = CREATE(MP_Prime_Gen_RabinTester);
172 RETVAL->mg.p = pgen_test;
173 RETVAL->mg.ctx = &RETVAL->r;
174 OUTPUT:
175 RETVAL
176
177 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::MagicProc
178
179 SV *
180 DESTROY(proc)
181 MP_Prime_Gen_MagicProc *proc
182 CODE:
183 DESTROY(proc);
184 XSRETURN_UNDEF;
185
186 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::FilterStepper
187
188 SV *
189 DESTROY(s)
190 MP_Prime_Gen_FilterStepper *s
191 CODE:
192 DESTROY(s);
193 XSRETURN_UNDEF;
194
195 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::JumpStepper
196
197 SV *
198 DESTROY(s)
199 MP_Prime_Gen_JumpStepper *s
200 CODE:
201 pfilt_destroy(&s->pf);
202 DESTROY(s);
203 XSRETURN_UNDEF;
204
205 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::RabinTester
206
207 SV *
208 DESTROY(t)
209 MP_Prime_Gen_RabinTester *t
210 CODE:
211 DESTROY(t);
212 XSRETURN_UNDEF;
213
214 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::Proc
215
216 MP_Prime_Gen_MagicProc *
217 ev(me)
218 SV *me
219 CODE:
220 RETVAL = CREATE(MP_Prime_Gen_MagicProc);
221 RETVAL->p = pgen_ev;
222 RETVAL->ctx = 0;
223 OUTPUT:
224 RETVAL
225
226 MP_Prime_Gen_MagicProc *
227 evspin(me)
228 SV *me
229 CODE:
230 RETVAL = CREATE(MP_Prime_Gen_MagicProc);
231 RETVAL->p = pgen_evspin;
232 RETVAL->ctx = 0;
233 OUTPUT:
234 RETVAL
235
236 MP_Prime_Gen_MagicProc *
237 subev(me)
238 SV *me
239 CODE:
240 RETVAL = CREATE(MP_Prime_Gen_MagicProc);
241 RETVAL->p = pgen_subev;
242 RETVAL->ctx = 0;
243 OUTPUT:
244 RETVAL
245
246 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime
247
248 mp *
249 gen(name, m, steps, stepper, tests, tester, events = &PL_sv_undef)
250 char *name
251 mp *m
252 MP_Prime_Gen_NullProc *events
253 unsigned steps
254 MP_Prime_Gen_Proc *stepper
255 unsigned tests
256 MP_Prime_Gen_Proc *tester
257 PREINIT:
258 pgen_proc *ev, *step, *test;
259 void *ectx, *sctx, *tctx;
260 CODE:
261 pgproc_get(events, &ev, &ectx);
262 pgproc_get(stepper, &step, &sctx);
263 pgproc_get(tester, &test, &tctx);
264 RETVAL = pgen(name, MP_NEW, m, ev, ectx,
265 steps, step, sctx, tests, test, tctx);
266 OUTPUT:
267 RETVAL
268
269 void
270 strongprime_setup(name, bits, r = &rand_global, n = 0, events = &PL_sv_undef)
271 char *name
272 unsigned bits
273 grand *r
274 unsigned n
275 MP_Prime_Gen_NullProc *events
276 PREINIT:
277 pgen_proc *ev;
278 void *ectx;
279 mp *d;
280 MP_Prime_Gen_JumpStepper *j;
281 PPCODE:
282 pgproc_get(events, &ev, &ectx);
283 j = CREATE(MP_Prime_Gen_JumpStepper);
284 d = strongprime_setup(name, MP_NEW, &j->pf, bits, r, n, ev, ectx);
285 EXTEND(SP, 2);
286 if (!d) {
287 DESTROY(j);
288 PUSHs(&PL_sv_undef);
289 PUSHs(&PL_sv_undef);
290 } else {
291 j->j.j = &j->pf;
292 j->mg.p = pgen_jump;
293 j->mg.ctx = &j->j;
294 PUSHs(RET_MP(d));
295 PUSHs(RET(j, "Catacomb::MP::Prime::Gen::JumpStepper"));
296 }
297
298 void
299 limlee(name, qbits, pbits, r = &rand_global, on = 0, oevents = &PL_sv_undef, ievents = &PL_sv_undef)
300 char *name
301 unsigned qbits
302 unsigned pbits
303 grand *r
304 unsigned on
305 MP_Prime_Gen_NullProc *oevents
306 MP_Prime_Gen_NullProc *ievents
307 PREINIT:
308 pgen_proc *oev, *iev;
309 void *oec, *iec;
310 mp **f;
311 size_t nf, i;
312 mp *x;
313 PPCODE:
314 pgproc_get(oevents, &oev, &oec);
315 pgproc_get(ievents, &iev, &iec);
316 if (GIMME_V == G_SCALAR) {
317 x = limlee(name, MP_NEW, MP_NEW, qbits, pbits, r, on,
318 oev, oec, iev, iec, 0, 0);
319 EXTEND(SP, 1);
320 PUSHs(RET_MP(x));
321 } else {
322 x = limlee(name, MP_NEW, MP_NEW, qbits, pbits, r, on,
323 oev, oec, iev, iec, &nf, &f);
324 EXTEND(SP, 1 + nf);
325 PUSHs(RET_MP(x));
326 for (i = 0; i < nf; i++)
327 PUSHs(RET_MP(f[i]));
328 xfree(f);
329 }
330
331 MODULE = Catacomb PACKAGE = Catacomb::MP::Prime::Gen::Event
332
333 char *
334 name(ev)
335 MP_Prime_Gen_Event *ev
336 CODE:
337 RETVAL = (char *)ev->name;
338 OUTPUT:
339 RETVAL
340
341 mp *
342 mp(ev, m = 0)
343 MP_Prime_Gen_Event *ev
344 mp *m
345 CODE:
346 RETVAL = mp_copy(ev->m);
347 if (items > 1) {
348 mp_drop(ev->m);
349 ev->m = mp_copy(m);
350 }
351 OUTPUT:
352 RETVAL
353
354 SV *
355 rand(ev)
356 MP_Prime_Gen_Event *ev
357 CODE:
358 RETVAL = MAKE(ev->r, "Catacomb::Rand::Magic");
359 OUTPUT:
360 RETVAL
361
362 #----- That's all, folks ----------------------------------------------------