Пример #1
0
def resolve_second_round_key_average(plaintext_to_ones, first_round_key):
    start_key = '0'*64
    simon = SimonCipher(0)

    current_key = start_key
    for index in range(len(start_key)):
        vote = 0
        print(index, current_key)
        zero_bucket = []
        for plaintext in plaintext_to_ones:
            # Take plaintext and run through one level of encryption given
            # the first round key. This allows us to use the same process we 
            # used for finding the first round key to get the next round key
            ones_for_plaintext = plaintext_to_ones[plaintext]
            plaintext_binary = str(bin(plaintext))[2:].zfill(128)
            right = plaintext_binary[len(plaintext_binary)//2:].zfill(64)
            left = plaintext_binary[:len(plaintext_binary)//2].zfill(64)
            binary_left = int(left, 2)
            binary_right = int(right, 2)
            first_round_ct1, first_round_ct2 = simon.encrypt_round(int(left,2), int(right,2), int(first_round_key, 2))

            # do same process as outlined in getting first round key
            next_round_ct1, _ = simon.encrypt_round(first_round_ct1, first_round_ct2, 0)
            pre_xor_bin = bin(next_round_ct1)[2:].zfill(64)
            pre_xor_ones = ones(int(pre_xor_bin, 2))
            value = pre_xor_bin[index]
            if value == '0':
                zero_bucket.append(ones_for_plaintext)
        zero_bucket_average = sum(zero_bucket)/max(len(zero_bucket),1)
        if zero_bucket_average >= 8703/2+.5:
            current_key = flip_next_one(current_key, index)
    return current_key
Пример #2
0
def resolve_first_round_key_average(plaintext_to_ones):
    start_key = '0'*64
    current_key = start_key
    simon = SimonCipher(0)
    for index in range(len(start_key)):
        print(index, current_key)
        zero_bucket = []
        for plaintext in plaintext_to_ones:
            # Take plaintext and run through one level of encryption with 
            # a key of all zeros. This allows us to get ct2 (which is just
            # the left bits) and the pre-xored ct1 (ct1 but has not been
            # xored with a key yet, we pass in a key of zeros so the xor 
            # does nothing). We then append the number of ones for this 
            # plaintext to the zero bucket only if the pre-xored ct1 at
            # the current index is zero
            ones_for_plaintext = plaintext_to_ones[plaintext]
            plaintext_binary = str(bin(plaintext))[2:].zfill(128)
            right = plaintext_binary[len(plaintext_binary)//2:].zfill(64)
            left = plaintext_binary[:len(plaintext_binary)//2].zfill(64)
            ct1, ct2 = simon.encrypt_round(int(left,2), int(right,2), 0)
            pre_xor_bin = bin(ct1)[2:].zfill(64)
            value = pre_xor_bin[index]
            if value == '0':
                zero_bucket.append(ones_for_plaintext)
        # flip the current entry to 1 if this threshold is met
        # this threshold is derived from (68*128-1)/2 (total number of bits
        # minus the bit we are fixing in this scenario, we then divide by 2).
        # This gives us the expected number of ones for all of the other bits
        # We then consider the case where we set the bit of the key at this 
        # index to 1. This can be modeled similar to part a where we either have
        # t regular coin flips or t regular coin flips + 1. So now, if we want to know
        # whether or not we have the t/2 or t/2+1 scenario, we set our threshold to be
        # in between these two distributions (i.e. t/2 + 0.5)
        zero_bucket_average = sum(zero_bucket)/max(len(zero_bucket),1)
        if zero_bucket_average >= 8703/2+.5:
            current_key = flip_next_one(current_key, index)
    return current_key