forked from akalin/cryptopals-python3
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchallenge18.py
45 lines (37 loc) · 1.32 KB
/
challenge18.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import base64
import struct
from Crypto.Cipher import AES
from Crypto.Util.strxor import strxor
class CTR:
def __init__(self, ECB, nonce):
self._ECB = ECB
self._nonce = nonce
self._blocksize = 16
self._keybytes = b''
self._blockcount = 0
def encrypt(self, plaintext):
# Work around strxor() not handling zero-length strings
# gracefully.
if len(plaintext) == 0:
return b''
keystream = self._keybytes
while len(keystream) < len(plaintext):
keyblock = self._ECB.encrypt(struct.pack('<QQ', self._nonce, self._blockcount))
keystream += keyblock
self._blockcount += 1
if len(keystream) > len(plaintext):
self._keybytes = keystream[len(plaintext):]
keystream = keystream[:len(plaintext)]
return strxor(plaintext, keystream)
def decrypt(self, ciphertext):
return self.encrypt(ciphertext)
if __name__ == '__main__':
x = base64.b64decode('L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ==')
key = b'YELLOW SUBMARINE'
cipher1 = CTR(AES.new(key, AES.MODE_ECB), 0)
y = cipher1.decrypt(x)
print(y)
cipher2 = CTR(AES.new(key, AES.MODE_ECB), 0)
z = cipher2.encrypt(y)
if x != z:
raise Exception(x + b' != ' + z)