-
Notifications
You must be signed in to change notification settings - Fork 166
Open
Description
I need to frequently generate RSA keys in bulk. I am using the following Rust code to generate a key:
let rsa_key = rsa::RsaPrivateKey::new(&mut rand::thread_rng(), 2048).unwrap();
Running this code in release mode to generate 100 RSA keys takes about 18 seconds on my machine. In comparison, I used the following code in C (OpenSSL) and C# (CNG) to generate the same-size RSA key.
C - OpenSSL
RSA *rsa_key = RSA_new();
BIGNUM *e = BN_new();
BN_set_word(e, RSA_F4);
RSA_generate_key_ex(rsa_key, 2048, e, NULL);
C# - CNG
var rsaKey = new RSACng(2048).Key;
To generate 100 keys, the C code takes about 6.7 seconds and the C# code takes about 5.5 seconds. I was surprised that the Rust key generation took about 3x more time than both C and C#.
Activity
aloucks commentedon Feb 5, 2022
I ran into this a while back as well. The bottleneck appears to be in the prime number generation:RSA/src/algorithms.rs
Line 99 in 7395997
EDIT: After benchmarking this some more, it actually looks like the number of primes used to generate the key is the influencing factor. I increased the number of primes from
2
to3
(based on the table 1 in the PDF linked below) and saw the time it took to generate 100 keys dropped from about16
seconds to7
seconds.RSA/src/key.rs
Line 279 in 7395997
https://cacr.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
dignifiedquire commentedon Oct 9, 2022
The main reason asfaik is that the underlying operations are nowhere nearly as optimized as the code in OpenSSL and whatever library C# is calling into.
@aloucks that will generate a different RSA key setup though, and most applications today assume using 2 primes and not more asfaik.
jellevos commentedon Oct 28, 2022
In https://github.com/jellevos/scicrypt/blob/master/scicrypt-numbertheory/src/lib.rs I have implemented an algorithm that is almost exactly the same as OpenSSL's. Depending on the machine and parameters it is slightly faster or slightly slower than OpenSSL. I am happy to give it a try to reimplement it in this crate (the algorithm is not complicated). Of course, if the bottleneck is the underlying arithmetic, then it might not make a large difference.
tarcieri commentedon Oct 28, 2022
@jellevos would definitely be curious what the performance is if you did port it over
r10s commentedon Oct 28, 2022
ftr: older issue with similar topic: #29
darconeous commentedon Jun 27, 2023
Once dignifiedquire/num-bigint#48 lands, prime generation should be a little faster.
dignifiedquire commentedon Jun 27, 2023
@darconeous
next_prime
is not actually used for prime generation in this crate, so that won't help unfortunately.darconeous commentedon Jun 27, 2023
do'h!
richarddd commentedon Jan 2, 2025
@jellevos can you open a PR?
tarcieri commentedon Jan 2, 2025
#394 switches to using
crypto-primes
which should be a fairly mature implementation of prime number generation and primality testing.I'm not sure if it improves performance as I haven't benchmarked it, but regardless whatever performance problems remain are in
crypto-bigint
itself.