On 27 January 2017 at 02:52, Yasuo Ohgaki <yohg...@ohgaki.net> wrote:
> Since mt_rand is predictable PRNG, there is possibility to be known to
> attackers always.
>
> What I would like to change is
>
>  - there is only 2^32 initial states

This needs to be thought of as 2^32 possible _streams_ with a period
of (2^19937)−1. Offset within the stream is as important as the stream
variation itself.

> Think of a code that generates "random password string" from mt_rand.
> (We know nobody should do this, but there are many codes do this)
>
> If password is alpha numeric+#$ and 10 chars long, there could be
>  64^10 = 2^60 patterns with pure random.

Statistical testing of MT shows it to be pretty good. The ability to
recover the state from full outputs doesn't subtract from the quality
of the randomness. It is absolutely not a cryptographic quality
generator, but it is a high quality source of entropy.

In fact state recovery is made harder in PHP because we only ever emit
31 of the 32 bits of output. This compounds over 624 outputs, and
while it doesn't make it impossible to recover it adds some difficulty
(especially when you don't know when the state will twist).

Another factor to consider is that people discard _most_ of the output
when they do things like using mt_rand to generate character strings,
so an observer only sees 8 out of 32 bits per call, making state
recovery exceptionally more difficult (again not knowing when the
state will be mutated).

> but with current mt_rand could generate only
>  2^32 patterns due to mt_rand() limited state.

The 2^32 vs 2^60 is a false equivalence. 2^32 is the theoretical
number of unique passwords that can be generated from a freshly
initialised state, while 2^60 represents the "bit strength" of a
_single_ password. Even with 2^32 possible initial states every
password generated will still have a bit strength of 2^60

> This is a lot less random than it could be.
>
> Hardening mt_rand() w/o salt value beneficial to general mt_rand() usage
> also.
> i.e. PHP app runs short periods of time and only use beginning of MT rand
> cycle.
> More than 99% random cycle is wasted currently.

You can force this kind of scenario if you have for example a CLI
script that generates a single password and then exits. In this case
you only have 2^32 possible unique outcomes, but this is rarely the
case.

The MT state is per-process, not per request. If you do not explicitly
re-seed it then you will continue down that 2^19937 period. So in fact
it is far safer to not re-seed MT explicitly from user-land code.

In most applications you cannot guarantee that your request is being
served by the same process, you will never get a full outputs, and you
never know your position within the state. State recovery is generally
going to be infeasible, even right now without any changes.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to