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 <alangley@gmail.com>
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
This commit is contained in:
Adam Langley 2018-03-30 13:43:59 -07:00 committed by CQ bot account: commit-bot@chromium.org
parent 5833dd807e
commit a0f1c8e3b1

View File

@ -12,11 +12,13 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <algorithm>
#include <string> #include <string>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <vector> #include <vector>
#include <assert.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -194,6 +196,59 @@ static bool SpeedRSA(const std::string &key_name, RSA *key,
return true; 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<BIGNUM> e(BN_new());
if (!BN_set_word(e.get(), 65537)) {
return false;
}
const std::vector<int> kSizes = {2048, 3072, 4096};
for (int size : kSizes) {
const uint64_t start = time_now();
unsigned num_calls = 0;
unsigned us;
std::vector<unsigned> durations;
for (;;) {
bssl::UniquePtr<RSA> 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<double>(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) { static uint8_t *align(uint8_t *in, unsigned alignment) {
return reinterpret_cast<uint8_t *>( return reinterpret_cast<uint8_t *>(
(reinterpret_cast<uintptr_t>(in) + alignment) & (reinterpret_cast<uintptr_t>(in) + alignment) &
@ -719,7 +774,8 @@ bool Speed(const std::vector<std::string> &args) {
!SpeedECDSA(selected) || !SpeedECDSA(selected) ||
!Speed25519(selected) || !Speed25519(selected) ||
!SpeedSPAKE2(selected) || !SpeedSPAKE2(selected) ||
!SpeedScrypt(selected)) { !SpeedScrypt(selected) ||
!SpeedRSAKeyGen(selected)) {
return false; return false;
} }