Пример #1
0
def _generate_messages(k):
    h = '\x00\x00'
    state_size = len(h)
    collisions = []

    while k > 0:
        lookup = {}
        prefix = '\x00' * AES.block_size * (2**(k - 1))
        pre_hash = mdhash(prefix, h)

        for _ in range(2**(state_size * 8)):
            m = urandom(state_size)
            lookup[mdhash(m, h)] = m

        m = urandom(state_size)
        hashed = mdhash(m, pre_hash)
        while hashed not in lookup:
            m = urandom(state_size)
            hashed = mdhash(m, pre_hash)

        collisions.append((prefix + m, lookup[hashed]))

        k -= 1
        h = hashed

    return collisions, hashed
Пример #2
0
def p53():
    k = 16
    M = urandom(AES.block_size * 2 ** k)
    intermediate_hashes = _block_hash_map(M)

    collision_pairs, final_state = _generate_messages(k)
    while final_state not in intermediate_hashes:
        collision_pairs, final_state = _generate_messages(k)

    bridge_index = intermediate_hashes[final_state]
    bridge_offset = bridge_index * AES.block_size
    print(f'Bridge block is at index {bridge_index}')

    prefix = _generate_prefix(bridge_index, collision_pairs)
    assert mdhash(prefix, b'\x00\x00', nopadding=True) == final_state
    assert len(prefix) == (bridge_index * AES.block_size)

    preimage = prefix + M[bridge_offset:]
    hashed = mdhash(M, b'\x00\x00')
    assert len(preimage) == len(M)
    assert mdhash(preimage, b'\x00\x00') == hashed

    return f'Found a preimage for message M with length 2^{k}\n' \
           f'M = {hexlify(M).decode()[:32]}...\n' \
           f'hash = {hexlify(hashed).decode()}\n' \
           f'preimage = {hexlify(preimage).decode()[:32]}...'
Пример #3
0
def p54():
    funnel = _generate_states(8)
    assert funnel[0][1] is None
    prediction = mdhash(b'', funnel[0][0])
    print(f'Prediction hash = {hexlify(prediction).decode()}')

    m = b'This message predicts every result for the coming baseball season'
    m = _generate_suffix(m, funnel)

    hashed = mdhash(m, b'\x00\x00')
    assert hashed == prediction
    return f'Generated message {m} with hash = {hexlify(hashed).decode()}'
Пример #4
0
def p54():
    funnel = _generate_states(8)
    assert funnel[0][1] is None
    prediction = mdhash('', funnel[0][0])
    print 'Prediction hash = {}'.format(hexlify(prediction))

    m = 'This message predicts every result for the coming baseball season'
    m = _generate_suffix(m, funnel)

    hashed = mdhash(m, '\x00\x00')
    assert hashed == prediction
    return 'Generated message {} with hash = {}'.format(
        repr(m), hexlify(hashed))
Пример #5
0
def _find_collision(h1, h2):
    lookup = {}

    for _ in xrange(2**8):
        m = urandom(2)
        hashed = mdhash(m, h1)
        lookup[hashed] = m

    m = urandom(2)
    hashed = mdhash(m, h2)
    while hashed not in lookup:
        m = urandom(2)
        hashed = mdhash(m, h2)

    return lookup[hashed], m, hashed
Пример #6
0
def p53():
    k = 16
    M = urandom(AES.block_size * 2**k)
    intermediate_hashes = _block_hash_map(M)

    collision_pairs, final_state = _generate_messages(k)
    while final_state not in intermediate_hashes:
        collision_pairs, final_state = _generate_messages(k)

    bridge_index = intermediate_hashes[final_state] + 1
    bridge_offset = bridge_index * AES.block_size
    print 'Bridge block is at index {}'.format(bridge_index)

    prefix = _generate_prefix(bridge_index, collision_pairs)
    assert len(prefix) == (bridge_index * AES.block_size)

    preimage = prefix + M[bridge_offset:]
    assert len(preimage) == len(M)
    assert mdhash(preimage, '\x00\x00') == mdhash(M, '\x00\x00')
    return 'Found a preimage for message M with length 2^{}'.format(k)
Пример #7
0
def _generate_suffix(m, funnel):
    target_states = {
        h: i
        for (i, (h, _)) in enumerate(funnel) if i > len(funnel) / 2
    }

    glue = urandom(2)
    hashed = mdhash(m + glue, '\x00\x00')
    while hashed not in target_states:
        glue = urandom(2)
        hashed = mdhash(m + glue, '\x00\x00')

    m = pkcs7(m + glue)
    i = target_states[hashed]
    while i != 0:
        h, a = funnel[i]
        m += pkcs7(a)
        i = (i - 1) / 2

    return m
Пример #8
0
def _generate_messages(k: int) -> Tuple[List[Tuple[bytes, bytes]], bytes]:
    h = b'\x00\x00'
    state_size = len(h)
    collisions = []
    hashed = b''

    while k > 0:
        lookup = {}
        prefix = b'\x00' * AES.block_size * (2 ** (k - 1))
        pre_hash = mdhash(prefix, h, nopadding=True)

        for _ in range(2 ** (state_size * 8)):
            m = urandom(state_size)
            lookup[mdhash(m, h)] = m

        m = urandom(state_size)
        hashed = mdhash(m, pre_hash)
        while hashed not in lookup:
            m = urandom(state_size)
            hashed = mdhash(m, pre_hash)

        single_block_hash = mdhash(lookup[hashed], h)
        klen_block_hash = mdhash(prefix + m, h)
        assert single_block_hash == klen_block_hash
        assert klen_block_hash == hashed
        assert hashed == single_block_hash

        collisions.append((prefix + m, lookup[hashed]))

        k -= 1
        h = hashed

    return collisions, hashed
Пример #9
0
def _block_hash_map(M):
    block_to_index = {}
    h = '\x00\x00'
    M = pkcs7(M)

    for i in range(len(M) / AES.block_size):
        start = i * AES.block_size
        end = start + AES.block_size
        block = M[start:end]

        hashed = mdhash(block, h, nopadding=True)
        block_to_index[hashed] = i
        h = hashed

    return block_to_index
Пример #10
0
def _block_hash_map(M: bytes) -> Dict[bytes, int]:
    state_to_index = {}
    h = b'\x00\x00'
    M = pkcs7(M)

    for i in range(len(M) // AES.block_size):
        state_to_index[h] = i

        start = i * AES.block_size
        end = start + AES.block_size
        block = M[start:end]

        hashed = mdhash(block, h, nopadding=True)
        h = hashed

    return state_to_index