diff options
-rw-r--r-- | crawl-ref/source/rng.cc | 20 | ||||
-rw-r--r-- | crawl-ref/source/sha256.cc | 63 | ||||
-rw-r--r-- | crawl-ref/source/sha256.h | 4 |
3 files changed, 82 insertions, 5 deletions
diff --git a/crawl-ref/source/rng.cc b/crawl-ref/source/rng.cc index 8c856e7229..4b7200093c 100644 --- a/crawl-ref/source/rng.cc +++ b/crawl-ref/source/rng.cc @@ -29,6 +29,12 @@ void seed_rng(unsigned long* seed_key, size_t num_keys) // MT19937 -- see mt19937ar.cc for details/licence init_by_array(seed_key, num_keys); + // Reset the sha256 generator to get predictable random numbers in case + // of a saved rng state. +#ifdef MORE_HARDENED_PRNG + reset_sha256_state(); +#endif + // for std::random_shuffle() srand(seed_key[0]); } @@ -38,6 +44,12 @@ void seed_rng(long seed) // MT19937 -- see mt19937ar.cc for details/licence init_genrand(seed); + // Reset the sha256 generator to get predictable random numbers in case + // of a saved rng state. +#ifdef MORE_HARDENED_PRNG + reset_sha256_state(); +#endif + // for std::random_shuffle() srand(seed); } @@ -87,11 +99,19 @@ unsigned long random_int( void ) void push_rng_state() { +#ifndef MORE_HARDENED_PRNG push_mt_state(); +#else + push_sha256_state(); +#endif } void pop_rng_state() { +#ifndef MORE_HARDENED_PRNG pop_mt_state(); +#else + pop_sha256_state(); +#endif } diff --git a/crawl-ref/source/sha256.cc b/crawl-ref/source/sha256.cc index a36d316d92..96443587a0 100644 --- a/crawl-ref/source/sha256.cc +++ b/crawl-ref/source/sha256.cc @@ -11,12 +11,13 @@ #include <stdint.h> typedef uint32_t u32; -typedef uint64_t u64; #include "mt19937ar.h" #ifdef MORE_HARDENED_PRNG +#include <stack> + #include <cstring> #include <cstdio> #include <cstdlib> @@ -137,12 +138,50 @@ void sha256chunk(const char* chunk, sha256state* ss) } } -// 256 bits -u32 mt_sha256_block[8], mt_block[8]; -u32 mt_block_index = 0; +struct sha256mt_state +{ + // 256 bits + u32 mt_sha256_block[8], mt_block[8]; + u32 mt_block_index; + + sha256mt_state() + { + mt_block_index = 0; + } +}; + +sha256mt_state effective_state; + +std::stack<sha256mt_state> sha256mt_state_stack; + +void reset_sha256_state() +{ + effective_state.mt_block_index = 0; +} + +void push_sha256_state() +{ + sha256mt_state_stack.push(effective_state); + push_mt_state(); +} + +void pop_sha256_state() +{ + if (sha256mt_state_stack.empty()) + return; + + effective_state = sha256mt_state_stack.top(); + + sha256mt_state_stack.pop(); + pop_mt_state(); +} unsigned long sha256_genrand() { + u32 &mt_block_index = effective_state.mt_block_index; + u32 *mt_sha256_block = effective_state.mt_sha256_block; + u32 *mt_block = effective_state.mt_block; + // Needs some hashing if (!(mt_block_index % 8)) { @@ -166,7 +205,21 @@ unsigned long sha256_genrand() return mt_sha256_block[mt_block_index++]; } #else // MORE_HARDENED_PRNG -// Stub this to MT function +// Stub these to MT functions +void push_sha256_state() +{ + push_mt_state(); +} + +void pop_sha256_state() +{ + pop_mt_state(); +} + +void reset_sha256_state() +{ +} + unsigned long sha256_genrand() { return genrand_int32(); diff --git a/crawl-ref/source/sha256.h b/crawl-ref/source/sha256.h index 44986adc6b..6ddbb0a0c6 100644 --- a/crawl-ref/source/sha256.h +++ b/crawl-ref/source/sha256.h @@ -2,6 +2,10 @@ #define sha256_h unsigned long sha256_genrand(); +void push_sha256_state(); +void pop_sha256_state(); + +void reset_sha256_state(); #endif |