Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Code

442 views
from sage.crypto.util import ascii_integer from sage.crypto.block_cipher.sdes import SimplifiedDES bin = BinaryStrings(); sigma = 0; def encrypt(m, k): ct = []; iv = ZZ.random_element(256); n = 0; for a in m: if n==0: pt = bin.encoding(chr(int(str(bin.encoding(a)), 2)^^iv)); else: pt = bin.encoding(chr(int(str(bin.encoding(a)), 2)^^int(ct[n-1],2))); c = sdes.encrypt(list(pt), k); ct.append(''.join(str(i) for i in c)); n = n + 1; return [format(iv, '08b')] + ct; def decrypt(ct, k): pt = ''; n = 0; iv = int(str(ct[0]), 2); for c in ct[1:]: p = sdes.decrypt(list(bin(c)), k); if n==0: p = chr(int(''.join(str(i) for i in p), 2) ^^ iv); else: p = chr(int(''.join(str(i) for i in p), 2) ^^ int(ct[n], 2)); pt += p; n = n + 1; return pt; def subverted_encrypt(bk, k, m): global sigma; ct = []; if sigma == 0: c = sdes.encrypt(k[:8], bk); fake_iv = ''.join(str(i) for i in c); iv = int(fake_iv, 2); else: iv = ZZ.random_element(256); sigma = sigma + 1; n = 0; for a in m: if n==0: pt = bin.encoding(chr(int(str(bin.encoding(a)), 2)^^iv)); else: pt = bin.encoding(chr(int(str(bin.encoding(a)), 2)^^int(ct[n-1],2))); c = sdes.encrypt(list(pt), k); ct.append(''.join(str(i) for i in c)); n = n + 1; return [format(iv, '08b')] + ct; def subverted_decrypt(bk, ct): pt = []; iv = int(str(ct[0]), 2); k = sdes.decrypt(list(bin.encoding(chr(iv))), bk); key = []; for i in range(4): k_cand = []; k_cand.append(int(i/2)); k_cand.append(int(i%2)); key.append(k + k_cand); pt.append(decrypt(ct, k + k_cand)); return [pt, key]; sdes = SimplifiedDES(); k = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]; m = 'Top Secret'; print "Message = ", m; #backdoor key bk = [1, 1, 1, 1, 1, 0, 0, 0, 0, 0]; ct = subverted_encrypt(bk, k, m); print "Fake IV = ", ct[0]; print "Ciphertext = ", ct[1:]; pt, key = subverted_decrypt(bk, ct); print "Possible Plaintexts = ", pt; print "Possible Keys = ", key; found = 0; ck = []; for i in range(len(key)): for t in pt[i]: ascii = int(str(bin.encoding(t)), 2) if ascii >= 32 and ascii <= 126: found = 1; ck = key[i]; continue; else: found = 0; ck = []; break; if found == 1: break; if len(ck) > 0: print "Correct Key = ", ck; m = "NSA secret"; print "Next Message = ", m; ct = subverted_encrypt(bk, k, m); print "IV = ", ct[0]; print "Ciphertext = ", ct[1:]; pt = decrypt(ct, ck); print "Plaintext = ", pt; else: print "Cannot find key"
Message = Top Secret Fake IV = 00100011 Ciphertext = ['00111001', '11011010', '11101000', '01111111', '10100000', '00000001', '10100110', '10110011', '01111100', '11001101'] Possible Plaintexts = ['\x9d\xa6\xbc\xec7\xa9o\xdb\t\xb8', '<\xa2u\xc8\xfe`\x0e\xba\xa8u', 'P\xce\xb9A2\x04nVA\xb9', 'Top Secret'] Possible Keys = [[0, 0, 0, 0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 0, 1, 1, 1, 0, 1], [0, 0, 0, 0, 0, 1, 1, 1, 1, 0], [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]] Correct Key = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] Next Message = NSA secret IV = 00100101 Ciphertext = ['01001111', '00100011', '10100110', '01111101', '11100011', '01111101', '00110100', '01101011', '11100011', '10000111'] Plaintext = NSA secret