rfc:improve_predictable_prng_random
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
rfc:improve_predictable_prng_random [2017/02/02 03:00] – Change to random object that is fully capable random object. yohgaki | rfc:improve_predictable_prng_random [2018/03/01 23:13] (current) – RFC is Under Discussion carusogabriel | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== PHP RFC: Improve predictable PRNG random ====== | + | ====== PHP RFC: Improve predictable PRNG random |
* Version: 0.9 | * Version: 0.9 | ||
* Date: 2017-02-01 | * Date: 2017-02-01 | ||
* Author: Yasuo Ohgaki < | * Author: Yasuo Ohgaki < | ||
- | * Status: | + | * Status: |
* First Published at: http:// | * First Published at: http:// | ||
Line 14: | Line 14: | ||
<code php> | <code php> | ||
// We need the same random numbers here | // We need the same random numbers here | ||
- | mt_srand(1234); | + | srand(1234); |
for ($i=0; $i < 10; $i++) { | for ($i=0; $i < 10; $i++) { | ||
// Use my PRNG state | // Use my PRNG state | ||
- | | + | |
} | } | ||
Line 29: | Line 29: | ||
</ | </ | ||
- | **This is not limited to specific request that calls mt_srand($some_value), | + | **Above code worked as it should. PHP 7.1 broke this code.** Similarly, shuffle()/ |
+ | |||
+ | <code php> | ||
+ | // We need the same random numbers here | ||
+ | mt_srand(1234); | ||
+ | for ($i=0; $i < 10; $i++) { | ||
+ | // Use my PRNG state | ||
+ | | ||
+ | } | ||
+ | |||
+ | // Somewhere later in code AND/OR even other requests | ||
+ | |||
+ | // We need to shuffle randomly | ||
+ | shuffle($my_random_array); | ||
+ | </ | ||
+ | |||
+ | **These behaviors are not limited to specific request that calls mt_srand($some_value)/ | ||
PHP should have system and user PRNG state to resolve this behavior. | PHP should have system and user PRNG state to resolve this behavior. | ||
Line 42: | Line 58: | ||
==== Rack of Reseeding ==== | ==== Rack of Reseeding ==== | ||
- | Reseeding is important for PRNG to mitigate guessed random value. Since MT rand is predictable PRNG, using the same PRNG state allows to guess random value. Current PHP only supports very weak initialization and keeps using the same PRNG state once it is initialized. This behavior makes trivial to guess MT rand generated random numbers. | + | Reseeding is important for PRNG to mitigate guessed random value. Since MT rand is predictable PRNG, using the same PRNG state allows to guess next random value easily. Current PHP only supports very weak initialization and keeps using the same PRNG state once it is initialized. This behavior makes trivial to guess MT rand generated random numbers. |
To resolve this issue, PHP should reseed MT rand when state is used certain number of times. | To resolve this issue, PHP should reseed MT rand when state is used certain number of times. | ||
Line 48: | Line 64: | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | ==== Return PRNG state object from mt_srand()/ | + | ==== Return PRNG random |
<code php> | <code php> | ||
- | | + | |
- | | + | |
</ | </ | ||
- | mt_srand()/ | + | mt_srand()/ |
Note: srand() is alias of mt_rand(). Python initializes MT rand state by string data like this proposal. | Note: srand() is alias of mt_rand(). Python initializes MT rand state by string data like this proposal. | ||
Line 70: | Line 86: | ||
<code php> | <code php> | ||
- | int mt_rand([RandomState | + | int mt_rand([RandomMT |
- | int mt_rand(int $min, int $max [, RandomState | + | int mt_rand(int $min, int $max [, RandomMT |
- | int rand([RandomState | + | int rand([Random |
- | int rand(int $min, int $max [, RandomState | + | int rand(int $min, int $max [, Random |
- | bool shuffle(array &$arr [, RandomSatate | + | bool shuffle(array &$arr [, Random |
</ | </ | ||
When user initialized PRNG state object is specified, specified state is used to generate random values. | When user initialized PRNG state object is specified, specified state is used to generate random values. | ||
- | ==== RandomState | + | ==== Random |
- | Create RandomeInterface, | + | Create RandomeInterface, |
<code php> | <code php> | ||
interface RandomInterface { | interface RandomInterface { | ||
- | public function | + | public function |
- | public function | + | public function |
public function getString(int $length, int $bits = 6); // String [0-9a-zA-Z, | public function getString(int $length, int $bits = 6); // String [0-9a-zA-Z, | ||
- | public function seed($seed = NULL); // No use of CSPRNG, return TRUE always. | + | public function seed($seed = NULL); // No use with CS RNG, raise exception. |
- | public function getCount(); // No use of CSPRNG, return 0 always. | + | public function getState(); // Return string representation PRNG state. No use with CS RNG, raise exception. |
- | public function getReseedCycle(); | + | public function setState(string $state); // Set PRNG state. No use with CS RNG, raise exception. |
- | public function setReseedCycle(int $count); // No use of CSPRNG, return TRUE always. | + | public function getCount(); // No use with CS RNG, raise exception. |
+ | public function getReseedCycle(); | ||
+ | public function setReseedCycle(int $count); // No use with CS RNG, raise exception. | ||
+ | } | ||
+ | |||
+ | class RandamCS implements RandomIterface { | ||
+ | // random_*() functions OO API | ||
+ | // Description omitted, see RandomMT | ||
+ | } | ||
+ | |||
+ | // Implement True RNG which may block process when TRNG abstraction function is implemented | ||
+ | class RandamTRNG implements RandomIterface { | ||
+ | // Description omitted, see RandomMT | ||
} | } | ||
Line 102: | Line 130: | ||
public function __construct($seed = NULL) { | public function __construct($seed = NULL) { | ||
$this-> | $this-> | ||
+ | } | ||
+ | |||
+ | private reseed() { | ||
+ | $this-> | ||
+ | if ($this-> | ||
+ | $this-> | ||
+ | $this-> | ||
+ | } | ||
} | } | ||
| | ||
- | public function | + | public function |
assert($min <= $max); | assert($min <= $max); | ||
+ | $this-> | ||
if ($min && $max) { | if ($min && $max) { | ||
return mt_rand($min, | return mt_rand($min, | ||
Line 120: | Line 157: | ||
} | } | ||
| | ||
- | public function | + | public function |
- | // Return raw random bytes | + | // Return raw random bytes. 3 out of 4 bytes are used not to disclose full PRNG state |
} | } | ||
| | ||
Line 135: | Line 172: | ||
// Update state by user seed | // Update state by user seed | ||
mt_srand($seed); | mt_srand($seed); | ||
+ | $this-> | ||
} else { | } else { | ||
// Seed by system generated random value | // Seed by system generated random value | ||
Line 160: | Line 198: | ||
} | } | ||
} | } | ||
+ | </ | ||
+ | |||
+ | Random object has getBytes() and getString(). Implement function also. | ||
+ | |||
+ | <code php> | ||
+ | string mt_rand_bytes(int $length [, RandomMT $rand]) | ||
+ | string mt_rand_string(int $length [, RandomMT $rand]) | ||
+ | string rand_bytes(int $length [, Random $rand] ) // Alias of mt_rand_raw() now, but signature differs from MT rand to allow better PRNG in the future. | ||
+ | string rand_string(int $length [,int $bits [, Random $rand]]) // Alias of mt_rand_string() | ||
+ | string random_string(int $length [,int $bits]) | ||
</ | </ | ||
Line 171: | Line 219: | ||
</ | </ | ||
- | uint32_t BG(mt_rand_is_seeded) is used for already seeded flag and counter. | + | uint32_t BG(mt_rand_is_seeded) is used for already seeded flag and counter. |
Line 179: | Line 227: | ||
mt_srand()/ | mt_srand()/ | ||
- | If users want static random values, they have to use RandomStatus | + | If users want static random values, they have to use Random |
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
Line 221: | Line 269: | ||
===== Future Scope ===== | ===== Future Scope ===== | ||
- | Add object based predictable PRNG API. | + | Add Random objects as it required |
===== Proposed Voting Choices ===== | ===== Proposed Voting Choices ===== |
rfc/improve_predictable_prng_random.1486004416.txt.gz · Last modified: 2017/09/22 13:28 (external edit)