Ejemplo n.º 1
0
def flip_a5_bit(X, a5i, check=True):
    s0 = md4.INITIAL_STATE
    [s1, s2, s3, s4] = md4.do_round1(X, s0)

    a1, _, _, _ = s1
    # a5i - 3 + 3
    a1_new = flip_nth_bit(a1, a5i)

    s1_new = [a1_new, s1[1], s1[2], s1[3]]
    X_new = invert_round1(s0, [s1_new, s2, s3, s4])

    if not check:
        return X_new

    for i in range(5, 16):
        assert_word_eq(X_new[i], X[i])

    round1_states_new = md4.do_round1(X_new, s0)
    expected_round1_states = [s1_new, s2, s3, s4]
    for i in range(4):
        if round1_states_new[i] != expected_round1_states[i]:
            raise Exception('expected s[{}]={}, got {}'.format(i, dump_s(expected_round1_states[i]), dump_s(round1_states_new[i])))

    round2_states_new = md4.do_round2(X_new, round1_states_new[-1])

    [s5, s6, s7, s8] = md4.do_round2(X, s4)
    expected_round1_states = [round2_states_new[0], s6, s7, s8]
    a5_new, _, _, _ = round2_states_new[0]

    a5, _, _, _ = s5
    if nth_bit(a5_new, a5i) == nth_bit(a5, a5i):
        raise Exception('a5 bit {} not flipped'.format(a5i))

    return X_new
Ejemplo n.º 2
0
def flip_d5_bit(X, d5i, check=True):
    s0 = md4.INITIAL_STATE
    [s1, s2, s3, s4] = md4.do_round1(X, s0)

    a2, _, _, _ = s2
    # d5i - 5 + 3
    a2_new = flip_nth_bit(a2, d5i - 2)

    s2_new = [a2_new, s2[1], s2[2], s2[3]]
    X_new = invert_round1(s0, [s1, s2_new, s3, s4])

    if not check:
        return X_new

    for i in list(range(0, 4)) + list(range(9, 16)):
        assert_word_eq(X_new[i], X[i])

    round1_states_new = md4.do_round1(X_new, s0)
    expected_round1_states = [s1, s2_new, s3, s4]
    for i in range(4):
        if round1_states_new[i] != expected_round1_states[i]:
            raise Exception('expected s[{}]={}, got {}'.format(i, dump_s(expected_round1_states[i]), dump_s(round1_states_new[i])))

    round2_states_new = md4.do_round2(X_new, round1_states_new[-1])

    [s5, s6, s7, s8] = md4.do_round2(X, s4)
    expected_round1_states = [round2_states_new[0], s6, s7, s8]
    _, _, _, d5_new = round2_states_new[0]

    _, _, _, d5 = s5
    if nth_bit(d5_new, d5i) == nth_bit(d5, d5i):
        raise Exception('d5 bit {} not flipped'.format(d5i))

    return X_new
Ejemplo n.º 3
0
def do_multi_step_mod(words, check=True):
    round1_states = md4.do_round1(words)
    _, _, _, c4 = round1_states[-1]

    words = do_a5_mod(words, 18, nth_bit(c4, 18), check)
    words = do_a5_mod(words, 25, 1, check)
    words = do_a5_mod(words, 26, 0, check)
    words = do_a5_mod(words, 28, 1, check)
    words = do_a5_mod(words, 31, 1, check)

    if check:
        assert_collidable_round1(words, extra=False)
        assert_collidable_round2_a5(words)

    round1_states = md4.do_round1(words)
    _, b4, _, _ = round1_states[-1]
    round2_states = md4.do_round2(words, round1_states[-1])
    a5, b5, c5, d5 = round2_states[0]

    words = do_d5_mod(words, 18, nth_bit(a5, 18), check)
    words = do_d5_mod(words, 25, nth_bit(b4, 25), check)
    words = do_d5_mod(words, 26, nth_bit(b4, 26), check)
    words = do_d5_mod(words, 28, nth_bit(b4, 28), check)

    if check:
        assert_collidable_round1(words, extra=False)
        assert_collidable_round2_a5(words)
        assert_collidable_round2_d5(words)

    round1_states = md4.do_round1(words)
    _, b4, _, _ = round1_states[-1]
    round2_states = md4.do_round2(words, round1_states[-1])
    a5, b5, c5, d5 = round2_states[0]

    words = do_c5_mod(words, 25, nth_bit(d5, 25), check)
    words = do_c5_mod(words, 26, nth_bit(d5, 26), check)
    # skip 28 for now
    # words = do_c5_mod(words, 28, nth_bit(d5, 28), check)
    words = do_c5_mod(words, 31, nth_bit(d5, 31), check)

    if check:
        assert_collidable_round1(words, extra=False)
        assert_collidable_round2_a5(words)
        assert_collidable_round2_d5(words)
        assert_collidable_round2_c5(words)

    return words
