def cryptanalysis_mixed(): if request.method == "POST": known_key = request.form.get("known_key") generated_key = request.form.get("generated_key") use_generated = bool(request.form.get("use_generated")) ciphertexts = request.form.get("ciphertexts", "").strip().splitlines() plaintexts = request.form.get("plaintexts", "").strip().splitlines() cipher = MixedAlphabet(known_key, wildcard="?") if request.form.get("action") == "Generate Key": use_generated = True generated_key = "".join(generate_key(cipher.alphabet, known_key)) if use_generated: cipher = MixedAlphabet(generated_key, wildcard="?") plaintexts = [cipher.decrypt(c) for c in ciphertexts] else: known_key = generated_key = "?" * 27 use_generated = False plaintexts = [] ciphertexts = [] return render_template( "cryptanalysis/mixed.html", known_key=known_key, generated_key=generated_key, use_generated=use_generated, plaintexts=plaintexts, ciphertexts=ciphertexts, )
def create_h4x0r_messages(group): # Short messages that can be brute forced messages = [ "BLACK", "BLUE", "BROWN", "GREEN", "ORANGE", "PINK", "PURPLE", "RED", "WHITE", "YELLOW" ] cipher = MixedAlphabet(key="FNGZPOXKT_HDLWEMQJRVCSYIBUA") for message in messages: yield create_message(group, "Mixed Alphabet", cipher.key, message, cipher.encrypt(message)) # Long message that can be frequency analysed cipher = MixedAlphabet(key="IGLKWSREJDCANUFBZYP_THMVXQO") message = "ALICE WAS BEGINNING TO GET VERY TIRED OF SITTING BY HER SISTER ON THE BANK AND OF HAVING NOTHING TO DO ONCE OR TWICE SHE HAD PEEPED INTO THE BOOK HER SISTER WAS READING BUT IT HAD NO PICTURES OR CONVERSATIONS IN IT AND WHAT IS THE USE OF A BOOK THOUGHT ALICE WITHOUT PICTURES OR CONVERSATION" yield create_message(group, "Mixed Alphabet", cipher.key, message, cipher.encrypt(message)) # Messages that build on each other to construct the key messages = [ "FIRST A LONG MESSAGE THAT HAS MOST LETTERS IN IT NOT ALL BUT MOST", "THEN A VERY SHORT MESSAGE", "FOLLOWED BY AN EXCEPTIONAL ONE" ] cipher = MixedAlphabet(key="AXT UWVCFGIMBOSNHZRYKEDJLPQ") for message in messages: yield create_message(group, "Mixed Alphabet", cipher.key, message, cipher.encrypt(message))
def test_from_worksheet(): cipher = MixedAlphabet(key="QWERTYUIOPASDFG HJKLZXCVBNM") ciphertext = cipher.encrypt("WELCOME TO VILLIERS PARK") assert cipher.compare_ciphertext("CTSEGDTMLGMXOSSOTJKM QJA", ciphertext) assert cipher.compare_plaintext("WELCOME TO VILLIERS PARK", cipher.decrypt(ciphertext)) plaintext = cipher.decrypt("WTLLTJMLIQFMEQTKQJ") assert cipher.compare_plaintext("BETTER THAN CAESAR", plaintext) assert cipher.compare_ciphertext("WTLLTJMLIQFMEQTKQJ", cipher.encrypt(plaintext))
def test_from_cryptanalysis_presentation(): cipher = MixedAlphabet(key="WEKIATBOZXMGNLCPURDJYQH_FSV") ciphertext = cipher.encrypt("HELLO EVERYONE") assert cipher.compare_ciphertext("OAGGCVAQARFCLA", ciphertext) assert cipher.compare_plaintext("HELLO EVERYONE", cipher.decrypt(ciphertext))
def hack(ciphertext): print('Hacking...') with open('/usr/src/app/scripts/hack/words.txt') as word_file: words = set(word.strip().upper() for word in word_file) best_match = (0, 0, '') guesses = 0 try: tick = time.time() for key in itertools.permutations(list(MixedAlphabet.alphabet)): key = ''.join(key) c = MixedAlphabet(key=key) plaintext = c.decrypt(ciphertext) print(f'\x1b[2K Trying key: {key}', end='\r') possible_words = set(plaintext.replace('_', ' ').split(' ')) matches = len(words.intersection(possible_words)) if matches > best_match[0]: best_match = (matches, key, plaintext) guesses += 1 print(f'\n\n Key: {best_match[1]}') print(f'Plaintext: {best_match[2]}', end='\n\n') except KeyboardInterrupt: tock = time.time() seconds = int(tock - tick) print(f'\n\nTried {guesses} guesses in {seconds} seconds') more = guesses / seconds * math.factorial(27) print(f'Need {more:.2E} more seconds to finish') hours = more / 60 / 60 print(f' - {hours:.2E} hours') days = hours / 24 print(f' - {days:.2E} days') years = days / 365 print(f' - {years:.2E} years') uni_lifetimes = years / 13.8E+9 print(f' - {uni_lifetimes:.2E} universe lifetimes') sheets_of_paper_to_moon = 400000000 / 0.0001 # Distance to moon (meters) over thickness of paper times_to_moon = years / sheets_of_paper_to_moon # One sheet of paper a year print(f' - {times_to_moon:.2E} ttmop') times_to_moon_and_back = 2 * times_to_moon / sheets_of_paper_to_moon # One sheet of paper everytime you get to the moon print(f' - {times_to_moon_and_back:.2f} ttmabop')
def test_key_has_repeating_chars(): with pytest.raises(ScytaleError): MixedAlphabet(key="aacdefghijklmnopqrstuvwxyz ")
def test_key_too_long(): with pytest.raises(ScytaleError): MixedAlphabet(key="abcdefghijklmnopqrstuvwxyz abc")
def test_key_too_short(): with pytest.raises(ScytaleError): MixedAlphabet(key="abcd")
import random from scytale.ciphers import MixedAlphabet if __name__ == '__main__': plaintext = input('Plaintext: ') key = input('Key: ') if not key: a = list(MixedAlphabet.alphabet) random.shuffle(a) key = ''.join(a) print(f'Random Key: {key}') ciphertext = MixedAlphabet(key=key).encrypt(plaintext) print(f'Ciphertext: {ciphertext}')