Make various BIGNUM comparisons constant-time.

Primality testing checks for small words in random places.

Median of 29 RSA keygens: 0m0.811s -> 0m0.521s
(Accuracy beyond 0.1s is questionable, and this "speed up" is certainly
noise.)

Bug: 238
Change-Id: Ie5efab7291302a42ac6e283d25da0c094d8577e7
Reviewed-on: https://boringssl-review.googlesource.com/25885
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2018-02-03 19:54:36 -05:00 committed by Adam Langley
parent ad066861dd
commit 0970d397c4

View File

@ -128,14 +128,14 @@ int bn_less_than_words(const BN_ULONG *a, const BN_ULONG *b, size_t len) {
} }
int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w) { int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w) {
switch (bn_minimal_width(bn)) { if (bn->width == 0) {
case 1: return w == 0;
return bn->d[0] == w;
case 0:
return w == 0;
default:
return 0;
} }
BN_ULONG mask = bn->d[0] ^ w;
for (int i = 1; i < bn->width; i++) {
mask |= bn->d[i];
}
return mask == 0;
} }
int BN_cmp_word(const BIGNUM *a, BN_ULONG b) { int BN_cmp_word(const BIGNUM *a, BN_ULONG b) {
@ -150,7 +150,7 @@ int BN_cmp_word(const BIGNUM *a, BN_ULONG b) {
} }
int BN_is_zero(const BIGNUM *bn) { int BN_is_zero(const BIGNUM *bn) {
return bn_minimal_width(bn) == 0; return bn_fits_in_words(bn, 0);
} }
int BN_is_one(const BIGNUM *bn) { int BN_is_one(const BIGNUM *bn) {