[Python-ideas] Should our default random number generator be secure?

Petr Viktorin encukou at gmail.com
Fri Sep 11 23:48:54 CEST 2015

On Fri, Sep 11, 2015 at 11:12 PM,  <random832 at fastmail.us> wrote:
> On Wed, Sep 9, 2015, at 17:02, Nathaniel Smith wrote:
>> Keeping that promise in mind, an alternative would be to keep both
>> generators around, use the cryptographically secure one by default, and
>> switch to MT when someone calls
>>   seed(1234, generator="INSECURE LEGACY MT")
>> But this would justifiably get us crucified by the security community,
>> because the above call would flip the insecure switch for your entire
>> program, including possibly other modules that were depending on random
>> to
>> provide secure bits.
> I just realized, OpenBSD has precisely this functionality, for the
> rand/random/rand48 functions, in the "_deterministic" versions of their
> respective seed functions. So that's probably not a terrible path to go
> down:
> Make a Random class that uses a CSPRNG and/or os.urandom until/unless it
> is explicitly seeded. Use that class for the global instance. We could
> probably skip the "make a separate function name to show you really mean
> it" because unlike C, Python has never encouraged explicitly seeding
> with the {time, pid, four bytes from /dev/random} when one doesn't
> actually want determinism. (The default seed in C for rand/random is
> *1*; for rand48 it is an implementation-defined, but specified to be
> constant, value).
> For completeness, have getstate return a tuple of a boolean (for which
> mode it is in) and whatever state Random returns. setstate can accept
> either this tuple, or for compatibility whatever Random uses.

Calling getstate() means yoy want to call setstate() at some point in
the future, and have deterministic results. Getting the CSRNG state is
dangerous (since it would allow replaying), and it's not even useful
(since system entropy gets mixed in occasionally).
Instead, in this scheme, getstate() should activate the deterministic
RNG (seeding it if it's the first use), and return its state.
setstate() would then also switch to the Twister, and seed it.

More information about the Python-ideas mailing list