Skip to content

Instantly share code, notes, and snippets.

@tajo
Created December 9, 2015 20:57
Show Gist options
  • Save tajo/f87fc8fdd23df7e42b62 to your computer and use it in GitHub Desktop.
Save tajo/f87fc8fdd23df7e42b62 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
import binascii
import sys
import time
import base64
from des import *
_pythonMajorVersion = sys.version_info[0]
def xor_bits(list1, list2):
res = []
for i in xrange(0, len(list1)):
res.append(xor(list1[i], list2[i]))
return res
def xor(bit1, bit2):
if (bit1 == bit2):
return 0
return 1
def bitfield(n):
bits = [int(digit) for digit in bin(n)[2:]]
while(len(bits) < 8):
bits.insert(0, 0)
return bits
def hexToBits(iv):
bits = []
for i in xrange(0, len(iv), 2):
bits += bitfield(int(iv[i] + iv[i+1], 16))
return bits
def keyToStr(key):
bitKey = hexToBits(key)
keyStr = ''
for i in xrange(0, len(bitKey), 8):
keyStr += chr(int(str(bitKey[i]) + str(bitKey[i+1]) + str(bitKey[i+2])
+ str(bitKey[i+3]) + str(bitKey[i+4]) + str(bitKey[i+5])
+ str(bitKey[i+6]) + str(bitKey[i+7]) , 2))
return keyStr
def strToBits(data):
if _pythonMajorVersion < 3:
data = [ord(c) for c in data]
l = len(data) * 8
result = [0] * l
pos = 0
for ch in data:
i = 7
while i >= 0:
if ch & (1 << i) != 0:
result[pos] = 1
else:
result[pos] = 0
pos += 1
i -= 1
return result
def bitsToStr(data):
result = []
pos = 0
c = 0
while pos < len(data):
c += data[pos] << (7 - (pos % 8))
if (pos % 8) == 7:
result.append(c)
c = 0
pos += 1
if _pythonMajorVersion < 3:
return ''.join([ chr(c) for c in result ])
else:
return bytes(result)
def cbc_encrypt(message, key, iv):
"""
Args:
message: string, bytes, cannot be unicode
key: string, bytes, cannot be unicode
Returns:
ciphertext: string
"""
# Message preprocessing & padding
bitMessage = strToBits(message)
bitMessage.append(1)
while len(bitMessage) % 64:
bitMessage.append(0)
# CBC
d = des(keyToStr(key))
xorWith = hexToBits(iv)
cipher = []
for i in xrange(0, len(bitMessage), 64):
xorWith = d.des_encrypt(xor_bits(xorWith, bitMessage[i:i+64]))
cipher += xorWith
return bitsToStr(cipher)
def cbc_decrypt(message, key, iv):
"""
Args:
message: string, bytes, cannot be unicode
key: string, bytes, cannot be unicode
Returns:
plaintext: string
"""
# decrypt CBC
bitMessage = hexToBits(binascii.hexlify(message))
d = des(keyToStr(key))
xorWith = hexToBits(iv)
plaintext = []
for i in xrange(0, len(bitMessage), 64):
plaintext += xor_bits(xorWith, d.des_decrypt(bitMessage[i:i+64]))
xorWith = bitMessage[i:i+64]
# remove padding
while plaintext[len(plaintext)-1] == 0:
plaintext.pop()
plaintext.pop()
return bitsToStr(plaintext)
def main(argv):
if len(argv) != 5:
print 'Wrong number of arguments!\npython task1.py $MODE $INFILE $KEYFILE $IVFILE $OUTFILE'
sys.exit(1)
mode = argv[0]
infile = argv[1]
keyfile = argv[2]
ivfile = argv[3]
outfile = argv[4]
message = None
key = None
iv = None
try:
message = open(infile, 'r').read()
key = open(keyfile, 'r').read()
iv = open(ivfile, 'r').read()
except:
print 'File Not Found'
start = time.time()
if mode == "enc":
output = cbc_encrypt(message, key, iv)
elif mode == "dec":
output = cbc_decrypt(message, key, iv)
else:
print "Wrong mode!"
sys.exit(1)
end = time.time()
print "Consumed CPU time=%f"% (end - start)
open(outfile, 'w').write(output)
if __name__=="__main__":
main(sys.argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment