- if ((rp->q = strongprime("q", MP_NEW, nbits/2, r, n, event, ectx)) == 0)
- goto fail_q;
+
+ /* --- Do painful fiddling with GCD steppers --- */
+
+ {
+ mp *q;
+ rabin rb;
+
+ if ((q = strongprime_setup("q", MP_NEWSEC, &g.jp, nbits / 2,
+ r, n, event, ectx)) == 0)
+ goto fail_q;
+ 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);
+ pfilt_destroy(&g.jp);
+ mp_drop(g.r);
+ if (!q) {
+ mp_drop(g.g);
+ if (n)
+ goto fail_q;
+ mp_drop(rp->p);
+ goto again;
+ }
+ rp->q = q;
+ }
+
+ /* --- Ensure that %$p > q$% --- *
+ *
+ * Also ensure that %$p$% and %$q$% are sufficiently different to deter
+ * square-root-based factoring methods.
+ */
+
+ phi = mp_sub(phi, rp->p, rp->q);
+ if (MP_LEN(phi) * 4 < MP_LEN(rp->p) * 3 ||
+ MP_LEN(phi) * 4 < MP_LEN(rp->q) * 3) {
+ mp_drop(rp->p);
+ mp_drop(g.g);
+ if (n)
+ goto fail_q;
+ mp_drop(rp->q);
+ goto again;
+ }
+
+ if (phi->f & MP_NEG) {
+ mp *z = rp->p;
+ rp->p = rp->q;
+ rp->q = z;
+ }