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 HMAC(K, m): Kp = data(K) m = data(m).bytes if len(K) < 64: Kp = data(b'\x00' * (64 - len(K)) + K) elif len(K) > 64: Kp = data(sha1(K), 'hex') opad = data(b'\x5c' * 64) ^ Kp ipad = data(b'\x36' * 64) ^ Kp return sha1(opad.bytes + data(sha1(ipad.bytes + m)).bytes)
def encrypt_one_token(): tokens = [ 'MDAwMDAwTm93IHRoYXQgdGhlIHBhcnR5IGlzIGp1bXBpbmc=', 'MDAwMDAxV2l0aCB0aGUgYmFzcyBraWNrZWQgaW4gYW5kIHRoZSBWZWdhJ3MgYXJlIHB1bXBpbic=', 'MDAwMDAyUXVpY2sgdG8gdGhlIHBvaW50LCB0byB0aGUgcG9pbnQsIG5vIGZha2luZw==', 'MDAwMDAzQ29va2luZyBNQydzIGxpa2UgYSBwb3VuZCBvZiBiYWNvbg==', 'MDAwMDA0QnVybmluZyAnZW0sIGlmIHlvdSBhaW4ndCBxdWljayBhbmQgbmltYmxl', 'MDAwMDA1SSBnbyBjcmF6eSB3aGVuIEkgaGVhciBhIGN5bWJhbA==', 'MDAwMDA2QW5kIGEgaGlnaCBoYXQgd2l0aCBhIHNvdXBlZCB1cCB0ZW1wbw==', 'MDAwMDA3SSdtIG9uIGEgcm9sbCwgaXQncyB0aW1lIHRvIGdvIHNvbG8=', 'MDAwMDA4b2xsaW4nIGluIG15IGZpdmUgcG9pbnQgb2g=', 'MDAwMDA5aXRoIG15IHJhZy10b3AgZG93biBzbyBteSBoYWlyIGNhbiBibG93' ] # token = data(tokens[0]).bytes token = data(random.sample(tokens, 1)[0], 'b64').bytes # iv = key[::-1] iv = int.to_bytes(random.getrandbits(16 * 8), 16, 'big') return (iv, CBC_encrypt(pad(token, 16), key, iv))
def cyphered_comment(comment): comment = '"comment1=cooking%20MCs;userdata="'+data(comment).ascii().replace("=","\=").replace(";","\;")+'";comment2=%20like%20a%20pound%20of%20bacon"' return CBC_encrypt(pad(data(comment).bytes),key)
def fake_admin(): return (data(cyphered_comment("\x00"*320))^data("\x00"*320+";admin=true;")).bytes
def is_admin(comment): # print(data(unpad(CBC_decrypt(comment,key))).bytes) return ";admin=true;" in data(unpad(CBC_decrypt(comment,key))).ascii()
def cyphered_comment(comment): comment = '"comment1=cooking%20MCs;userdata="' + data( comment).ascii().replace("=", "\=").replace( ";", "\;") + '";comment2=%20like%20a%20pound%20of%20bacon"' return CTR_encrypt(pad(data(comment).bytes), key) #counterfunction and nonce have default values
def decode_with_key(i, key): print(xor(key, data(texts[i]).bytes)[:len(texts[i])])
def key_if(guess, i, reference_i): return (data(guess) ^ data( (texts[reference_i][i:]))).bytes[i:len(guess) + i]
from ctr import CTR_encrypt, counter_function from bytestring_tools import data, chunk, xor texts = open("cryptopals_19.txt").readlines() texts = [data(x.strip(), 'b64').bytes for x in texts] texts = [ CTR_encrypt(x, b"Yellow submarine", counter_function, 0) for x in texts ] abc = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,!."\'' 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) # cyphertext ^ correct_guess ^ different_cyphertext = plaintext; this estimates plaintext (badly) def best_guesses(i, reference_i): guesses = sorted([(score_guess(x, i, reference_i), x) for x in abc])[::-1][:10] return (''.join([y for x, y in guesses if x > 0.9])) def table_of_guesses(reference_i, start=0):
def is_admin(comment): # print(data(unpad(CBC_decrypt(comment,key))).bytes) unencrypted = data(unpad(CBC_decrypt(comment, key, iv=key))) verify_ascii_compliance(unencrypted.bytes) return ";admin=true;" in unencrypted.ascii()