[Python-Dev] RNG in the core

Christian Heimes lists at cheimes.de
Tue Jan 3 14:18:34 CET 2012


all proposed fixes for a randomized hashing function raise and fall with
a good random number generator to feed the random seed. The seed must be
created very early in the startup phase of the interpreter, preferable
before the basic types are initialized. CPython already have multiple
sources for random data (win32_urandom in Modules/posixmodule.c, urandom
in Lib/os.py, Mersenne twister in Modules/_randommodule.c). However we
can't use them because they are wrapped inside Python modules which
require infrastructure like initialized base types.

I propose an addition to the current Python C API:

int PyOS_URandom(char *buf, Py_ssize_t len)

Read "len" chars from the OS's RNG into the pre-allocated buffer "buf".
The RNG should be suitable for cryptography. In case of an error the
function returns -1 and sets an exception, otherwise it returns 0.
On Windows I can re-use most of the code of win32_urandom(). For POSIX I
have to implement os.urandom() in C in order to read data from
/dev/urandom. That's simple and straight forward.

Since some platforms may not have /dev/urandom, we need a PRNG in the
core, too. I therefore propose to move the Mersenne twister from
randommodule.c into the core, too.

typedef struct {
    unsigned long state[N];
    int index;
} _Py_MT_RandomState;

unsigned long _Py_MT_GenRand_Int32(_Py_MT_RandomState *state); //
double _Py_MT_GenRand_Res53(_Py_MT_RandomState *state); // random_random()
void _Py_MT_GenRand_Init(_Py_MT_RandomState *state, unsigned long seed);
// init_genrand()
void _Py_MT_GenRand_InitArray(_Py_MT_RandomState *state, unsigned long
init_key[], unsigned long key_length); // init_by_array

I suggest Python/random.c as source file and Python/pyrandom.h as header
file. Comments?


More information about the Python-Dev mailing list