-
Notifications
You must be signed in to change notification settings - Fork 4
/
common.py
147 lines (118 loc) · 3.56 KB
/
common.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
def score(string):
freq = dict()
freq['a'] = 834
freq['b'] = 154
freq['c'] = 273
freq['d'] = 414
freq['e'] = 1260
freq['f'] = 203
freq['g'] = 192
freq['h'] = 611
freq['i'] = 671
freq['j'] = 23
freq['k'] = 87
freq['l'] = 424
freq['m'] = 253
freq['n'] = 680
freq['o'] = 770
freq['p'] = 166
freq['q'] = 9
freq['r'] = 568
freq['s'] = 611
freq['t'] = 937
freq['u'] = 285
freq['v'] = 106
freq['w'] = 234
freq['x'] = 20
freq['y'] = 204
freq['z'] = 6
freq[' '] = 2320
ret = 0
for c in string.lower():
if c in freq:
ret += freq[c]
return ret
def randstr(n):
from random import randint
return ''.join(chr(randint(0, 255)) for _ in range(n))
def pad(data, blocksize=16):
l = (len(data) / blocksize + 1) * blocksize
m = l - len(data)
return data + chr(m) * m
def unpad(data, blocksize=16):
if len(data) % blocksize != 0:
raise Exception
must_unpad = ord(data[-1])
if must_unpad < 0 or must_unpad > blocksize:
raise Exception
if data[-must_unpad:] != chr(must_unpad) * must_unpad:
raise Exception
return data[:-must_unpad]
def AES_ECB_encrypt(data, key):
assert(len(key) == 16)
assert(len(data) % 16 == 0)
from Crypto.Cipher import AES
cipher = AES.new(key, AES.MODE_ECB)
return cipher.encrypt(data)
def AES_ECB_decrypt(data, key):
assert(len(key) == 16)
assert(len(data) % 16 == 0)
from Crypto.Cipher import AES
cipher = AES.new(key, AES.MODE_ECB)
return cipher.decrypt(data)
def xor_str(x, y):
return ''.join(chr(ord(a) ^ ord(b)) for a, b in zip(x, y))
def AES_CBC_encrypt(data, key, iv):
assert(len(key) == 16)
assert(len(iv) == 16)
assert(len(data) % 16 == 0)
ret = ''
left = iv
for i in range(0, len(data), 16):
right = data[i: i + 16]
left = AES_ECB_encrypt(xor_str(left, right), key)
ret += left
return ret
def AES_CBC_decrypt(data, key, iv):
assert(len(key) == 16)
assert(len(iv) == 16)
assert(len(data) % 16 == 0)
ret = ''
left = iv
for i in range(0, len(data), 16):
ret += xor_str(left, AES_ECB_decrypt(data[i: i + 16], key))
left = data[i: i + 16]
return ret
def AES_CTR_keystream_block(key, nonce, block_number):
from struct import pack
data1 = pack('<Q', nonce) # Little-endian, 64 bits
data2 = pack('<Q', block_number)
return AES_ECB_encrypt(data1 + data2, key)
def AES_CTR_keystream(key, nonce):
block_number = 0
while True:
ks_block = AES_CTR_keystream_block(key, nonce, block_number)
for k in ks_block:
yield k
block_number += 1
def AES_CTR(data, key, nonce):
return xor_str(data, AES_CTR_keystream(key, nonce))
if __name__ == '__main__':
assert(pad("YELLOW SUBMARINE", 20) == "YELLOW SUBMARINE\x04\x04\x04\x04")
assert(unpad("YELLOW SUBMARINE\x04\x04\x04\x04", 20) == "YELLOW SUBMARINE")
assert(
AES_ECB_decrypt(
AES_ECB_encrypt('this is sparta!!',
'yellow submarine'),
'yellow submarine') == 'this is sparta!!')
assert(
AES_CBC_decrypt(
AES_CBC_encrypt(pad('SPACey'),
'yellow submarine', '\x00' * 16),
'yellow submarine', '\x00' * 16) == pad('SPACey', 16))
assert(
AES_CTR(
AES_CTR('Outta spaceeeeee',
'YELLOW SUBMARINE', 0),
'YELLOW SUBMARINE', 0) == 'Outta spaceeeeee')
print "All tests pass"