@@ -360,6 +360,9 @@ class RNGState {
360
360
uint64_t m_counter GUARDED_BY (m_mutex) = 0;
361
361
bool m_strongly_seeded GUARDED_BY (m_mutex) = false;
362
362
363
+ Mutex m_events_mutex;
364
+ CSHA256 m_events_hasher GUARDED_BY (m_events_mutex);
365
+
363
366
public:
364
367
RNGState () noexcept
365
368
{
@@ -370,6 +373,35 @@ class RNGState {
370
373
{
371
374
}
372
375
376
+ void AddEvent (uint32_t event_info) noexcept
377
+ {
378
+ LOCK (m_events_mutex);
379
+
380
+ m_events_hasher.Write ((const unsigned char *)&event_info, sizeof (event_info));
381
+ // Get the low four bytes of the performance counter. This translates to roughly the
382
+ // subsecond part.
383
+ uint32_t perfcounter = (GetPerformanceCounter () & 0xffffffff );
384
+ m_events_hasher.Write ((const unsigned char *)&perfcounter, sizeof (perfcounter));
385
+ }
386
+
387
+ /* *
388
+ * Feed (the hash of) all events added through AddEvent() to hasher.
389
+ */
390
+ void SeedEvents (CSHA512& hasher) noexcept
391
+ {
392
+ // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
393
+ // since we want it to be fast as network peers may be able to trigger it repeatedly.
394
+ LOCK (m_events_mutex);
395
+
396
+ unsigned char events_hash[32 ];
397
+ m_events_hasher.Finalize (events_hash);
398
+ hasher.Write (events_hash, 32 );
399
+
400
+ // Re-initialize the hasher with the finalized state to use later.
401
+ m_events_hasher.Reset ();
402
+ m_events_hasher.Write (events_hash, 32 );
403
+ }
404
+
373
405
/* * Extract up to 32 bytes of entropy from the RNG state, mixing in new entropy from hasher.
374
406
*
375
407
* If this function has never been called with strong_seed = true, false is returned.
@@ -440,24 +472,7 @@ static void SeedFast(CSHA512& hasher) noexcept
440
472
SeedTimestamp (hasher);
441
473
}
442
474
443
- // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
444
- // since we want it to be fast as network peers may be able to trigger it repeatedly.
445
- static Mutex events_mutex;
446
- static CSHA256 events_hasher;
447
- static void SeedEvents (CSHA512& hasher)
448
- {
449
- LOCK (events_mutex);
450
-
451
- unsigned char events_hash[32 ];
452
- events_hasher.Finalize (events_hash);
453
- hasher.Write (events_hash, 32 );
454
-
455
- // Re-initialize the hasher with the finalized state to use later.
456
- events_hasher.Reset ();
457
- events_hasher.Write (events_hash, 32 );
458
- }
459
-
460
- static void SeedSlow (CSHA512& hasher) noexcept
475
+ static void SeedSlow (CSHA512& hasher, RNGState& rng) noexcept
461
476
{
462
477
unsigned char buffer[32 ];
463
478
@@ -469,7 +484,7 @@ static void SeedSlow(CSHA512& hasher) noexcept
469
484
hasher.Write (buffer, sizeof (buffer));
470
485
471
486
// Add the events hasher into the mix
472
- SeedEvents (hasher);
487
+ rng. SeedEvents (hasher);
473
488
474
489
// High-precision timestamp.
475
490
//
@@ -497,7 +512,7 @@ static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
497
512
SeedTimestamp (hasher);
498
513
499
514
// Add the events hasher into the mix
500
- SeedEvents (hasher);
515
+ rng. SeedEvents (hasher);
501
516
502
517
// Dynamic environment data (performance monitoring, ...)
503
518
auto old_size = hasher.Size ();
@@ -514,7 +529,7 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
514
529
SeedHardwareSlow (hasher);
515
530
516
531
// Everything that the 'slow' seeder includes.
517
- SeedSlow (hasher);
532
+ SeedSlow (hasher, rng );
518
533
519
534
// Dynamic environment data (performance monitoring, ...)
520
535
auto old_size = hasher.Size ();
@@ -534,7 +549,7 @@ enum class RNGLevel {
534
549
PERIODIC, // !< Called by RandAddPeriodic()
535
550
};
536
551
537
- static void ProcRand (unsigned char * out, int num, RNGLevel level)
552
+ static void ProcRand (unsigned char * out, int num, RNGLevel level) noexcept
538
553
{
539
554
// Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
540
555
RNGState& rng = GetRNGState ();
@@ -547,7 +562,7 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
547
562
SeedFast (hasher);
548
563
break ;
549
564
case RNGLevel::SLOW:
550
- SeedSlow (hasher);
565
+ SeedSlow (hasher, rng );
551
566
break ;
552
567
case RNGLevel::PERIODIC:
553
568
SeedPeriodic (hasher, rng);
@@ -566,15 +581,7 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
566
581
void GetRandBytes (unsigned char * buf, int num) noexcept { ProcRand (buf, num, RNGLevel::FAST); }
567
582
void GetStrongRandBytes (unsigned char * buf, int num) noexcept { ProcRand (buf, num, RNGLevel::SLOW); }
568
583
void RandAddPeriodic () noexcept { ProcRand (nullptr , 0 , RNGLevel::PERIODIC); }
569
-
570
- void RandAddEvent (const uint32_t event_info) {
571
- LOCK (events_mutex);
572
- events_hasher.Write ((const unsigned char *)&event_info, sizeof (event_info));
573
- // Get the low four bytes of the performance counter. This translates to roughly the
574
- // subsecond part.
575
- uint32_t perfcounter = (GetPerformanceCounter () & 0xffffffff );
576
- events_hasher.Write ((const unsigned char *)&perfcounter, sizeof (perfcounter));
577
- }
584
+ void RandAddEvent (const uint32_t event_info) noexcept { GetRNGState ().AddEvent (event_info); }
578
585
579
586
bool g_mock_deterministic_tests{false };
580
587
0 commit comments