« back to discussion

Rebuild internal state of Mersenne Twister RND

I thought this was fascinating, saw it on HN and thought it deserved a second look:

https://spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-php

about 4 years ago, by bonzai

2 Replies

301

I wonder how many bits of "randomness" ruby seeds into the MT. It only mentions python, perl and php

301, about 4 years ago

bonzai
posted by 301 on Wed, Dec 5 at 11:41PM

I wonder how many bits of "randomness" ruby seeds into the MT. It only mentions python, perl and php

I just had a look through random.c to form an educated guess... and with my C knowledge I know about as much as I do before I looked.

The code is quite pretty though

rand_init(struct MT *mt, VALUE vseed)
{
    volatile VALUE seed;
    long blen = 0;
    long fixnum_seed;
    int i, j, len;
    unsigned int buf0[SIZEOF_LONG / SIZEOF_INT32 * 4], *buf = buf0;

    seed = rb_to_int(vseed);
    switch (TYPE(seed)) {
      case T_FIXNUM:
    len = 1;
    fixnum_seed = FIX2LONG(seed);
        if (fixnum_seed < 0)
            fixnum_seed = -fixnum_seed;
    buf[0] = (unsigned int)(fixnum_seed & 0xffffffff);
#if SIZEOF_LONG > SIZEOF_INT32
    if ((long)(int32_t)fixnum_seed != fixnum_seed) {
        if ((buf[1] = (unsigned int)(fixnum_seed >> 32)) != 0) ++len;
    }
#endif
    break;
      case T_BIGNUM:
    blen = RBIGNUM_LEN(seed);
    if (blen == 0) {
        len = 1;
    }
    else {
        if (blen > MT_MAX_STATE * SIZEOF_INT32 / SIZEOF_BDIGITS)
        blen = MT_MAX_STATE * SIZEOF_INT32 / SIZEOF_BDIGITS;
        len = roomof((int)blen * SIZEOF_BDIGITS, SIZEOF_INT32);
    }
    /* allocate ints for init_by_array */
    if (len > numberof(buf0)) buf = ALLOC_N(unsigned int, len);
    memset(buf, 0, len * sizeof(*buf));
    len = 0;
    for (i = (int)(blen-1); 0 <= i; i--) {
        j = i * SIZEOF_BDIGITS / SIZEOF_INT32;
#if SIZEOF_BDIGITS < SIZEOF_INT32
        buf[j] <<= BITSPERDIG;
#endif
        buf[j] |= RBIGNUM_DIGITS(seed)[i];
        if (!len && buf[j]) len = j;
    }
    ++len;
    break;
      default:
    rb_raise(rb_eTypeError, "failed to convert %s into Integer",
         rb_obj_classname(vseed));
    }
    if (len <= 1) {
        init_genrand(mt, buf[0]);
    }
    else {
        if (buf[len-1] == 1) /* remove leading-zero-guard */
            len--;
        init_by_array(mt, buf, len);
    }
    if (buf != buf0) xfree(buf);
    return seed;
}

bonzai, about 4 years ago


Login or to comment.

« back to discussion

Tutorials are any resources you learn from.

Examples: an intro to html5 screencast, a pdf about git, photoshop effects tutorials, meta-programming in ruby, lambda calculus, higher-order fixed-point combinators.

Tools are websites, apps or services used -on- your project (indirectly), to aid the process.

Examples: A color scheme generator, email marketing software, usability heat maps, css3 code generators, a downloadable png compressor.

Assets are downloadable files used -in- your projects, usually as code, textures, or images.

Examples: a jquery sticky menu, photoshop brushes, background textures, mvc frameworks, twitter bootstrap, 960 grid system.