@@ -365,6 +365,9 @@ class RNGState {
365
365
uint64_t m_counter GUARDED_BY (m_mutex) = 0;
366
366
bool m_strongly_seeded GUARDED_BY (m_mutex) = false;
367
367
368
+ Mutex m_events_mutex;
369
+ CSHA256 m_events_hasher GUARDED_BY (m_events_mutex);
370
+
368
371
public:
369
372
RNGState () noexcept
370
373
{
@@ -375,6 +378,35 @@ class RNGState {
375
378
{
376
379
}
377
380
381
+ void AddEvent (uint32_t event_info) noexcept
382
+ {
383
+ LOCK (m_events_mutex);
384
+
385
+ m_events_hasher.Write ((const unsigned char *)&event_info, sizeof (event_info));
386
+ // Get the low four bytes of the performance counter. This translates to roughly the
387
+ // subsecond part.
388
+ uint32_t perfcounter = (GetPerformanceCounter () & 0xffffffff );
389
+ m_events_hasher.Write ((const unsigned char *)&perfcounter, sizeof (perfcounter));
390
+ }
391
+
392
+ /* *
393
+ * Feed (the hash of) all events added through AddEvent() to hasher.
394
+ */
395
+ void SeedEvents (CSHA512& hasher) noexcept
396
+ {
397
+ // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
398
+ // since we want it to be fast as network peers may be able to trigger it repeatedly.
399
+ LOCK (m_events_mutex);
400
+
401
+ unsigned char events_hash[32 ];
402
+ m_events_hasher.Finalize (events_hash);
403
+ hasher.Write (events_hash, 32 );
404
+
405
+ // Re-initialize the hasher with the finalized state to use later.
406
+ m_events_hasher.Reset ();
407
+ m_events_hasher.Write (events_hash, 32 );
408
+ }
409
+
378
410
/* * Extract up to 32 bytes of entropy from the RNG state, mixing in new entropy from hasher.
379
411
*
380
412
* If this function has never been called with strong_seed = true, false is returned.
@@ -445,24 +477,7 @@ static void SeedFast(CSHA512& hasher) noexcept
445
477
SeedTimestamp (hasher);
446
478
}
447
479
448
- // We use only SHA256 for the events hashing to get the ASM speedups we have for SHA256,
449
- // since we want it to be fast as network peers may be able to trigger it repeatedly.
450
- static Mutex events_mutex;
451
- static CSHA256 events_hasher;
452
- static void SeedEvents (CSHA512& hasher)
453
- {
454
- LOCK (events_mutex);
455
-
456
- unsigned char events_hash[32 ];
457
- events_hasher.Finalize (events_hash);
458
- hasher.Write (events_hash, 32 );
459
-
460
- // Re-initialize the hasher with the finalized state to use later.
461
- events_hasher.Reset ();
462
- events_hasher.Write (events_hash, 32 );
463
- }
464
-
465
- static void SeedSlow (CSHA512& hasher) noexcept
480
+ static void SeedSlow (CSHA512& hasher, RNGState& rng) noexcept
466
481
{
467
482
unsigned char buffer[32 ];
468
483
@@ -474,7 +489,7 @@ static void SeedSlow(CSHA512& hasher) noexcept
474
489
hasher.Write (buffer, sizeof (buffer));
475
490
476
491
// Add the events hasher into the mix
477
- SeedEvents (hasher);
492
+ rng. SeedEvents (hasher);
478
493
479
494
// High-precision timestamp.
480
495
//
@@ -502,7 +517,7 @@ static void SeedPeriodic(CSHA512& hasher, RNGState& rng) noexcept
502
517
SeedTimestamp (hasher);
503
518
504
519
// Add the events hasher into the mix
505
- SeedEvents (hasher);
520
+ rng. SeedEvents (hasher);
506
521
507
522
// Dynamic environment data (performance monitoring, ...)
508
523
auto old_size = hasher.Size ();
@@ -519,7 +534,7 @@ static void SeedStartup(CSHA512& hasher, RNGState& rng) noexcept
519
534
SeedHardwareSlow (hasher);
520
535
521
536
// Everything that the 'slow' seeder includes.
522
- SeedSlow (hasher);
537
+ SeedSlow (hasher, rng );
523
538
524
539
// Dynamic environment data (performance monitoring, ...)
525
540
auto old_size = hasher.Size ();
@@ -539,7 +554,7 @@ enum class RNGLevel {
539
554
PERIODIC, // !< Called by RandAddPeriodic()
540
555
};
541
556
542
- static void ProcRand (unsigned char * out, int num, RNGLevel level)
557
+ static void ProcRand (unsigned char * out, int num, RNGLevel level) noexcept
543
558
{
544
559
// Make sure the RNG is initialized first (as all Seed* function possibly need hwrand to be available).
545
560
RNGState& rng = GetRNGState ();
@@ -552,7 +567,7 @@ static void ProcRand(unsigned char* out, int num, RNGLevel level)
552
567
SeedFast (hasher);
553
568
break ;
554
569
case RNGLevel::SLOW:
555
- SeedSlow (hasher);
570
+ SeedSlow (hasher, rng );
556
571
break ;
557
572
case RNGLevel::PERIODIC:
558
573
SeedPeriodic (hasher, rng);
@@ -581,15 +596,7 @@ std::chrono::milliseconds GetRandMillis(std::chrono::milliseconds duration_max)
581
596
void GetRandBytes (unsigned char * buf, int num) noexcept { ProcRand (buf, num, RNGLevel::FAST); }
582
597
void GetStrongRandBytes (unsigned char * buf, int num) noexcept { ProcRand (buf, num, RNGLevel::SLOW); }
583
598
void RandAddPeriodic () noexcept { ProcRand (nullptr , 0 , RNGLevel::PERIODIC); }
584
-
585
- void RandAddEvent (const uint32_t event_info) {
586
- LOCK (events_mutex);
587
- events_hasher.Write ((const unsigned char *)&event_info, sizeof (event_info));
588
- // Get the low four bytes of the performance counter. This translates to roughly the
589
- // subsecond part.
590
- uint32_t perfcounter = (GetPerformanceCounter () & 0xffffffff );
591
- events_hasher.Write ((const unsigned char *)&perfcounter, sizeof (perfcounter));
592
- }
599
+ void RandAddEvent (const uint32_t event_info) noexcept { GetRNGState ().AddEvent (event_info); }
593
600
594
601
bool g_mock_deterministic_tests{false };
595
602
0 commit comments