def decrypt(self, ct: bytes) -> bytes: blks = ([self.IV]+split_blocks(ct, 16))[::-1] prev = self.decrypt_ecb(blks[0]) for i in blks[1:]: self.pt += [xor(i,prev)] prev = self.decrypt_ecb(i) return pkcs7_unpad(b''.join(self.pt[::-1]))
def encrypt(self, pt: bytes) -> bytes: blks = [self.IV]+split_blocks(pkcs7_pad(pt, 16), 16) prev = blks[0] for i in blks[1:]: self.ct += [self.encrypt_ecb(xor(prev,i))] prev = self.ct[-1] return b''.join(self.ct)
def ctr_break(): key = urandom(16) ct = [ctr(i, key, nonce) for i in pt] x = repeated_xor(b''.join( [j for i in ct for j in split_blocks(i) if (len(j) == 16)])) key = split_blocks(x.find_key(x.find_key_size()))[0] return [xor(i, key) for i in ct] == pt
#!/usr/bin/python3 from Cryptopals import xor if __name__ == '__main__': a = '1c0111001f010100061a024b53535009181c' b = '686974207468652062756c6c277320657965' assert xor( bytes.fromhex(a), bytes.fromhex(b)).hex() == '746865206b696420646f6e277420706c6179'
def solve_xor(cip: bytes) -> bytes: scr = [get_english_score(xor(cip, bytes([i]))) for i in range(255)] return bytes([scr.index(max(scr))])
#!/usr/bin/python3 from Cryptopals import xor, get_english_score def solve_xor(cip: bytes) -> bytes: scr = [get_english_score(xor(cip, bytes([i]))) for i in range(255)] return bytes([scr.index(max(scr))]) if __name__ == '__main__': cip = bytes.fromhex( '1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736') assert xor(cip, solve_xor(cip)) == b"Cooking MC's like a pound of bacon"
#!/usr/bin/python3 from Cryptopals import xor inp = b"Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal" key = b"ICE" res = "0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a3124333a653e2b2027630c692b20283165286326302e27282f" if __name__ == '__main__': assert xor(inp, key).hex() == res
def cipher(pt, seed): prng = mersenne(seed) key = b''.join([bytes([(prng.next()) % 1 << 8]) for _ in range(len(pt))]) print(key) return xor(pt, key)
def ctr(ct: bytes, key: bytes, counter) -> bytes: ret = b'' for j, i in enumerate(split_blocks(ct)): ret += xor(ecb_encrypt(counter(j), key, False), i) return ret[:len(ct)]
def find_key_size(cip: bytes) -> bytes: normalized_val_list = [] for key_size in KEYSIZE: blocks = split_blocks(cip, key_size)[:-1] avg_ham_dist = sum(func_blocks(blocks, hamming_dist)) / (len(blocks) - 1) normalized_val_list += [avg_ham_dist / key_size] return normalized_val_list.index(min(normalized_val_list)) + KEYSIZE[0] byte_split_blocks = lambda blocks, key: b"".join( [bytes([blk[key]]) for blk in blocks]) def find_key(cip: bytes, key_size: bytes) -> bytes: blocks = split_blocks(cip, key_size)[:-1] return b"".join( [solve_xor(byte_split_blocks(blocks, i)) for i in range(key_size)]) def break_repeated_xor(cip: bytes) -> bytes: return find_key(cip, find_key_size(cip)) if __name__ == '__main__': cip = b64decode(open('6.txt', 'r').read()) plt = b64decode(open('6_sol.txt', 'r').read()) assert xor(cip, break_repeated_xor(cip)) == plt