diff --git a/primecandidate.c b/primecandidate.c
index 353dc4adb74a742ba759329a2cee0a8eda14d164..b7620fec780f0c3308f7c1acddadeb9a1e83be6a 100644
--- a/primecandidate.c
+++ b/primecandidate.c
@@ -32,6 +32,10 @@ struct PrimeCandidateSource {
      * (modulus, residue) pairs we want to avoid. */
     struct avoid *avoids;
     size_t navoids, avoidsize;
+
+    /* List of known primes that our number will be congruent to 1 modulo */
+    mp_int **kps;
+    size_t nkps, kpsize;
 };
 
 PrimeCandidateSource *pcs_new_with_firstbits(unsigned bits,
@@ -44,6 +48,9 @@ PrimeCandidateSource *pcs_new_with_firstbits(unsigned bits,
     s->bits = bits;
     s->ready = false;
 
+    s->kps = NULL;
+    s->nkps = s->kpsize = 0;
+
     s->avoids = NULL;
     s->navoids = s->avoidsize = 0;
 
@@ -83,7 +90,10 @@ void pcs_free(PrimeCandidateSource *s)
     mp_free(s->limit);
     mp_free(s->factor);
     mp_free(s->addend);
+    for (size_t i = 0; i < s->nkps; i++)
+        mp_free(s->kps[i]);
     sfree(s->avoids);
+    sfree(s->kps);
     sfree(s);
 }
 
@@ -196,6 +206,14 @@ void pcs_require_residue_1(PrimeCandidateSource *s, mp_int *mod)
     mp_free(res);
 }
 
+void pcs_require_residue_1_mod_prime(PrimeCandidateSource *s, mp_int *mod)
+{
+    pcs_require_residue_1(s, mod);
+
+    sgrowarray(s->kps, s->kpsize, s->nkps);
+    s->kps[s->nkps++] = mp_copy(mod);
+}
+
 void pcs_avoid_residue_small(PrimeCandidateSource *s,
                              unsigned mod, unsigned res)
 {
@@ -362,3 +380,9 @@ unsigned pcs_get_bits(PrimeCandidateSource *pcs)
 {
     return pcs->bits;
 }
+
+mp_int **pcs_get_known_prime_factors(PrimeCandidateSource *pcs, size_t *nout)
+{
+    *nout = pcs->nkps;
+    return pcs->kps;
+}
diff --git a/sshdssg.c b/sshdssg.c
index ad3fcc029ccf2e070cf6494b27d09c6ba2d5119f..3b5272566d9caf896bdedf460cbfddfee196f5b2 100644
--- a/sshdssg.c
+++ b/sshdssg.c
@@ -53,7 +53,7 @@ int dsa_generate(struct dss_key *key, int bits, PrimeGenerationContext *pgc,
      */
     progress_start_phase(prog, phase_p);
     pcs = pcs_new(bits);
-    pcs_require_residue_1(pcs, q);
+    pcs_require_residue_1_mod_prime(pcs, q);
     mp_int *p = primegen_generate(pgc, pcs, prog);
     progress_report_phase_complete(prog);
 
diff --git a/sshkeygen.h b/sshkeygen.h
index cccb1fb2be65e830b7699bd359e7a5ecf8b9d9e6..6a9594f2a4bfaf90d8fcd90cf6e69ebe242f53a9 100644
--- a/sshkeygen.h
+++ b/sshkeygen.h
@@ -41,6 +41,10 @@ void pcs_require_residue(PrimeCandidateSource *s, mp_int *mod, mp_int *res);
 /* Convenience wrapper for the common case where res = 1 */
 void pcs_require_residue_1(PrimeCandidateSource *s, mp_int *mod);
 
+/* Same as pcs_require_residue_1, but also records that the modulus is
+ * known to be prime */
+void pcs_require_residue_1_mod_prime(PrimeCandidateSource *s, mp_int *mod);
+
 /* Insist that generated numbers must _not_ be congruent to 'res' mod
  * 'mod'. This is used to avoid being 1 mod the RSA public exponent,
  * which is small, so it only needs ordinary integer parameters. */
@@ -66,6 +70,7 @@ void pcs_inspect(PrimeCandidateSource *pcs, mp_int **limit_out,
 
 /* Query functions for primegen to use */
 unsigned pcs_get_bits(PrimeCandidateSource *pcs);
+mp_int **pcs_get_known_prime_factors(PrimeCandidateSource *pcs, size_t *nout);
 
 /* ----------------------------------------------------------------------
  * A system for doing Miller-Rabin probabilistic primality tests.
diff --git a/testcrypt.h b/testcrypt.h
index 89cbaadf05aa69149e7699c6865ceae80f98a876..59135c6e15833215d01b014b176e19d855b2dbd3 100644
--- a/testcrypt.h
+++ b/testcrypt.h
@@ -273,6 +273,7 @@ FUNC1(val_pcs, pcs_new, uint)
 FUNC3(val_pcs, pcs_new_with_firstbits, uint, uint, uint)
 FUNC3(void, pcs_require_residue, val_pcs, val_mpint, val_mpint)
 FUNC2(void, pcs_require_residue_1, val_pcs, val_mpint)
+FUNC2(void, pcs_require_residue_1_mod_prime, val_pcs, val_mpint)
 FUNC3(void, pcs_avoid_residue_small, val_pcs, uint, uint)
 FUNC1(void, pcs_ready, val_pcs)
 FUNC4(void, pcs_inspect, val_pcs, out_val_mpint, out_val_mpint, out_val_mpint)