Пример #1
0
def feistel_round(half_block, subkey):
    assert len(half_block) == 32
    assert len(subkey) == 48

    expansion_output = destools.permute(half_block, EXPANSION)
    xor_output = destools.xor(expansion_output, subkey)
    sbox_output = substituion_round(xor_output)
    permute_output = destools.permute(sbox_output, PERMUTATION)

    log("       Feistel(Right Block, Subkey):");
    log("       Expand(Right Block)=", convert_bits_to_string(expansion_output))
    log("       Expanded(...) XOR Subkey=", convert_bits_to_string(xor_output, 6))
    log("       S-Box(...)=", convert_bits_to_string(sbox_output))
    log("       Permutation(...) (output) =", convert_bits_to_string(permute_output))

    return permute_output
Пример #2
0
def encrypt(block, key, decrypt=False):
    nrounds = 16
    assert len(block) == 64
    assert len(key) == 64

    if decrypt:
        log("Decrypting text to plaintext:", convert_bits_to_string(block))
    else:
        log("Encrypting plaintext to ciphertext:", convert_bits_to_string(block))

    # Generate substitution keys
    subkeys = []
    key_left = destools.permute(key, PERMUTED_CHOICE_1_LEFT)
    key_right = destools.permute(key, PERMUTED_CHOICE_1_RIGHT)
    assert len(key_left) == 28
    assert len(key_right) == 28
    log("Generating Subkeys:")
    log("    Initial Key =", convert_bits_to_string(key))
    log("    Permuting into Left and Right keys")
    log("    Left Half  =", convert_bits_to_string(key_left))
    log("    Right Half =", convert_bits_to_string(key_right))
    for i in xrange(nrounds):
        shift_amount = KEY_SHIFT_AMOUNTS[i]
        destools.left_shift(key_left, shift_amount)
        destools.left_shift(key_right, shift_amount)
        subkey = destools.permute(key_left + key_right, PERMUTED_CHOICE_2)
        subkeys.append(subkey)

        log("")
        log("Subkey %s:" % i)
        log("    Shifting key halves to the left by %s bits" % shift_amount)
        log("    Left Half  =", convert_bits_to_string(key_left))
        log("    Right Half =", convert_bits_to_string(key_right))
        log("    Permuting Left and Right key into subkey")
        log("    Subkey =", convert_bits_to_string(subkey))

    # Apply subkeys in reverse order if decrypting
    log("")
    if decrypt:
        log("Reversing order of subkeys")
        subkeys = subkeys[::-1]

    # Initial Permutation
    block = destools.permute(block, INITIAL_PERMUTATION)
    log("Initial Permutation:", convert_bits_to_string(block))
    log("")

    # Rounds
    left_block = block[0:32]
    right_block = block[32:]
    for i in xrange(nrounds):

        log("Round %s:" % i)
        log("    Input:")
        log("        Subkey      =", convert_bits_to_string(subkeys[i]))
        log("        Left Block  =", convert_bits_to_string(left_block))
        log("        Right Block =", convert_bits_to_string(right_block))

        tmp = right_block
        fiestel_out = feistel_round(right_block, subkeys[i])
        right_block = destools.xor(left_block, fiestel_out)
        left_block = tmp

        log("    Output:")
        log("        Left Block = Left Block XOR Feistel(...)")
        log("                   =", convert_bits_to_string(right_block))
        log("        Right Block (Unchanged)")
        if i == 15:
            log("    DO NOT SWITCH right and left block after the last round")
        else:
            log("    Left and Right blocks are switched and input into next round.")
        log("")

    # Final Permutation
    # right and left are switched here because the final round does not switch
    # them.  Here we just switch them back.
    encrypted = destools.permute(right_block + left_block, FINAL_PERMUTATION)
    log("Result after all rounds = Left Block + Right Block")
    log("                        =", convert_bits_to_string(right_block+left_block))
    log("After Final Permutation =", convert_bits_to_string(encrypted))
    log("")

    return encrypted