41
41
//! [Jitterentropy]: http://www.chronox.de/jent.html
42
42
//! [discussion]: https://github.com/rust-random/rand/issues/699
43
43
44
- #![ doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png" ,
45
- html_favicon_url = "https://www.rust-lang.org/favicon.ico" ,
46
- html_root_url = "https://rust-random.github.io/rand/" ) ]
47
-
44
+ #![ doc(
45
+ html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png" ,
46
+ html_favicon_url = "https://www.rust-lang.org/favicon.ico" ,
47
+ html_root_url = "https://rust-random.github.io/rand/"
48
+ ) ]
48
49
#![ deny( missing_docs) ]
49
50
#![ deny( missing_debug_implementations) ]
50
51
#![ doc( test( attr( allow( unused_variables) , deny( warnings) ) ) ) ]
51
-
52
52
// Note: the C implementation of `Jitterentropy` relies on being compiled
53
53
// without optimizations. This implementation goes through lengths to make the
54
54
// compiler not optimize out code which does influence timing jitter, but is
@@ -64,7 +64,7 @@ pub use rand_core;
64
64
macro_rules! doc_comment {
65
65
( $x: expr) => {
66
66
#[ doc = $x]
67
- extern { }
67
+ fn _doc_comment ( ) { }
68
68
} ;
69
69
}
70
70
@@ -102,12 +102,12 @@ macro_rules! error { ($($x:tt)*) => (
102
102
}
103
103
) }
104
104
105
+ mod error;
105
106
#[ cfg( feature = "std" ) ]
106
107
mod platform;
107
- mod error;
108
108
109
- use rand_core:: { RngCore , Error , impls} ;
110
109
pub use crate :: error:: TimerError ;
110
+ use rand_core:: { impls, Error , RngCore } ;
111
111
112
112
use core:: { fmt, mem, ptr} ;
113
113
#[ cfg( feature = "std" ) ]
@@ -191,7 +191,9 @@ impl<F> fmt::Debug for JitterRng<F> {
191
191
}
192
192
193
193
impl < F > Clone for JitterRng < F >
194
- where F : Clone {
194
+ where
195
+ F : Clone ,
196
+ {
195
197
fn clone ( & self ) -> JitterRng < F > {
196
198
JitterRng {
197
199
data : self . data ,
@@ -209,9 +211,7 @@ where F: Clone {
209
211
#[ cfg( all( feature = "std" , not( target_arch = "wasm32" ) ) ) ]
210
212
static JITTER_ROUNDS : AtomicUsize = AtomicUsize :: new ( 0 ) ;
211
213
212
- impl < F > JitterRng < F >
213
- where F : Fn ( ) -> u64 + Send + Sync {
214
- /* FIXME: this method is broken - see #16
214
+ impl JitterRng < ( ) > {
215
215
/// Create a new `JitterRng`. Makes use of `std::time` for a timer, or a
216
216
/// platform-specific function with higher accuracy if necessary and
217
217
/// available.
@@ -220,7 +220,7 @@ where F: Fn() -> u64 + Send + Sync {
220
220
/// hundred times. If this does not pass basic quality tests, an error is
221
221
/// returned. The test result is cached to make subsequent calls faster.
222
222
#[ cfg( all( feature = "std" , not( target_arch = "wasm32" ) ) ) ]
223
- pub fn new() -> Result<JitterRng<fn () -> u64>, TimerError> {
223
+ pub fn new ( ) -> Result < JitterRng < impl Fn ( ) -> u64 + Send + Sync > , TimerError > {
224
224
if cfg ! ( target_arch = "wasm32" ) {
225
225
return Err ( TimerError :: NoTimer ) ;
226
226
}
@@ -239,8 +239,12 @@ where F: Fn() -> u64 + Send + Sync {
239
239
state. gen_entropy ( ) ;
240
240
Ok ( state)
241
241
}
242
- */
242
+ }
243
243
244
+ impl < F > JitterRng < F >
245
+ where
246
+ F : Fn ( ) -> u64 + Send + Sync ,
247
+ {
244
248
/// Create a new `JitterRng`.
245
249
/// A custom timer can be supplied, making it possible to use `JitterRng` in
246
250
/// `no_std` environments.
@@ -352,7 +356,7 @@ where F: Fn() -> u64 + Send + Sync {
352
356
// the loop in this function implies that careful retesting must be done.
353
357
#[ inline( never) ]
354
358
fn lfsr_time ( & mut self , time : u64 , var_rounds : bool ) {
355
- fn lfsr ( mut data : u64 , time : u64 ) -> u64 {
359
+ fn lfsr ( mut data : u64 , time : u64 ) -> u64 {
356
360
for i in 1 ..65 {
357
361
let mut tmp = time << ( 64 - i) ;
358
362
tmp >>= 64 - 1 ;
@@ -382,7 +386,9 @@ where F: Fn() -> u64 + Send + Sync {
382
386
// other rounds are not optimised out, we first run all but the last
383
387
// round on a throw-away value instead of the real `self.data`.
384
388
let mut lfsr_loop_cnt = 0 ;
385
- if var_rounds { lfsr_loop_cnt = self . random_loop_cnt ( 4 ) } ;
389
+ if var_rounds {
390
+ lfsr_loop_cnt = self . random_loop_cnt ( 4 )
391
+ } ;
386
392
387
393
let mut throw_away: u64 = 0 ;
388
394
for _ in 0 ..lfsr_loop_cnt {
@@ -412,7 +418,9 @@ where F: Fn() -> u64 + Send + Sync {
412
418
#[ inline( never) ]
413
419
fn memaccess ( & mut self , mem : & mut [ u8 ; MEMORY_SIZE ] , var_rounds : bool ) {
414
420
let mut acc_loop_cnt = 128 ;
415
- if var_rounds { acc_loop_cnt += self . random_loop_cnt ( 4 ) } ;
421
+ if var_rounds {
422
+ acc_loop_cnt += self . random_loop_cnt ( 4 )
423
+ } ;
416
424
417
425
let mut index = self . mem_prev_index as usize ;
418
426
for _ in 0 ..acc_loop_cnt {
@@ -454,7 +462,9 @@ where F: Fn() -> u64 + Send + Sync {
454
462
455
463
// Check whether we have a stuck measurement (i.e. does the last
456
464
// measurement holds entropy?).
457
- if ec. stuck ( current_delta) { return None } ;
465
+ if ec. stuck ( current_delta) {
466
+ return None ;
467
+ } ;
458
468
459
469
// Rotate the data buffer by a prime number (any odd number would
460
470
// do) to ensure that every bit position of the input time stamp
@@ -599,21 +609,29 @@ where F: Fn() -> u64 + Send + Sync {
599
609
// already have had an impact on the caches, branch prediction,
600
610
// etc. with the goal to clear it to get the worst case
601
611
// measurements.
602
- if i < CLEARCACHE { continue ; }
612
+ if i < CLEARCACHE {
613
+ continue ;
614
+ }
603
615
604
- if ec. stuck ( delta) { count_stuck += 1 ; }
616
+ if ec. stuck ( delta) {
617
+ count_stuck += 1 ;
618
+ }
605
619
606
620
// Test whether we have an increasing timer.
607
- if time2 <= time { time_backwards += 1 ; }
621
+ if time2 <= time {
622
+ time_backwards += 1 ;
623
+ }
608
624
609
625
// Count the number of times the counter increases in steps of 100ns
610
626
// or greater.
611
- if ( delta % 100 ) == 0 { count_mod += 1 ; }
627
+ if ( delta % 100 ) == 0 {
628
+ count_mod += 1 ;
629
+ }
612
630
613
631
// Ensure that we have a varying delta timer which is necessary for
614
632
// the calculation of entropy -- perform this check only after the
615
633
// first loop is executed as we need to prime the old_delta value
616
- delta_sum += ( delta - old_delta) . abs ( ) as u64 ;
634
+ delta_sum += ( delta - old_delta) . unsigned_abs ( ) as u64 ;
617
635
old_delta = delta;
618
636
}
619
637
@@ -674,14 +692,15 @@ where F: Fn() -> u64 + Send + Sync {
674
692
if delta_average >= 16 {
675
693
let log2 = 64 - delta_average. leading_zeros ( ) ;
676
694
// Do something similar to roundup(64/(log2/2)):
677
- Ok ( ( ( 64u32 * 2 + log2 - 1 ) / log2) as u8 )
695
+ Ok ( ( ( 64u32 * 2 + log2 - 1 ) / log2) as u8 )
678
696
} else {
679
697
// For values < 16 the rounding error becomes too large, use a
680
698
// lookup table.
681
699
// Values 0 and 1 are invalid, and filtered out by the
682
700
// `delta_sum < TESTLOOPCOUNT` test above.
683
- let log2_lookup = [ 0 , 0 , 128 , 81 , 64 , 56 , 50 , 46 ,
684
- 43 , 41 , 39 , 38 , 36 , 35 , 34 , 33 ] ;
701
+ let log2_lookup = [
702
+ 0 , 0 , 128 , 81 , 64 , 56 , 50 , 46 , 43 , 41 , 39 , 38 , 36 , 35 , 34 , 33 ,
703
+ ] ;
685
704
Ok ( log2_lookup[ delta_average as usize ] )
686
705
}
687
706
}
@@ -721,8 +740,10 @@ fn black_box<T>(dummy: T) -> T {
721
740
}
722
741
}
723
742
724
- impl < F > RngCore for JitterRng < F >
725
- where F : Fn ( ) -> u64 + Send + Sync {
743
+ impl < F > RngCore for JitterRng < F >
744
+ where
745
+ F : Fn ( ) -> u64 + Send + Sync ,
746
+ {
726
747
fn next_u32 ( & mut self ) -> u32 {
727
748
// We want to use both parts of the generated entropy
728
749
if self . data_half_used {
@@ -736,8 +757,8 @@ where F: Fn() -> u64 + Send + Sync {
736
757
}
737
758
738
759
fn next_u64 ( & mut self ) -> u64 {
739
- self . data_half_used = false ;
740
- self . gen_entropy ( )
760
+ self . data_half_used = false ;
761
+ self . gen_entropy ( )
741
762
}
742
763
743
764
fn fill_bytes ( & mut self , dest : & mut [ u8 ] ) {
0 commit comments