Exemple #1
0
    def test_mt19937(s):
        seed = 0xdeadbeef
        mt = mt19937(seed)
        random.seed(seed)
        s.assertEqual(mt.next(), 956529277)
        s.assertEqual(mt.next(), 3842322136)
        s.assertEqual(mt.next(), 3319553134)
        s.assertEqual(mt.next(), 1843186657)
        s.assertEqual(mt.next(), 2704993644)

        d = []
        for _ in xrange(624):
            d += [random.getrandbits(32)]
        mt = prngutil.crack_mt19937(d)
        for x in xrange(624):
            s.assertEqual(mt.next(), d[x])
        for x in xrange(624):
            s.assertEqual(mt.next(), random.getrandbits(32))
        for x in xrange(624):
            mt.prev()
        for x in d[::-1]:
            s.assertEqual(mt.prev(), x)

        mt = mt19937(seed)
        rand = [mt.next() for _ in xrange(624)]
        s.assertEqual(
            prngutil.crack_mt19937_using_index_difference(
                rand[227], rand[0], 227, 0), [seed])
Exemple #2
0
def crack_mt19937(random_bits):
    """
  Attack to MT19937 : Known Random-bits
  Args:
    random_bits : A list of 624 random elements
  Return: mt19937 class object
  """
    from scryptos.crypto import mt19937
    assert len(random_bits) == mt19937.N
    mt = mt19937(state=list(map(mt19937.untempering, random_bits)))
    return mt
Exemple #3
0
def crack_mt19937_using_index_difference(mA, mB, idxA, idxB):
    """
  Attack to MT19937 : Guess initial state and seed cracking
  Args:
    mA   : A generated random value 1
    mB   : A generated random value 2
    idxA : An index of `mA`
    idxB : An index of `mB`
  Return: Seed Candidates
  See: Scrapbox [Mersenne Twister]
  """
    from scryptos.math import modinv
    from scryptos.crypto import mt19937
    assert (idxA + 397) % 624 == idxB
    # untempering
    mA_ = mt19937.untempering(mA)
    mB_ = mt19937.untempering(mB)
    res = []
    y_ = (mA_ ^ mB_)
    # Guess LSB
    for lsb in [0, 1]:
        y = y_
        if lsb == 1:
            y ^= mt19937.MATRIX_A
        y = (y << 1) & 0xffffffff
        if lsb == 1:
            y |= 1
        # Guess MSB of mt[idxA] and mt[idxA+1]
        invMult = modinv(0x6c078965, mt19937.MOD)
        for msb_mA in [0, 1]:
            for msb_mC in [0, 1]:
                mC = y ^ (msb_mA << 31) ^ (msb_mC << 31)
                x = mC
                for i in range(idxA + 1, 0, -1):
                    x = ((x - i) * invMult) % mt19937.MOD
                    x = x ^ (x >> 30)
                res += [x]
    ret = set()
    for seed in res:
        mt = mt19937(seed=seed)
        rand = [mt.next() for _ in range(max(idxA, idxB) + 1)]
        if mA in rand and mB in rand:
            ret.add(seed)
    return sorted(map(int, ret))