Skip to content

Commit a649ce1

Browse files
authored
feat: allow for custom public exponent value in keygen
This commit adds a function to `rsa::algorithms` called `generate_multi_prime_key_with_exp` which allows the caller to specify a custom value for the public key exponent. This commit also adds a convenience routine to `rsa::RSAPrivateKey` called `new_with_exp` which allows the caller to specify the custom value for the public key exponent as part of `rsa::RSAPrivateKey` constructor. Exposing the public key exponent matches an OpenSSL call `openssl::rsa::generate_with_e` which is useful in certain settings such when generating the signing keys for SGX enclaves.
1 parent af31a45 commit a649ce1

File tree

2 files changed

+50
-14
lines changed

2 files changed

+50
-14
lines changed

src/algorithms.rs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,46 @@ use crate::key::RSAPrivateKey;
1010
/// Default exponent for RSA keys.
1111
const EXP: u64 = 65537;
1212

13-
// Generates a multi-prime RSA keypair of the given bit
14-
// size and the given random source, as suggested in [1]. Although the public
15-
// keys are compatible (actually, indistinguishable) from the 2-prime case,
16-
// the private keys are not. Thus it may not be possible to export multi-prime
17-
// private keys in certain formats or to subsequently import them into other
18-
// code.
19-
//
20-
// Table 1 in [2] suggests maximum numbers of primes for a given size.
21-
//
22-
// [1] US patent 4405829 (1972, expired)
23-
// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
13+
/// Generates a multi-prime RSA keypair of the given bit size,
14+
/// and the given random source, as suggested in [1]. Although the public
15+
/// keys are compatible (actually, indistinguishable) from the 2-prime case,
16+
/// the private keys are not. Thus it may not be possible to export multi-prime
17+
/// private keys in certain formats or to subsequently import them into other
18+
/// code.
19+
///
20+
/// Uses default public key exponent of `65537`. If you want to use a custom
21+
/// public key exponent value, use `algorithms::generate_multi_prime_key_with_exp`
22+
/// instead.
23+
///
24+
/// Table 1 in [2] suggests maximum numbers of primes for a given size.
25+
///
26+
/// [1] US patent 4405829 (1972, expired)
27+
/// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
2428
pub fn generate_multi_prime_key<R: Rng>(
2529
rng: &mut R,
2630
nprimes: usize,
2731
bit_size: usize,
32+
) -> Result<RSAPrivateKey> {
33+
let exp = BigUint::from_u64(EXP).expect("invalid static exponent");
34+
generate_multi_prime_key_with_exp(rng, nprimes, bit_size, &exp)
35+
}
36+
37+
/// Generates a multi-prime RSA keypair of the given bit size, public exponent,
38+
/// and the given random source, as suggested in [1]. Although the public
39+
/// keys are compatible (actually, indistinguishable) from the 2-prime case,
40+
/// the private keys are not. Thus it may not be possible to export multi-prime
41+
/// private keys in certain formats or to subsequently import them into other
42+
/// code.
43+
///
44+
/// Table 1 in [2] suggests maximum numbers of primes for a given size.
45+
///
46+
/// [1] US patent 4405829 (1972, expired)
47+
/// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
48+
pub fn generate_multi_prime_key_with_exp<R: Rng>(
49+
rng: &mut R,
50+
nprimes: usize,
51+
bit_size: usize,
52+
exp: &BigUint,
2853
) -> Result<RSAPrivateKey> {
2954
if nprimes < 2 {
3055
return Err(Error::NprimesTooSmall);
@@ -96,7 +121,6 @@ pub fn generate_multi_prime_key<R: Rng>(
96121
continue 'next;
97122
}
98123

99-
let exp = BigUint::from_u64(EXP).expect("invalid static exponent");
100124
if let Some(d) = exp.mod_inverse(totient) {
101125
n_final = n;
102126
d_final = d.to_biguint().unwrap();
@@ -106,7 +130,7 @@ pub fn generate_multi_prime_key<R: Rng>(
106130

107131
Ok(RSAPrivateKey::from_components(
108132
n_final,
109-
BigUint::from_u64(EXP).expect("invalid static exponent"),
133+
exp.clone(),
110134
d_final,
111135
primes,
112136
))

src/key.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use serde_crate::{Deserialize, Serialize};
88
use std::ops::Deref;
99
use zeroize::Zeroize;
1010

11-
use crate::algorithms::generate_multi_prime_key;
11+
use crate::algorithms::{generate_multi_prime_key, generate_multi_prime_key_with_exp};
1212
use crate::errors::{Error, Result};
1313

1414
use crate::padding::PaddingScheme;
@@ -338,6 +338,18 @@ impl RSAPrivateKey {
338338
generate_multi_prime_key(rng, 2, bit_size)
339339
}
340340

341+
/// Generate a new RSA key pair of the given bit size and the public exponent
342+
/// using the passed in `rng`.
343+
///
344+
/// Unless you have specific needs, you should use `RSAPrivateKey::new` instead.
345+
pub fn new_with_exp<R: Rng>(
346+
rng: &mut R,
347+
bit_size: usize,
348+
exp: &BigUint,
349+
) -> Result<RSAPrivateKey> {
350+
generate_multi_prime_key_with_exp(rng, 2, bit_size, exp)
351+
}
352+
341353
/// Constructs an RSA key pair from the individual components.
342354
pub fn from_components(
343355
n: BigUint,

0 commit comments

Comments
 (0)