Skip to content

Commit 986c9a9

Browse files
committed
Take Option of bit size in high-level API to avoid repetition
1 parent 4591582 commit 986c9a9

File tree

3 files changed

+38
-27
lines changed

3 files changed

+38
-27
lines changed

benches/bench.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -207,23 +207,23 @@ fn bench_presets(c: &mut Criterion) {
207207

208208
let mut rng = make_rng();
209209
group.bench_function("(U128) Random prime", |b| {
210-
b.iter(|| prime_with_rng::<{ nlimbs!(128) }>(&mut rng, 128))
210+
b.iter(|| prime_with_rng::<{ nlimbs!(128) }>(&mut rng, None))
211211
});
212212

213213
let mut rng = make_rng();
214214
group.bench_function("(U1024) Random prime", |b| {
215-
b.iter(|| prime_with_rng::<{ nlimbs!(1024) }>(&mut rng, 1024))
215+
b.iter(|| prime_with_rng::<{ nlimbs!(1024) }>(&mut rng, None))
216216
});
217217

218218
let mut rng = make_rng();
219219
group.bench_function("(U128) Random safe prime", |b| {
220-
b.iter(|| safe_prime_with_rng::<{ nlimbs!(128) }>(&mut rng, 128))
220+
b.iter(|| safe_prime_with_rng::<{ nlimbs!(128) }>(&mut rng, None))
221221
});
222222

223223
group.sample_size(20);
224224
let mut rng = make_rng();
225225
group.bench_function("(U1024) Random safe prime", |b| {
226-
b.iter(|| safe_prime_with_rng::<{ nlimbs!(1024) }>(&mut rng, 1024))
226+
b.iter(|| safe_prime_with_rng::<{ nlimbs!(1024) }>(&mut rng, None))
227227
});
228228

229229
group.finish();
@@ -233,19 +233,19 @@ fn bench_presets(c: &mut Criterion) {
233233

234234
let mut rng = make_rng();
235235
group.bench_function("(U128) Random safe prime", |b| {
236-
b.iter(|| safe_prime_with_rng::<{ nlimbs!(128) }>(&mut rng, 128))
236+
b.iter(|| safe_prime_with_rng::<{ nlimbs!(128) }>(&mut rng, None))
237237
});
238238

239239
// The performance should scale with the prime size, not with the Uint size.
240240
// So we should strive for this test's result to be as close as possible
241241
// to that of the previous one and as far away as possible from the next one.
242242
group.bench_function("(U256) Random 128 bit safe prime", |b| {
243-
b.iter(|| safe_prime_with_rng::<{ nlimbs!(256) }>(&mut rng, 128))
243+
b.iter(|| safe_prime_with_rng::<{ nlimbs!(256) }>(&mut rng, Some(128)))
244244
});
245245

246246
// The upper bound for the previous test.
247247
group.bench_function("(U256) Random 256 bit safe prime", |b| {
248-
b.iter(|| safe_prime_with_rng::<{ nlimbs!(256) }>(&mut rng, 256))
248+
b.iter(|| safe_prime_with_rng::<{ nlimbs!(256) }>(&mut rng, None))
249249
});
250250

251251
group.finish();

src/presets.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,21 @@ use crate::hazmat::{
99
};
1010

1111
/// Returns a random prime of size `bit_length` using [`OsRng`] as the RNG.
12+
/// If `bit_length` is `None`, the full size of `Uint<L>` is used.
1213
///
1314
/// See [`is_prime_with_rng`] for details about the performed checks.
1415
#[cfg(feature = "default-rng")]
15-
pub fn prime<const L: usize>(bit_length: usize) -> Uint<L> {
16+
pub fn prime<const L: usize>(bit_length: Option<usize>) -> Uint<L> {
1617
prime_with_rng(&mut OsRng, bit_length)
1718
}
1819

1920
/// Returns a random safe prime (that is, such that `(n - 1) / 2` is also prime)
2021
/// of size `bit_length` using [`OsRng`] as the RNG.
22+
/// If `bit_length` is `None`, the full size of `Uint<L>` is used.
2123
///
2224
/// See [`is_prime_with_rng`] for details about the performed checks.
2325
#[cfg(feature = "default-rng")]
24-
pub fn safe_prime<const L: usize>(bit_length: usize) -> Uint<L> {
26+
pub fn safe_prime<const L: usize>(bit_length: Option<usize>) -> Uint<L> {
2527
safe_prime_with_rng(&mut OsRng, bit_length)
2628
}
2729

@@ -44,11 +46,16 @@ pub fn is_safe_prime<const L: usize>(num: &Uint<L>) -> bool {
4446
}
4547

4648
/// Returns a random prime of size `bit_length` using the provided RNG.
49+
/// If `bit_length` is `None`, the full size of `Uint<L>` is used.
4750
///
4851
/// Panics if `bit_length` is less than 2, or greater than the bit size of the target `Uint`.
4952
///
5053
/// See [`is_prime_with_rng`] for details about the performed checks.
51-
pub fn prime_with_rng<const L: usize>(rng: &mut impl CryptoRngCore, bit_length: usize) -> Uint<L> {
54+
pub fn prime_with_rng<const L: usize>(
55+
rng: &mut impl CryptoRngCore,
56+
bit_length: Option<usize>,
57+
) -> Uint<L> {
58+
let bit_length = bit_length.unwrap_or(Uint::<L>::BITS);
5259
if bit_length < 2 {
5360
panic!("`bit_length` must be 2 or greater.");
5461
}
@@ -65,14 +72,16 @@ pub fn prime_with_rng<const L: usize>(rng: &mut impl CryptoRngCore, bit_length:
6572

6673
/// Returns a random safe prime (that is, such that `(n - 1) / 2` is also prime)
6774
/// of size `bit_length` using the provided RNG.
75+
/// If `bit_length` is `None`, the full size of `Uint<L>` is used.
6876
///
6977
/// Panics if `bit_length` is less than 3, or is greater than the bit size of the target `Uint`.
7078
///
7179
/// See [`is_prime_with_rng`] for details about the performed checks.
7280
pub fn safe_prime_with_rng<const L: usize>(
7381
rng: &mut impl CryptoRngCore,
74-
bit_length: usize,
82+
bit_length: Option<usize>,
7583
) -> Uint<L> {
84+
let bit_length = bit_length.unwrap_or(Uint::<L>::BITS);
7685
if bit_length < 3 {
7786
panic!("`bit_length` must be 3 or greater.");
7887
}
@@ -240,7 +249,7 @@ mod tests {
240249
#[test]
241250
fn generate_prime() {
242251
for bit_length in (28..=128).step_by(10) {
243-
let p: U128 = prime(bit_length);
252+
let p: U128 = prime(Some(bit_length));
244253
assert!(p.bits_vartime() == bit_length);
245254
assert!(is_prime(&p));
246255
}
@@ -249,7 +258,7 @@ mod tests {
249258
#[test]
250259
fn generate_safe_prime() {
251260
for bit_length in (28..=128).step_by(10) {
252-
let p: U128 = safe_prime(bit_length);
261+
let p: U128 = safe_prime(Some(bit_length));
253262
assert!(p.bits_vartime() == bit_length);
254263
assert!(is_safe_prime(&p));
255264
}
@@ -282,25 +291,25 @@ mod tests {
282291
#[test]
283292
#[should_panic(expected = "`bit_length` must be 2 or greater")]
284293
fn generate_prime_too_few_bits() {
285-
let _p: U64 = prime_with_rng(&mut OsRng, 1);
294+
let _p: U64 = prime_with_rng(&mut OsRng, Some(1));
286295
}
287296

288297
#[test]
289298
#[should_panic(expected = "`bit_length` must be 3 or greater")]
290299
fn generate_safe_prime_too_few_bits() {
291-
let _p: U64 = safe_prime_with_rng(&mut OsRng, 2);
300+
let _p: U64 = safe_prime_with_rng(&mut OsRng, Some(2));
292301
}
293302

294303
#[test]
295304
#[should_panic(expected = "The requested bit length (65) is larger than the chosen Uint size")]
296305
fn generate_prime_too_many_bits() {
297-
let _p: U64 = prime_with_rng(&mut OsRng, 65);
306+
let _p: U64 = prime_with_rng(&mut OsRng, Some(65));
298307
}
299308

300309
#[test]
301310
#[should_panic(expected = "The requested bit length (65) is larger than the chosen Uint size")]
302311
fn generate_safe_prime_too_many_bits() {
303-
let _p: U64 = safe_prime_with_rng(&mut OsRng, 65);
312+
let _p: U64 = safe_prime_with_rng(&mut OsRng, Some(65));
304313
}
305314

306315
fn is_prime_ref(num: Word) -> bool {
@@ -311,7 +320,7 @@ mod tests {
311320
fn corner_cases_generate_prime() {
312321
for bits in 2usize..5 {
313322
for _ in 0..100 {
314-
let p: U64 = prime(bits);
323+
let p: U64 = prime(Some(bits));
315324
let p_word = p.as_words()[0];
316325
assert!(is_prime_ref(p_word));
317326
}
@@ -322,7 +331,7 @@ mod tests {
322331
fn corner_cases_generate_safe_prime() {
323332
for bits in 3usize..5 {
324333
for _ in 0..100 {
325-
let p: U64 = safe_prime(bits);
334+
let p: U64 = safe_prime(Some(bits));
326335
let p_word = p.as_words()[0];
327336
assert!(is_prime_ref(p_word) && is_prime_ref(p_word / 2));
328337
}
@@ -360,7 +369,7 @@ mod tests_openssl {
360369

361370
// Generate primes, let OpenSSL check them
362371
for _ in 0..100 {
363-
let p: U128 = prime(128);
372+
let p: U128 = prime(Some(128));
364373
let p_bn = to_openssl(&p);
365374
assert!(
366375
openssl_is_prime(&p_bn, &mut ctx),
@@ -419,7 +428,7 @@ mod tests_gmp {
419428
fn gmp_cross_check() {
420429
// Generate primes, let GMP check them
421430
for _ in 0..100 {
422-
let p: U128 = prime(128);
431+
let p: U128 = prime(Some(128));
423432
let p_bn = to_gmp(&p);
424433
assert!(gmp_is_prime(&p_bn), "GMP reports {p} as composite");
425434
}

src/traits.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,21 @@ use crate::{is_prime_with_rng, is_safe_prime_with_rng, prime_with_rng, safe_prim
77
/// and primality checking, wrapping the standalone functions ([`is_prime_with_rng`] etc).
88
pub trait RandomPrimeWithRng {
99
/// Returns a random prime of size `bit_length` using the provided RNG.
10+
/// If `bit_length` is `None`, the full size of `Uint<L>` is used.
1011
///
1112
/// Panics if `bit_length` is less than 2, or greater than the bit size of the target `Uint`.
1213
///
1314
/// See [`is_prime_with_rng`] for details about the performed checks.
14-
fn prime_with_rng(rng: &mut impl CryptoRngCore, bit_length: usize) -> Self;
15+
fn prime_with_rng(rng: &mut impl CryptoRngCore, bit_length: Option<usize>) -> Self;
1516

1617
/// Returns a random safe prime (that is, such that `(n - 1) / 2` is also prime)
1718
/// of size `bit_length` using the provided RNG.
19+
/// If `bit_length` is `None`, the full size of `Uint<L>` is used.
1820
///
1921
/// Panics if `bit_length` is less than 3, or greater than the bit size of the target `Uint`.
2022
///
2123
/// See [`is_prime_with_rng`] for details about the performed checks.
22-
fn safe_prime_with_rng(rng: &mut impl CryptoRngCore, bit_length: usize) -> Self;
24+
fn safe_prime_with_rng(rng: &mut impl CryptoRngCore, bit_length: Option<usize>) -> Self;
2325

2426
/// Checks probabilistically if the given number is prime using the provided RNG.
2527
///
@@ -33,10 +35,10 @@ pub trait RandomPrimeWithRng {
3335
}
3436

3537
impl<const L: usize> RandomPrimeWithRng for Uint<L> {
36-
fn prime_with_rng(rng: &mut impl CryptoRngCore, bit_length: usize) -> Self {
38+
fn prime_with_rng(rng: &mut impl CryptoRngCore, bit_length: Option<usize>) -> Self {
3739
prime_with_rng(rng, bit_length)
3840
}
39-
fn safe_prime_with_rng(rng: &mut impl CryptoRngCore, bit_length: usize) -> Self {
41+
fn safe_prime_with_rng(rng: &mut impl CryptoRngCore, bit_length: Option<usize>) -> Self {
4042
safe_prime_with_rng(rng, bit_length)
4143
}
4244
fn is_prime_with_rng(&self, rng: &mut impl CryptoRngCore) -> bool {
@@ -62,7 +64,7 @@ mod tests {
6264
assert!(!U64::from(13u32).is_safe_prime_with_rng(&mut OsRng));
6365
assert!(U64::from(11u32).is_safe_prime_with_rng(&mut OsRng));
6466

65-
assert!(U64::prime_with_rng(&mut OsRng, 10).is_prime_with_rng(&mut OsRng));
66-
assert!(U64::safe_prime_with_rng(&mut OsRng, 10).is_safe_prime_with_rng(&mut OsRng));
67+
assert!(U64::prime_with_rng(&mut OsRng, Some(10)).is_prime_with_rng(&mut OsRng));
68+
assert!(U64::safe_prime_with_rng(&mut OsRng, Some(10)).is_safe_prime_with_rng(&mut OsRng));
6769
}
6870
}

0 commit comments

Comments
 (0)