From a0f1c8e3b16feb49c787f7a7c158a6f1d9460f67 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Fri, 30 Mar 2018 13:43:59 -0700 Subject: [PATCH] Add RSA key generation to speed.cc On a Skylake machine, the improvements to make RSA key generation constant-time did slow things down a bit: Before: Did 217 RSA 2048 key-gen operations in 30231344us (7.2 ops/sec) min: 17154us, median: 117284us, max: 518336us Did 70 RSA 3072 key-gen operations in 30188611us (2.3 ops/sec) min: 57759us, median: 348873us, max: 1760351us Did 27 RSA 4096 key-gen operations in 30264235us (0.9 ops/sec) min: 202096us, median: 980160us, max: 4282915us After: Did 186 RSA 2048 key-gen operations in 30021173us (6.2 ops/sec) min: 74850us, median: 147650us, max: 407031us Did 54 RSA 3072 key-gen operations in 30111667us (1.8 ops/sec) min: 292050us, median: 483786us, max: 1294105us Did 18 RSA 4096 key-gen operations in 30662495us (0.6 ops/sec) min: 902547us, median: 1446689us, max: 3660302us Change-Id: I52a96bb41bab759aa7ef6239bdfa533707a9eb3c Reviewed-on: https://boringssl-review.googlesource.com/26904 Commit-Queue: Adam Langley Commit-Queue: David Benjamin Reviewed-by: David Benjamin CQ-Verified: CQ bot account: commit-bot@chromium.org --- tool/speed.cc | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/tool/speed.cc b/tool/speed.cc index f4b452fc..9f5259f5 100644 --- a/tool/speed.cc +++ b/tool/speed.cc @@ -12,11 +12,13 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include #include +#include #include #include #include @@ -194,6 +196,59 @@ static bool SpeedRSA(const std::string &key_name, RSA *key, return true; } +static bool SpeedRSAKeyGen(const std::string &selected) { + // Don't run this by default because it's so slow. + if (selected != "RSAKeyGen") { + return true; + } + + bssl::UniquePtr e(BN_new()); + if (!BN_set_word(e.get(), 65537)) { + return false; + } + + const std::vector kSizes = {2048, 3072, 4096}; + for (int size : kSizes) { + const uint64_t start = time_now(); + unsigned num_calls = 0; + unsigned us; + std::vector durations; + + for (;;) { + bssl::UniquePtr rsa(RSA_new()); + + const uint64_t iteration_start = time_now(); + if (!RSA_generate_key_ex(rsa.get(), size, e.get(), nullptr)) { + fprintf(stderr, "RSA_generate_key_ex failed.\n"); + ERR_print_errors_fp(stderr); + return false; + } + const uint64_t iteration_end = time_now(); + + num_calls++; + durations.push_back(iteration_end - iteration_start); + + us = iteration_end - start; + if (us > 30 * 1000000 /* 30 secs */) { + break; + } + } + + std::sort(durations.begin(), durations.end()); + printf("Did %u RSA %d key-gen operations in %uus (%.1f ops/sec)\n", + num_calls, size, us, + (static_cast(num_calls) / us) * 1000000); + const size_t n = durations.size(); + assert(n > 0); + unsigned median = n & 1 ? durations[n / 2] + : (durations[n / 2 - 1] + durations[n / 2]) / 2; + printf(" min: %uus, median: %uus, max: %uus\n", durations[0], median, + durations[n - 1]); + } + + return true; +} + static uint8_t *align(uint8_t *in, unsigned alignment) { return reinterpret_cast( (reinterpret_cast(in) + alignment) & @@ -719,7 +774,8 @@ bool Speed(const std::vector &args) { !SpeedECDSA(selected) || !Speed25519(selected) || !SpeedSPAKE2(selected) || - !SpeedScrypt(selected)) { + !SpeedScrypt(selected) || + !SpeedRSAKeyGen(selected)) { return false; }