Ejemplo n.º 4
0
def flip_c5_bit(X, c5i, check=True):
    s0 = md4.INITIAL_STATE
    [s1, s2, s3, s4] = md4.do_round1(X, s0)

    _, a2, _, d2 = s2
    # ?
    d2_new = flip_nth_bit(d2, c5i - 9)

    if c5i == 28:
        a2_new = flip_nth_bit(a2, c5i - 9)
    else:
        a2_new = a2

    s2_new = [s2[0], a2_new, s2[2], d2_new]
    X_new = invert_round1(s0, [s1, s2_new, s3, s4])

    if not check:
        return X_new

    for i in list(range(0, 4)) + list(range(12, 16)):
        assert_word_eq(X_new[i], X[i])

    if a2_new == a2:
        for i in [4, 10, 11]:
            assert_word_eq(X_new[i], X[i])

    [s5, s6, s7, s8] = md4.do_round2(X, s4)

    round1_states_new = md4.do_round1(X_new, s0)
    expected_round1_states = [s1, s2_new, s3, s4]
    for i in range(4):
        if round1_states_new[i] != expected_round1_states[i]:
            raise Exception('expected s[{}]={}, got {}'.format(
                i, dump_s(expected_round1_states[i]),
                dump_s(round1_states_new[i])))

    round2_states_new = md4.do_round2(X_new, round1_states_new[-1])

    [s5, s6, s7, s8] = md4.do_round2(X, s4)
    expected_round1_states = [round2_states_new[0], s6, s7, s8]
    _, _, c5_new, _ = round2_states_new[0]

    _, _, c5, _ = s5
    if nth_bit(c5_new, c5i) == nth_bit(c5, c5i):
        raise Exception('c5 bit {} not flipped'.format(c5i))

    return X_new
Ejemplo n.º 5
0
def assert_collidable_round3(words):
    round1_states = md4.do_round1(words)
    round2_states = md4.do_round2(words, round1_states[-1])
    round3_states = md4.do_round3(words, round2_states[-1])
    _, b9, _, _ = round3_states[0]
    a10, _, _, _ = round3_states[1]

    assert_bit1(b9, 32, 1)
    assert_bit1(a10, 32, 1)
Ejemplo n.º 6
0
def do_a5_mod(words, a5i, b, check=True):
    if check:
        assert_collidable_round1(words, extra=False)

    round1_states = md4.do_round1(words)
    round2_states = md4.do_round2(words, round1_states[-1])
    a5, b5, c5, d5 = round2_states[0]

    if nth_bit(a5, a5i) == b:
        return words

    words_new = flip_a5_bit(words, a5i, check)

    if check:
        assert_collidable_round1(words_new, extra=False)
        assert_collidable_round2_a5(words_new, a5i)

    return words_new
