if ((rp->p = strongprime("p", MP_NEWSEC, nbits/2, r, n, event, ectx)) == 0)
goto fail_p;
- /* --- Do painful fiddling with GCD steppers --- */
+ /* --- Do painful fiddling with GCD steppers --- *
+ *
+ * Also, arrange that %$q \ge \lceil 2^{N-1}/p \rceil$%, so that %$p q$%
+ * has the right length.
+ */
{
mp *q;
+ mp *t = MP_NEW, *u = MP_NEW;
rabin rb;
if ((q = strongprime_setup("q", MP_NEWSEC, &g.jp, nbits / 2,
r, n, event, ectx)) == 0)
goto fail_q;
+ t = mp_lsl(t, MP_ONE, nbits - 1);
+ mp_div(&t, &u, t, rp->p);
+ if (!MP_ZEROP(u)) t = mp_add(t, t, MP_ONE);
+ if (MP_CMP(q, <, t)) q = mp_leastcongruent(q, t, q, g.jp.m);
+ mp_drop(t);
+
g.r = mp_lsr(MP_NEW, rp->p, 1);
g.g = MP_NEW;
g.max = MP_256;
q = pgen("q", q, q, event, ectx, n, pgen_gcdstep, &g,
- rabin_iters(nbits/2), pgen_test, &rb);
+ rabin_iters(nbits/2), pgen_test, &rb);
pfilt_destroy(&g.jp);
mp_drop(g.r);
if (!q) {