1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Fix occasional hang in SPP_MAURER_COMPLEX logic.

I generated a list of sizes in bits for factors of p-1, knowing a
range of bit sizes that I wanted their product to fall in. But I
forgot that when you multiply together two or more numbers of
particular bit sizes, you can get more than one possible bit size
back. My code was estimating at the low end of the possible range, so
sometimes it would end up with more bits of the output prime specified
than it expected, and be left without enough variable bits to actually
be able to find a prime somewhere in the remaining space.

Now when I'm planning the factor list, I compute both the min and max
sizes of the product of the factors, and abort if any part of the
possible range is outside the safe zone.
This commit is contained in:
Simon Tatham 2020-03-02 18:49:07 +00:00
parent a82e1da0b7
commit bf3aa818e4

View File

@ -556,13 +556,17 @@ static mp_int *provableprime_generate_inner(
got_list:;
/*
* Now translate those real numbers into actual bit
* counts, and do a last-minute check to make sure we
* haven't generated one too close to the final output
* size.
* counts, and do a last-minute check to make sure
* their product is going to be in range.
*
* We have to check both the min and max sizes of the
* total. A b-bit number is in [2^{b-1},2^b). So the
* product of numbers of sizes b_1,...,b_k is at least
* 2^{\sum (b_i-1)}, and less than 2^{\sum b_i}.
*/
nsizes = 0;
unsigned total = 1; /* account for leading 1 */
unsigned min_total = 0, max_total = 0;
for (size_t i = 0; i < ns; i++) {
/* These sizes are measured in actual entropy, so
@ -573,15 +577,16 @@ static mp_int *provableprime_generate_inner(
sgrowarray(sizes, sizesize, nsizes);
sizes[nsizes++] = this_size;
total += this_size - 1;
min_total += this_size - 1;
max_total += this_size;
}
debug_f(" total bits = %u", total);
if (total < real_min || total > real_max) {
debug_f(" total bits = [%u,%u)", min_total, max_total);
if (min_total < real_min || max_total > real_max+1) {
debug_f(" total out of range, try again");
} else {
debug_f(" success! %"SIZEu" sub-primes totalling %u bits",
nsizes, total);
debug_f(" success! %"SIZEu" sub-primes totalling [%u,%u) "
"bits", nsizes, min_total, max_total);
break;
}
}