1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-08 08:58:00 +00:00

PrimeCandidateSource: remember prime factors of n-1.

We already had a function pcs_require_residue_1() which lets you ask
PrimeCandidateSource to ensure it only returns numbers congruent to 1
mod a given value. pcs_require_residue_1_mod_prime() is the same, but
it also records the number in a list of prime factors of n-1, which
can be queried later.

The idea is that if you're generating a DSA key, in which the small
prime q must divide p-1, the upcoming provable generation algorithm
will be able to recover q from the PrimeCandidateSource and use it as
part of the primality certificate, which reduces the number of bits of
extra prime factors it also has to make up.
This commit is contained in:
Simon Tatham 2020-02-29 06:33:26 +00:00
parent 2be70baa0d
commit 18be6aec58
4 changed files with 31 additions and 1 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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.

View File

@ -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)