Пример #1
0
def break_bounded_length_code_with_mcmc_monogram_criteria(
        encryption, alphabet, n_list, coefs, log_distributions, steps_constant,
        lower_bound, upper_bound, monogram_log_distribution, scrabble):
    max_weight = float("-inf")
    max_state = [cipher.get_zero_mono_key()]
    coprimes = cipher.get_coprimes(alphabet.length)
    for length in range(lower_bound, upper_bound + 1):
        state = get_max_monogram_state(encryption, monogram_log_distribution,
                                       length, alphabet)[0]
        if length > (lower_bound + upper_bound) / 2:
            state = break_fixed_length_code_with_mcmc(
                encryption, alphabet, state, n_list, coefs, log_distributions,
                int(steps_constant * alphabet.length * length *
                    (2 + log(length))), coprimes)[0]
        words_list = cipher.encrypt_decrypt_text(encryption, state,
                                                 alphabet).get_words_list()
        weight = sum([word in scrabble
                      for word in words_list]) / len(words_list)
        if weight > max_weight:
            max_weight = weight
            max_state = state
        if max_weight > 0.5:
            break
    return break_fixed_length_code_with_mcmc(
        encryption, alphabet, max_state, n_list, coefs, log_distributions,
        int(steps_constant * alphabet.length * len(max_state) *
            (10 + log(len(max_state)))), coprimes)
Пример #2
0
def break_fixed_length_code_with_mcmc(encryption,
                                      alphabet,
                                      starting_state,
                                      n_list,
                                      coefs,
                                      log_distributions,
                                      steps,
                                      coprimes=[],
                                      true_decrypting_code=[],
                                      consistency_thresholds=[]):
    consistency_index = 0
    consistency_list = []
    if not coprimes:
        coprimes = cipher.get_coprimes(alphabet.length)
    current_state = starting_state
    current_decryption = cipher.encrypt_decrypt_text(encryption, current_state,
                                                     alphabet, coprimes)
    start = generate_frequencies_and_state_weight(current_decryption, n_list,
                                                  coefs, log_distributions)
    current_frequencies = start[0]
    current_state_weight = start[1]
    max_weight = current_state_weight
    max_state = current_state
    for step in range(steps):
        candidate = neighbours.get_candidate(current_state, alphabet, coprimes)
        frequency_and_weight_change = generate_frequency_and_weight_change(
            current_state, candidate, n_list, coefs, log_distributions,
            current_decryption, encryption, alphabet, coprimes)
        frequencies_change = frequency_and_weight_change[0]
        weight_change = frequency_and_weight_change[1]
        changed_index = candidate[0]
        u = random.random()
        if log(u) < weight_change:
            cipher.update_decryption_by_key_index(current_decryption,
                                                  encryption, changed_index,
                                                  candidate[1],
                                                  len(current_state), alphabet,
                                                  coprimes)
            current_state[changed_index] = candidate[1]
            for f in range(len(frequencies_change)):
                common.update_frequency(current_frequencies[f],
                                        frequencies_change[f])
            current_state_weight += weight_change
            if current_state_weight > max_weight:
                max_state = current_state[:]
                max_weight = current_state_weight
                if true_decrypting_code and \
                        common.consistency(current_state, true_decrypting_code, alphabet) >= \
                        consistency_thresholds[consistency_index]:
                    consistency_index += 1
                    consistency_list.append(step)
                    if consistency_index >= len(consistency_thresholds):
                        return max_state, max_weight, consistency_list
    return max_state, max_weight, consistency_list
Пример #3
0
def get_max_monogram_state(encryption, monogram_log_distribution, key_length,
                           alphabet):
    coprimes = cipher.get_coprimes(alphabet.length)
    max_monogram_key = []
    max_weight = 0
    for coordinate in range(key_length):
        max_coord = get_max_monogram_state_coord(encryption, coordinate,
                                                 monogram_log_distribution,
                                                 key_length, alphabet,
                                                 coprimes)
        max_monogram_key.append(max_coord[0])
        max_weight += max_coord[1]
    return max_monogram_key, max_weight
Пример #4
0
def break_bounded_length_code_with_mcmc(encryption, alphabet, n_list, coefs,
                                        log_distributions, steps, boundary,
                                        monogram_log_distribution):
    max_weight = float("-inf")
    max_state = [cipher.get_zero_mono_key()]
    coprimes = cipher.get_coprimes(alphabet.length)
    for length in range(1, boundary + 1):
        start = get_max_monogram_state(encryption, monogram_log_distribution,
                                       length, alphabet)[0]
        break_attempt = break_fixed_length_code_with_mcmc(
            encryption, alphabet, start, n_list, coefs, log_distributions,
            steps, coprimes)
        if break_attempt[1] > max_weight:
            max_state = break_attempt[0]
            max_weight = break_attempt[1]
    return max_state, max_weight
Пример #5
0
def get_max_bigram_state(encryption, bigram_log_distribution, key_length,
                         alphabet):
    coprimes = cipher.get_coprimes(alphabet.length)
    all_mono_keys = cipher.get_all_mono_keys(alphabet, coprimes)
    codes = {
        a: {
            b: [cipher.get_zero_mono_key() for i in range(key_length - 1)]
            for b in all_mono_keys
        }
        for a in all_mono_keys
    }
    values = {
        a: {
            b:
            get_bigram_part_weight(encryption, (a, b), 0, key_length,
                                   bigram_log_distribution, alphabet, coprimes)
            for b in all_mono_keys
        }
        for a in all_mono_keys
    }
    new_values = {a: {b: 0 for b in all_mono_keys} for a in all_mono_keys}
    for r in range(1, key_length):
        for i in all_mono_keys:
            for j in codes[i]:
                max_func = float("-inf")
                max_arg = cipher.get_zero_mono_key()
                for k in codes[i]:
                    func = values[i][k] + get_bigram_part_weight(
                        encryption, (k, j), r, key_length,
                        bigram_log_distribution, alphabet, coprimes)
                    if func > max_func:
                        max_func = func
                        max_arg = k
                new_values[i][j] = max_func
                codes[i][j][r - 1] = max_arg

        aux = values
        values = new_values
        new_values = aux

    return get_max_bigram_key_and_weight(values, codes, all_mono_keys)
Пример #6
0
 def setUp(self):
     self.alphabet = alphabetic.Alphabet("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
     self.coprimes = extended.get_coprimes(self.alphabet.length)