Skip to content

Instantly share code, notes, and snippets.

@daniman
Last active April 11, 2016 21:44
Show Gist options
  • Save daniman/2d6f7183f48c4cb226f2 to your computer and use it in GitHub Desktop.
Save daniman/2d6f7183f48c4cb226f2 to your computer and use it in GitHub Desktop.
Code to decrypt the secret message in 6.857's first pset.
import ffield
F = ffield.FField(8) # 0 - 255
c1 = map(lambda x: int(x, 16), "50 90 5f 98 db 20 fb 0a 7a 1c 8b 71 14 f7 e4 b1 b2 8b 63 a6 f7 3d 8a 46 e2 c6 a7 51 1f 97 7e fe 71 b8 36 3c cd 20 89 df".split(' '))
c2 = map(lambda x: int(x, 16), "2a 5a fe 23 db bb 9e ba 5d 42 3b c8 f9 0b 97 18 1f b5 06 7e cf 18 d2 0b d5 f6 e5 75 d4 7f ea 65 27 b8 9a d4 ca cd de 37".split(' '))
c3 = map(lambda x: int(x, 16), "b5 2f 00 98 89 85 fb 8d d5 00 d1 df 26 33 91 ce d5 bb 9a 61 42 6a c9 21 58 57 a7 7b 47 57 55 21 f8 9b d9 d3 ca 41 de 1c".split(' '))
c4 = map(lambda x: int(x, 16), "11 4d 2a 70 2b 02 f3 48 d9 cc 7e c8 97 c4 7b f6 73 b5 b5 0b 69 65 ff 47 d5 c3 a7 7d 61 5b a6 a3 bb b8 8f d4 71 da 84 cb".split(' '))
c5 = map(lambda x: int(x, 16), "fd 5e be ea 45 3d 9e 48 a9 b6 f2 c2 26 f4 7f ea 1f e8 ba 79 7e 73 88 38 58 e3 a7 7b b5 4c 32 bc 91 85 4a d3 6b b3 0d b5".split(' '))
c6 = map(lambda x: int(x, 16), "50 2f b4 ed 6e 3d 63 9e 7a 1c a4 71 f9 f0 52 ce 0f 35 e5 02 2c 18 93 f7 f3 9c a7 7d b5 97 4d 00 7a 55 d9 d4 18 41 82 c6".split(' '))
c7 = map(lambda x: int(x, 16), "11 70 f6 85 38 02 17 e1 06 6f 3b f6 7a 0b 93 5e 0f a8 2f 61 69 18 ee a2 57 3d 73 4b df c7 55 7c 27 3e a5 e5 8d a6 4f 37".split(' '))
c8 = map(lambda x: int(x, 16), "50 63 f6 84 fa 7c 63 77 5e 6f 8b c8 26 f7 46 b1 1f bb 9a 61 7e 18 8a e8 d5 53 a7 d3 1f 4c 55 ae 7a b8 3e e5 cd 41 84 e5".split(' '))
ciphers = [(c1[i], c2[i], c3[i], c4[i], c5[i], c6[i], c7[i], c8[i]) for i in xrange(len(c1))]
messages = [[] for i in xrange(len(c1))]
# decimal equivalents for ' ', 'a' - 'z'
plain_text = [32, 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]
# find original messages in decimal
for i in xrange(len(ciphers)):
print "Processing Column:", i
for p in xrange(1, 256):
for q in xrange(0, 256):
valid = True
for c in ciphers[i]:
poss_m = F.Multiply(F.Subtract(c, q), F.Inverse(p))
if poss_m not in plain_text:
valid = False
if valid:
print "Found PQ:", p, q
chars = [-1, -1, -1, -1, -1, -1, -1, -1, (p, q)]
for j in range(len(ciphers[i])):
c = ciphers[i][j]
chars[j] = F.Multiply(F.Subtract(c, q), F.Inverse(p))
messages[i].append(chars)
# translate into ASCII characters again
for i in xrange(len(messages)):
for j in xrange(len(messages[i])):
pq = messages[i][j][8]
messages[i][j] = messages[i][j][:8]
messages[i][j] = map(lambda x: chr(x), messages[i][j])
messages[i][j].append(pq)
# format answer
ans = ['', '', '', '', '', '', '', '']
pq = []
for i in xrange(len(messages)): # for each column
options = messages[i]
if len(options) <= 1: # handle 38/40 columns
pq.append(options[0][8])
for j in xrange(len(ans)):
ans[j] += options[0][j]
else:
options = filter(lambda x: x[7] == ' ', options)
if len(options) <= 1: # handle column 36 case
pq.append(options[0][8])
for j in xrange(len(ans)):
ans[j] += options[0][j]
else: # handle column 27 case
options = filter(lambda x: x[0] == ' ', options)
options = filter(lambda x: x[1] == 'n', options)
pq.append(options[0][8])
for j in xrange(len(ans)):
ans[j] += options[0][j]
print "----------------------------------------" \
"\nDecrypted Message:\n" \
"----------------------------------------"
print "\n".join(ans)
print "P (hex):", (' ').join([hex(p[0]).lstrip('0x') for p in pq])
print "Q (hex):", (' ').join([hex(q[1]).lstrip('0x') for q in pq])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment