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