@ -507,22 +507,16 @@ static void SeedSlow(CSHA512& hasher) noexcept
}
/** Extract entropy from rng, strengthen it, and feed it into hasher. */
static void SeedStrengthen ( CSHA512 & hasher , RNGState & rng ) noexcept
static void SeedStrengthen ( CSHA512 & hasher , RNGState & rng , int microseconds ) noexcept
{
static std : : atomic < int64_t > last_strengthen { 0 } ;
int64_t last_time = last_strengthen . load ( ) ;
int64_t current_time = GetTimeMicros ( ) ;
if ( current_time > last_time + 60000000 ) { // Only run once a minute
// Generate 32 bytes of entropy from the RNG, and a copy of the entropy already in hasher.
unsigned char strengthen_seed [ 32 ] ;
rng . MixExtract ( strengthen_seed , sizeof ( strengthen_seed ) , CSHA512 ( hasher ) , false ) ;
// Strengthen it for 10ms (100ms on first run), and feed it into hasher.
Strengthen ( strengthen_seed , last_time = = 0 ? 100000 : 10000 , hasher ) ;
last_strengthen = current_time ;
}
// Strengthen the seed, and feed it into hasher.
Strengthen ( strengthen_seed , microseconds , hasher ) ;
}
static void Seed Sleep ( CSHA512 & hasher , RNGState & rng )
static void Seed Periodic ( CSHA512 & hasher , RNGState & rng )
{
// Everything that the 'fast' seeder includes
SeedFast ( hasher ) ;
@ -530,17 +524,11 @@ static void SeedSleep(CSHA512& hasher, RNGState& rng)
// High-precision timestamp
SeedTimestamp ( hasher ) ;
// Sleep for 1ms
MilliSleep ( 1 ) ;
// High-precision timestamp after sleeping (as we commit to both the time before and after, this measures the delay)
SeedTimestamp ( hasher ) ;
// Dynamic environment data (performance monitoring, ...; once every 10 minutes)
// Dynamic environment data (performance monitoring, ...)
RandAddDynamicEnv ( hasher ) ;
// Strengthen every minute
SeedStrengthen ( hasher , rng );
// Strengthen for 10 ms
SeedStrengthen ( hasher , rng , 10000 ) ;
}
static void SeedStartup ( CSHA512 & hasher , RNGState & rng ) noexcept
@ -551,20 +539,20 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
// Everything that the 'slow' seeder includes.
SeedSlow ( hasher ) ;
// Dynamic environment data
// Dynamic environment data (performance monitoring, ...)
RandAddDynamicEnv ( hasher ) ;
// Static environment data
RandAddStaticEnv ( hasher ) ;
// Strengthen
SeedStrengthen ( hasher , rng );
// Strengthen for 100 ms
SeedStrengthen ( hasher , rng , 100000 );
}
enum class RNGLevel {
FAST , //!< Automatically called by GetRandBytes
SLOW , //!< Automatically called by GetStrongRandBytes
SLEEP, //!< Called by RandAddSeedSleep ()
PERIODIC, //!< Called by RandAddPeriodic ()
} ;
static void ProcRand ( unsigned char * out , int num , RNGLevel level )
@ -582,8 +570,8 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
case RNGLevel : : SLOW :
SeedSlow ( hasher ) ;
break ;
case RNGLevel : : SLEEP :
Seed Sleep ( hasher , rng ) ;
case RNGLevel : : PERIODIC :
Seed Periodic ( hasher , rng ) ;
break ;
}
@ -606,7 +594,7 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
void GetRandBytes ( unsigned char * buf , int num ) noexcept { ProcRand ( buf , num , RNGLevel : : FAST ) ; }
void GetStrongRandBytes ( unsigned char * buf , int num ) noexcept { ProcRand ( buf , num , RNGLevel : : SLOW ) ; }
void RandAdd SeedSleep ( ) { ProcRand ( nullptr , 0 , RNGLevel : : SLEEP ) ; }
void RandAdd Periodic ( ) { ProcRand ( nullptr , 0 , RNGLevel : : PERIODIC ) ; }
bool g_mock_deterministic_tests { false } ;