Handle edge cases with MP_8BIT and use correct upper limit for the random witnesses
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
diff --git a/bn_mp_prime_is_prime.c b/bn_mp_prime_is_prime.c
index 6ed5d62..dd83680 100644
--- a/bn_mp_prime_is_prime.c
+++ b/bn_mp_prime_is_prime.c
@@ -70,6 +70,12 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result)
return MP_OKAY;
}
}
+#ifdef MP_8BIT
+ // The search in the loop above was exhaustive in this case
+ if (a->used == 1 && PRIME_SIZE >= 31) {
+ return MP_OKAY;
+ }
+#endif
/* first perform trial division */
if ((err = mp_prime_is_divisible(a, &res)) != MP_OKAY) {
@@ -276,21 +282,39 @@ int mp_prime_is_prime(const mp_int *a, int t, int *result)
}
fips_rand <<= sizeof(mp_digit) * CHAR_BIT;
fips_rand |= (unsigned int) b.dp[0];
+ fips_rand &= mask;
}
#endif
// Ceil, because small numbers have a right to live, too,
- len = (int) ( ((fips_rand & mask) + DIGIT_BIT) / DIGIT_BIT);
+ len = (int) ( (fips_rand + DIGIT_BIT) / DIGIT_BIT);
// Unlikely.
if(len < 0){
ix--;
continue;
}
+ // As mentioned above, one 8-bit digit is too small and
+ // although it can only happen in the unlikely case that
+ // an "unsigned int" is smaller than 16 bit a simple test
+ // is cheap and the correction even cheaper.
+#ifdef MP_8BIT
+ // All "a" < 2^8 have been caught before
+ if(len == 1){
+ len++;
+ }
+#endif
if ((err = mp_rand(&b, len)) != MP_OKAY) {
goto LBL_B;
}
+ // That number might got too big and the witness has to be
+ // smaller than or equal to "a"
+ len = mp_count_bits(&b);
+ if (len > size_a) {
+ len = len - size_a;
+ mp_div_2d(&b, len, &b, NULL);
+ }
// Although the chance for b <= 3 is miniscule, try again.
- if(mp_cmp_d(&b,3) != MP_GT) {
+ if (mp_cmp_d(&b,3) != MP_GT) {
ix--;
continue;
}