@@ -6,10 +6,10 @@ use core::marker::PhantomData;
6
6
use core:: num:: { NonZero , NonZeroU32 } ;
7
7
8
8
use crypto_bigint:: { Integer , Odd , RandomBits , RandomBitsError } ;
9
- use rand_core:: { CryptoRng , TryCryptoRng } ;
9
+ use rand_core:: CryptoRng ;
10
10
11
- use crate :: hazmat :: precomputed:: { SmallPrime , LAST_SMALL_PRIME , RECIPROCALS , SMALL_PRIMES } ;
12
- use crate :: presets:: Flavor ;
11
+ use super :: precomputed:: { SmallPrime , LAST_SMALL_PRIME , RECIPROCALS , SMALL_PRIMES } ;
12
+ use crate :: { error :: Error , presets:: Flavor } ;
13
13
14
14
/// Decide how prime candidates are manipulated by setting certain bits before primality testing,
15
15
/// influencing the range of the prime.
@@ -33,18 +33,26 @@ pub enum SetBits {
33
33
///
34
34
/// Returns an error variant if `bit_length` is greater than the maximum allowed for `T`
35
35
/// (applies to fixed-length types).
36
- pub fn random_odd_integer < T , R > (
37
- rng : & mut R ,
38
- bit_length : NonZeroU32 ,
39
- set_bits : SetBits ,
40
- ) -> Result < Odd < T > , RandomBitsError < R :: Error > >
36
+ pub fn random_odd_integer < T , R > ( rng : & mut R , bit_length : NonZeroU32 , set_bits : SetBits ) -> Result < Odd < T > , Error >
41
37
where
42
38
T : Integer + RandomBits ,
43
- R : TryCryptoRng + ?Sized ,
39
+ R : CryptoRng + ?Sized ,
44
40
{
45
41
let bit_length = bit_length. get ( ) ;
46
42
47
- let mut random = T :: try_random_bits ( rng, bit_length) ?;
43
+ let mut random = T :: try_random_bits ( rng, bit_length) . map_err ( |err| match err {
44
+ RandomBitsError :: RandCore ( _) => unreachable ! ( "`rng` impls `CryptoRng` and therefore is infallible" ) ,
45
+ RandomBitsError :: BitsPrecisionMismatch { .. } => {
46
+ unreachable ! ( "we are not requesting a specific `bits_precision`" )
47
+ }
48
+ RandomBitsError :: BitLengthTooLarge {
49
+ bit_length,
50
+ bits_precision,
51
+ } => Error :: BitLengthTooLarge {
52
+ bit_length,
53
+ bits_precision,
54
+ } ,
55
+ } ) ?;
48
56
49
57
// Make it odd
50
58
// `bit_length` is non-zero, so the 0-th bit exists.
@@ -302,11 +310,13 @@ pub trait SieveFactory {
302
310
/// Makes a sieve given an RNG and the previous exhausted sieve (if any).
303
311
///
304
312
/// Returning `None` signals that the prime generation should stop.
305
- fn make_sieve < R : CryptoRng + ? Sized > (
313
+ fn make_sieve < R > (
306
314
& mut self ,
307
315
rng : & mut R ,
308
316
previous_sieve : Option < & Self :: Sieve > ,
309
- ) -> Option < Self :: Sieve > ;
317
+ ) -> Result < Option < Self :: Sieve > , Error >
318
+ where
319
+ R : CryptoRng + ?Sized ;
310
320
}
311
321
312
322
/// A sieve returning numbers that are not multiples of a set of small factors.
@@ -366,18 +376,20 @@ where
366
376
{
367
377
type Item = T ;
368
378
type Sieve = SmallPrimesSieve < T > ;
369
- fn make_sieve < R : CryptoRng + ? Sized > (
379
+ fn make_sieve < R > (
370
380
& mut self ,
371
381
rng : & mut R ,
372
382
_previous_sieve : Option < & Self :: Sieve > ,
373
- ) -> Option < Self :: Sieve > {
374
- let start =
375
- random_odd_integer :: < T , _ > ( rng, self . max_bit_length , self . set_bits ) . expect ( "random_odd_integer() failed" ) ;
376
- Some ( SmallPrimesSieve :: new (
383
+ ) -> Result < Option < Self :: Sieve > , Error >
384
+ where
385
+ R : CryptoRng + ?Sized ,
386
+ {
387
+ let start = random_odd_integer :: < T , _ > ( rng, self . max_bit_length , self . set_bits ) ?;
388
+ Ok ( Some ( SmallPrimesSieve :: new (
377
389
start. get ( ) ,
378
390
self . max_bit_length ,
379
391
self . safe_primes ,
380
- ) )
392
+ ) ) )
381
393
}
382
394
}
383
395
@@ -391,7 +403,7 @@ mod tests {
391
403
use crypto_bigint:: U64 ;
392
404
use num_prime:: nt_funcs:: factorize64;
393
405
use rand_chacha:: ChaCha8Rng ;
394
- use rand_core:: { OsRng , SeedableRng } ;
406
+ use rand_core:: { OsRng , SeedableRng , TryRngCore } ;
395
407
396
408
use super :: { random_odd_integer, SetBits , SmallPrimesSieve , SmallPrimesSieveFactory } ;
397
409
use crate :: { hazmat:: precomputed:: SMALL_PRIMES , Flavor } ;
@@ -500,7 +512,7 @@ mod tests {
500
512
#[ test]
501
513
fn random_below_max_length ( ) {
502
514
for _ in 0 ..10 {
503
- let r = random_odd_integer :: < U64 , _ > ( & mut OsRng , NonZero :: new ( 50 ) . unwrap ( ) , SetBits :: Msb )
515
+ let r = random_odd_integer :: < U64 , _ > ( & mut OsRng . unwrap_mut ( ) , NonZero :: new ( 50 ) . unwrap ( ) , SetBits :: Msb )
504
516
. unwrap ( )
505
517
. get ( ) ;
506
518
assert_eq ! ( r. bits( ) , 50 ) ;
@@ -509,7 +521,9 @@ mod tests {
509
521
510
522
#[ test]
511
523
fn random_odd_uint_too_many_bits ( ) {
512
- assert ! ( random_odd_integer:: <U64 , _>( & mut OsRng , NonZero :: new( 65 ) . unwrap( ) , SetBits :: Msb ) . is_err( ) ) ;
524
+ assert ! (
525
+ random_odd_integer:: <U64 , _>( & mut OsRng . unwrap_mut( ) , NonZero :: new( 65 ) . unwrap( ) , SetBits :: Msb ) . is_err( )
526
+ ) ;
513
527
}
514
528
515
529
#[ test]
@@ -549,27 +563,31 @@ mod tests {
549
563
#[ test]
550
564
fn set_bits ( ) {
551
565
for _ in 0 ..10 {
552
- let x = random_odd_integer :: < U64 , _ > ( & mut OsRng , NonZero :: new ( 64 ) . unwrap ( ) , SetBits :: Msb ) . unwrap ( ) ;
566
+ let x =
567
+ random_odd_integer :: < U64 , _ > ( & mut OsRng . unwrap_mut ( ) , NonZero :: new ( 64 ) . unwrap ( ) , SetBits :: Msb ) . unwrap ( ) ;
553
568
assert ! ( bool :: from( x. bit( 63 ) ) ) ;
554
569
}
555
570
556
571
for _ in 0 ..10 {
557
- let x = random_odd_integer :: < U64 , _ > ( & mut OsRng , NonZero :: new ( 64 ) . unwrap ( ) , SetBits :: TwoMsb ) . unwrap ( ) ;
572
+ let x = random_odd_integer :: < U64 , _ > ( & mut OsRng . unwrap_mut ( ) , NonZero :: new ( 64 ) . unwrap ( ) , SetBits :: TwoMsb )
573
+ . unwrap ( ) ;
558
574
assert ! ( bool :: from( x. bit( 63 ) ) ) ;
559
575
assert ! ( bool :: from( x. bit( 62 ) ) ) ;
560
576
}
561
577
562
578
// 1 in 2^30 chance of spurious failure... good enough?
563
579
assert ! ( ( 0 ..30 )
564
- . map( |_| { random_odd_integer:: <U64 , _>( & mut OsRng , NonZero :: new( 64 ) . unwrap( ) , SetBits :: None ) . unwrap( ) } )
580
+ . map( |_| {
581
+ random_odd_integer:: <U64 , _>( & mut OsRng . unwrap_mut( ) , NonZero :: new( 64 ) . unwrap( ) , SetBits :: None ) . unwrap( )
582
+ } )
565
583
. any( |x| !bool :: from( x. bit( 63 ) ) ) ) ;
566
584
}
567
585
568
586
#[ test]
569
587
fn set_two_msb_small_bit_length ( ) {
570
588
// Check that when technically there isn't a second most significant bit,
571
589
// `random_odd_integer()` still returns a number.
572
- let x = random_odd_integer :: < U64 , _ > ( & mut OsRng , NonZero :: new ( 1 ) . unwrap ( ) , SetBits :: TwoMsb )
590
+ let x = random_odd_integer :: < U64 , _ > ( & mut OsRng . unwrap_mut ( ) , NonZero :: new ( 1 ) . unwrap ( ) , SetBits :: TwoMsb )
573
591
. unwrap ( )
574
592
. get ( ) ;
575
593
assert_eq ! ( x, U64 :: ONE ) ;
0 commit comments