Today I would like to share you the power of cryptography.
I made this software 2011 in Eindhoven, Netherlands (country of cryptography) where I was having my exchange studies at the time.
The software is about the Data Encryption Standard or DES, however you like to call it.
DES With 14 Bits
Data Encryption Standard is the old queen of cryptography, which eventually got caught for being too easy to solve. There is a great article in Wikipedia about the topic and how it has influenced modern cryptography.
What I did was kinda experiment if I could code this thing together with some tweaking to the original Standard. DES was created to encrypt with key sizes of 56 bits and block sizes of 64 bits doing 16 rounds of crypting in total.
To learn the standard and the basics of cryptography, I chose to do it with key sizes of 14 bits and block sizes of 16 bits doing 2 rounds of crypting in total. I actually succeeded on this and did a little software with Python to prove it.
Mathematics
Here are the mathematics from my version of the Data Encryption Standard.
Permutations
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 |
PC1 = [12, 5, 14, 1, 10, 2, 6, 9, 15, 4, 13, 7, 11, 3] PC2 = [ 6, 11, 4, 8, 13, 3, 12, 5, 1, 10, 2, 9] IP = [ 2, 14, 6, 10, 12, 8, 16, 4, 5, 13, 3, 9, 11, 1, 15, 7] IP-1 = [ 14, 1, 11, 8, 9, 3, 16, 6, 12, 4, 13, 5, 10, 2, 15, 7] E = [ 8, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1] S = [ [ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12], [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11] ] P = [ 6, 4, 7, 3, 5, 1, 8, 2] |
Calculations
We choose a sub key K’ of 12 bits
1 |
000110 110000 |
Calculations of F(R, K’) as R = 1011 0110
1 2 3 4 |
E(R) = 010110 101101 K (+) E(R) = 010000 011101 S7(B1)S8(B2) = 0011 1001 F(R, K') = 0101 1010 |
We choose a key K of 16 bits
1 |
0100 0110 0100 1001 |
And calculate the two keys K1 and K2
1 2 3 4 5 6 7 8 9 |
K+ = 0000 1110 0011 00 C0 = 0000111 D0 = 0001100 C1 = 0111000 D1 = 1100000 C2 = 1000011 D2 = 0000110 K1 = 001101000011 K2 = 100010101000 |
We choose an input I of 15 bits (e.g. the ASCI-coding of the characters ‘v’ and ‘b’)
1 |
0111 0110 0110 0001 |
And encrypt I using the DESHI-algorithm where we use the given IP and the calculated K1, K2 and IP-1.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
IP = 1011 0001 0010 1011 L0 = 1011 0001 R0 = 0010 1011 R1 = L0 (+) F(R0, K1) E(R0) = 100101 010110 K1 = 001101000011 K1 (+) E(R0) = 101000 010101 S7(B1) S8(B2) = 1100 0110 F(R, K’) = 1010 0101 R1 = L0 (+) F(R0, K1) = 0001 0100 L1 = R0 = 0010 1011 R2 = L0 (+) F(R1, K2) E(R1) = 000010 101000 K2 = 1000010 101000 K2 (+) E(R1) = 100000 000000 S7(B1) S8(B2) = 0001 1101 F(R, K’) = 1100 1010 R2 = L1 (+) F(R1, K2) = 1110 0001 L2 = R0 = 0001 0100 R2L2 = 1110 0001 0001 0100 IP-1 = 1101 0100 1000 0100 |
Software
Program is made with Python version 3.2. The program can probably be run if the system has 3.0 or newer version of Python, but only tested with 3.2. The latest version can be downloaded from: http://www.python.org/download/. The program can be used in Linux or Windows as long as there is Python installed into the system.
Here are some screenshots with the same examples as used in the earlier handwritten DES encryption.
After clicking the encrypt button.
After clicking the decrypt button
Usage
This was just an experiment if I could learn DES and some cryptography, this software should not be used in real life situations. The method I used actually made DES weaker against attacks because I did it with less bits than the usual version. I hope maybe someone may find this information useful and maybe learn some cryptography. In my opinion it’s a really complex world and so much different from traditional software development, because of the mathematics that are included.
Source Code
Here is the source code for this software. To run the software, just copy/paste the code into .py file and run it.
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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# GNU GPL # des.py - Python version used: 3.2 from tkinter import * # UI tool import from tkinter.messagebox import showerror # copies showerror fieldnames = ('key', 'message', 'cipher', 'binary') pc1 = [12, 5, 14, 1, 10, 2, 6, 9, 15, 4, 13, 7, 11, 3] leftshifts = [3, 3] pc2 = [ 6, 11, 4, 8, 13, 3, 12, 5, 1, 10, 2, 9] ip = [ 2, 14, 6, 10, 12, 8, 16, 4, 5, 13, 3, 9, 11, 1, 15, 7] e = [ 8, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 1] s = [ [ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12], [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11] ] p = [ 6, 4, 7, 3, 5, 1, 8, 2] ip1 = [ 14, 1, 11, 8, 9, 3, 16, 6, 12, 4, 13, 5, 10, 2, 15, 7] def makeWidgets(): # makeWidgets function global entries window = Tk() window.title('DES') form = Frame(window) form.pack() entries = {} for(ix, label) in enumerate(fieldnames): # creation of labels and entries into two columns lab = Label(form, text=label) ent = Entry(form, width=50) lab.grid(row=ix, column=0) ent.grid(row=ix, column=1) entries[label] = ent Button(window, text='Encrypt', command=en).pack(side=TOP) # encrypt button, click takes to function en() Button(window, text='Decrypt', command=de).pack(side=TOP) # decrypt button, click takes to function de() return window def stringToBits(data): # string to bits function data = [ord(c) for c in data] # creates unicodes to list result = [] for ch in data: i = 7 while i >= 0: # bit selection if ch & (1 << i) != 0: result.append(1) else: result.append(0) i -= 1 return result # returns a list of created bits def bitsToString(bits): # bits to string function strinG = [] position = 0 a = 0 while position < len(bits): a += bits[position] << (7 - (position % 8)) if (position % 8) == 7: strinG.append(a) a = 0 position += 1 return ''.join([chr(a) for a in strinG]) # returns a string of characters made from bytes def permutate(table, block): # permutation function return list(map(lambda x: block[x], table)) # returns the permutated list def createSubkeys(key, pc1, pc2, leftshifts): # subkeys creation key = permutate(pc1, [0] + stringToBits(key)) # pc1 permutation i = 0 L = key[:7] # slices the permutation into LEFT and RIGHT R = key[7:] subkeys = [] while i < 2: j = 0 while j < leftshifts[i]: # leftshifts the bits from beginning to end L.append(L[0]) del L[0] R.append(R[0]) del R[0] j += 1 subkeys.append(permutate(pc2, [0] + L + R)) # pc2 permutation i += 1 return subkeys def des(message, ip, e, s, p, ip1, subkeys, crypt): # des function if not message: return "" if len(message) % 2 != 0: showerror(title='Error', message='The message or encrypted data must be a multiple of 16 bits!') return "" a = 0 result = [] while a < len(message): cryptob = stringToBits(message[a:a+2]) # gets part of the string and turns it to bits ipresult = permutate(ip, [0] + cryptob) # ip permutation L = ipresult[:8] # slices the variable into LEFT and RIGHT R = ipresult[8:] if crypt == 'en': # sets the variables for the encryption or decryption it = 0 itadd = 1 if crypt == 'de': it = 1 itadd = -1 i = 0 while i < 2: # encryption R2 = R[:] R = permutate(e, [0] + R) # E permutation R = list(map(lambda x, y: x ^ y, R, subkeys[it])) # XOR the permutation B = [R[:6], R[6:]] # slices the permutation into list B[0] and B[1] k = 0 bg = [0] * 8 position = 0 while k < 2: f = (B[k][0] << 1) + B[k][5] # for clarification << means left shifting and >> right shifting g = (B[k][1] << 3) + (B[k][2] << 2) + (B[k][3] << 1) + B[k][4] h = s[k][(f << 4) + g] bg[position] = (h & 8) >> 3 bg[position + 1] = (h & 4) >> 2 bg[position + 2] = (h & 2) >> 1 bg[position + 3] = h & 1 position += 4 k += 1 R = permutate(p, [0] + bg) # P permutation R = list(map(lambda x, y: x ^ y, R, L)) # XOR the permutation L = R2 i += 1 it += itadd ip1result = permutate(ip1, [0] + R + L) # ip-1 permutation result.append(bitsToString(ip1result)) # adds the crypted part as string to result a += 2 return ''.join(result) # returns result list as one joined string def en(): #encrypt click crypt_click('en') def de(): #decrypt click crypt_click('de') def crypt_click(crypttype): #process of encryption or decryption depending of the click key = entries['key'].get() # gets the key from the UI if not key: showerror(title='Error', message='You have to enter a key!') else: if len(key) % 2 != 0: showerror(title='Error', message='The key must be 16 bits!') else: subkeys = createSubkeys(key, pc1, pc2, leftshifts) # creation of subkeys in createSubkeys() functions if crypttype == 'en': # sets the variables to message or to cipher depending on what the user clicked textfrom = 'message' textto = 'cipher' entries['cipher'].delete(0, END) else: textfrom = 'cipher' textto = 'message' messageOrCipher = entries[textfrom].get() # gets message or cipher result = des(messageOrCipher, ip, e, s, p, ip1, subkeys, crypttype) # actual result from the des() function binary = ''.join(map(str, stringToBits(result))) # makes the binary of the result entries[textfrom].delete(0, END) # UI entry delete entries[textto].insert(0, result) # UI entry insert entries['binary'].delete(0, END) entries['binary'].insert(0, binary) window = makeWidgets() # creates the UI window.mainloop() # mainloop of the UI to get actions |