-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchallenge18.py
52 lines (35 loc) · 1.15 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
46
47
48
49
50
51
52
import math, base64
from challenge7 import ecb_enc_raw
from util import xor, randombytes
def little_endian(int):
return int.to_bytes(8, byteorder='little')
def op_ctr(data: bytearray, key: bytearray, nonce: int):
"""
Encrypt or decrypt under ctr mode.
:return: bytearray
"""
assert nonce <= 0xffffffffffffffff
nonce_bytes = little_endian(nonce)
counter = 0
retval = bytearray()
chunksize = math.ceil(len(data) / 16)
for i in range(chunksize):
dub = nonce_bytes + little_endian(counter)
chunk = data[i*16:(i+1)*16]
retval += op_ctr_raw(chunk, key, dub)
counter += 1
return retval
def op_ctr_raw(chunk, key, dub):
keystream = ecb_enc_raw(dub, key)
return xor(chunk, keystream[:len(chunk)])
def challenge():
ciphertext = base64.b64decode('L77na/nrFsKvynd6HzOoG7GHTLXsTVu9qvY/2syLXzhPweyyMTJULu/6/kXX0KSvoOLSFQ==')
plaintext = op_ctr(ciphertext, b'YELLOW SUBMARINE', 0)
print(plaintext)
def main():
key = randombytes(16)
input = randombytes(16)
assert op_ctr(op_ctr(input, key, 0), key, 0) == input
challenge()
if __name__ == '__main__':
main()