diff --git a/primecandidate.c b/primecandidate.c index 353dc4ad..b7620fec 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 ad3fcc02..3b527256 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 cccb1fb2..6a9594f2 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 89cbaadf..59135c6e 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)