Example #1
0
 def default_gen_key(cls: MT19937Cipher, mt: MT19937) -> int:
     """
     params:
         mt: seeded MT19937
     returns:
         sequence of ints to be used as keystream
     """
     generated = list(mt.extract_number().to_bytes(4, byteorder="little"))
     byte_index = -1
     while True:
         byte_index += 1
         if byte_index >= 4:
             generated = list(mt.extract_number().to_bytes(
                 4, byteorder="little"))
             byte_index = 0
         yield generated[byte_index]
Example #2
0
def clone_mt19937(mt: MT19937) -> MT19937:
    """
    params:
        mt: seeded MT19937 generator
    returns:
        cloned MT19937 with state spliced from that of `mt`
    side-effect:
        `mt` will have been tapped 624 times
    """
    cloned = MT19937()

    cloned.index = 0
    for i in range(mt.n):
        cloned.MT[i] = untemper(mt.extract_number())

    return cloned
Example #3
0
    def test_break_currtime_mt19937_nominal_case(self):
        actual_seed = int(time.time())

        mt = MT19937()
        mt.seed_mt(actual_seed)
        cracked_seed = break_currtime_mt19937(mt.extract_number(), eps=10)

        self.assertEqual(actual_seed, cracked_seed)
Example #4
0
    def test_break_currtime_mt19937_seed_outside_search_range_returns_none(
            self):
        actual_seed = int(time.time()) - 100

        mt = MT19937()
        mt.seed_mt(actual_seed)

        self.assertIsNone(break_currtime_mt19937(mt.extract_number(), eps=10))
Example #5
0
    def test_untemper_nominal_case(self):
        mt = MT19937()
        mt.seed_mt(123)

        self.assertEqual(untemper(mt.extract_number()), mt.MT[0])
        self.assertEqual(untemper(mt.extract_number()), mt.MT[1])
        self.assertEqual(untemper(mt.extract_number()), mt.MT[2])
        self.assertEqual(untemper(mt.extract_number()), mt.MT[3])
        self.assertEqual(untemper(mt.extract_number()), mt.MT[4])
Example #6
0
    def test_clone_mt19937_nominal_case(self):
        mt = MT19937()
        mt.seed_mt(123)

        cloned_mt = clone_mt19937(mt)

        for i in range(mt.n):
            cloned_mt.extract_number()

        for i in range(5):
            self.assertEqual(mt.extract_number(), cloned_mt.extract_number())
Example #7
0
    def test_default_gen_key_verify_first_two_random_numbers(self):
        expected_ints = [254, 205, 75, 178, 109, 61, 132, 182]
        mt = MT19937()
        mt.seed_mt(123)

        actual_ints = []
        i = 0
        for b in MT19937Cipher.default_gen_key(mt):
            actual_ints.append(b)
            i += 1
            if i == 8:
                break

        self.assertEqual(expected_ints, actual_ints)
Example #8
0
def mt19937_oracle() -> Tuple[int, int]:
    """
    Waits a random number of seconds between
    Seeds the RNG with the current Unix timestamp
    Waits a random number of seconds again.
    Returns the first 32 bit output of the RNG and current time used as seed
    """
    time.sleep(random.randint(40, 1000))

    curr_time = int(time.time())
    mt = MT19937()
    mt.seed_mt(curr_time)

    time.sleep(random.randint(40, 1000))
    return mt.extract_number(), curr_time
Example #9
0
    def encrypt(self: MT19937Cipher, plaintext: bytes) -> bytes:
        """
        params:
            plaintext: bytes to encrypt
        returns:
            `plaintext` XORed with keystream generated by `gen_key`
        """
        mt = MT19937()
        mt.seed_mt(self.seed)
        ciphertext = b''

        for plain, key in zip(plaintext, self.gen_key(mt)):
            ciphertext += (plain ^ key).to_bytes(1, byteorder="little")

        return ciphertext
Example #10
0
    def test_extract_number_nominal_case(self):
        # Expected numbers generated from MT19937 with a seed of 123
        # obtained from: https://asecuritysite.com/encryption/twister
        expected_numbers = (
            2991312382,
            3062119789,
            1228959102,
            1840268610,
            974319580,
        )

        mt = MT19937()
        mt.seed_mt(123)
        for expected in expected_numbers:
            self.assertEqual(expected, mt.extract_number())
Example #11
0
def break_currtime_mt19937(rand_num: int, eps: int = 1200) -> int:
    """
    params:
        rand_num: first number generated by MT19937 using current UNIX time
                  as seed
        eps: number of seconds in the past to look back through
    returns:
        seed used by MT19937 to generate `rand_num`
        None if seed not found
    """
    curr_time = int(time.time())
    for t in range(curr_time - eps, curr_time + 1):
        mt = MT19937()
        mt.seed_mt(t)
        if mt.extract_number() == rand_num:
            return t
    return None
Example #12
0
 def test_extract_number_without_seeding_raises(self):
     mt = MT19937()
     with self.assertRaises(Exception):
         mt.extract_number()