Ejemplo n.º 7
0
def assert_collidable_round2_d5(words, d5i=None):
    round1_states = md4.do_round1(words)
    a4, b4, c4, d4 = round1_states[-1]

    round2_states = md4.do_round2(words, round1_states[-1])
    a5, b5, c5, d5 = round2_states[0]

    if d5i is None or d5i >= 18:
        assert_bit(d5, 18, nth_bit(a5, 18))

    if d5i is None or d5i >= 25:
        assert_bit(d5, 25, nth_bit(b4, 25))

    if d5i is None or d5i >= 26:
        assert_bit(d5, 26, nth_bit(b4, 26))

    if d5i is None or d5i >= 28:
        assert_bit(d5, 28, nth_bit(b4, 28))
Ejemplo n.º 8
0
def assert_collidable_round2_c5(words, c5i=False):
    round1_states = md4.do_round1(words)
    a4, b4, c4, d4 = round1_states[-1]

    round2_states = md4.do_round2(words, round1_states[-1])
    a5, b5, c5, d5 = round2_states[0]

    if c5i is None or c5i >= 25:
        assert_bit(c5, 25, nth_bit(d5, 25))

    if c5i is None or c5i >= 26:
        assert_bit(c5, 26, nth_bit(d5, 26))

    # skip 28 for now
#    if c5i is None or c5i >= 28:
#        assert_bit(c5, 28, nth_bit(d5, 28))

    if c5i is None or c5i >= 31:
        assert_bit(c5, 31, nth_bit(d5, 31))
Ejemplo n.º 9
0
def assert_collidable_round2(words):
    round1_states = md4.do_round1(words)
    a4, b4, c4, d4 = round1_states[-1]

    round2_states = md4.do_round2(words, round1_states[-1])
    a5, b5, c5, d5 = round2_states[0]
    a6, b6, c6, d6 = round2_states[1]

    assert_bit1(a5, 19, c4, 19)
    assert_bit1(a5, 26, 1)
    assert_bit1(a5, 27, 0)
    assert_bit1(a5, 29, 1)
    assert_bit1(a5, 32, 1)

    assert_bit1(d5, 19, a5, 19)
    assert_bit1(d5, 26, b4, 26)
    assert_bit1(d5, 27, b4, 27)
    assert_bit1(d5, 29, b4, 29)
    assert_bit1(d5, 32, b4, 32)

    assert_bit1(c5, 26, d5, 26)
    assert_bit1(c5, 27, d5, 27)
    assert_bit1(c5, 29, d5, 29)
    assert_bit1(c5, 30, d5, 30)
    assert_bit1(c5, 32, d5, 32)

    assert_bit1(b5, 29, c5, 29)
    assert_bit1(b5, 30, 1)
    assert_bit1(b5, 32, 0)

    assert_bit1(a6, 29, 1)
    assert_bit1(a6, 32, 1)

    # From https://eprint.iacr.org/2005/151.pdf
    assert_bit1(a6, 30, 0)

    assert_bit1(d6, 29, b5, 29)

    assert_bit1(c6, 29, d6, 29)
    assert_bit1(c6, 30, (1 + nth_bit(d6, 30 - 1)) % 2)
    assert_bit1(c6, 32, (1 + nth_bit(d6, 32 - 1)) % 2)
Ejemplo n.º 10
0
def assert_collidable_round2_a5(words, a5i=None):
    round1_states = md4.do_round1(words)
    a4, b4, c4, d4 = round1_states[-1]

    round2_states = md4.do_round2(words, round1_states[-1])
    a5, b5, c5, d5 = round2_states[0]

    if a5i is None or a5i >= 18:
        assert_bit(a5, 18, nth_bit(c4, 18))

    if a5i is None or a5i >= 25:
        assert_bit(a5, 25, 1)

    if a5i is None or a5i >= 26:
        assert_bit(a5, 26, 0)

    if a5i is None or a5i >= 28:
        assert_bit(a5, 28, 1)

    if a5i is None or a5i >= 31:
        assert_bit(a5, 31, 1)