def score_guess(guess, i, reference_i): guess = data(guess).bytes plain_chars = set([x for x in abc]) compare_with = [x for x in texts if len(x) > i] reference = texts[reference_i] return sum([ data(xor(xor(x[i:i + 1], guess), reference[i:i + 1])).ascii() in plain_chars for x in compare_with ]) / len(compare_with)
def decode_with_keydict(keydict): key = b'' for i in sorted(keydict.keys()): while len(key) < i: key += b'\x00' key += keydict[i] print(xor(key, data(texts[0]).bytes))
def get_iv(): cyphertext = cyphered_comment(b'') try: is_admin(cyphertext[:16] + b'\x00' * 16 + cyphertext) except Exception as e: plain = (e.args[0][20:-1]) # 18 is the length of the cruft plain = codecs.escape_decode(bytes(plain, "utf-8"))[0] return xor(plain[:16], plain[32:48])
def break_ragged_xor(cyphertexts): b = transpose_bytes(sorted(cyphertexts, key=len)[::-1]) key = [b'\x00'] * len(b) for i in range(len(key)): def score(test_key): return (Xsq(xor(b[i], test_key * len(b[i]))), test_key) key[i] = sorted(possible_bytes(), key=score)[0] print(i, xor(b[i], key[i] * len(b[i]))) return b''.join(key)
def break_block(block, previous_block, oracle, blocksize): """Decrypts a block encrypted with CBC using a padding oracle. written to use check_padding. """ right_bytes = b'' # invariant: rightbytes is the rightmost known bytes of plaintext. l = 0 def leftpad(_bytes): return b'\x00' * (blocksize - len(_bytes)) + _bytes all_bytes = [int.to_bytes(x, 1, 'big') for x in range(256)] while l < blocksize: padmask1 = pad(b'\x00' * (blocksize - 1 - l), blocksize) # both padmasks have correct padding padmask2 = pad( b'\xFF' * (blocksize - 1 - l), blocksize ) # therefore, (padmask ^ plaintext ^ (leftpad(right_bytes)) ^ previous_block) has correct padding for x in all_bytes: test_bytes = xor(leftpad(x + right_bytes), previous_block) #DUH if oracle(xor(test_bytes, padmask1), block) and oracle( xor(test_bytes, padmask2), block): right_bytes = x + right_bytes break l += 1 return right_bytes
def CTR_encrypt(_bytes, key, counter_function=counter_function, nonce=0): return xor(_bytes, CTR_keystream(key, counter_function, len(_bytes), nonce))
def decode_with_key(i, key): print(xor(key, data(texts[i]).bytes)[:len(texts[i])])
def score(test_key): return (Xsq(xor(b[i], test_key * len(b[i]))), test_key)
from ctr import CTR_encrypt, counter_function from bytestring_tools import data, chunk, xor from vigenere_xor import transpose_bytes, possible_bytes from h2b import plaintext_similarity_chi_sq as Xsq texts = open("cryptopals_20.txt").readlines() texts = [data(x.strip(), 'b64').bytes for x in texts] cyphertexts = [ CTR_encrypt(x, b"Yellow submarine", counter_function, 0) for x in texts ] def break_ragged_xor(cyphertexts): b = transpose_bytes(sorted(cyphertexts, key=len)[::-1]) key = [b'\x00'] * len(b) for i in range(len(key)): def score(test_key): return (Xsq(xor(b[i], test_key * len(b[i]))), test_key) key[i] = sorted(possible_bytes(), key=score)[0] print(i, xor(b[i], key[i] * len(b[i]))) return b''.join(key) key = break_ragged_xor(cyphertexts) for x in cyphertexts: print(xor(x, key[:len(x)])) # print(break_vigenere(cyphertext))
def encrypt(self, _bytes): return xor(_bytes, self.keystream(len(_bytes)))