Example #1
0
    def test_challenge20(self):
        plaintexts = [
            base64_to_bytes(line)
            for line in utils.readlines('20.txt')
        ]

        key = encryption_key()
        nonce = '\0' * 8
        ciphertexts = [
            ctr_encrypt(m, key, nonce)
            for m in plaintexts
        ]

        # Because of the fixed-nonce, the encrypted keystream bytes are
        # repeated for every plaintext message.
        #
        # ciphertext[i] ^ keystream[i] = plaintext[i]
        #
        # We can create a transposed ciphertext message by concatenating
        # ciphertext[i] from every encrypted message and then xor'ing that
        # against a guessed keystream byte. Then we can test whether the
        # resulting plaintext looks like english based on character
        # distributions. If so, then we've figured out the keystream byte.

        keystream = ''
        for index in itertools.count():
            transposed = ''.join(m[index:index+1] for m in ciphertexts)
            if not transposed:
                break

            allowed_chars = None
            if index == 0:
                allowed_chars = string.ascii_uppercase + '"\''

            score, _, key = crack.find_best_single_byte_key(
                transposed,
                allowed_chars=allowed_chars
            )
            # print 'Best score for index {}: {}'.format(index, score)
            keystream += key[0]

        recovered_plaintexts = [
            bitops.xor(m, keystream) for m in ciphertexts
        ]

        # for m in recovered_plaintexts:
        #     print m

        self.assertIn(
            '\'Cause my girl is definitely mad / \'Cause it took us too long to do this album',
            recovered_plaintexts
        )
Example #2
0
    def test_challenge18(self):
        ciphertext = base64_to_bytes('L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ==')
        nonce = '\x00' * 8
        plaintext = ctr_decrypt(ciphertext, 'YELLOW SUBMARINE', nonce)
        self.assertEqual(
            'Yo, VIP Let\'s kick it Ice, Ice, baby Ice, Ice, baby ',
            plaintext
        )

        plaintext = 'the quick brown fox jumped over the lazy dog.'
        key = encryption_key()
        ciphertext = ctr_encrypt(plaintext, key, nonce)
        self.assertEqual(plaintext, ctr_decrypt(ciphertext, key, nonce))
Example #3
0
    def test_challenge25(self):
        ciphertext = convert.base64_to_bytes(utils.read('25.txt'))
        plaintext = crypto.ecb_decrypt(ciphertext, 'YELLOW SUBMARINE')

        key = crypto.encryption_key()
        nonce = '\x00' * 8
        ciphertext = crypto.ctr_encrypt(plaintext, key, nonce)

        # The edit function lets us recover the original keystream because
        # in CTR mode: plaintext ^ keystream = ciphertext and then through
        # the magic of xor:
        #
        # plaintext ^ ciphertext = keystream
        #
        # Through the edit function, we know the plaintext and ciphertext
        # for every index in the byte stream.

        keystream = ''
        for offset in range(len(ciphertext)):
            new_ciphertext = edit(ciphertext, key, nonce, offset, 'A')
            keystream += bitops.xor(new_ciphertext[offset], 'A')

        recovered_plaintext = bitops.xor(ciphertext, keystream)
        self.assertEquals(plaintext, recovered_plaintext)
Example #4
0
            'U28gZGFyaW5nIGFuZCBzd2VldCBoaXMgdGhvdWdodC4=',
            'VGhpcyBvdGhlciBtYW4gSSBoYWQgZHJlYW1lZA==',
            'QSBkcnVua2VuLCB2YWluLWdsb3Jpb3VzIGxvdXQu',
            'SGUgaGFkIGRvbmUgbW9zdCBiaXR0ZXIgd3Jvbmc=',
            'VG8gc29tZSB3aG8gYXJlIG5lYXIgbXkgaGVhcnQs',
            'WWV0IEkgbnVtYmVyIGhpbSBpbiB0aGUgc29uZzs=',
            'SGUsIHRvbywgaGFzIHJlc2lnbmVkIGhpcyBwYXJ0',
            'SW4gdGhlIGNhc3VhbCBjb21lZHk7',
            'SGUsIHRvbywgaGFzIGJlZW4gY2hhbmdlZCBpbiBoaXMgdHVybiw=',
            'VHJhbnNmb3JtZWQgdXR0ZXJseTo=',
            'QSB0ZXJyaWJsZSBiZWF1dHkgaXMgYm9ybi4=',
        ]
    ]

    key = encryption_key()
    nonce = '\x00' * 8
    ciphertexts = [
        ctr_encrypt(m, key, nonce)
        for m in plaintexts
    ]

    translations = Translations(ciphertexts)
    view = TranslationsView(translations)
    curses.wrapper(view.event_loop)

    # Answer: Easter 1916 by Yeats
    # Set the line third from the bottom to:
    #
    # He, too, has been changed in his turn,
    #
    # To generate the complete keystream
Example #5
0
def encrypt_kvps(content, key, nonce):
    full_content = ('comment1=cooking%20MCs;userdata=' +
                    urllib.quote(content) +
                    ';comment2=%20like%20a%20pound%20of%20bacon')

    return crypto.ctr_encrypt(full_content, key, nonce)
Example #6
0
def edit(ciphertext, key, nonce, offset, plaintext):
    orig_plaintext = crypto.ctr_decrypt(ciphertext, key, nonce)
    new_plaintext = (orig_plaintext[:offset] + plaintext +
                     orig_plaintext[offset + len(plaintext):])
    return crypto.ctr_encrypt(new_plaintext, key, nonce)