int pgen_test(int rq, pgen_event *ev, void *p)
{
rabin *r = p;
+ mp *a = MP_NEW;
int rc = PGEN_ABORT;
switch (rq) {
rc = PGEN_TRY;
break;
case PGEN_TRY:
- if (!ev->tests)
- rc = rabin_rtest(r, MP_TWO);
- else {
- mp *a = mprand_range(MP_NEW, ev->m, ev->r, 0);
- rc = rabin_rtest(r, a);
- mp_drop(a);
- }
+ a = mprand_range(a, ev->m, ev->r, 0);
+ rc = rabin_rtest(r, a);
break;
case PGEN_DONE:
rabin_destroy(r);
break;
}
+ mp_drop(a);
+ return (rc);
+}
+
+/* --- @pgen_bailliepswtest@ --- */
+
+int pgen_bailliepswtest(int rq, pgen_event *ev, void *p)
+{
+ rabin r;
+ int rc;
+
+ switch (rq) {
+ case PGEN_BEGIN:
+ if (ev->tests != 2) rc = PGEN_ABORT;
+ else rc = PGEN_TRY;
+ break;
+
+ case PGEN_DONE:
+ rc = PGEN_DONE;
+ break;
+
+ case PGEN_TRY:
+ switch (ev->tests) {
+ case 2:
+ rabin_create(&r, ev->m);
+ rc = rabin_test(&r, MP_TWO);
+ rabin_destroy(&r);
+ break;
+ case 1:
+ rc = pgen_granfrob(ev->m, 0, 0);
+ break;
+ default:
+ rc = PGEN_ABORT;
+ break;
+ }
+ break;
+
+ default:
+ rc = PGEN_ABORT;
+ break;
+ }
+
return (rc);
}
ev.m = MP_COPY(m);
else
ev.m = 0;
- ev.steps = 0;
- ev.tests = 0;
+ ev.steps = steps;
+ ev.tests = tests;
ev.r = fibrand_create(0);
/* --- Tell the event handler we're under way --- */
/* --- If decrementing counters is requested, do that --- */
if ((act & A_STEP) && steps) {
- ev.steps++;
- if (ev.steps == steps) {
+ ev.steps--;
+ if (!ev.steps) {
act |= A_EVENT | A_ENDSTEP | A_DONE;
rc = PGEN_ABORT;
}
- ev.tests = 0;
+ ev.tests = tests;
}
if ((act & A_TEST) && tests) {
- ev.tests++;
- if (ev.tests == tests) {
+ ev.tests--;
+ if (!ev.tests) {
act |= A_ENDTEST | A_ENDSTEP | A_DONE;
rc = PGEN_DONE;
}