From 0970d397c415de754e43c1aea8c84e8592f070f4 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sat, 3 Feb 2018 19:54:36 -0500 Subject: [PATCH] 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 --- crypto/fipsmodule/bn/cmp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/crypto/fipsmodule/bn/cmp.c b/crypto/fipsmodule/bn/cmp.c index 89775c0f..692adb5a 100644 --- a/crypto/fipsmodule/bn/cmp.c +++ b/crypto/fipsmodule/bn/cmp.c @@ -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) { - switch (bn_minimal_width(bn)) { - case 1: - return bn->d[0] == w; - case 0: - return w == 0; - default: - return 0; + if (bn->width == 0) { + return w == 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) { @@ -150,7 +150,7 @@ int BN_cmp_word(const BIGNUM *a, BN_ULONG b) { } 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) {