def __iter__(self): reverse_sorted_guesses = [] for key_size in range(self.min_key_size, self.max_key_size + 1): iter_positions = blocks.positions(len(self.ba), key_size) distances = [] first_block = None prev_block = None for position in itertools.islice(iter_positions, self.sample_block_count): # Break if block size isn't as expected. # This occurs when data size isn't a multiple of the key size # and we've reached end of the data. if key_size != (position.end - position.start): break block = list(position.slice(self.ba)) if prev_block is None: first_block = block else: distances.append(hamming.distance(block, prev_block)) prev_block = block if block != first_block: distances.append(hamming.distance(block, first_block)) average_distance = (sum(distances) / float(len(distances))) / key_size guess = self.Guess(average_distance, key_size) bisect.insort_left(reverse_sorted_guesses, guess) yield self.State(guess, reverse_sorted_guesses)
def test(self): self.assertEqual(list(blocks.positions(64, 16)), [ blocks.Position(start=0, end=16), blocks.Position(start=16, end=32), blocks.Position(start=32, end=48), blocks.Position(start=48, end=64) ])
def decrypt_ecb(key, data): key = bytes(key) null_iv = bytes([0] * BLOCK_SIZE) result = bytearray() for position in blocks.positions(len(data), BLOCK_SIZE): enc_block = bytes(position.slice(data)) dec_block = oscrypto.symmetric.aes_cbc_no_padding_decrypt(key, enc_block, null_iv) result.extend(dec_block) return result
def encrypt_cbc(key, iv, data): key = bytes(key) null_iv = bytes([0] * BLOCK_SIZE) prev_enc_block = iv result = bytearray() for position in blocks.positions(len(data), BLOCK_SIZE): block = bytes(position.slice(data)) block = bytes(xor.repeating_bytes(block, prev_enc_block)) _, enc_block = oscrypto.symmetric.aes_cbc_no_padding_encrypt(key, block, null_iv) result.extend(enc_block) prev_enc_block = enc_block return result
def count_blocks(data): return collections.Counter( bytes(position.slice(data)) for position in blocks.positions(len(data), BLOCK_SIZE) )