├── .gitignore ├── README.md ├── project1 ├── FreqAnalysis.py ├── ManualSubCipherTool.py ├── README.md ├── input.txt ├── output1.txt └── output2.txt ├── project2 ├── README.md ├── RainbowAttack.py ├── TableGenerator.py ├── table.csv └── test.py ├── project3 ├── README.md ├── breaker.py ├── ciphertext_sheet3.txt └── plaintext.txt ├── worksheet1 ├── CBCSubCipher │ ├── CBCSubCipher.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── CBCSubCipher │ │ ├── CBCSubCipher.1 │ │ └── main.c ├── PythonBruteforce │ └── BruteForce.py ├── woorksheet 1.pdf └── woorksheet 1.tex ├── worksheet2 ├── exercise14 │ └── graph.py ├── exercise15 │ ├── Exercise15.py.lprof │ ├── README.md │ ├── covered-points.csv │ ├── exercise15.py │ ├── graph.png │ └── table.csv ├── exercise16.md └── exercise17 │ ├── README.md │ ├── covered-keys.csv │ ├── exercise17.py │ ├── graph.png │ └── table.csv └── worksheet3 ├── Entropy.py ├── README.md └── results.csv /.gitignore: -------------------------------------------------------------------------------- 1 | ######################### 2 | # .gitignore file for Xcode4 / OS X Source projects 3 | # 4 | # Version 2.1 5 | # For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects 6 | # 7 | # 2013 updates: 8 | # - fixed the broken "save personal Schemes" 9 | # - added line-by-line explanations for EVERYTHING (some were missing) 10 | # 11 | # NB: if you are storing "built" products, this WILL NOT WORK, 12 | # and you should use a different .gitignore (or none at all) 13 | # This file is for SOURCE projects, where there are many extra 14 | # files that we want to exclude 15 | # 16 | ######################### 17 | 18 | ##### 19 | # OS X temporary files that should never be committed 20 | # 21 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 22 | 23 | .DS_Store 24 | 25 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 26 | 27 | .Trashes 28 | 29 | # c.f. http://www.westwind.com/reference/os-x/invisibles.html 30 | 31 | *.swp 32 | 33 | # *.lock - this is used and abused by many editors for many different things. 34 | # For the main ones I use (e.g. Eclipse), it should be excluded 35 | # from source-control, but YMMV 36 | 37 | *.lock 38 | 39 | # 40 | # profile - REMOVED temporarily (on double-checking, this seems incorrect; I can't find it in OS X docs?) 41 | #profile 42 | 43 | 44 | #### 45 | # Xcode temporary files that should never be committed 46 | # 47 | # NB: NIB/XIB files still exist even on Storyboard projects, so we want this... 48 | 49 | *~.nib 50 | 51 | 52 | #### 53 | # Xcode build files - 54 | # 55 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" 56 | 57 | DerivedData/ 58 | 59 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" 60 | 61 | build/ 62 | 63 | 64 | ##### 65 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) 66 | # 67 | # This is complicated: 68 | # 69 | # SOMETIMES you need to put this file in version control. 70 | # Apple designed it poorly - if you use "custom executables", they are 71 | # saved in this file. 72 | # 99% of projects do NOT use those, so they do NOT want to version control this file. 73 | # ..but if you're in the 1%, comment out the line "*.pbxuser" 74 | 75 | # .pbxuser: http://lists.apple.com/archives/xcode-users/2004/Jan/msg00193.html 76 | 77 | *.pbxuser 78 | 79 | # .mode1v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html 80 | 81 | *.mode1v3 82 | 83 | # .mode2v3: http://lists.apple.com/archives/xcode-users/2007/Oct/msg00465.html 84 | 85 | *.mode2v3 86 | 87 | # .perspectivev3: http://stackoverflow.com/questions/5223297/xcode-projects-what-is-a-perspectivev3-file 88 | 89 | *.perspectivev3 90 | 91 | # NB: also, whitelist the default ones, some projects need to use these 92 | !default.pbxuser 93 | !default.mode1v3 94 | !default.mode2v3 95 | !default.perspectivev3 96 | 97 | 98 | #### 99 | # Xcode 4 - semi-personal settings 100 | # 101 | # 102 | # OPTION 1: --------------------------------- 103 | # throw away ALL personal settings (including custom schemes! 104 | # - unless they are "shared") 105 | # 106 | # NB: this is exclusive with OPTION 2 below 107 | xcuserdata 108 | 109 | # OPTION 2: --------------------------------- 110 | # get rid of ALL personal settings, but KEEP SOME OF THEM 111 | # - NB: you must manually uncomment the bits you want to keep 112 | # 113 | # NB: this is exclusive with OPTION 1 above 114 | # 115 | #xcuserdata/**/* 116 | 117 | # (requires option 2 above): Personal Schemes 118 | # 119 | #!xcuserdata/**/xcschemes/* 120 | 121 | #### 122 | # XCode 4 workspaces - more detailed 123 | # 124 | # Workspaces are important! They are a core feature of Xcode - don't exclude them :) 125 | # 126 | # Workspace layout is quite spammy. For reference: 127 | # 128 | # /(root)/ 129 | # /(project-name).xcodeproj/ 130 | # project.pbxproj 131 | # /project.xcworkspace/ 132 | # contents.xcworkspacedata 133 | # /xcuserdata/ 134 | # /(your name)/xcuserdatad/ 135 | # UserInterfaceState.xcuserstate 136 | # /xcsshareddata/ 137 | # /xcschemes/ 138 | # (shared scheme name).xcscheme 139 | # /xcuserdata/ 140 | # /(your name)/xcuserdatad/ 141 | # (private scheme).xcscheme 142 | # xcschememanagement.plist 143 | # 144 | # 145 | 146 | #### 147 | # Xcode 4 - Deprecated classes 148 | # 149 | # Allegedly, if you manually "deprecate" your classes, they get moved here. 150 | # 151 | # We're using source-control, so this is a "feature" that we do not want! 152 | 153 | *.moved-aside 154 | 155 | #### 156 | # UNKNOWN: recommended by others, but I can't discover what these files are 157 | # 158 | # ...none. Everything is now explained. 159 | 160 | .#* 161 | \#*# 162 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CryptoAnalysis 2 | ============== 3 | 4 | Practical Cryptoanalysis 5 | 6 | Includes: 7 | * Worksheet 1 8 | * Worksheet 2 9 | * Worksheet 3 10 | * Project 1 11 | * Project 2 12 | * Project 3 13 | -------------------------------------------------------------------------------- /project1/FreqAnalysis.py: -------------------------------------------------------------------------------- 1 | from sys import argv 2 | import os 3 | 4 | if __name__ == '__main__': 5 | """Tool for analysing an input text, and outputting a frequency 6 | analysis of mono/dia/trigrams in a given input text. Takes the input file and runs through it, saving the 7 | ammount of times a character and dia/trigrams is present. Then outputs the given values to 2 .txt files. 8 | If a british english text is given as a input file, a representation close to the frequency of letters of the english alphabet should be outputtet.""" 9 | os.system('clear') 10 | 11 | # Check if enough argument were given 12 | argcount = 0 13 | for arg in argv: 14 | argcount += 1 15 | if argcount < 2: 16 | print "Error: No input file spesified" 17 | 18 | script, inputfile = argv 19 | 20 | # Open files for reading and writing 21 | input = open(inputfile, 'r') 22 | output1 = open("output1.txt", 'w') 23 | output2 = open("output2.txt", 'w') 24 | 25 | # Declare variables to scope 26 | dict = {} 27 | count = [0, 0] 28 | 29 | # Itereate lines in input file 30 | for line in input: 31 | line = line.upper() # Clean line 32 | 33 | # For every leagal permutation 34 | for i in xrange(0, len(line)): 35 | # Mono-, dia- and trigrams 36 | for j in xrange(1, 4): 37 | ch = line[i:i+j] # Substring w/ *gram 38 | 39 | # Continue if not all letters 40 | if not ch.isalpha(): continue 41 | 42 | # Lazy create and inc counter 43 | if ch in dict: 44 | dict[ch] += 1 45 | else: 46 | dict[ch] = 1 47 | 48 | # Increment total number of *grams 49 | count[0 if len(ch) < 2 else 1] += 1 50 | 51 | # Print all monograms to file 52 | for key, value in sorted(dict.iteritems()): 53 | if len(key) > 1: continue 54 | output1.write("{0}: {2:.3%}\n".format( 55 | key, value, float(value)/float(count[0]))) 56 | 57 | # Print all di- and trigrams to file 58 | for key, value in sorted(dict.iteritems(), 59 | key=lambda (k, v): (v, k), reverse=True): 60 | if len(key) <= 1: continue 61 | output2.write("{0}: {2:.3%}\n".format( 62 | key, value, float(value)/float(count[0]))) 63 | 64 | print "Successfully analyzed %s" % inputfile 65 | 66 | # Close files before finish 67 | input.close() 68 | output1.close() 69 | output2.close() 70 | 71 | -------------------------------------------------------------------------------- /project1/ManualSubCipherTool.py: -------------------------------------------------------------------------------- 1 | # 2 | # Manual Substitution Cipher Tool 3 | # Project 1 4 | # 5 | # 01435 Practiacal Cryptanalysis 6 | # Technical University of Denmark 7 | 8 | # Markus Faerevaag (s123692@student.dtu.dk) 9 | # Christian Mathias Rohde Kiaer (s123812@student.dtu.dk) 10 | # Jonathan Becktor (s123094@student.dtu.dk) 11 | # 12 | 13 | from sys import argv 14 | import os 15 | 16 | 17 | def decryption(cipher): 18 | """Menu for assisting in decryption of ciphertext. 19 | Gives you possibilities for assigning plaintext letters to ciphertext letters, 20 | unassign letters in plaintext and display most frequent mono/dia/tri""" 21 | found = False 22 | 23 | cip = list(cipher) 24 | 25 | plaintext = ['-'] * len(cip) 26 | 27 | remove_space(plaintext, cip) 28 | 29 | os.system('clear') 30 | 31 | while not found: 32 | print "Cipher: " + ''.join(cip) 33 | print "Plaintext: " +''.join(plaintext) 34 | 35 | print """What would you like to do? 36 | 1) Assign plaintext to cipher 37 | 2) Unassign plaintext 38 | 3) Letter frequencies in cipher/english 39 | 4) Most frequent diagrams in cipher/text 40 | 5) Finish decryption""" 41 | 42 | keyPressed = int(right_input(5)) 43 | 44 | if keyPressed == 1: 45 | assignPlainToCipher(cip, plaintext) 46 | elif keyPressed == 2: 47 | unasignPlain(plaintext) 48 | elif keyPressed == 3: 49 | display_letter(cip) 50 | elif keyPressed == 4: 51 | display_diagrams(cip) 52 | elif keyPressed == 5: 53 | print "This is the plaintext you found: " + ''.join(plaintext) 54 | found = True 55 | 56 | os.system('clear') 57 | 58 | def assignPlainToCipher(cip, plaintext): 59 | """Assign plaintext character to corresponding ciphertext character. 60 | First input to console is the ciphertext letter you want to assign a new letter to. 61 | Second input is the plaintext letter you want to assign to a ciphertext letter. 62 | Then loops over entire cipher change every character.""" 63 | keyToChange = str(raw_input("What cipher do you want to assign a plain character? ")).upper() 64 | keyChanged = str(raw_input("What letter do you want to input? ")).lower() 65 | for x in range(0, len(cip)): 66 | if cip[x] == keyToChange: 67 | plaintext[x] = keyChanged 68 | 69 | def unasignPlain(plaintext): 70 | """Unassign previous assigned plaintext to ciphertext 71 | Input the plaintext character you want to unasign. 72 | Loops through entire plaintext to remove every character.""" 73 | keyToChange = str(raw_input("What plaintext character do you want to unassign? ")).lower() 74 | for x in range(0, len(plaintext)): 75 | if plaintext[x] == keyToChange: 76 | plaintext[x] = '-' 77 | 78 | def right_input(i): 79 | """Get input from user and validate. 80 | Function to make sure the right input is given. 81 | Right inputs is between 0 and the given i. Gives user another try if wrong key is pressed""" 82 | while True: 83 | x = raw_input("Please enter a value: ") 84 | try: 85 | keyPressed = int(x) 86 | if(keyPressed <= i): 87 | break 88 | else: 89 | print "Wrong input, try again" 90 | except: 91 | print "Wrong input, try again" 92 | return x 93 | 94 | def remove_space(plaintext, cip): 95 | """Remove whitespaces from ciphertext. Loops over the ciphertext 96 | and sets corresponding plaintext position as whitespace.""" 97 | for x in xrange(0,len(cip)): 98 | if cip[x] == ' ': 99 | plaintext[x] = ' ' 100 | 101 | 102 | def display_diagrams(cip): 103 | """Display dia and trigram frequencies in given ciphertext and compare to the given language's. 104 | Opens the output2.txt from created from the FreqAnalysis tool. Runs through the cipher text 105 | storing dia/trigrams in a dictonary. The ammount of appearances and the tri/diagram is then saved and printed. 106 | Then prints the most frequent dia/trigams from the english language""" 107 | input_grams = open("output2.txt", "r") 108 | 109 | print "Ciphers frequency of dia/trigrams:" 110 | 111 | dict = {} 112 | 113 | count = 0 114 | 115 | for i in range(0, len(cip)): 116 | for j in range(2,4): 117 | ch = str(''.join(cip[i:i+j])) 118 | if not ch.isalpha(): continue 119 | 120 | if ch in dict: 121 | dict[ch] += 1 122 | else: 123 | dict[ch] = 1 124 | count += 1 125 | 126 | for key, value in sorted(dict.iteritems(), key=lambda (k,v): (v,k), reverse=True): 127 | if len(key) <= 1: continue 128 | print "{0}: {2:.3%}".format(key, value, 129 | float(value)/float(count)) 130 | 131 | print "English languge frequencies of tri/diagrams:" 132 | print ''.join(input_grams.readlines()[:20]) 133 | 134 | raw_input("Press any key to continue: ") 135 | input_grams.close() 136 | 137 | def display_letter(cip): 138 | """Display letter frequencies in given ciphertext and compare to the given language's 139 | Opens the output1.txt generated from the FreqAnalysis tool. Runs through the cipher text and stores each letter and the ammount of times 140 | it's present in the text. Prints the character and corresponding ammount. Then outputs the frequencies of the english language 141 | from output2.txt""" 142 | input_frequency = open("output1.txt", "r") 143 | 144 | dict = {} 145 | 146 | print "Ciphers frequency of letters:" 147 | for i in range(0, len(cip)): 148 | ch = str(''.join(cip[i:i+1])) 149 | 150 | if not ch.isalpha() or len(ch) > 1: continue 151 | 152 | if ch in dict: 153 | dict[ch] += 1 154 | else: 155 | dict[ch] = 1 156 | 157 | 158 | for key, value in sorted(dict.iteritems()): 159 | print "{0}: {2:.3%}".format(key, value, float(value)/float(len(cipher))) 160 | 161 | print "English languge frequencies of letters:" 162 | print ''.join(input_frequency.readlines()) 163 | 164 | raw_input("Press any key to continue") 165 | input_frequency.close() 166 | 167 | if __name__ == '__main__': 168 | """Tool for manual assitance in decryption of a substitution ciphertext. 169 | Possible to get analysis of both ciphertext and from the english language""" 170 | os.system('clear') 171 | 172 | script, cipher = argv 173 | 174 | print "Hello! \nWelcome to our decryption assistance tool! How may I help you?" 175 | print "1) Decrypt" 176 | print "0) Exit" 177 | 178 | keyPressed = int(right_input(1)) 179 | 180 | if keyPressed == 0: 181 | exit 182 | elif keyPressed == 1: 183 | decryption(cipher.upper()) 184 | else: 185 | print "Exiting" 186 | -------------------------------------------------------------------------------- /project1/README.md: -------------------------------------------------------------------------------- 1 | Programming Project 1 2 | ===================== 3 | 4 | **A tool for analyzing and decrypting a simple substitution cipher.** 5 | 6 | ## Overview 7 | 8 | Consists of two Python scripts: 9 | 10 | * **FreqAnalysis.py**: Count the frequencies of letters, diagrams and 11 | trigrams in a given file. 12 | 13 | * **ManualSubCipherTool.py**: Helps to manually decrypt a given 14 | cipher by showing frequency analysis and comparing to the output 15 | for the previous mentioned script. 16 | 17 | *NOTE:* Written in markdown. Open in browser to have good support. 18 | ## Usage 19 | 20 | ### FreqAnalysis 21 | 22 | Store the text you want analyzed in a file in the 23 | same directory as the `FreqAnalysis.py`, the run the script with: 24 | 25 | python FreqAnalysis.py input.txt 26 | 27 | Where `input.txt` is your input file. 28 | 29 | The output will then be stored in two files: 30 | 31 | 1. `output1.txt`: Letter frequencies 32 | 2. `output2.txt`: Dia- and trigram frequencies 33 | 34 | Docstrings is inserted for offical Python documentation. 35 | 36 | *NOTE:* Out of the box contains `input.txt` a sample English text by 37 | [Project Gutenberg](www.gutenberg.org). Given another input text, the 38 | output frequencies will be different. 39 | 40 | ### ManualSubCipherTool 41 | 42 | Uses a ciphertext as input. Run with: 43 | 44 | python ManualSubCipherTool.py "CyPhErTeXt" 45 | 46 | Where "CyPhErTeXt" is the substituted cipher text. 47 | 48 | You will now be prompted with an interactive command line interface. 49 | It will be possible to navigate through with keyboard commands as input. 50 | 51 | The tool uses the output from the FreqAnalysis tool for showing 52 | frequencies of mono/dia/trigrams. 53 | 54 | Docstrings is inserted for offical Python documentation. 55 | 56 | *NOTE:* As noted under FreqAnalysis, it comes with a sample English 57 | word analysis. If your ciphertext is of a different language, you 58 | will have to run the FreqAnalysis tool of text in the wanted language. 59 | 60 | 61 | ## Logic behind. 62 | 63 | The FreqAnalysis tool is based on an input .txt file. It the uses the following: 64 | 65 | 1. Input text is loaded 66 | 2. The tool runs through the input text, saving all characters/dia/trigrams and the ammount of times they have been spotted. 67 | 3. Outputs two .txt files containing, one containing the frequencies of letters and one containing frequencies of dia/trigrams in the text. 68 | 69 | The ManualSubCipherTool is based around assistance in decryption of a cipher text. It follows this order: 70 | 71 | 1. The tool is started with a input cipher. 72 | 2. 5 Possibilities are given: 73 | 1. Assign a plaintext letter to a ciphertext letter. 74 | 2. Unassign a plaintext letter. 75 | 3. Display frequencies of letters in cipher/english language. 76 | 4. Display frequencies of dia/trigrams in cipher/english language. 77 | 5. Finish your decryption 78 | 3. This is repeated untill you find the desired plaintext. 79 | 80 | The following snippet of code is the corner stone of the two tools, wich gives us the frequencies of mono/dia/trigrams in our cipher and the english language: 81 | 82 | #Itereate lines in input file 83 | for line in input: 84 | line = line.upper() # Clean line 85 | 86 | # For every leagal permutation 87 | for i in xrange(0, len(line)): 88 | # Mono-, dia- and trigrams 89 | for j in xrange(1, 4): 90 | ch = line[i:i+j] # Substring w/ *gram 91 | 92 | # Continue if not all letters 93 | if not ch.isalpha(): continue 94 | 95 | # Lazy create and inc counter 96 | if ch in dict: 97 | dict[ch] += 1 98 | else: 99 | dict[ch] = 1 100 | 101 | # Increment total number of *grams 102 | count[0 if len(ch) < 2 else 1] += 1 103 | 104 | It lets us assign mono/dia/trigrams in a HashTable and assign the value as the ammount of times they have been checked. 105 | 106 | ## Further Help 107 | 108 | For further help or explanation please contact one of us by mail and 109 | we'll be happy to help: 110 | 111 | * Markus Faerevaag [s123692@student.dtu.dk](mailto:s123692@student.dtu.dk) 112 | * Christian Mathias Rohde Kiaer [s123812@student.dtu.dk](mailto:s123812@student.dtu.dk) 113 | * Jonathan Becktor [s123094@student.dtu.dk](mailto:s123094@student.dtu.dk) 114 | -------------------------------------------------------------------------------- /project1/input.txt: -------------------------------------------------------------------------------- 1 | 76. I must ask you, in order to make these lectures of any permanent use, to be careful in keeping note of the main conclusion at which we arrive in the course of each, and of the sequence of such results. In the first, I tried to show you that Art was only wise when unselfish in her labour; in the second, that Science was only wise when unselfish in her statement; in the third, that wise Art was the shadow, or visible reflection, of wise Science; and in the fourth, that all these conditions of good must be pursued temperately and peacefully. I have now farther to tell you that they must be pursued independently. 2 | 3 | 77. You have not often heard me use that word “independence.” And, in the sense in which of late it has been accepted, you have never heard me use it but with contempt. For the true strength of every human soul is to be dependent on as many nobler as it can discern, and to be depended upon, by as many inferior as it can reach. 4 | 5 | But to-day I use the word in a widely different sense. I think you must have felt, in what amplification I was able to give you of the idea of wisdom as an unselfish influence in Art and Science, how the highest skill and knowledge were founded in human tenderness, and that the kindly Art-wisdom which rejoices in the habitable parts of the earth, is only another form of the lofty Scientific charity, which rejoices ‘in the truth.’ And as the first order of Wisdom is to know thyself—though the least creature that can be known—so the first order of Charity is to be sufficient for thyself, though the least creature that can be sufficed; and thus contented and appeased, to be girded and strong for the ministry to others. If sufficient to thy day is the evil thereof, how much more should be the good! 6 | 7 | 78. I have asked you to recollect one aphorism respecting Science, one respecting Art; let me—and I will ask no more at this time of asking—press you to learn, farther, by heart, those lines of the Song of the Sirens: six lines of Homer, I trust, will not be a weariness to you— 8 | 9 | “No one ever rowed past this way in his black ship, before he had listened to the honey-sweet singing of our lips. But he stays pleased, though he may know much. For we know all things which the Greeks and Trojans did in the wide Trojan plain, by the will of the gods, and we know what things take place in the much nourishing earth.” And this, remember, is absolutely true. No man ever went past in the black ship,—obeying the grave and sad law of life by which it is appointed for mortals to be victors on the ocean,—but he was tempted, as he drew near that deadly island, wise as he might be, (καὶ πλείονα εἰδώς,) by the voices of those who told him that they knew everything which had been done by the will of God, and everything which took place in earth for the service of man. 10 | 11 | 79. Now observe those two great temptations. You are to know everything that has been done by the will of God: and to know everything that is vital in the earth. And try to realize to yourselves, for a little while, the way in which these two siren promises have hitherto troubled the paths of men. Think of the books that have been written in false explanation of Divine Providence: think of the efforts that have been made to show that the particular conduct which we approve in others, or wish ourselves to follow, is according to the will of God. Think what ghastly convulsions in thought, and vileness in action, have been fallen into by the sects which thought they had adopted, for their patronage, the perfect purposes of Heaven. Think of the vain research, the wasted centuries of those who have tried to penetrate the secrets of life, or of its support. The elixir vitæ, the philosopher’s stone, the germ-cells in meteoric iron, ‘ἐπὶ χθονὶ πουλυβοτείρῃ.’ But at this day, when we have loosed the last band from the masts of the black ship, and when, instead of plying every oar to escape, as the crew of Homer’s Ulysses, we row like the crew of Dante’s Ulysses, and of our oars make wings for our foolish flight, 12 | 13 | E, volta nostra poppe nel mattino 14 | De’ remi facemmo ale al folle volo— 15 | the song of the sirens becomes fatal as never yet it has been in time. We think ourselves privileged, first among men, to know the secrets of Heaven, and fulfil the economy of earth; and the result is, that of all the races that yet have been put to shame by their false wisdom or false art,—which have given their labour for that which is not bread, and their strength for that which satisfieth not,—we have most madly abandoned the charity which is for itself sufficing, and for others serviceable, and have become of all creatures the most insufficient to ourselves, and the most malignant to our neighbours. Granted a given degree of knowledge—granted the ‘καὶ πλείονα εἰδώς’ in science, in art, and in literature,—and the present relations of feeling between France and Germany, between England and America, are the most horrible at once in their stupidity and malignity, that have ever taken place on the globe we inhabit, even though all its great histories, are of sin, and all its great songs, of death. 16 | 17 | 80. Gentlemen, I pray you very solemnly to put that idea of knowing all things in Heaven and Earth out of your hearts and heads. It is very little that we can ever know, either of the ways of Providence, or the laws of existence. But that little is enough, and exactly enough: to strive for more than that little is evil for us; and be assured that beyond the need of our narrow being,—beyond the range of the kingdom over which it is ordained for each of us to rule in serene αὐτάρκεια and self-possession, he that increaseth toil, increaseth folly; and he that increaseth knowledge, increaseth sorrow. 18 | 19 | 81. My endeavour, therefore, to-day will be to point out to you how in the best wisdom, that there may be happy advance, there must first be happy contentment; that, in one sense, we must always be entering its kingdom as a little child, and pleased yet for a time not to put away childish things. And while I hitherto have endeavoured only to show how modesty and gentleness of disposition purified Art and Science, by permitting us to recognize the superiority of the work of others to our own—to-day, on the contrary, I wish to indicate for you the uses of infantine self-satisfaction; and to show you that it is by no error or excess in our nature, by no corruption or distortion of our being, that we are disposed to take delight in the little things that we can do ourselves, more than in the great things done by other people. So only that we recognize the littleness and the greatness, it is as much a part of true Temperance to be pleased with the little we know, and the little we can do, as with the little that we have. On the one side Indolence, on the other Covetousness, are as much to be blamed, with respect to our Arts, as our possessions; and every man is intended to find an exquisite personal happiness in his own small skill, just as he is intended to find happiness in his own small house or garden, while he respects, without coveting, the grandeur of larger domains. 20 | 21 | 82. Nay, more than this: by the wisdom of Nature, it has been appointed that more pleasure may be taken in small things than in great, and more in rude Art than in the finest. Were it otherwise, we might be disposed to complain of the narrow limits which have been set to the perfection of human skill. 22 | 23 | I pointed out to you, in a former lecture, that the excellence of sculpture had been confined in past time to the Athenian and Etrurian vales. The absolute excellence of painting has been reached only by the inhabitants of a single city in the whole world; and the faultless manner of religious architecture holds only for a period of fifty years out of six thousand. We are at present tormenting ourselves with the vain effort to teach men everywhere to rival Venice and Athens,—with the practical result of having lost the enjoyment of Art altogether;—instead of being content to amuse ourselves still with the painting and carving which were possible once, and would be pleasant always, in Paris, and London, at Strasbourg, and at York. 24 | 25 | I do not doubt that you are greatly startled at my saying that greater pleasure is to be received from inferior Art than from the finest. But what do you suppose makes all men look back to the time of childhood with so much regret, (if their childhood has been, in any moderate degree, healthy or peaceful)? That rich charm, which the least possession had for us, was in consequence of the poorness of our treasures. That miraculous aspect of the nature around us, was because we had seen little, and knew less. Every increased possession loads us with a new weariness; every piece of new knowledge diminishes the faculty of admiration; and Death is at last appointed to take us from a scene in which, if we were to stay longer, no gift could satisfy us, and no miracle surprise. 26 | 27 | 83. Little as I myself know, or can do, as compared with any man of essential power, my life has chanced to be one of gradual progress in the things which I began in childish choice; so that I can measure with almost mathematical exactitude the degree of feeling with which less and greater degrees of wealth or skill affect my mind. 28 | 29 | I well remember the delight with which, when I was beginning mineralogy, I received from a friend, who had made a voyage to Peru, a little bit of limestone about the size of a hazel nut, with a small film of native silver adhering to its surface. I was never weary of contemplating my treasure, and could not have felt myself richer had I been master of the mines of Copiapo. 30 | 31 | I am now about to use as models for your rock drawings stones which my year’s income, when I was a boy, would not have bought. But I have long ceased to take any pleasure in their possession; and am only thinking, now, to whom else they can be of use, since they can be of no more to me. 32 | 33 | 84. But the loss of pleasure to me caused by advance in knowledge of drawings has been far greater than that induced by my riches in minerals. 34 | 35 | I have placed, in your reference series, one or two drawings of architecture, made when I was a youth of twenty, with perfect ease to myself, and some pleasure to other people. A day spent in sketching then brought with it no weariness, and infinite complacency. I know better now what drawing should be; the effort to do my work rightly fatigues me in an hour, and I never care to look at it again from that day forward. 36 | 37 | 85. It is true that men of great and real power do the best things with comparative ease; but you will never hear them express the complacency which simple persons feel in partial success. There is nothing to be regretted in this; it is appointed for all men to enjoy, but for few to achieve. 38 | 39 | And do not think that I am wasting your time in dwelling on these simple moralities. From the facts I have been stating we must derive this great principle for all effort. That we must endeavour to do, not what is absolutely best, but what is easily within our power and adapted to our temper and condition. 40 | 41 | 86. In your educational series is a lithographic drawing, by Prout, of an old house in Strasbourg. The carvings of its woodwork are in a style altogether provincial, yet of which the origin is very distant. The delicate Renaissance architecture of Italy was affected, even in its finest periods, by a tendency to throw out convex masses at the bases of its pillars; the wood-carvers of the 16th century adopted this bulged form as their first element of ornamentation, and these windows of Strasbourg are only imitations by the German peasantry of what, in its finest type, you must seek as far away as the Duomo of Bergamo. 42 | 43 | But the burgher, or peasant, of Alsace enjoyed his rude imitation, adapted, as it was, boldly and frankly to the size of his house and the grain of the larch logs of which he built it, infinitely more than the refined Italian enjoyed the floral luxuriance of his marble; and all the treasures of a great exhibition could not have given him the tenth part of the exultation with which he saw the gable of his roof completed over its jutting fret-work; and wrote among the rude intricacies of its sculpture, in flourished black letter, that “He and his wife had built their house with God’s help, and prayed Him to let them live long in it,—they, and their children.” 44 | 45 | 87. But it is not only the rustic method of architecture which I wish you to note in this plate; it is the rustic method of drawing also. The manner in which these blunt timber carvings are drawn by Prout is just as provincial as the carvings themselves. Born in a faraway district of England, and learning to draw, unhelped, with fishing-boats for his models; making his way instinctively until he had command of his pencil enough to secure a small income by lithographic drawing; and finding picturesque character in buildings from which all the finest lines of their carving had been effaced by time; possessing also an instinct in the expression of such subjects so peculiar as to win for him a satisfying popularity, and, far better, to enable him to derive perpetual pleasure in the seclusion of country hamlets, and the quiet streets of deserted cities,—Prout had never any motive to acquaint himself with the refinements, or contend with the difficulties, of a more accomplished art. So far from this, his manner of work was, by its very imperfection, in the most perfect sympathy with the subjects he enjoyed. The broad chalk touches in which he has represented to us this house at Strasbourg are entirely sufficient to give true idea of its effect. To have drawn its ornaments with subtlety of Leonardesque delineation would only have exposed their faults, and mocked their rusticity. The drawing would have become painful to you from the sense of the time which it had taken to represent what was not worth the labour, and to direct your attention to what could only, if closely examined, be matter of offence. But here you have a simple and provincial draughtsman happily and adequately expressing a simple and provincial architecture; nor could either builder or painter have become wiser, but to their loss. 46 | 47 | 88. Is it then, you will ask me, seriously to be recommended, and, however recommendable, is it possible, that men should remain contented with attainments which they know to be imperfect? and that now, as in former times, large districts of country, and generations of men, should be enriched or amused by the products of a clumsy ignorance? I do not know how far it is possible, but I know that wherever you desire to have true art, it is necessary. Ignorance, which is contented and clumsy, will produce what is imperfect, but not offensive. But ignorance discontented and dexterous, learning what it cannot understand, and imitating what it cannot enjoy, produces the most loathsome forms of manufacture that can disgrace or mislead humanity. Some years since, as I was looking through the modern gallery at the quite provincial German School of Düsseldorf, I was fain to leave all their epic and religious designs, that I might stay long before a little painting of a shepherd boy carving his dog out of a bit of deal. The dog was sitting by, with the satisfied and dignified air of a personage about for the first time in his life to be worthily represented in sculpture; and his master was evidently succeeding to his mind in expressing the features of his friend. The little scene was one which, as you know, must take place continually among the cottage artists who supply the toys of Nuremberg and Berne. Happy, these! so long as, undisturbed by ambition, they spend their leisure time in work pretending only to amuse, yet capable, in its own way, of showing accomplished dexterity, and vivid perception of nature. We, in the hope of doing great things, have surrounded our workmen with Italian models, and tempted them with prizes into competitive mimicry of all that is best, or that we imagine to be best, in the work of every people under the sun. And the result of our instruction is only that we are able to produce—I am now quoting the statement I made last May, “the most perfectly and roundly ill-done things” that ever came from human hands. I should thankfully put upon my chimney-piece the wooden dog cut by the shepherd boy; but I should be willing to forfeit a large sum rather than keep in my room the number 1 of the Kensington Museum—thus described in its catalogue—“Statue in black and white marble, of a Newfoundland dog standing on a serpent, which rests on a marble cushion;—the pedestal ornamented with Pietra Dura fruits in relief.” 48 | 49 | 89. You will, however, I fear, imagine me indulging in my usual paradox, when I assure you that all the efforts we have been making to surround ourselves with heterogeneous means of instruction, will have the exactly reverse effect from that which we intend;—and that, whereas formerly we were able only to do a little well, we are qualifying ourselves now to do everything ill. Nor is the result confined to our workmen only. The introduction of French dexterity and of German erudition has been harmful chiefly to our most accomplished artists—and in the last Exhibition of our Royal Academy there was, I think, no exception to the manifest fact that every painter of reputation painted worse than he did ten years ago. 50 | 51 | 90. Admitting, however, (not that I suppose you will at once admit, but for the sake of argument, supposing,) that this is true, what, we have further to ask, can be done to discourage ourselves from calamitous emulation, and withdraw our workmen from the sight of what is too good to be of use to them? 52 | 53 | But this question is not one which can be determined by the needs, or limited to the circumstances of Art. To live generally more modest and contented lives; to win the greatest possible pleasure from the smallest things; to do what is likely to be serviceable to our immediate neighbours, whether it seem to them admirable or not; to make no pretence of admiring what has really no hold upon our hearts; and to be resolute in refusing all additions to our learning, until we have perfectly arranged and secured what learning we have got;—these are conditions, and laws, of unquestionable σοφία and σωφροσύνη, which will indeed lead us up to fine art if we are resolved to have it fine; but will also do what is much better, make rude art precious. 54 | 55 | 91. It is not, however, by any means necessary that provincial art should be rude, though it may be singular. Often it is no less delicate than quaint, and no less refined in grace than original in character. This is likely always to take place when a people of naturally fine artistic temper work with the respect which, as I endeavoured to show you in a former lecture, ought always to be paid to local material and circumstance. 56 | 57 | I have placed in your educational series the photograph of the door of a wooden house in Abbeville, and of the winding stair above; both so exquisitely sculptured that the real vine-leaves which had wreathed themselves about their pillars, cannot, in the photograph, be at once discerned from the carved foliage. The latter, quite as graceful, can only be known for art by its quaint setting. 58 | 59 | Yet this school of sculpture is altogether provincial. It could only have risen in a richly-wooded chalk country, where the sapling trees beside the brooks gave example to the workman of the most intricate tracery, and the white cliffs above the meadows furnished docile material to his hand. 60 | 61 | 92. I have now, to my sorrow, learned to despise the elaborate intricacy, and the playful realizations, of the Norman designers; and can only be satisfied by the reserved and proud imagination of the master schools. But the utmost pleasure I now take in these is almost as nothing, compared to the joy I used to have, when I knew no better, in the fretted pinnacles of Rouen, and white lace, rather than stonework, of the chapels of Reu and Amboise. 62 | 63 | Yet observe that the first condition of this really precious provincial work is its being the best that can be done under the given circumstances; and the second is, that though provincial, it is not in the least frivolous or ephemeral, but as definitely civic, or public, in design, and as permanent in the manner of it, as the work of the most learned academies: while its execution brought out the energies of each little state, not necessarily in rivalship, but severally in the perfecting of styles which Nature had rendered it impossible for their neighbours to imitate. 64 | 65 | 93. This civic unity, and the feeling of the workman that he is performing his part in a great scene which is to endure for centuries, while yet, within the walls of his city, it is to be a part of his own peculiar life, and to be separate from all the world besides, developes, together, whatever duty he acknowledges as a patriot, and whatever complacency he feels as an artist. 66 | 67 | We now build, in our villages, by the rules of the Academy of London; and if there be a little original vivacity or genius in any provincial workman, he is almost sure to spend it in making a ridiculous toy. Nothing is to me much more pathetic than the way that our neglected workmen thus throw their lives away. As I was walking the other day through the Crystal Palace, I came upon a toy which had taken the leisure of five years to make; you dropped a penny into the chink of it, and immediately a little brass steam-engine in the middle started into nervously hurried action; some bell-ringers pulled strings at the bottom of a church steeple which had no top; two regiments of cavalry marched out from the sides, and manœuvred in the middle; and two well-dressed persons in a kind of opera-box expressed their satisfaction by approving gestures. 68 | 69 | In old Ghent, or Bruges, or York, such a man as the one who made this toy, with companions similarly minded, would have been taught how to employ himself, not to their less amusement, but to better purpose; and in their five years of leisure hours they would have carved a flamboyant crown for the belfry-tower, and would have put chimes into it that would have told the time miles away, with a pleasant tune for the hour, and a variation for the quarters, and cost the passers-by in all the city and plain not so much as the dropping of a penny into a chink. 70 | 71 | 94. Do not doubt that I feel, as strongly as any of you can feel, the utter impossibility at present of restoring provincial simplicity to our country towns. 72 | 73 | My despondency respecting this, and nearly all other matters which I know to be necessary, is at least as great,—it is certainly more painful to me,—in the decline of life,—than that which any of my younger hearers can feel. But what I have to tell you of the unchanging principles of nature, and of art, must not be affected by either hope or fear. And if I succeed in convincing you what these principles are, there are many practical consequences which you may deduce from them, if ever you find yourselves, as young Englishmen are often likely to find themselves, in authority over foreign tribes of peculiar or limited capacities. 74 | 75 | Be assured that you can no more drag or compress men into perfection than you can drag or compress plants. If ever you find yourselves set in a position of authority, and are entrusted to determine modes of education, ascertain first what the people you would teach have been in the habit of doing, and encourage them to do that better. Set no other excellence before their eyes; disturb none of their reverence for the past; do not think yourselves bound to dispel their ignorance, or to contradict their superstitions; teach them only gentleness and truth; redeem them by example from habits which you know to be unhealthy or degrading; but cherish, above all things, local associations, and hereditary skill. 76 | 77 | It is the curse of so-called civilization to pretend to originality by the wilful invention of new methods of error, while it quenches wherever it has power, the noble originality of nations, rising out of the purity of their race, and the love of their native land. 78 | 79 | 95. I could say much more, but I think I have said enough to justify for the present what you might otherwise have thought singular in the methods I shall adopt for your exercise in the drawing schools. I shall indeed endeavour to write down for you the laws of the art which is centrally best; and to exhibit to you a certain number of its unquestionable standards: but your own actual practice shall be limited to objects which will explain to you the meaning, and awaken you to the beauty, of the art of your own country. 80 | 81 | The first series of my lectures on sculpture must have proved to you that I do not despise either the workmanship or the mythology of Greece; but I must assert with more distinctness than even in my earliest works, the absolute unfitness of all its results to be made the guides of English students or artists. 82 | 83 | Every nation can represent, with prudence, or success, only the realities in which it delights. What you have with you, and before you, daily, dearest to your sight and heart, that, by the magic of your hand, or of your lips, you can gloriously express to others; and what you ought to have in your sight and heart,—what, if you have not, nothing else can be truly seen or loved,—is the human life of your own people, understood in its history, and admired in its presence. 84 | 85 | And unless that be first made beautiful, idealism must be false and imagination monstrous. 86 | 87 | It is your influence on the existing world which, in your studies here, you ought finally to consider; and although it is not, in that influence, my function to direct you, I hope you will not be discontented to know that I shall ask no effort from your art-genius, beyond the rational suggestion of what we may one day hope to see actually realized in England, in the sweetness of her landscape, and the dignity of her people. -------------------------------------------------------------------------------- /project1/output1.txt: -------------------------------------------------------------------------------- 1 | A: 7.392% 2 | B: 1.536% 3 | C: 2.906% 4 | D: 3.582% 5 | E: 12.466% 6 | F: 2.615% 7 | G: 1.725% 8 | H: 5.837% 9 | I: 7.557% 10 | J: 0.087% 11 | K: 0.642% 12 | L: 4.000% 13 | M: 2.231% 14 | N: 7.057% 15 | O: 7.761% 16 | P: 1.832% 17 | Q: 0.102% 18 | R: 5.842% 19 | S: 6.172% 20 | T: 9.788% 21 | U: 3.125% 22 | V: 1.162% 23 | W: 2.236% 24 | X: 0.194% 25 | Y: 2.104% 26 | Z: 0.049% 27 | -------------------------------------------------------------------------------- /project1/output2.txt: -------------------------------------------------------------------------------- 1 | TH: 3.106% 2 | HE: 2.284% 3 | IN: 2.182% 4 | THE: 1.866% 5 | AN: 1.502% 6 | RE: 1.346% 7 | ER: 1.273% 8 | EN: 1.220% 9 | HA: 1.196% 10 | OU: 1.176% 11 | ND: 1.176% 12 | AT: 1.166% 13 | OF: 1.128% 14 | IT: 1.113% 15 | TO: 1.064% 16 | ES: 1.055% 17 | ON: 0.953% 18 | IS: 0.948% 19 | OR: 0.928% 20 | HI: 0.894% 21 | SE: 0.880% 22 | VE: 0.836% 23 | AND: 0.831% 24 | AR: 0.826% 25 | ST: 0.807% 26 | TE: 0.778% 27 | LE: 0.778% 28 | UR: 0.768% 29 | ED: 0.763% 30 | NG: 0.758% 31 | EA: 0.739% 32 | AS: 0.734% 33 | TI: 0.705% 34 | BE: 0.656% 35 | AL: 0.656% 36 | ING: 0.632% 37 | NT: 0.608% 38 | CH: 0.598% 39 | NE: 0.588% 40 | DE: 0.588% 41 | CE: 0.583% 42 | WH: 0.559% 43 | NO: 0.559% 44 | IC: 0.530% 45 | HAT: 0.530% 46 | THA: 0.476% 47 | LI: 0.467% 48 | WI: 0.462% 49 | LL: 0.447% 50 | EL: 0.447% 51 | ME: 0.442% 52 | RI: 0.437% 53 | MA: 0.437% 54 | RA: 0.428% 55 | RO: 0.423% 56 | YO: 0.418% 57 | LY: 0.413% 58 | HO: 0.408% 59 | NC: 0.403% 60 | IO: 0.403% 61 | OW: 0.399% 62 | YOU: 0.394% 63 | PE: 0.394% 64 | US: 0.389% 65 | OUR: 0.389% 66 | CO: 0.389% 67 | EC: 0.365% 68 | UT: 0.360% 69 | SS: 0.360% 70 | AC: 0.360% 71 | UL: 0.350% 72 | CT: 0.350% 73 | RT: 0.345% 74 | ION: 0.345% 75 | IL: 0.340% 76 | CA: 0.335% 77 | FO: 0.330% 78 | AV: 0.330% 79 | WE: 0.321% 80 | OM: 0.321% 81 | ET: 0.321% 82 | LA: 0.311% 83 | WHI: 0.306% 84 | TS: 0.306% 85 | SI: 0.306% 86 | OT: 0.306% 87 | RS: 0.301% 88 | PR: 0.296% 89 | IR: 0.296% 90 | ENT: 0.296% 91 | AVE: 0.296% 92 | TR: 0.292% 93 | TIO: 0.292% 94 | FOR: 0.292% 95 | AD: 0.292% 96 | PL: 0.287% 97 | ICH: 0.287% 98 | SU: 0.282% 99 | FI: 0.282% 100 | HER: 0.277% 101 | THI: 0.272% 102 | TA: 0.272% 103 | HIC: 0.272% 104 | EE: 0.272% 105 | DO: 0.272% 106 | HAV: 0.267% 107 | URE: 0.262% 108 | IM: 0.248% 109 | DI: 0.248% 110 | ART: 0.248% 111 | MO: 0.238% 112 | OS: 0.233% 113 | ITH: 0.233% 114 | ESS: 0.233% 115 | CI: 0.233% 116 | WO: 0.228% 117 | VER: 0.228% 118 | SH: 0.228% 119 | RES: 0.228% 120 | EV: 0.228% 121 | NS: 0.224% 122 | NCE: 0.224% 123 | FE: 0.224% 124 | EI: 0.224% 125 | IE: 0.219% 126 | EM: 0.219% 127 | VI: 0.214% 128 | TU: 0.214% 129 | MI: 0.214% 130 | GE: 0.214% 131 | ALL: 0.214% 132 | WA: 0.209% 133 | TT: 0.209% 134 | LD: 0.209% 135 | GH: 0.209% 136 | EVE: 0.209% 137 | PO: 0.204% 138 | HIS: 0.204% 139 | REA: 0.199% 140 | ECT: 0.199% 141 | WIT: 0.194% 142 | RY: 0.194% 143 | NOT: 0.194% 144 | HIN: 0.194% 145 | GR: 0.194% 146 | AY: 0.194% 147 | ATI: 0.194% 148 | MP: 0.190% 149 | EAR: 0.190% 150 | BY: 0.190% 151 | BU: 0.190% 152 | NOW: 0.185% 153 | NA: 0.185% 154 | LO: 0.185% 155 | TED: 0.180% 156 | UN: 0.175% 157 | SO: 0.175% 158 | PA: 0.175% 159 | INE: 0.175% 160 | IG: 0.175% 161 | TY: 0.170% 162 | TUR: 0.170% 163 | OD: 0.170% 164 | NTE: 0.170% 165 | IV: 0.170% 166 | ENC: 0.170% 167 | EAS: 0.170% 168 | AB: 0.170% 169 | TL: 0.165% 170 | MAN: 0.165% 171 | EX: 0.165% 172 | BL: 0.165% 173 | AI: 0.165% 174 | TER: 0.156% 175 | BUT: 0.156% 176 | BO: 0.156% 177 | UC: 0.151% 178 | SEL: 0.151% 179 | RU: 0.151% 180 | PLE: 0.151% 181 | PER: 0.151% 182 | MEN: 0.151% 183 | IF: 0.151% 184 | FR: 0.151% 185 | CON: 0.151% 186 | OL: 0.146% 187 | MU: 0.146% 188 | KN: 0.146% 189 | ILL: 0.146% 190 | AM: 0.146% 191 | WHA: 0.141% 192 | SC: 0.141% 193 | LEA: 0.141% 194 | KE: 0.141% 195 | INT: 0.141% 196 | IA: 0.141% 197 | EST: 0.141% 198 | WOR: 0.136% 199 | OO: 0.136% 200 | NDE: 0.136% 201 | HOU: 0.136% 202 | HEI: 0.136% 203 | FA: 0.136% 204 | EIR: 0.136% 205 | AIN: 0.136% 206 | LIT: 0.131% 207 | KNO: 0.131% 208 | ITS: 0.131% 209 | INC: 0.131% 210 | GI: 0.131% 211 | EF: 0.131% 212 | CAN: 0.131% 213 | AP: 0.131% 214 | UG: 0.126% 215 | TIN: 0.126% 216 | TEN: 0.126% 217 | PRO: 0.126% 218 | OV: 0.126% 219 | NES: 0.126% 220 | GRE: 0.126% 221 | ERE: 0.126% 222 | BLE: 0.126% 223 | ATE: 0.126% 224 | UE: 0.122% 225 | TLE: 0.122% 226 | THO: 0.122% 227 | SA: 0.122% 228 | NI: 0.122% 229 | IVE: 0.122% 230 | END: 0.122% 231 | EEN: 0.122% 232 | EAT: 0.122% 233 | ARE: 0.122% 234 | WAS: 0.117% 235 | UGH: 0.117% 236 | OUL: 0.117% 237 | ONE: 0.117% 238 | NL: 0.117% 239 | MY: 0.117% 240 | ITY: 0.117% 241 | ID: 0.117% 242 | GS: 0.117% 243 | COM: 0.117% 244 | AW: 0.117% 245 | ACE: 0.117% 246 | ULD: 0.112% 247 | SUR: 0.112% 248 | PRE: 0.112% 249 | OP: 0.112% 250 | NLY: 0.112% 251 | NGS: 0.112% 252 | LT: 0.112% 253 | LS: 0.112% 254 | ITT: 0.112% 255 | HT: 0.112% 256 | HAN: 0.112% 257 | GHT: 0.112% 258 | FIN: 0.112% 259 | FF: 0.112% 260 | CU: 0.112% 261 | VIN: 0.107% 262 | UST: 0.107% 263 | USE: 0.107% 264 | ROM: 0.107% 265 | RM: 0.107% 266 | RK: 0.107% 267 | POS: 0.107% 268 | OUS: 0.107% 269 | OUG: 0.107% 270 | ORK: 0.107% 271 | ORE: 0.107% 272 | ESE: 0.107% 273 | AK: 0.107% 274 | URS: 0.102% 275 | QU: 0.102% 276 | PP: 0.102% 277 | ONL: 0.102% 278 | IND: 0.102% 279 | FRO: 0.102% 280 | DR: 0.102% 281 | CTI: 0.102% 282 | BEE: 0.102% 283 | STA: 0.097% 284 | ONS: 0.097% 285 | OG: 0.097% 286 | ITE: 0.097% 287 | ISH: 0.097% 288 | ERY: 0.097% 289 | ERS: 0.097% 290 | ERI: 0.097% 291 | EP: 0.097% 292 | AST: 0.097% 293 | YE: 0.092% 294 | WIL: 0.092% 295 | VES: 0.092% 296 | TTL: 0.092% 297 | PT: 0.092% 298 | PLA: 0.092% 299 | OTH: 0.092% 300 | MUS: 0.092% 301 | DIS: 0.092% 302 | AKE: 0.092% 303 | STR: 0.087% 304 | RN: 0.087% 305 | OY: 0.087% 306 | OUT: 0.087% 307 | MPL: 0.087% 308 | MOR: 0.087% 309 | LVE: 0.087% 310 | LV: 0.087% 311 | IST: 0.087% 312 | HAD: 0.087% 313 | CHI: 0.087% 314 | WIS: 0.083% 315 | SP: 0.083% 316 | SER: 0.083% 317 | RSE: 0.083% 318 | RD: 0.083% 319 | PI: 0.083% 320 | OST: 0.083% 321 | LAC: 0.083% 322 | ITI: 0.083% 323 | IES: 0.083% 324 | DU: 0.083% 325 | DES: 0.083% 326 | AG: 0.083% 327 | ACT: 0.083% 328 | WIN: 0.078% 329 | WHE: 0.078% 330 | UM: 0.078% 331 | STI: 0.078% 332 | RV: 0.078% 333 | ROV: 0.078% 334 | ROU: 0.078% 335 | NCI: 0.078% 336 | LF: 0.078% 337 | KI: 0.078% 338 | IGH: 0.078% 339 | HOW: 0.078% 340 | FU: 0.078% 341 | FEC: 0.078% 342 | EY: 0.078% 343 | ELV: 0.078% 344 | DRA: 0.078% 345 | DA: 0.078% 346 | CR: 0.078% 347 | BOU: 0.078% 348 | YS: 0.073% 349 | WN: 0.073% 350 | WAY: 0.073% 351 | TTE: 0.073% 352 | TRU: 0.073% 353 | SSI: 0.073% 354 | SSE: 0.073% 355 | SEN: 0.073% 356 | SED: 0.073% 357 | RF: 0.073% 358 | PU: 0.073% 359 | OMP: 0.073% 360 | NY: 0.073% 361 | NK: 0.073% 362 | LES: 0.073% 363 | ISE: 0.073% 364 | IME: 0.073% 365 | IDE: 0.073% 366 | IAL: 0.073% 367 | HES: 0.073% 368 | HEN: 0.073% 369 | HEA: 0.073% 370 | ELY: 0.073% 371 | DER: 0.073% 372 | COU: 0.073% 373 | CES: 0.073% 374 | UP: 0.068% 375 | UCH: 0.068% 376 | SIN: 0.068% 377 | RST: 0.068% 378 | RC: 0.068% 379 | RAW: 0.068% 380 | OVI: 0.068% 381 | OUN: 0.068% 382 | OSS: 0.068% 383 | ONT: 0.068% 384 | OI: 0.068% 385 | NTR: 0.068% 386 | NAT: 0.068% 387 | MOS: 0.068% 388 | LU: 0.068% 389 | HIL: 0.068% 390 | HEM: 0.068% 391 | GRA: 0.068% 392 | GN: 0.068% 393 | GIN: 0.068% 394 | ETH: 0.068% 395 | ENE: 0.068% 396 | ELF: 0.068% 397 | DEA: 0.068% 398 | CUL: 0.068% 399 | ANC: 0.068% 400 | TIM: 0.063% 401 | TAT: 0.063% 402 | SK: 0.063% 403 | SHO: 0.063% 404 | SES: 0.063% 405 | RR: 0.063% 406 | REN: 0.063% 407 | RED: 0.063% 408 | RAC: 0.063% 409 | PAR: 0.063% 410 | OWN: 0.063% 411 | OSE: 0.063% 412 | ORI: 0.063% 413 | ONG: 0.063% 414 | OND: 0.063% 415 | NTI: 0.063% 416 | NF: 0.063% 417 | INK: 0.063% 418 | IEN: 0.063% 419 | IB: 0.063% 420 | HAS: 0.063% 421 | ELI: 0.063% 422 | EAL: 0.063% 423 | DEN: 0.063% 424 | CTU: 0.063% 425 | ATU: 0.063% 426 | ASE: 0.063% 427 | APP: 0.063% 428 | ANY: 0.063% 429 | ANT: 0.063% 430 | ALI: 0.063% 431 | ABL: 0.063% 432 | VEN: 0.058% 433 | UND: 0.058% 434 | UI: 0.058% 435 | UA: 0.058% 436 | TIS: 0.058% 437 | RTH: 0.058% 438 | RIT: 0.058% 439 | RIN: 0.058% 440 | RIE: 0.058% 441 | RIC: 0.058% 442 | RG: 0.058% 443 | RFE: 0.058% 444 | RAT: 0.058% 445 | RAN: 0.058% 446 | PH: 0.058% 447 | PEN: 0.058% 448 | OVE: 0.058% 449 | OME: 0.058% 450 | NED: 0.058% 451 | MIT: 0.058% 452 | MIN: 0.058% 453 | LLY: 0.058% 454 | IGN: 0.058% 455 | FUL: 0.058% 456 | EW: 0.058% 457 | ERF: 0.058% 458 | EG: 0.058% 459 | ECO: 0.058% 460 | CRE: 0.058% 461 | CIE: 0.058% 462 | CIA: 0.058% 463 | BI: 0.058% 464 | ATH: 0.058% 465 | ASU: 0.058% 466 | VO: 0.053% 467 | ULT: 0.053% 468 | UD: 0.053% 469 | TRI: 0.053% 470 | TRA: 0.053% 471 | TEM: 0.053% 472 | TAK: 0.053% 473 | STE: 0.053% 474 | SPE: 0.053% 475 | REC: 0.053% 476 | ORT: 0.053% 477 | OOD: 0.053% 478 | ODE: 0.053% 479 | NN: 0.053% 480 | NER: 0.053% 481 | MS: 0.053% 482 | LLE: 0.053% 483 | LIN: 0.053% 484 | LAR: 0.053% 485 | KIN: 0.053% 486 | ITA: 0.053% 487 | IRS: 0.053% 488 | IMI: 0.053% 489 | ICA: 0.053% 490 | HU: 0.053% 491 | FIR: 0.053% 492 | ERA: 0.053% 493 | EO: 0.053% 494 | ELL: 0.053% 495 | DUC: 0.053% 496 | DS: 0.053% 497 | CHA: 0.053% 498 | CAR: 0.053% 499 | BIT: 0.053% 500 | ALS: 0.053% 501 | ADE: 0.053% 502 | ABO: 0.053% 503 | WER: 0.049% 504 | VA: 0.049% 505 | TIC: 0.049% 506 | TEL: 0.049% 507 | PEC: 0.049% 508 | OWE: 0.049% 509 | ORM: 0.049% 510 | NDI: 0.049% 511 | MUC: 0.049% 512 | LIF: 0.049% 513 | LED: 0.049% 514 | IP: 0.049% 515 | INF: 0.049% 516 | IMP: 0.049% 517 | ILE: 0.049% 518 | ICE: 0.049% 519 | HIT: 0.049% 520 | GO: 0.049% 521 | GL: 0.049% 522 | ETT: 0.049% 523 | ERM: 0.049% 524 | EMP: 0.049% 525 | EAV: 0.049% 526 | EAC: 0.049% 527 | DEL: 0.049% 528 | DED: 0.049% 529 | CEN: 0.049% 530 | BES: 0.049% 531 | AU: 0.049% 532 | ARI: 0.049% 533 | XP: 0.044% 534 | WOU: 0.044% 535 | TLY: 0.044% 536 | TAL: 0.044% 537 | STO: 0.044% 538 | SM: 0.044% 539 | SIO: 0.044% 540 | RVI: 0.044% 541 | ROW: 0.044% 542 | RET: 0.044% 543 | RCH: 0.044% 544 | RAL: 0.044% 545 | QUE: 0.044% 546 | PAI: 0.044% 547 | ONA: 0.044% 548 | NSE: 0.044% 549 | NAL: 0.044% 550 | MB: 0.044% 551 | MAK: 0.044% 552 | LEN: 0.044% 553 | LAN: 0.044% 554 | JO: 0.044% 555 | IZ: 0.044% 556 | ILD: 0.044% 557 | IFE: 0.044% 558 | HIM: 0.044% 559 | HEY: 0.044% 560 | HED: 0.044% 561 | GER: 0.044% 562 | FL: 0.044% 563 | FIC: 0.044% 564 | FAC: 0.044% 565 | EXP: 0.044% 566 | ESP: 0.044% 567 | ENS: 0.044% 568 | EME: 0.044% 569 | EFF: 0.044% 570 | ECE: 0.044% 571 | DON: 0.044% 572 | DOM: 0.044% 573 | DAY: 0.044% 574 | CL: 0.044% 575 | CK: 0.044% 576 | CC: 0.044% 577 | CAT: 0.044% 578 | AWI: 0.044% 579 | ARV: 0.044% 580 | ACH: 0.044% 581 | ZE: 0.039% 582 | YET: 0.039% 583 | VED: 0.039% 584 | URI: 0.039% 585 | UNT: 0.039% 586 | UEN: 0.039% 587 | UDE: 0.039% 588 | TW: 0.039% 589 | TRY: 0.039% 590 | TRO: 0.039% 591 | TAN: 0.039% 592 | SHI: 0.039% 593 | SHE: 0.039% 594 | SET: 0.039% 595 | SEC: 0.039% 596 | RTI: 0.039% 597 | RRO: 0.039% 598 | RKM: 0.039% 599 | RIV: 0.039% 600 | RIS: 0.039% 601 | RIO: 0.039% 602 | REF: 0.039% 603 | REE: 0.039% 604 | PPO: 0.039% 605 | OIN: 0.039% 606 | NEW: 0.039% 607 | MPE: 0.039% 608 | MOD: 0.039% 609 | MER: 0.039% 610 | MAL: 0.039% 611 | MAD: 0.039% 612 | LP: 0.039% 613 | LIS: 0.039% 614 | LIG: 0.039% 615 | KM: 0.039% 616 | IRE: 0.039% 617 | INS: 0.039% 618 | GEN: 0.039% 619 | FFE: 0.039% 620 | FEE: 0.039% 621 | FAR: 0.039% 622 | ETE: 0.039% 623 | ENG: 0.039% 624 | EEL: 0.039% 625 | EAD: 0.039% 626 | DL: 0.039% 627 | DIT: 0.039% 628 | DIN: 0.039% 629 | CTS: 0.039% 630 | CIT: 0.039% 631 | CHE: 0.039% 632 | BET: 0.039% 633 | BER: 0.039% 634 | ASS: 0.039% 635 | ARS: 0.039% 636 | ARC: 0.039% 637 | AME: 0.039% 638 | AGE: 0.039% 639 | WHO: 0.034% 640 | VIL: 0.034% 641 | UF: 0.034% 642 | UB: 0.034% 643 | UAL: 0.034% 644 | TRE: 0.034% 645 | SUP: 0.034% 646 | SUC: 0.034% 647 | SON: 0.034% 648 | SOL: 0.034% 649 | SMA: 0.034% 650 | SIB: 0.034% 651 | SF: 0.034% 652 | SCI: 0.034% 653 | SAT: 0.034% 654 | RUE: 0.034% 655 | RUD: 0.034% 656 | RMA: 0.034% 657 | RL: 0.034% 658 | PTE: 0.034% 659 | PEO: 0.034% 660 | ORD: 0.034% 661 | ORA: 0.034% 662 | OPL: 0.034% 663 | OLD: 0.034% 664 | OC: 0.034% 665 | OB: 0.034% 666 | NTS: 0.034% 667 | NTO: 0.034% 668 | NST: 0.034% 669 | NOR: 0.034% 670 | NIT: 0.034% 671 | NGL: 0.034% 672 | MAY: 0.034% 673 | MAT: 0.034% 674 | LON: 0.034% 675 | LEC: 0.034% 676 | JOY: 0.034% 677 | IZE: 0.034% 678 | ISF: 0.034% 679 | INA: 0.034% 680 | IGI: 0.034% 681 | IED: 0.034% 682 | ICI: 0.034% 683 | IBL: 0.034% 684 | HAR: 0.034% 685 | HAP: 0.034% 686 | GA: 0.034% 687 | FFI: 0.034% 688 | ERV: 0.034% 689 | ERT: 0.034% 690 | EOP: 0.034% 691 | ELS: 0.034% 692 | EGR: 0.034% 693 | CAL: 0.034% 694 | BR: 0.034% 695 | ASK: 0.034% 696 | ARN: 0.034% 697 | ANN: 0.034% 698 | ALT: 0.034% 699 | ACK: 0.034% 700 | YTH: 0.029% 701 | YT: 0.029% 702 | YEA: 0.029% 703 | XPR: 0.029% 704 | XA: 0.029% 705 | WLE: 0.029% 706 | WL: 0.029% 707 | VOU: 0.029% 708 | VIC: 0.029% 709 | UMA: 0.029% 710 | ULP: 0.029% 711 | UFF: 0.029% 712 | TTI: 0.029% 713 | TOR: 0.029% 714 | TOG: 0.029% 715 | TIV: 0.029% 716 | THY: 0.029% 717 | TEA: 0.029% 718 | SUL: 0.029% 719 | SUF: 0.029% 720 | STU: 0.029% 721 | SKI: 0.029% 722 | SIM: 0.029% 723 | SIG: 0.029% 724 | SHA: 0.029% 725 | SDO: 0.029% 726 | SD: 0.029% 727 | SCU: 0.029% 728 | SCE: 0.029% 729 | SAN: 0.029% 730 | RVE: 0.029% 731 | RTS: 0.029% 732 | RNE: 0.029% 733 | RIG: 0.029% 734 | RDE: 0.029% 735 | QUA: 0.029% 736 | PUT: 0.029% 737 | PUR: 0.029% 738 | PTU: 0.029% 739 | PRI: 0.029% 740 | POI: 0.029% 741 | PLI: 0.029% 742 | OWL: 0.029% 743 | OPE: 0.029% 744 | OOK: 0.029% 745 | OK: 0.029% 746 | OA: 0.029% 747 | NU: 0.029% 748 | NJO: 0.029% 749 | NJ: 0.029% 750 | NIN: 0.029% 751 | NEV: 0.029% 752 | MM: 0.029% 753 | MIR: 0.029% 754 | MBE: 0.029% 755 | LSE: 0.029% 756 | LPT: 0.029% 757 | LIA: 0.029% 758 | LET: 0.029% 759 | LAT: 0.029% 760 | KEN: 0.029% 761 | IVI: 0.029% 762 | ISD: 0.029% 763 | IOU: 0.029% 764 | HY: 0.029% 765 | HUM: 0.029% 766 | HOO: 0.029% 767 | HAL: 0.029% 768 | GU: 0.029% 769 | GIV: 0.029% 770 | FT: 0.029% 771 | FFO: 0.029% 772 | EXA: 0.029% 773 | ESU: 0.029% 774 | ESI: 0.029% 775 | ENJ: 0.029% 776 | EED: 0.029% 777 | EDG: 0.029% 778 | ECU: 0.029% 779 | DMI: 0.029% 780 | DM: 0.029% 781 | DGE: 0.029% 782 | DG: 0.029% 783 | CY: 0.029% 784 | CER: 0.029% 785 | CED: 0.029% 786 | BS: 0.029% 787 | BLA: 0.029% 788 | AYS: 0.029% 789 | AWA: 0.029% 790 | ATT: 0.029% 791 | ARY: 0.029% 792 | ARD: 0.029% 793 | ARA: 0.029% 794 | ADO: 0.029% 795 | ADM: 0.029% 796 | YSE: 0.024% 797 | YIN: 0.024% 798 | YI: 0.024% 799 | XCE: 0.024% 800 | XC: 0.024% 801 | WS: 0.024% 802 | WOO: 0.024% 803 | WEA: 0.024% 804 | UTH: 0.024% 805 | UTE: 0.024% 806 | URG: 0.024% 807 | UPP: 0.024% 808 | UMS: 0.024% 809 | ULA: 0.024% 810 | UIL: 0.024% 811 | UCT: 0.024% 812 | UCE: 0.024% 813 | TWO: 0.024% 814 | TON: 0.024% 815 | TIE: 0.024% 816 | TEC: 0.024% 817 | TAI: 0.024% 818 | STS: 0.024% 819 | SSA: 0.024% 820 | SL: 0.024% 821 | SIT: 0.024% 822 | SID: 0.024% 823 | SEE: 0.024% 824 | RYT: 0.024% 825 | RUS: 0.024% 826 | RP: 0.024% 827 | ROD: 0.024% 828 | RNI: 0.024% 829 | RME: 0.024% 830 | RIA: 0.024% 831 | REP: 0.024% 832 | REM: 0.024% 833 | REL: 0.024% 834 | RB: 0.024% 835 | RAS: 0.024% 836 | QUI: 0.024% 837 | PRA: 0.024% 838 | PON: 0.024% 839 | PIN: 0.024% 840 | PEA: 0.024% 841 | PAT: 0.024% 842 | PAS: 0.024% 843 | ORN: 0.024% 844 | OOL: 0.024% 845 | ONC: 0.024% 846 | OLU: 0.024% 847 | OGR: 0.024% 848 | OGE: 0.024% 849 | ODU: 0.024% 850 | NTL: 0.024% 851 | NOU: 0.024% 852 | NGE: 0.024% 853 | NFI: 0.024% 854 | NDO: 0.024% 855 | NCY: 0.024% 856 | NCR: 0.024% 857 | MSE: 0.024% 858 | MPA: 0.024% 859 | MET: 0.024% 860 | MEA: 0.024% 861 | MAS: 0.024% 862 | MAG: 0.024% 863 | LUT: 0.024% 864 | LOS: 0.024% 865 | LIM: 0.024% 866 | KIL: 0.024% 867 | ISC: 0.024% 868 | INI: 0.024% 869 | ILY: 0.024% 870 | ICT: 0.024% 871 | IAN: 0.024% 872 | HIP: 0.024% 873 | HAB: 0.024% 874 | GOD: 0.024% 875 | GNI: 0.024% 876 | GES: 0.024% 877 | FIE: 0.024% 878 | FAL: 0.024% 879 | EXC: 0.024% 880 | ERN: 0.024% 881 | EIT: 0.024% 882 | EFU: 0.024% 883 | EFO: 0.024% 884 | DLY: 0.024% 885 | DEG: 0.024% 886 | CTE: 0.024% 887 | CHO: 0.024% 888 | CCE: 0.024% 889 | BUI: 0.024% 890 | BEC: 0.024% 891 | AVO: 0.024% 892 | APH: 0.024% 893 | AGI: 0.024% 894 | ACC: 0.024% 895 | ABI: 0.024% 896 | YED: 0.019% 897 | WR: 0.019% 898 | WEV: 0.019% 899 | WEL: 0.019% 900 | WEE: 0.019% 901 | VID: 0.019% 902 | VAL: 0.019% 903 | URA: 0.019% 904 | UPO: 0.019% 905 | UES: 0.019% 906 | UCC: 0.019% 907 | TOY: 0.019% 908 | TNE: 0.019% 909 | TN: 0.019% 910 | THR: 0.019% 911 | SPO: 0.019% 912 | SOM: 0.019% 913 | SIR: 0.019% 914 | SCH: 0.019% 915 | SBO: 0.019% 916 | SB: 0.019% 917 | SAR: 0.019% 918 | RTA: 0.019% 919 | RSO: 0.019% 920 | RON: 0.019% 921 | RMI: 0.019% 922 | REV: 0.019% 923 | RAP: 0.019% 924 | RAG: 0.019% 925 | RAD: 0.019% 926 | PPI: 0.019% 927 | POW: 0.019% 928 | PHE: 0.019% 929 | ORR: 0.019% 930 | OLL: 0.019% 931 | OIC: 0.019% 932 | OFT: 0.019% 933 | ODS: 0.019% 934 | NV: 0.019% 935 | NNE: 0.019% 936 | NH: 0.019% 937 | NEC: 0.019% 938 | NDU: 0.019% 939 | NCT: 0.019% 940 | MPT: 0.019% 941 | MON: 0.019% 942 | MME: 0.019% 943 | MIG: 0.019% 944 | MES: 0.019% 945 | MAR: 0.019% 946 | LWA: 0.019% 947 | LW: 0.019% 948 | LTH: 0.019% 949 | LOU: 0.019% 950 | LOO: 0.019% 951 | LOG: 0.019% 952 | LM: 0.019% 953 | LIZ: 0.019% 954 | LIV: 0.019% 955 | LIK: 0.019% 956 | LIC: 0.019% 957 | LFI: 0.019% 958 | LAW: 0.019% 959 | LAS: 0.019% 960 | LAI: 0.019% 961 | LAB: 0.019% 962 | KS: 0.019% 963 | KME: 0.019% 964 | KMA: 0.019% 965 | JU: 0.019% 966 | ISP: 0.019% 967 | ISI: 0.019% 968 | IRA: 0.019% 969 | IMA: 0.019% 970 | IKE: 0.019% 971 | IK: 0.019% 972 | IFI: 0.019% 973 | IBI: 0.019% 974 | IAT: 0.019% 975 | HRO: 0.019% 976 | HR: 0.019% 977 | HOS: 0.019% 978 | HOR: 0.019% 979 | HOP: 0.019% 980 | HOL: 0.019% 981 | HOD: 0.019% 982 | GNO: 0.019% 983 | GET: 0.019% 984 | FY: 0.019% 985 | FOL: 0.019% 986 | FIS: 0.019% 987 | FER: 0.019% 988 | EVI: 0.019% 989 | ETS: 0.019% 990 | EQU: 0.019% 991 | EQ: 0.019% 992 | EPR: 0.019% 993 | EPE: 0.019% 994 | ENO: 0.019% 995 | ENI: 0.019% 996 | EIN: 0.019% 997 | EIG: 0.019% 998 | EFI: 0.019% 999 | EDU: 0.019% 1000 | EDI: 0.019% 1001 | EAN: 0.019% 1002 | DOW: 0.019% 1003 | DOG: 0.019% 1004 | DEP: 0.019% 1005 | CTL: 0.019% 1006 | CLU: 0.019% 1007 | CEL: 0.019% 1008 | CEA: 0.019% 1009 | CCO: 0.019% 1010 | CAP: 0.019% 1011 | BSO: 0.019% 1012 | BRO: 0.019% 1013 | BOY: 0.019% 1014 | BEY: 0.019% 1015 | BEI: 0.019% 1016 | BEF: 0.019% 1017 | BA: 0.019% 1018 | AUT: 0.019% 1019 | ASB: 0.019% 1020 | ASA: 0.019% 1021 | ARR: 0.019% 1022 | ARG: 0.019% 1023 | ANS: 0.019% 1024 | ANI: 0.019% 1025 | AMU: 0.019% 1026 | AMO: 0.019% 1027 | ALW: 0.019% 1028 | ABS: 0.019% 1029 | YON: 0.015% 1030 | YA: 0.015% 1031 | XTE: 0.015% 1032 | XT: 0.015% 1033 | XI: 0.015% 1034 | XHI: 0.015% 1035 | XH: 0.015% 1036 | XAM: 0.015% 1037 | XAC: 0.015% 1038 | VOL: 0.015% 1039 | USL: 0.015% 1040 | USI: 0.015% 1041 | URR: 0.015% 1042 | URP: 0.015% 1043 | UNS: 0.015% 1044 | ULY: 0.015% 1045 | ULL: 0.015% 1046 | ULI: 0.015% 1047 | UIT: 0.015% 1048 | UCA: 0.015% 1049 | UBT: 0.015% 1050 | UAI: 0.015% 1051 | TWE: 0.015% 1052 | TUD: 0.015% 1053 | TUA: 0.015% 1054 | TOU: 0.015% 1055 | TOO: 0.015% 1056 | TIT: 0.015% 1057 | TIL: 0.015% 1058 | TIF: 0.015% 1059 | THU: 0.015% 1060 | TAY: 0.015% 1061 | TAR: 0.015% 1062 | SY: 0.015% 1063 | SUB: 0.015% 1064 | STY: 0.015% 1065 | SSU: 0.015% 1066 | SLY: 0.015% 1067 | SFI: 0.015% 1068 | SEQ: 0.015% 1069 | SCO: 0.015% 1070 | RW: 0.015% 1071 | RUL: 0.015% 1072 | RTE: 0.015% 1073 | RRI: 0.015% 1074 | ROO: 0.015% 1075 | RNA: 0.015% 1076 | RLY: 0.015% 1077 | RLD: 0.015% 1078 | RIB: 0.015% 1079 | RGE: 0.015% 1080 | REW: 0.015% 1081 | REG: 0.015% 1082 | RCU: 0.015% 1083 | RBL: 0.015% 1084 | PY: 0.015% 1085 | PTI: 0.015% 1086 | PPY: 0.015% 1087 | PPE: 0.015% 1088 | PIL: 0.015% 1089 | PIE: 0.015% 1090 | PHO: 0.015% 1091 | PHI: 0.015% 1092 | PED: 0.015% 1093 | OYE: 0.015% 1094 | OYA: 0.015% 1095 | OUB: 0.015% 1096 | OTE: 0.015% 1097 | OSI: 0.015% 1098 | ORL: 0.015% 1099 | OPT: 0.015% 1100 | OPP: 0.015% 1101 | ONV: 0.015% 1102 | OMM: 0.015% 1103 | OLO: 0.015% 1104 | OLE: 0.015% 1105 | NTU: 0.015% 1106 | NSI: 0.015% 1107 | NNO: 0.015% 1108 | NIS: 0.015% 1109 | NGT: 0.015% 1110 | NGI: 0.015% 1111 | NFL: 0.015% 1112 | NEI: 0.015% 1113 | NEA: 0.015% 1114 | NDL: 0.015% 1115 | NCO: 0.015% 1116 | NCH: 0.015% 1117 | NAR: 0.015% 1118 | NAM: 0.015% 1119 | NAB: 0.015% 1120 | MYS: 0.015% 1121 | MST: 0.015% 1122 | MED: 0.015% 1123 | MAI: 0.015% 1124 | LUE: 0.015% 1125 | LTS: 0.015% 1126 | LTO: 0.015% 1127 | LSO: 0.015% 1128 | LMO: 0.015% 1129 | LLA: 0.015% 1130 | LK: 0.015% 1131 | LEM: 0.015% 1132 | LEI: 0.015% 1133 | LDI: 0.015% 1134 | LAM: 0.015% 1135 | KNE: 0.015% 1136 | KEL: 0.015% 1137 | JUS: 0.015% 1138 | JEC: 0.015% 1139 | JE: 0.015% 1140 | IX: 0.015% 1141 | IVA: 0.015% 1142 | ISU: 0.015% 1143 | IRC: 0.015% 1144 | IPL: 0.015% 1145 | IOR: 0.015% 1146 | IFF: 0.015% 1147 | IET: 0.015% 1148 | ICU: 0.015% 1149 | IAR: 0.015% 1150 | HUS: 0.015% 1151 | HOM: 0.015% 1152 | HIB: 0.015% 1153 | HET: 0.015% 1154 | HBO: 0.015% 1155 | HB: 0.015% 1156 | GT: 0.015% 1157 | GOO: 0.015% 1158 | GLA: 0.015% 1159 | GHE: 0.015% 1160 | GHB: 0.015% 1161 | GED: 0.015% 1162 | FTE: 0.015% 1163 | FRI: 0.015% 1164 | FRE: 0.015% 1165 | FOU: 0.015% 1166 | FLU: 0.015% 1167 | FEA: 0.015% 1168 | EYO: 0.015% 1169 | EXT: 0.015% 1170 | EXH: 0.015% 1171 | EU: 0.015% 1172 | ETR: 0.015% 1173 | ETI: 0.015% 1174 | ERG: 0.015% 1175 | EPT: 0.015% 1176 | EPH: 0.015% 1177 | EMS: 0.015% 1178 | EMB: 0.015% 1179 | EIS: 0.015% 1180 | EET: 0.015% 1181 | EEP: 0.015% 1182 | DRE: 0.015% 1183 | DOP: 0.015% 1184 | DIC: 0.015% 1185 | DH: 0.015% 1186 | DEX: 0.015% 1187 | DEM: 0.015% 1188 | DEE: 0.015% 1189 | DD: 0.015% 1190 | CUR: 0.015% 1191 | CUM: 0.015% 1192 | CIV: 0.015% 1193 | CIR: 0.015% 1194 | CIP: 0.015% 1195 | CEP: 0.015% 1196 | CEF: 0.015% 1197 | CAD: 0.015% 1198 | BT: 0.015% 1199 | BOV: 0.015% 1200 | BJE: 0.015% 1201 | BJ: 0.015% 1202 | AWS: 0.015% 1203 | ARL: 0.015% 1204 | ARB: 0.015% 1205 | APE: 0.015% 1206 | ANG: 0.015% 1207 | AMP: 0.015% 1208 | AMB: 0.015% 1209 | ALM: 0.015% 1210 | ALK: 0.015% 1211 | AKI: 0.015% 1212 | AFF: 0.015% 1213 | AF: 0.015% 1214 | ACI: 0.015% 1215 | ACA: 0.015% 1216 | ZAT: 0.010% 1217 | ZA: 0.010% 1218 | YSS: 0.010% 1219 | YOR: 0.010% 1220 | YM: 0.010% 1221 | YLE: 0.010% 1222 | YL: 0.010% 1223 | XU: 0.010% 1224 | XQU: 0.010% 1225 | XQ: 0.010% 1226 | XPL: 0.010% 1227 | XIS: 0.010% 1228 | XE: 0.010% 1229 | WRI: 0.010% 1230 | WID: 0.010% 1231 | WEN: 0.010% 1232 | WAL: 0.010% 1233 | VIV: 0.010% 1234 | VIT: 0.010% 1235 | VET: 0.010% 1236 | VEL: 0.010% 1237 | VAN: 0.010% 1238 | VAI: 0.010% 1239 | UTY: 0.010% 1240 | UTT: 0.010% 1241 | UTI: 0.010% 1242 | URT: 0.010% 1243 | URB: 0.010% 1244 | UPE: 0.010% 1245 | UO: 0.010% 1246 | UNQ: 0.010% 1247 | UNH: 0.010% 1248 | UNG: 0.010% 1249 | UNC: 0.010% 1250 | UMB: 0.010% 1251 | ULO: 0.010% 1252 | ULG: 0.010% 1253 | ULE: 0.010% 1254 | UIS: 0.010% 1255 | UED: 0.010% 1256 | UDI: 0.010% 1257 | UBL: 0.010% 1258 | UBJ: 0.010% 1259 | TYL: 0.010% 1260 | TTA: 0.010% 1261 | TOW: 0.010% 1262 | TOL: 0.010% 1263 | TM: 0.010% 1264 | TIA: 0.010% 1265 | THS: 0.010% 1266 | TEV: 0.010% 1267 | SWE: 0.010% 1268 | SW: 0.010% 1269 | SUE: 0.010% 1270 | SQU: 0.010% 1271 | SQ: 0.010% 1272 | SPI: 0.010% 1273 | SOR: 0.010% 1274 | SKE: 0.010% 1275 | SIZ: 0.010% 1276 | SIX: 0.010% 1277 | SIL: 0.010% 1278 | SFY: 0.010% 1279 | SFA: 0.010% 1280 | SCA: 0.010% 1281 | SAY: 0.010% 1282 | RWI: 0.010% 1283 | RUT: 0.010% 1284 | RUC: 0.010% 1285 | RTO: 0.010% 1286 | RSU: 0.010% 1287 | RPO: 0.010% 1288 | RPE: 0.010% 1289 | ROR: 0.010% 1290 | ROP: 0.010% 1291 | ROJ: 0.010% 1292 | ROG: 0.010% 1293 | REJ: 0.010% 1294 | RAY: 0.010% 1295 | PUL: 0.010% 1296 | PS: 0.010% 1297 | PPR: 0.010% 1298 | POP: 0.010% 1299 | PLY: 0.010% 1300 | PIS: 0.010% 1301 | PIC: 0.010% 1302 | PET: 0.010% 1303 | PEL: 0.010% 1304 | OX: 0.010% 1305 | OWS: 0.010% 1306 | OWI: 0.010% 1307 | OTT: 0.010% 1308 | OTO: 0.010% 1309 | OTI: 0.010% 1310 | ORS: 0.010% 1311 | ORF: 0.010% 1312 | OOR: 0.010% 1313 | ONF: 0.010% 1314 | OLS: 0.010% 1315 | OLI: 0.010% 1316 | OKS: 0.010% 1317 | OJA: 0.010% 1318 | OJ: 0.010% 1319 | OGY: 0.010% 1320 | OGN: 0.010% 1321 | OFF: 0.010% 1322 | OCK: 0.010% 1323 | OCI: 0.010% 1324 | OCA: 0.010% 1325 | OBS: 0.010% 1326 | OBL: 0.010% 1327 | OBE: 0.010% 1328 | OAT: 0.010% 1329 | OAR: 0.010% 1330 | OAD: 0.010% 1331 | NVE: 0.010% 1332 | NUM: 0.010% 1333 | NQU: 0.010% 1334 | NQ: 0.010% 1335 | NOB: 0.010% 1336 | NNY: 0.010% 1337 | NIZ: 0.010% 1338 | NIU: 0.010% 1339 | NIF: 0.010% 1340 | NHE: 0.010% 1341 | NHA: 0.010% 1342 | NGU: 0.010% 1343 | NGD: 0.010% 1344 | NFU: 0.010% 1345 | NFE: 0.010% 1346 | NEY: 0.010% 1347 | NEN: 0.010% 1348 | NEE: 0.010% 1349 | NDS: 0.010% 1350 | NDA: 0.010% 1351 | NAG: 0.010% 1352 | MSY: 0.010% 1353 | MPR: 0.010% 1354 | MPO: 0.010% 1355 | MN: 0.010% 1356 | MIS: 0.010% 1357 | MIL: 0.010% 1358 | MID: 0.010% 1359 | MEM: 0.010% 1360 | MBO: 0.010% 1361 | LYS: 0.010% 1362 | LUS: 0.010% 1363 | LUM: 0.010% 1364 | LTA: 0.010% 1365 | LOV: 0.010% 1366 | LOR: 0.010% 1367 | LOC: 0.010% 1368 | LOA: 0.010% 1369 | LLS: 0.010% 1370 | LLI: 0.010% 1371 | LIP: 0.010% 1372 | LIE: 0.010% 1373 | LG: 0.010% 1374 | LER: 0.010% 1375 | LDH: 0.010% 1376 | KEE: 0.010% 1377 | KED: 0.010% 1378 | JOI: 0.010% 1379 | JAN: 0.010% 1380 | JA: 0.010% 1381 | IZA: 0.010% 1382 | IUS: 0.010% 1383 | IU: 0.010% 1384 | ISM: 0.010% 1385 | ISL: 0.010% 1386 | IRD: 0.010% 1387 | IPS: 0.010% 1388 | IOD: 0.010% 1389 | INN: 0.010% 1390 | INH: 0.010% 1391 | IMS: 0.010% 1392 | IMM: 0.010% 1393 | ILT: 0.010% 1394 | ILI: 0.010% 1395 | IFY: 0.010% 1396 | IFT: 0.010% 1397 | IEF: 0.010% 1398 | IEC: 0.010% 1399 | IDI: 0.010% 1400 | IDD: 0.010% 1401 | IBE: 0.010% 1402 | HYS: 0.010% 1403 | HUR: 0.010% 1404 | HTS: 0.010% 1405 | HS: 0.010% 1406 | HOT: 0.010% 1407 | HOG: 0.010% 1408 | HIE: 0.010% 1409 | HEP: 0.010% 1410 | HEL: 0.010% 1411 | HAM: 0.010% 1412 | GY: 0.010% 1413 | GUL: 0.010% 1414 | GUE: 0.010% 1415 | GTH: 0.010% 1416 | GLO: 0.010% 1417 | GLI: 0.010% 1418 | GLE: 0.010% 1419 | GIO: 0.010% 1420 | GDO: 0.010% 1421 | GD: 0.010% 1422 | FYI: 0.010% 1423 | FUR: 0.010% 1424 | FTY: 0.010% 1425 | FRA: 0.010% 1426 | FLO: 0.010% 1427 | FIV: 0.010% 1428 | FIL: 0.010% 1429 | FEN: 0.010% 1430 | FEL: 0.010% 1431 | FAU: 0.010% 1432 | FAT: 0.010% 1433 | EXQ: 0.010% 1434 | EXI: 0.010% 1435 | EXE: 0.010% 1436 | ETW: 0.010% 1437 | ESQ: 0.010% 1438 | ESO: 0.010% 1439 | ESC: 0.010% 1440 | ERW: 0.010% 1441 | ERU: 0.010% 1442 | ERR: 0.010% 1443 | ERP: 0.010% 1444 | ERO: 0.010% 1445 | ERD: 0.010% 1446 | ERC: 0.010% 1447 | EPI: 0.010% 1448 | ENN: 0.010% 1449 | ENA: 0.010% 1450 | EMY: 0.010% 1451 | EMI: 0.010% 1452 | EMA: 0.010% 1453 | ELT: 0.010% 1454 | ELP: 0.010% 1455 | ELA: 0.010% 1456 | EK: 0.010% 1457 | EJO: 0.010% 1458 | EJ: 0.010% 1459 | EIV: 0.010% 1460 | EGI: 0.010% 1461 | EFL: 0.010% 1462 | EES: 0.010% 1463 | EEM: 0.010% 1464 | EEK: 0.010% 1465 | EDE: 0.010% 1466 | ECR: 0.010% 1467 | ECL: 0.010% 1468 | ECI: 0.010% 1469 | EAU: 0.010% 1470 | EAB: 0.010% 1471 | DW: 0.010% 1472 | DVA: 0.010% 1473 | DV: 0.010% 1474 | DUR: 0.010% 1475 | DRO: 0.010% 1476 | DOU: 0.010% 1477 | DOI: 0.010% 1478 | DLE: 0.010% 1479 | DIR: 0.010% 1480 | DIG: 0.010% 1481 | DIF: 0.010% 1482 | DID: 0.010% 1483 | DIA: 0.010% 1484 | DHO: 0.010% 1485 | DET: 0.010% 1486 | DDL: 0.010% 1487 | DAP: 0.010% 1488 | DAI: 0.010% 1489 | CUT: 0.010% 1490 | CRY: 0.010% 1491 | COV: 0.010% 1492 | COR: 0.010% 1493 | COG: 0.010% 1494 | CLI: 0.010% 1495 | CLE: 0.010% 1496 | CIO: 0.010% 1497 | CIN: 0.010% 1498 | CIL: 0.010% 1499 | CEI: 0.010% 1500 | CEE: 0.010% 1501 | CAU: 0.010% 1502 | CAM: 0.010% 1503 | CAC: 0.010% 1504 | BSE: 0.010% 1505 | BOT: 0.010% 1506 | BOR: 0.010% 1507 | BEL: 0.010% 1508 | BEG: 0.010% 1509 | BED: 0.010% 1510 | BEA: 0.010% 1511 | BAN: 0.010% 1512 | AWN: 0.010% 1513 | AUS: 0.010% 1514 | AUL: 0.010% 1515 | AUG: 0.010% 1516 | ATR: 0.010% 1517 | ATA: 0.010% 1518 | ARM: 0.010% 1519 | APT: 0.010% 1520 | APA: 0.010% 1521 | ANK: 0.010% 1522 | ANE: 0.010% 1523 | AMI: 0.010% 1524 | ALO: 0.010% 1525 | ALE: 0.010% 1526 | ALA: 0.010% 1527 | AIR: 0.010% 1528 | AID: 0.010% 1529 | ADV: 0.010% 1530 | ADS: 0.010% 1531 | ADL: 0.010% 1532 | ADI: 0.010% 1533 | ADA: 0.010% 1534 | ACU: 0.010% 1535 | ACL: 0.010% 1536 | ZES: 0.005% 1537 | ZEL: 0.005% 1538 | ZED: 0.005% 1539 | YWH: 0.005% 1540 | YW: 0.005% 1541 | YST: 0.005% 1542 | YPE: 0.005% 1543 | YP: 0.005% 1544 | YMP: 0.005% 1545 | YME: 0.005% 1546 | YFU: 0.005% 1547 | YF: 0.005% 1548 | YES: 0.005% 1549 | YAN: 0.005% 1550 | YAL: 0.005% 1551 | YAG: 0.005% 1552 | XUR: 0.005% 1553 | XUL: 0.005% 1554 | XPO: 0.005% 1555 | XIR: 0.005% 1556 | XER: 0.005% 1557 | XEC: 0.005% 1558 | WRO: 0.005% 1559 | WRE: 0.005% 1560 | WNS: 0.005% 1561 | WIF: 0.005% 1562 | WFO: 0.005% 1563 | WF: 0.005% 1564 | WED: 0.005% 1565 | WAR: 0.005% 1566 | WAK: 0.005% 1567 | VUL: 0.005% 1568 | VU: 0.005% 1569 | VRE: 0.005% 1570 | VR: 0.005% 1571 | VOY: 0.005% 1572 | VOI: 0.005% 1573 | VIS: 0.005% 1574 | VEX: 0.005% 1575 | VAR: 0.005% 1576 | VAC: 0.005% 1577 | UXU: 0.005% 1578 | UX: 0.005% 1579 | UVR: 0.005% 1580 | UV: 0.005% 1581 | UTM: 0.005% 1582 | UTA: 0.005% 1583 | USU: 0.005% 1584 | USN: 0.005% 1585 | USH: 0.005% 1586 | USA: 0.005% 1587 | URY: 0.005% 1588 | URN: 0.005% 1589 | URF: 0.005% 1590 | URC: 0.005% 1591 | UPT: 0.005% 1592 | UPI: 0.005% 1593 | UOT: 0.005% 1594 | UOM: 0.005% 1595 | UNL: 0.005% 1596 | UNI: 0.005% 1597 | UNF: 0.005% 1598 | UNE: 0.005% 1599 | UME: 0.005% 1600 | ULS: 0.005% 1601 | ULF: 0.005% 1602 | UIE: 0.005% 1603 | UID: 0.005% 1604 | UGG: 0.005% 1605 | UGE: 0.005% 1606 | UFA: 0.005% 1607 | UAT: 0.005% 1608 | UAR: 0.005% 1609 | TYP: 0.005% 1610 | TUP: 0.005% 1611 | TUN: 0.005% 1612 | TUE: 0.005% 1613 | TTO: 0.005% 1614 | TSM: 0.005% 1615 | TSE: 0.005% 1616 | TOP: 0.005% 1617 | TOM: 0.005% 1618 | TOI: 0.005% 1619 | TMO: 0.005% 1620 | TME: 0.005% 1621 | TIR: 0.005% 1622 | TIG: 0.005% 1623 | THD: 0.005% 1624 | TES: 0.005% 1625 | TEO: 0.005% 1626 | TEE: 0.005% 1627 | TCH: 0.005% 1628 | TC: 0.005% 1629 | TAU: 0.005% 1630 | TAG: 0.005% 1631 | TAB: 0.005% 1632 | SYM: 0.005% 1633 | SUN: 0.005% 1634 | SUM: 0.005% 1635 | SUG: 0.005% 1636 | SUA: 0.005% 1637 | STL: 0.005% 1638 | SSO: 0.005% 1639 | SOU: 0.005% 1640 | SOP: 0.005% 1641 | SOC: 0.005% 1642 | SNE: 0.005% 1643 | SN: 0.005% 1644 | SLE: 0.005% 1645 | SLA: 0.005% 1646 | SIV: 0.005% 1647 | SHM: 0.005% 1648 | SGR: 0.005% 1649 | SG: 0.005% 1650 | SEV: 0.005% 1651 | SEU: 0.005% 1652 | SEP: 0.005% 1653 | SEM: 0.005% 1654 | SEA: 0.005% 1655 | SCR: 0.005% 1656 | SAW: 0.005% 1657 | SAP: 0.005% 1658 | SAK: 0.005% 1659 | SAI: 0.005% 1660 | SAD: 0.005% 1661 | SAC: 0.005% 1662 | RYW: 0.005% 1663 | RYS: 0.005% 1664 | RWA: 0.005% 1665 | RVO: 0.005% 1666 | RUR: 0.005% 1667 | RUP: 0.005% 1668 | RUI: 0.005% 1669 | RUG: 0.005% 1670 | RTL: 0.005% 1671 | RRU: 0.005% 1672 | RRA: 0.005% 1673 | RPR: 0.005% 1674 | ROY: 0.005% 1675 | ROT: 0.005% 1676 | ROC: 0.005% 1677 | ROA: 0.005% 1678 | RMS: 0.005% 1679 | RMF: 0.005% 1680 | RLI: 0.005% 1681 | RKS: 0.005% 1682 | RIZ: 0.005% 1683 | RIL: 0.005% 1684 | RIF: 0.005% 1685 | RID: 0.005% 1686 | RGU: 0.005% 1687 | RGI: 0.005% 1688 | RGH: 0.005% 1689 | RGA: 0.005% 1690 | RFO: 0.005% 1691 | RFA: 0.005% 1692 | REU: 0.005% 1693 | RER: 0.005% 1694 | REO: 0.005% 1695 | REI: 0.005% 1696 | RDS: 0.005% 1697 | RDI: 0.005% 1698 | RDA: 0.005% 1699 | RCI: 0.005% 1700 | RCE: 0.005% 1701 | RBE: 0.005% 1702 | RAV: 0.005% 1703 | RAU: 0.005% 1704 | RAR: 0.005% 1705 | RAI: 0.005% 1706 | RAB: 0.005% 1707 | QUO: 0.005% 1708 | PUB: 0.005% 1709 | PTA: 0.005% 1710 | PRU: 0.005% 1711 | PPL: 0.005% 1712 | POR: 0.005% 1713 | POO: 0.005% 1714 | PLO: 0.005% 1715 | PID: 0.005% 1716 | PIA: 0.005% 1717 | PES: 0.005% 1718 | PAN: 0.005% 1719 | PAL: 0.005% 1720 | PAC: 0.005% 1721 | PAB: 0.005% 1722 | OYS: 0.005% 1723 | OYM: 0.005% 1724 | OUE: 0.005% 1725 | OUD: 0.005% 1726 | OUC: 0.005% 1727 | OSO: 0.005% 1728 | ORY: 0.005% 1729 | ORW: 0.005% 1730 | OPU: 0.005% 1731 | OPI: 0.005% 1732 | OPH: 0.005% 1733 | OOS: 0.005% 1734 | OOM: 0.005% 1735 | OOF: 0.005% 1736 | ONO: 0.005% 1737 | OMY: 0.005% 1738 | OMO: 0.005% 1739 | OMI: 0.005% 1740 | OMA: 0.005% 1741 | OLV: 0.005% 1742 | OLT: 0.005% 1743 | OKI: 0.005% 1744 | OIS: 0.005% 1745 | OIL: 0.005% 1746 | OGU: 0.005% 1747 | OGS: 0.005% 1748 | ODW: 0.005% 1749 | OCE: 0.005% 1750 | OBJ: 0.005% 1751 | NVU: 0.005% 1752 | NVI: 0.005% 1753 | NUT: 0.005% 1754 | NUR: 0.005% 1755 | NUF: 0.005% 1756 | NUA: 0.005% 1757 | NTY: 0.005% 1758 | NTM: 0.005% 1759 | NTH: 0.005% 1760 | NTA: 0.005% 1761 | NSU: 0.005% 1762 | NSH: 0.005% 1763 | NRI: 0.005% 1764 | NR: 0.005% 1765 | NOS: 0.005% 1766 | NON: 0.005% 1767 | NOM: 0.005% 1768 | NNI: 0.005% 1769 | NNA: 0.005% 1770 | NME: 0.005% 1771 | NM: 0.005% 1772 | NLE: 0.005% 1773 | NKL: 0.005% 1774 | NKI: 0.005% 1775 | NKF: 0.005% 1776 | NIO: 0.005% 1777 | NIC: 0.005% 1778 | NIA: 0.005% 1779 | NFA: 0.005% 1780 | NET: 0.005% 1781 | NEO: 0.005% 1782 | NEM: 0.005% 1783 | NEL: 0.005% 1784 | NEG: 0.005% 1785 | NCL: 0.005% 1786 | NAY: 0.005% 1787 | NAN: 0.005% 1788 | NAI: 0.005% 1789 | NAC: 0.005% 1790 | MYT: 0.005% 1791 | MUL: 0.005% 1792 | MOT: 0.005% 1793 | MOC: 0.005% 1794 | MNL: 0.005% 1795 | MNE: 0.005% 1796 | MMO: 0.005% 1797 | MMA: 0.005% 1798 | MLE: 0.005% 1799 | ML: 0.005% 1800 | MIM: 0.005% 1801 | MIE: 0.005% 1802 | MIC: 0.005% 1803 | MFU: 0.005% 1804 | MF: 0.005% 1805 | MBI: 0.005% 1806 | LYI: 0.005% 1807 | LUX: 0.005% 1808 | LUN: 0.005% 1809 | LTY: 0.005% 1810 | LTL: 0.005% 1811 | LTI: 0.005% 1812 | LSI: 0.005% 1813 | LSH: 0.005% 1814 | LSA: 0.005% 1815 | LRY: 0.005% 1816 | LR: 0.005% 1817 | LPE: 0.005% 1818 | LOY: 0.005% 1819 | LOW: 0.005% 1820 | LOP: 0.005% 1821 | LOF: 0.005% 1822 | LOB: 0.005% 1823 | LLO: 0.005% 1824 | LKI: 0.005% 1825 | LIX: 0.005% 1826 | LGI: 0.005% 1827 | LGE: 0.005% 1828 | LFU: 0.005% 1829 | LFR: 0.005% 1830 | LEO: 0.005% 1831 | LEG: 0.005% 1832 | LDS: 0.005% 1833 | LDR: 0.005% 1834 | LDO: 0.005% 1835 | LDL: 0.005% 1836 | LDE: 0.005% 1837 | LAY: 0.005% 1838 | LAG: 0.005% 1839 | KLY: 0.005% 1840 | KL: 0.005% 1841 | KFU: 0.005% 1842 | KF: 0.005% 1843 | KET: 0.005% 1844 | KES: 0.005% 1845 | JUT: 0.005% 1846 | IXI: 0.005% 1847 | IVO: 0.005% 1848 | ITU: 0.005% 1849 | ITO: 0.005% 1850 | ITN: 0.005% 1851 | ISS: 0.005% 1852 | ISG: 0.005% 1853 | IRO: 0.005% 1854 | IRI: 0.005% 1855 | IOT: 0.005% 1856 | INV: 0.005% 1857 | INU: 0.005% 1858 | INO: 0.005% 1859 | INM: 0.005% 1860 | INL: 0.005% 1861 | IMN: 0.005% 1862 | IMB: 0.005% 1863 | ILV: 0.005% 1864 | ILO: 0.005% 1865 | ILM: 0.005% 1866 | ILF: 0.005% 1867 | ILA: 0.005% 1868 | IGU: 0.005% 1869 | IFU: 0.005% 1870 | IEV: 0.005% 1871 | ICR: 0.005% 1872 | IAP: 0.005% 1873 | IAG: 0.005% 1874 | HTL: 0.005% 1875 | HSO: 0.005% 1876 | HON: 0.005% 1877 | HOI: 0.005% 1878 | HME: 0.005% 1879 | HM: 0.005% 1880 | HLY: 0.005% 1881 | HL: 0.005% 1882 | HIR: 0.005% 1883 | HIO: 0.005% 1884 | HIG: 0.005% 1885 | HDR: 0.005% 1886 | HD: 0.005% 1887 | HAZ: 0.005% 1888 | GUM: 0.005% 1889 | GUI: 0.005% 1890 | GTO: 0.005% 1891 | GOT: 0.005% 1892 | GNS: 0.005% 1893 | GNE: 0.005% 1894 | GNA: 0.005% 1895 | GLY: 0.005% 1896 | GIR: 0.005% 1897 | GIM: 0.005% 1898 | GIF: 0.005% 1899 | GIE: 0.005% 1900 | GIC: 0.005% 1901 | GHA: 0.005% 1902 | GGE: 0.005% 1903 | GG: 0.005% 1904 | GAV: 0.005% 1905 | GAR: 0.005% 1906 | GAN: 0.005% 1907 | GAM: 0.005% 1908 | GAL: 0.005% 1909 | GAI: 0.005% 1910 | GAB: 0.005% 1911 | FUS: 0.005% 1912 | FUN: 0.005% 1913 | FS: 0.005% 1914 | FRY: 0.005% 1915 | FRU: 0.005% 1916 | FOO: 0.005% 1917 | FLY: 0.005% 1918 | FLI: 0.005% 1919 | FLE: 0.005% 1920 | FLA: 0.005% 1921 | FIT: 0.005% 1922 | FIF: 0.005% 1923 | FFS: 0.005% 1924 | FFA: 0.005% 1925 | FEW: 0.005% 1926 | FES: 0.005% 1927 | FEI: 0.005% 1928 | FAN: 0.005% 1929 | FAI: 0.005% 1930 | EYI: 0.005% 1931 | EYE: 0.005% 1932 | EXU: 0.005% 1933 | EWO: 0.005% 1934 | EWF: 0.005% 1935 | EUR: 0.005% 1936 | EUM: 0.005% 1937 | ETY: 0.005% 1938 | ETU: 0.005% 1939 | ETO: 0.005% 1940 | ETN: 0.005% 1941 | ETC: 0.005% 1942 | ERL: 0.005% 1943 | EPU: 0.005% 1944 | EPL: 0.005% 1945 | EPA: 0.005% 1946 | EOU: 0.005% 1947 | EOR: 0.005% 1948 | EON: 0.005% 1949 | EOF: 0.005% 1950 | ENR: 0.005% 1951 | EMU: 0.005% 1952 | EMN: 0.005% 1953 | EMM: 0.005% 1954 | ELO: 0.005% 1955 | ELE: 0.005% 1956 | ELD: 0.005% 1957 | EKS: 0.005% 1958 | EGL: 0.005% 1959 | EGE: 0.005% 1960 | EGA: 0.005% 1961 | EFE: 0.005% 1962 | EEC: 0.005% 1963 | EDS: 0.005% 1964 | ECA: 0.005% 1965 | EAM: 0.005% 1966 | DWO: 0.005% 1967 | DWE: 0.005% 1968 | DUT: 0.005% 1969 | DUO: 0.005% 1970 | DUL: 0.005% 1971 | DUA: 0.005% 1972 | DSC: 0.005% 1973 | DOX: 0.005% 1974 | DOR: 0.005% 1975 | DOO: 0.005% 1976 | DOL: 0.005% 1977 | DOC: 0.005% 1978 | DLA: 0.005% 1979 | DIV: 0.005% 1980 | DIM: 0.005% 1981 | DIE: 0.005% 1982 | DHE: 0.005% 1983 | DEV: 0.005% 1984 | DEU: 0.005% 1985 | DEQ: 0.005% 1986 | DEF: 0.005% 1987 | DEC: 0.005% 1988 | DDI: 0.005% 1989 | DAR: 0.005% 1990 | DAN: 0.005% 1991 | DAB: 0.005% 1992 | CUS: 0.005% 1993 | CTO: 0.005% 1994 | CTN: 0.005% 1995 | CRO: 0.005% 1996 | CRI: 0.005% 1997 | CQU: 0.005% 1998 | CQ: 0.005% 1999 | COT: 0.005% 2000 | COS: 0.005% 2001 | COP: 0.005% 2002 | COL: 0.005% 2003 | CLO: 0.005% 2004 | CKN: 0.005% 2005 | CKE: 0.005% 2006 | CIS: 0.005% 2007 | CHU: 0.005% 2008 | CHL: 0.005% 2009 | CEM: 0.005% 2010 | CAV: 0.005% 2011 | BUR: 0.005% 2012 | BUL: 0.005% 2013 | BTL: 0.005% 2014 | BRU: 0.005% 2015 | BRE: 0.005% 2016 | BRA: 0.005% 2017 | BOX: 0.005% 2018 | BOO: 0.005% 2019 | BOL: 0.005% 2020 | BOI: 0.005% 2021 | BOA: 0.005% 2022 | BLU: 0.005% 2023 | BLI: 0.005% 2024 | BIL: 0.005% 2025 | BEV: 0.005% 2026 | BBE: 0.005% 2027 | BB: 0.005% 2028 | BAS: 0.005% 2029 | BAC: 0.005% 2030 | AZE: 0.005% 2031 | AZ: 0.005% 2032 | AYI: 0.005% 2033 | AYF: 0.005% 2034 | AYE: 0.005% 2035 | AVI: 0.005% 2036 | AVA: 0.005% 2037 | ATS: 0.005% 2038 | ATN: 0.005% 2039 | ATL: 0.005% 2040 | ASP: 0.005% 2041 | ASI: 0.005% 2042 | ASC: 0.005% 2043 | ARO: 0.005% 2044 | APO: 0.005% 2045 | APL: 0.005% 2046 | ANU: 0.005% 2047 | ANO: 0.005% 2048 | ANA: 0.005% 2049 | AML: 0.005% 2050 | ALY: 0.005% 2051 | ALR: 0.005% 2052 | AIS: 0.005% 2053 | AIL: 0.005% 2054 | AGO: 0.005% 2055 | AGA: 0.005% 2056 | ADU: 0.005% 2057 | ADH: 0.005% 2058 | ADD: 0.005% 2059 | ACY: 0.005% 2060 | ACQ: 0.005% 2061 | ABB: 0.005% 2062 | ABA: 0.005% 2063 | -------------------------------------------------------------------------------- /project2/README.md: -------------------------------------------------------------------------------- 1 | Project 2 2 | ========= 3 | 4 | A simulated TMTO-attack of car-key authentication system using Rainbow-tables. 5 | 6 | 7 | ## Content 8 | 9 | * `TableGenerator.py` - Script generating Rainbow-tables with given 10 | parameters and hardcoded `u` 11 | * `RainbowAttack.py` - Script using the Rainbow-table to crack 12 | hardcoded `u` 13 | * `table.csv` - Rainbowtable generated from TableGenerator.py 14 | * `test.py` - Used to test the Rainbowtable as we had lots of problems with the generating the table. 15 | 16 | *NOTE:* As we have discussed, our rainbowtable attack is not fully functional. We don't know why and what we are doing wrong, but the success rate is extremely low. We have testet our tables, and they are infact correct. Our only guess right now, is the computation of the respone r's successors is wrong or we have misunderstood how to do it. 17 | 18 | ## Attack idea 19 | 20 | Our attacker is a person who tries to steal the car. He proceeds as follows: 21 | 22 | * He picks an arbitrary, fixed challenge u and precomputes a Rainbow Table for the function f(s) = lowest 28 bit of MD5(s||u). 23 | * When he gets access to a car key for a short time, he presses the button on the key fob. Then he acts on behalf of the car by sending a challenge u and receiving the response r. 24 | * He now uses his Rainbow Table to find a value s with f(s) = r. 25 | * He verifies this secret by sending some trial challenges to the key fob and checking whether he can compute the right response. If he can, then he has found the correct secret, meaning that he now can open the car at will. 26 | 27 | ## Rainbowtable attacks described 28 | 29 | Rainbowtables are a time memory tradeoff attack, wich makes it possible to crack hashed passwords. Rainbowtables computes a table of m rows and t chains, only storing the random selected starting point and the computed end point. Each computation in the chain applies a reduction function on the hashed values. 30 | 31 | The reduction functions of a rainbow table are all different (one per column), but are generally built as an extension of a single reduction function. 32 | 33 | In our example we use the reduction function f(s) = (s + 1) % BITSIZE. 34 | 35 | ## Usage 36 | 37 | `TableGenerator.py` creates a Rainbow-table with a hardcoded `u` and 38 | parameters. The resulting table is printed to a cvs called `table.cvs`. It 39 | is run with, simply: 40 | 41 | $ python TableGenerator.py 42 | 43 | The generated table should now contain 2^18 rows and with the chains included around 2^28 covered points(this will be lower, cause of collisions). 44 | 45 | `RainbowAttack.py` uses the previously created Rainbow-table and 46 | hardcoded `u` to search for a matching key `s`. 47 | 48 | $ python RainbowAttack.py 49 | 50 | RainbowAttack computes all the successor of a response r (computed from the given equations), and checks if any of these successors is in the loaded table. If a successor is equal to an endpoint, this row will be used to compute the password. The startpoint of the table is used to compute the chain of reduction functions. If one of these functions matches r, the value before should be the password. This is not 100% certain, as the could be in the table without the key being there. 51 | 52 | ## Logic 53 | 54 | With a generator table, the `RainbowAttack.py` script the following: 55 | 56 | 1. The key broadcasts to car (in this case the **adversary**) 57 | 2. The car/eve responds with a challenge `u`. 58 | 3. The key then responds with a hash consisting of `MD5(s||u)`. 59 | 4. Eve now uses the Rainbow-table to crack `s`. 60 | 61 | Once this is done Eve can open the car at will. 62 | 63 | 64 | ## Further Help 65 | 66 | For further help or explanation please contact one of us by mail and 67 | we'll be happy to help: 68 | 69 | * Markus Faerevaag [s123692@student.dtu.dk](mailto:s123692@student.dtu.dk) 70 | * Christian Mathias Rohde Kiaer [s123812@student.dtu.dk](mailto:s123812@student.dtu.dk) 71 | * Jonathan Becktor [s123094@student.dtu.dk](mailto:s123094@student.dtu.dk) 72 | -------------------------------------------------------------------------------- /project2/RainbowAttack.py: -------------------------------------------------------------------------------- 1 | # 2 | # Project 2 3 | # 4 | # 01435 Practiacal Cryptanalysis 5 | # Technical University of Denmark 6 | 7 | # Markus Faerevaag (s123692@student.dtu.dk) 8 | # Christian Mathias Rohde Kiaer (s123812@student.dtu.dk) 9 | # Jonathan Becktor (s123094@student.dtu.dk) 10 | # 11 | 12 | from termcolor import colored 13 | import md5, random, csv, os 14 | 15 | BIT_SIZE = 28 16 | CHAIN_LEN = 2**10 17 | TABLE_NAME = "table.csv" 18 | SERIAL_NO = "0123456" 19 | 20 | #s ='0x46d2260' 21 | s ='0x8b392c4' 22 | #s ='0x31e6ee3' 23 | #s ='0x56259ab' 24 | #s = hex(random.randint(16777216, 268435455)) 25 | 26 | u = "daffeda" 27 | 28 | def reduction(cipher, iteration = 0): 29 | """Lowest 28 bits of (MD5(s||u) % i). 30 | Reduction function from the rainbow tables. 31 | Returns the hex value""" 32 | return hex((int(cipher, 16) + iteration) % 2**BIT_SIZE)[-BIT_SIZE/4 - 3: -1] 33 | 34 | def md5_hash(s): 35 | """Hashes the original string and returns a hex string""" 36 | return '0x' + md5.new(str(s) + str(u)).hexdigest()[:-1] 37 | 38 | #def f(s, i=0): 39 | # """Lowest 28 bits of (MD5(s||u) % i)""" 40 | # digest = '0x' + md5.new(str(s) + str(u)).hexdigest() 41 | # result = hex((int(digest, 16) + i) % 2**BIT_SIZE)[:BIT_SIZE/4+2] 42 | # return result 43 | 44 | 45 | def read_table(): 46 | """Read Rainbow Table from csv file""" 47 | dict = {} 48 | with open(TABLE_NAME, 'rb') as csvfile: 49 | table = csv.reader(csvfile, delimiter=',', quotechar='|') 50 | for row in table: 51 | dict[str(row[0])] = str(row[1]) 52 | return dict 53 | 54 | 55 | def find_key(table, r): 56 | """Search for matching respons in Rainbow-table 57 | First generates the successors of r. 58 | Then checks through the loaded rainbowtable if any matching values between the successors and the rainbowtable are found. 59 | If a match is found, the starting point of the given match is used to compute the predecessor of r. 60 | The predecessor of r, should be the key we are looking for.""" 61 | #Initialize the list of successors of r. 62 | succ = [r] 63 | #Fills the list of successors of r. 64 | for i in xrange(1, CHAIN_LEN): 65 | succ.append(reduction(md5_hash(succ[i - 1]), i)) 66 | 67 | #Looks through the dictonary given in the input. 68 | for key, value in table.iteritems(): 69 | #If a value is in the successor list, ss = key. 70 | if value in succ: 71 | print "\tCollition: %s -> %s" % (key, value) 72 | ss = key 73 | #Starts with ss and computes the predecessor of r. 74 | for i in xrange(0, CHAIN_LEN): 75 | rs = reduction(md5_hash(ss), i) 76 | #if rs is equal to r, then the key should've been found. 77 | if rs==r: 78 | #returns the predecessor. 79 | return ss 80 | ss = rs 81 | return -1 82 | 83 | 84 | def main(): 85 | """main method for Rainbow attack on a car.""" 86 | os.system('clear') 87 | #Printouts for console. 88 | print " Fob > Hello, key fob no. %s is here!" % SERIAL_NO 89 | 90 | print " Eve > Challenge: 0x%s" % u 91 | #Generates r 92 | r = reduction(md5_hash(s)) 93 | print " Fob > Response: %s" % r 94 | #loads the table from the csv file. 95 | table = read_table() 96 | print " Eve > Cracking..." 97 | 98 | #Tries to find the key 99 | key = find_key(table, r) 100 | 101 | if key is -1: 102 | print " Eve > %s" % colored('No key found!', 'red') 103 | else: 104 | print " Eve > %s: %s" % (colored('Key found', 'green'), key) 105 | 106 | print "\tActual key: %s" % s 107 | 108 | 109 | 110 | if __name__ == '__main__': 111 | main() 112 | -------------------------------------------------------------------------------- /project2/TableGenerator.py: -------------------------------------------------------------------------------- 1 | # 2 | # Project 2 3 | # 4 | # 01435 Practiacal Cryptanalysis 5 | # Technical University of Denmark 6 | 7 | # Markus Faerevaag (s123692@student.dtu.dk) 8 | # Christian Mathias Rohde Kiaer (s123812@student.dtu.dk) 9 | # Jonathan Becktor (s123094@student.dtu.dk) 10 | # 11 | 12 | import md5, random, csv, time 13 | 14 | #Constants used to create the table. 15 | BIT_SIZE = 28 16 | NUM_CHAINS = 2**18 17 | CHAIN_LEN = 2**10 18 | TABLE_NAME = "tabletest.csv" 19 | LOG_FREQ = 5000 20 | #Challenge key u 21 | u = "daffeda" 22 | 23 | def reduction(cipher, iteration): 24 | """Lowest 28 bits of (MD5(s||u) % i)""" 25 | return hex((int(cipher, 16) + iteration) % 2**BIT_SIZE)[-BIT_SIZE/4 - 3: -1] 26 | 27 | def md5_hash(s): 28 | """Hashes the original string and returns a hex string""" 29 | return '0x' + md5.new(str(s) + str(u)).hexdigest()[:-1] 30 | 31 | def generate_table(): 32 | """Generates a rainbow table. 33 | Fills a hashtable with random generated start points and their corresponding endpoints. 34 | Runs through the given number of chains and length of each chain. Ends of with writing the dictonary to a .csv file.""" 35 | dict = {} 36 | 37 | #Runs the loop through the number of chains 38 | for i in xrange(0, NUM_CHAINS): 39 | red = hex(random.randint(16777216, 268435455)) 40 | 41 | #Random generated startpoint. 42 | red_start_point = red 43 | 44 | #Computes the end point, by hashing the start point through the number of chains. 45 | for x in xrange(0, CHAIN_LEN): 46 | cipher = md5_hash(red) 47 | red = reduction(cipher, x) 48 | 49 | #Endpoint for storage in table. 50 | red_end_point = red 51 | 52 | #Prints ammount of times loop has run. 53 | if i % LOG_FREQ == 0: 54 | print "Took i calls: %d" % (i) 55 | dict[red_start_point] = red_end_point 56 | 57 | write_to_csv(dict) 58 | 59 | 60 | def write_to_csv(dict): 61 | """Writes the rainbow table to a .csv file""" 62 | w = csv.writer(open(TABLE_NAME, 'w')) 63 | for key, value in dict.items(): 64 | w.writerow([key, value]) 65 | 66 | 67 | def main(): 68 | """Tool for generating a rainbowtable from given constants.""" 69 | start = time.clock() 70 | generate_table() 71 | end = time.clock() 72 | print "Took: ", (end - start), " s" 73 | 74 | if __name__ == '__main__': 75 | main() 76 | 77 | -------------------------------------------------------------------------------- /project2/test.py: -------------------------------------------------------------------------------- 1 | import os, md5, random, csv 2 | 3 | u = "daffeda" 4 | BIT_SIZE = 28 5 | CHAIN_LEN = 2**10 6 | TABLE_NAME = "table.csv" 7 | SERIAL_NO = "0123456" 8 | 9 | def reduction(cipher, iteration = 0): 10 | """Lowest 28 bits of (MD5(s||u) % i)""" 11 | return hex((int(cipher, 16) + iteration) % 2**BIT_SIZE)[-BIT_SIZE/4 - 3: -1] 12 | 13 | def md5_hash(s): 14 | """Hashes the original string and returns a hex string""" 15 | return '0x' + md5.new(str(s) + str(u)).hexdigest()[:-1] 16 | 17 | def a(s, i=0): 18 | """Lowest 28 bits of (MD5(s||u) % i)""" 19 | digest = md5.new(str(s) + str(u)).hexdigest()[-BIT_SIZE/4:] 20 | result = (int(digest, 16) + i) % 2**BIT_SIZE 21 | return result 22 | 23 | s ="0x8e01844" 24 | temp = s 25 | lol = [reduction(md5_hash(s))] 26 | print lol[0] 27 | for x in xrange(0, CHAIN_LEN): 28 | print x, 29 | hej = reduction(md5_hash(temp), x) 30 | temp = hej 31 | lol.append(hej) 32 | print hej 33 | print len(lol) 34 | -------------------------------------------------------------------------------- /project3/README.md: -------------------------------------------------------------------------------- 1 | Project 3 2 | ========= 3 | 4 | A Python script for cracking known ciphertexts with a known 5 | encryption algorithm. 6 | 7 | 8 | ## Content 9 | 10 | * `Breaker.py` - The script used for the "breaking" of the ciphertext 11 | * `ciphertext.txt` - The file containing the ciphertext 12 | * `plaintext.txt` - The produced plaintext from the ciphertext 13 | 14 | ## The idea behind the attack 15 | 16 | The bruteforce attack on the key generated by the GCC generator is possible, because of the timespamp the generator leaves on the generated key. It makes it possible to narrow down the interval needed to be checked by a bruteforce search, and makes it possible to break even large keys. 17 | 18 | ## Usage 19 | 20 | To decipher the ciphertext, run the `Breaker.py` script with an input 21 | file, containing the ciphertext: 22 | 23 | $ python Breaker.py ciphertext_sheet3.txt 24 | This requiers the ciphertext file to be in the same directory as the script. 25 | This will produce a file called plaintext.txt, if it is successful. 26 | 27 | ## Functionality 28 | 29 | The script has a couple of functions that will be described: 30 | 31 | 1. `calc_time(date, date_format)` This simply finds the seconds from 1.1.1970 to the given date. 32 | 2. `update(s)` This function is the update function given in the assignment for each new key initialization 33 | 3. `load_cipher(inputfile)` takes an inputfile and puts every character in a list and returns it 34 | 4. `encrypt(c, key, i)` takes 3 variables a caracter form the caracter list the a key and i which is from the start point to end point of time when the file could have been encrypted. 35 | 5. `check_plain(plain)` this function checks if our decrypted text is equal to any of our plaintexts. 36 | 37 | The main function of the script is the bruteforce search 38 | 39 | key = init_key(i) 40 | 41 | ciphertext = load_cipher() 42 | 43 | plain = '' 44 | for j in xrange(0, len(ciphertext)-1): 45 | c = chr(encrypt(ciphertext[j], key, j)) 46 | plain += c 47 | 48 | #Checks if any of the guessed plaintext words is in the decrypted text. Breaks if found. 49 | if check_plain(plain): 50 | print "Found plaintext after %i tries!" % (i - start) 51 | print "Key: ", 52 | for k in key: 53 | print chr(int(k, 2)), 54 | print "\n-----------------------------------------------------\n" 55 | print plain 56 | f = open(PLAINFILE, 'w') 57 | f.write(plain) 58 | f.close() 59 | break 60 | 61 | The search runs through the interval of the start and end date, and updates the keys internal state on every iteration. If a plaintext match is found, the search stops. 62 | 63 | 64 | ## Logic 65 | 66 | The script essentially runs a **smart brute-force** attack: 67 | 68 | 1. We first calculate the relevant time interval within the cipher was 69 | created. 70 | 2. Ciphertext loaded from file 71 | 3. Start brute-force search for every possible time 72 | 1. Initialize key with current time / internal state 73 | 2. Encrypt every character in ciphertext with current state 74 | 3. Check if result contains any of the words in the array of 75 | possible known plaintext elements. 76 | 4. If found, print key and write to file 77 | 78 | 79 | ## Further Help 80 | 81 | For further help or explanation please contact one of us by mail and 82 | we'll be happy to help: 83 | 84 | * Markus Faerevaag [s123692@student.dtu.dk](mailto:s123692@student.dtu.dk) 85 | * Christian Mathias Rohde Kiaer [s123812@student.dtu.dk](mailto:s123812@student.dtu.dk) 86 | * Jonathan Becktor [s123094@student.dtu.dk](mailto:s123094@student.dtu.dk) 87 | -------------------------------------------------------------------------------- /project3/breaker.py: -------------------------------------------------------------------------------- 1 | # 2 | # Project 3 3 | # 4 | # 01435 Practiacal Cryptanalysis 5 | # Technical University of Denmark 6 | 7 | # Markus Faerevaag (s123692@student.dtu.dk) 8 | # Christian Mathias Rohde Kiaer (s123812@student.dtu.dk) 9 | # Jonathan Becktor (s123094@student.dtu.dk) 10 | # 11 | 12 | import time 13 | 14 | #Constants used across the breaker. 15 | START_DATE = '2009-06-22 00:00:00' 16 | END_DATE = '2009-06-28 23:59:59' 17 | 18 | CIPHERFILE = "ciphertext_sheet3.txt" 19 | PLAINFILE = 'plaintext.txt' 20 | KNOWN_PLAINTEXT = ['Snowden', 21 | 'Obama', 22 | 'Biden', 23 | 'Risen', 24 | 'Nelson', 25 | 'NSA', 'National Security Agency', 26 | 'China', 27 | 'Whistleblower', 28 | 'Hong Kong'] 29 | 30 | # Given constants 31 | a = 69069 32 | c = 5 33 | m = 2**32 34 | 35 | 36 | def update(s): 37 | """Update internal state""" 38 | return (a * s + c) % m 39 | 40 | 41 | def init_key(s): 42 | """Init key with internal state. 43 | Internal state is given from the time the key is generated from.""" 44 | key = [] 45 | for i in xrange(0, 16): 46 | s = update(s) 47 | key.append(str(bin(s)[-8:])) 48 | 49 | return key 50 | 51 | 52 | def load_cipher(): 53 | """Load ciphertext from file""" 54 | f = open(CIPHERFILE, 'r') 55 | ciphertext = [] 56 | for line in f: 57 | for c in line: 58 | ciphertext.append(c) 59 | 60 | f.close() 61 | return ciphertext 62 | 63 | 64 | def encrypt(c, key, i): 65 | """Encrypt character with i in key""" 66 | return ord(c) ^ int(key[i % 16], 2) 67 | 68 | 69 | def check_plain(plain): 70 | """Check if text contains any of known plaintexts. 71 | Checks for everyword in the known plaintext. 72 | If theres a match, returns true.""" 73 | for word in KNOWN_PLAINTEXT: 74 | if word in plain: 75 | return True 76 | 77 | return False 78 | 79 | 80 | def main(): 81 | """Tool for breaking a random key generated by the GCC generator given a specified date interval. 82 | Initializes the date interval the key was generated in. 83 | Bruteforce attacks the dates, by applying keys corresponding to the time.""" 84 | # Calculcate time interval 85 | date_format = '%Y-%m-%d %H:%M:%S' 86 | start = int(time.mktime(time.strptime(START_DATE, date_format))) - time.timezone 87 | end = int(time.mktime(time.strptime(END_DATE, date_format))) - time.timezone 88 | 89 | # Start bruteforce search 90 | for i in xrange(start, end): 91 | key = init_key(i) 92 | 93 | ciphertext = load_cipher() 94 | 95 | plain = '' 96 | for j in xrange(0, len(ciphertext)-1): 97 | c = chr(encrypt(ciphertext[j], key, j)) 98 | plain += c 99 | 100 | #Checks if any of the guessed plaintext words is in the decrypted text. Breaks if found. 101 | if check_plain(plain): 102 | print "Found plaintext after %i tries!" % (i - start) 103 | print "Key: ", 104 | for k in key: 105 | print chr(int(k, 2)), 106 | print "\n-----------------------------------------------------\n" 107 | 108 | print plain 109 | f = open(PLAINFILE, 'w') 110 | f.write(plain) 111 | f.close() 112 | 113 | break 114 | 115 | 116 | if __name__ == '__main__': 117 | main() 118 | -------------------------------------------------------------------------------- /project3/ciphertext_sheet3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfaerevaag/cryptanalysis/c44a14c812c8e99e2ffdf9e0c413f7c5592eccb9/project3/ciphertext_sheet3.txt -------------------------------------------------------------------------------- /project3/plaintext.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfaerevaag/cryptanalysis/c44a14c812c8e99e2ffdf9e0c413f7c5592eccb9/project3/plaintext.txt -------------------------------------------------------------------------------- /worksheet1/CBCSubCipher/CBCSubCipher.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A9EF4F4B1769B86F0058DBF3 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = A9EF4F4A1769B86F0058DBF3 /* main.c */; }; 11 | A9EF4F4D1769B86F0058DBF3 /* CBCSubCipher.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = A9EF4F4C1769B86F0058DBF3 /* CBCSubCipher.1 */; }; 12 | /* End PBXBuildFile section */ 13 | 14 | /* Begin PBXCopyFilesBuildPhase section */ 15 | A9EF4F451769B86F0058DBF3 /* CopyFiles */ = { 16 | isa = PBXCopyFilesBuildPhase; 17 | buildActionMask = 2147483647; 18 | dstPath = /usr/share/man/man1/; 19 | dstSubfolderSpec = 0; 20 | files = ( 21 | A9EF4F4D1769B86F0058DBF3 /* CBCSubCipher.1 in CopyFiles */, 22 | ); 23 | runOnlyForDeploymentPostprocessing = 1; 24 | }; 25 | /* End PBXCopyFilesBuildPhase section */ 26 | 27 | /* Begin PBXFileReference section */ 28 | A9EF4F471769B86F0058DBF3 /* CBCSubCipher */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = CBCSubCipher; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | A9EF4F4A1769B86F0058DBF3 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; 30 | A9EF4F4C1769B86F0058DBF3 /* CBCSubCipher.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = CBCSubCipher.1; sourceTree = ""; }; 31 | /* End PBXFileReference section */ 32 | 33 | /* Begin PBXFrameworksBuildPhase section */ 34 | A9EF4F441769B86F0058DBF3 /* Frameworks */ = { 35 | isa = PBXFrameworksBuildPhase; 36 | buildActionMask = 2147483647; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXFrameworksBuildPhase section */ 42 | 43 | /* Begin PBXGroup section */ 44 | A9EF4F3E1769B86F0058DBF3 = { 45 | isa = PBXGroup; 46 | children = ( 47 | A9EF4F491769B86F0058DBF3 /* CBCSubCipher */, 48 | A9EF4F481769B86F0058DBF3 /* Products */, 49 | ); 50 | sourceTree = ""; 51 | }; 52 | A9EF4F481769B86F0058DBF3 /* Products */ = { 53 | isa = PBXGroup; 54 | children = ( 55 | A9EF4F471769B86F0058DBF3 /* CBCSubCipher */, 56 | ); 57 | name = Products; 58 | sourceTree = ""; 59 | }; 60 | A9EF4F491769B86F0058DBF3 /* CBCSubCipher */ = { 61 | isa = PBXGroup; 62 | children = ( 63 | A9EF4F4A1769B86F0058DBF3 /* main.c */, 64 | A9EF4F4C1769B86F0058DBF3 /* CBCSubCipher.1 */, 65 | ); 66 | path = CBCSubCipher; 67 | sourceTree = ""; 68 | }; 69 | /* End PBXGroup section */ 70 | 71 | /* Begin PBXNativeTarget section */ 72 | A9EF4F461769B86F0058DBF3 /* CBCSubCipher */ = { 73 | isa = PBXNativeTarget; 74 | buildConfigurationList = A9EF4F501769B86F0058DBF3 /* Build configuration list for PBXNativeTarget "CBCSubCipher" */; 75 | buildPhases = ( 76 | A9EF4F431769B86F0058DBF3 /* Sources */, 77 | A9EF4F441769B86F0058DBF3 /* Frameworks */, 78 | A9EF4F451769B86F0058DBF3 /* CopyFiles */, 79 | ); 80 | buildRules = ( 81 | ); 82 | dependencies = ( 83 | ); 84 | name = CBCSubCipher; 85 | productName = CBCSubCipher; 86 | productReference = A9EF4F471769B86F0058DBF3 /* CBCSubCipher */; 87 | productType = "com.apple.product-type.tool"; 88 | }; 89 | /* End PBXNativeTarget section */ 90 | 91 | /* Begin PBXProject section */ 92 | A9EF4F3F1769B86F0058DBF3 /* Project object */ = { 93 | isa = PBXProject; 94 | attributes = { 95 | LastUpgradeCheck = 0460; 96 | ORGANIZATIONNAME = "Christian Kiær"; 97 | }; 98 | buildConfigurationList = A9EF4F421769B86F0058DBF3 /* Build configuration list for PBXProject "CBCSubCipher" */; 99 | compatibilityVersion = "Xcode 3.2"; 100 | developmentRegion = English; 101 | hasScannedForEncodings = 0; 102 | knownRegions = ( 103 | en, 104 | ); 105 | mainGroup = A9EF4F3E1769B86F0058DBF3; 106 | productRefGroup = A9EF4F481769B86F0058DBF3 /* Products */; 107 | projectDirPath = ""; 108 | projectRoot = ""; 109 | targets = ( 110 | A9EF4F461769B86F0058DBF3 /* CBCSubCipher */, 111 | ); 112 | }; 113 | /* End PBXProject section */ 114 | 115 | /* Begin PBXSourcesBuildPhase section */ 116 | A9EF4F431769B86F0058DBF3 /* Sources */ = { 117 | isa = PBXSourcesBuildPhase; 118 | buildActionMask = 2147483647; 119 | files = ( 120 | A9EF4F4B1769B86F0058DBF3 /* main.c in Sources */, 121 | ); 122 | runOnlyForDeploymentPostprocessing = 0; 123 | }; 124 | /* End PBXSourcesBuildPhase section */ 125 | 126 | /* Begin XCBuildConfiguration section */ 127 | A9EF4F4E1769B86F0058DBF3 /* Debug */ = { 128 | isa = XCBuildConfiguration; 129 | buildSettings = { 130 | ALWAYS_SEARCH_USER_PATHS = NO; 131 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 132 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 133 | CLANG_CXX_LIBRARY = "libc++"; 134 | CLANG_ENABLE_OBJC_ARC = YES; 135 | CLANG_WARN_CONSTANT_CONVERSION = YES; 136 | CLANG_WARN_EMPTY_BODY = YES; 137 | CLANG_WARN_ENUM_CONVERSION = YES; 138 | CLANG_WARN_INT_CONVERSION = YES; 139 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 140 | COPY_PHASE_STRIP = NO; 141 | GCC_C_LANGUAGE_STANDARD = gnu99; 142 | GCC_DYNAMIC_NO_PIC = NO; 143 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 144 | GCC_OPTIMIZATION_LEVEL = 0; 145 | GCC_PREPROCESSOR_DEFINITIONS = ( 146 | "DEBUG=1", 147 | "$(inherited)", 148 | ); 149 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 150 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 151 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 152 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 153 | GCC_WARN_UNUSED_VARIABLE = YES; 154 | MACOSX_DEPLOYMENT_TARGET = 10.8; 155 | ONLY_ACTIVE_ARCH = YES; 156 | SDKROOT = macosx; 157 | }; 158 | name = Debug; 159 | }; 160 | A9EF4F4F1769B86F0058DBF3 /* Release */ = { 161 | isa = XCBuildConfiguration; 162 | buildSettings = { 163 | ALWAYS_SEARCH_USER_PATHS = NO; 164 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 165 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 166 | CLANG_CXX_LIBRARY = "libc++"; 167 | CLANG_ENABLE_OBJC_ARC = YES; 168 | CLANG_WARN_CONSTANT_CONVERSION = YES; 169 | CLANG_WARN_EMPTY_BODY = YES; 170 | CLANG_WARN_ENUM_CONVERSION = YES; 171 | CLANG_WARN_INT_CONVERSION = YES; 172 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 173 | COPY_PHASE_STRIP = YES; 174 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 175 | GCC_C_LANGUAGE_STANDARD = gnu99; 176 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 177 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 178 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 179 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 180 | GCC_WARN_UNUSED_VARIABLE = YES; 181 | MACOSX_DEPLOYMENT_TARGET = 10.8; 182 | SDKROOT = macosx; 183 | }; 184 | name = Release; 185 | }; 186 | A9EF4F511769B86F0058DBF3 /* Debug */ = { 187 | isa = XCBuildConfiguration; 188 | buildSettings = { 189 | PRODUCT_NAME = "$(TARGET_NAME)"; 190 | }; 191 | name = Debug; 192 | }; 193 | A9EF4F521769B86F0058DBF3 /* Release */ = { 194 | isa = XCBuildConfiguration; 195 | buildSettings = { 196 | PRODUCT_NAME = "$(TARGET_NAME)"; 197 | }; 198 | name = Release; 199 | }; 200 | /* End XCBuildConfiguration section */ 201 | 202 | /* Begin XCConfigurationList section */ 203 | A9EF4F421769B86F0058DBF3 /* Build configuration list for PBXProject "CBCSubCipher" */ = { 204 | isa = XCConfigurationList; 205 | buildConfigurations = ( 206 | A9EF4F4E1769B86F0058DBF3 /* Debug */, 207 | A9EF4F4F1769B86F0058DBF3 /* Release */, 208 | ); 209 | defaultConfigurationIsVisible = 0; 210 | defaultConfigurationName = Release; 211 | }; 212 | A9EF4F501769B86F0058DBF3 /* Build configuration list for PBXNativeTarget "CBCSubCipher" */ = { 213 | isa = XCConfigurationList; 214 | buildConfigurations = ( 215 | A9EF4F511769B86F0058DBF3 /* Debug */, 216 | A9EF4F521769B86F0058DBF3 /* Release */, 217 | ); 218 | defaultConfigurationIsVisible = 0; 219 | }; 220 | /* End XCConfigurationList section */ 221 | }; 222 | rootObject = A9EF4F3F1769B86F0058DBF3 /* Project object */; 223 | } 224 | -------------------------------------------------------------------------------- /worksheet1/CBCSubCipher/CBCSubCipher.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /worksheet1/CBCSubCipher/CBCSubCipher/CBCSubCipher.1: -------------------------------------------------------------------------------- 1 | .\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. 2 | .\"See Also: 3 | .\"man mdoc.samples for a complete listing of options 4 | .\"man mdoc for the short list of editing options 5 | .\"/usr/share/misc/mdoc.template 6 | .Dd 13/06/13 \" DATE 7 | .Dt CBCSubCipher 1 \" Program name and manual section number 8 | .Os Darwin 9 | .Sh NAME \" Section Header - required - don't modify 10 | .Nm CBCSubCipher, 11 | .\" The following lines are read in generating the apropos(man -k) database. Use only key 12 | .\" words here as the database is built based on the words here and in the .ND line. 13 | .Nm Other_name_for_same_program(), 14 | .Nm Yet another name for the same program. 15 | .\" Use .Nm macro to designate other names for the documented program. 16 | .Nd This line parsed for whatis database. 17 | .Sh SYNOPSIS \" Section Header - required - don't modify 18 | .Nm 19 | .Op Fl abcd \" [-abcd] 20 | .Op Fl a Ar path \" [-a path] 21 | .Op Ar file \" [file] 22 | .Op Ar \" [file ...] 23 | .Ar arg0 \" Underlined argument - use .Ar anywhere to underline 24 | arg2 ... \" Arguments 25 | .Sh DESCRIPTION \" Section Header - required - don't modify 26 | Use the .Nm macro to refer to your program throughout the man page like such: 27 | .Nm 28 | Underlining is accomplished with the .Ar macro like this: 29 | .Ar underlined text . 30 | .Pp \" Inserts a space 31 | A list of items with descriptions: 32 | .Bl -tag -width -indent \" Begins a tagged list 33 | .It item a \" Each item preceded by .It macro 34 | Description of item a 35 | .It item b 36 | Description of item b 37 | .El \" Ends the list 38 | .Pp 39 | A list of flags and their descriptions: 40 | .Bl -tag -width -indent \" Differs from above in tag removed 41 | .It Fl a \"-a flag as a list item 42 | Description of -a flag 43 | .It Fl b 44 | Description of -b flag 45 | .El \" Ends the list 46 | .Pp 47 | .\" .Sh ENVIRONMENT \" May not be needed 48 | .\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1 49 | .\" .It Ev ENV_VAR_1 50 | .\" Description of ENV_VAR_1 51 | .\" .It Ev ENV_VAR_2 52 | .\" Description of ENV_VAR_2 53 | .\" .El 54 | .Sh FILES \" File used or created by the topic of the man page 55 | .Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact 56 | .It Pa /usr/share/file_name 57 | FILE_1 description 58 | .It Pa /Users/joeuser/Library/really_long_file_name 59 | FILE_2 description 60 | .El \" Ends the list 61 | .\" .Sh DIAGNOSTICS \" May not be needed 62 | .\" .Bl -diag 63 | .\" .It Diagnostic Tag 64 | .\" Diagnostic informtion here. 65 | .\" .It Diagnostic Tag 66 | .\" Diagnostic informtion here. 67 | .\" .El 68 | .Sh SEE ALSO 69 | .\" List links in ascending order by section, alphabetically within a section. 70 | .\" Please do not reference files that do not exist without filing a bug report 71 | .Xr a 1 , 72 | .Xr b 1 , 73 | .Xr c 1 , 74 | .Xr a 2 , 75 | .Xr b 2 , 76 | .Xr a 3 , 77 | .Xr b 3 78 | .\" .Sh BUGS \" Document known, unremedied bugs 79 | .\" .Sh HISTORY \" Document history if command behaves in a unique manner -------------------------------------------------------------------------------- /worksheet1/CBCSubCipher/CBCSubCipher/main.c: -------------------------------------------------------------------------------- 1 | // 2 | // main.c 3 | // CBCSubCipher 4 | // 5 | // Created by Christian Kiær on 13/06/13. 6 | // Copyright (c) 2013 Christian Kiær. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | 12 | int initVector; 13 | int key[] = { 13, 4, 3, 12, 1, 0, 8, 10, 14, 6, 9, 14 | 15, 11, 2, 5, 7 }; 15 | int plaintext[] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 16 | 3, 3, 3, 3, 3, 3 }; 17 | int cipher[16]; 18 | int bitSize = 16; 19 | clock_t begin, end; 20 | double timeSpent; 21 | 22 | void encrypt(int *plainText, int initVector){ 23 | 24 | cipher[0] = key[initVector ^ plainText[0]]; 25 | 26 | for (int i = 1; i < bitSize; i++) { 27 | cipher[i] = key[cipher[i - 1] ^ plainText[i]]; 28 | } 29 | } 30 | 31 | int main(int argc, const char * argv[]) 32 | { 33 | begin = clock(); 34 | for (int i = 0; i < bitSize; i++) { 35 | initVector = i; 36 | 37 | encrypt(plaintext, initVector); 38 | printf("InitVector: %d Cipher: ", initVector); 39 | for (int j = 0; j < bitSize; j++) { 40 | printf("%d ", cipher[j]); 41 | } 42 | printf("\n"); 43 | } 44 | end = clock(); 45 | printf("Elapsed: %f seconds\n", (double)(end - begin) / CLOCKS_PER_SEC); 46 | 47 | } -------------------------------------------------------------------------------- /worksheet1/PythonBruteforce/BruteForce.py: -------------------------------------------------------------------------------- 1 | from itertools import izip, cycle 2 | import time 3 | time1 = time.clock() 4 | cntr = 0; 5 | myKey="AAAAAAAAAAAADDAz" 6 | plaintext="Secretfoemotherd" 7 | def xor(data, key): 8 | return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(data, cycle(key))) 9 | encrypted = xor(plaintext, key=myKey) 10 | lostKey=[65]*16 11 | while True: 12 | original = xor(encrypted, key=''.join(chr(i) for i in lostKey)) 13 | if original == plaintext: 14 | print "Wohoo we found the key again" 15 | print "Plaintext is: "+plaintext+" the bruteforce text is: "+original 16 | print "I ran: %d Times"%cntr 17 | runspeed = time.clock()-time1 18 | print "Time in seconds: %f"%runspeed 19 | break 20 | index = 15; 21 | lostKey[index]=lostKey[index]+1 22 | while index >= 0 and lostKey[index] >= 123: 23 | lostKey[index] = 65 24 | index=index-1 25 | if index < 0: 26 | break 27 | lostKey[index]=lostKey[index]+1 28 | cntr = cntr +1 -------------------------------------------------------------------------------- /worksheet1/woorksheet 1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfaerevaag/cryptanalysis/c44a14c812c8e99e2ffdf9e0c413f7c5592eccb9/worksheet1/woorksheet 1.pdf -------------------------------------------------------------------------------- /worksheet1/woorksheet 1.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,12pt]{article} 2 | \usepackage[utf8]{inputenc} 3 | \usepackage[T1]{fontenc} 4 | \usepackage{setspace} % This package is used to control linespacing; With \onehalfspacing for instance 5 | \usepackage[danish]{babel} 6 | \renewcommand{\danishhyphenmins}{22} % bedre orddeling 7 | \usepackage{bm} 8 | \usepackage{fnbreak} 9 | \usepackage{sectsty} 10 | \usepackage{wrapfig} 11 | \usepackage[scriptsize]{caption} 12 | \usepackage[danish,textsize=tiny,backgroundcolor=red,bordercolor=blue]{todonotes} 13 | \usepackage[isbn,issn]{dk-bib} 14 | \interfootnotelinepenalty=10000 15 | \usepackage{graphicx} 16 | \usepackage{usecases} 17 | \usepackage{pdfpages} 18 | 19 | \addto\captionsdanish{ 20 | \renewcommand\abstractname{Abstract} 21 | } 22 | %----------------------------------------------------- 23 | \newcommand{\doctitle}{Worksheet1} 24 | \newcommand{\docsubject}{01435 Cryptanalysis)} 25 | \newcommand{\docauthor}{Markus Færevaag s123692} 26 | \newcommand{\docdate}{\today} 27 | \newcommand{\docplace}{Danmarks Tekniske Universitet} 28 | \newcommand{\HRule}{\rule{\linewidth}{0.5mm}} 29 | %\newcommand{\docsubtitle}{Undertitle} 30 | %----------------------------------------------------- 31 | 32 | %-----------Scientific and mathematical packages begin----------- 33 | % Math package 34 | \usepackage{amsmath} 35 | 36 | % Vector symbols and functions (for example \vv) 37 | \usepackage{esvect} 38 | 39 | % Mathematical symbols 40 | \usepackage{amssymb} 41 | \DeclareMathOperator{\p}{\cdot} 42 | \DeclareMathOperator{\N}{\mathbb{N}} 43 | \DeclareMathOperator{\Z}{\mathbb{Z}} 44 | \DeclareMathOperator{\C}{\mathbb{C}} 45 | \DeclareMathOperator{\R}{\mathbb{R}} 46 | \newcommand{\nn}{\nonumber} 47 | % SI Units 48 | %\usepackage[output-decimal-marker={,}]{siunitx} %http://mirrors.dotsrc.org/ctan/macros/latex/begincontrib/siunitx/siunitx.pdf 49 | %\sisetup{unitsep= \cdot } 50 | 51 | % For Chemistry 52 | %\usepackage{chemscheme} % http://ctan.org/pkg/chemscheme 53 | %\usepackage{chemsym} % http://ctan.org/pkg/chemsym 54 | %\usepackage{mhchem} % http://mirrors.dotsrc.org/ctan/macros/latex/contrib/chemstyle/chemstyle.pdf 55 | %\DeclareSIUnit\Molar{\textsc{m}} 56 | %-----------Scientific and mathematical packages end-------------- 57 | 58 | % Non-default fonts - has to come _after_ some of the mathematical packages 59 | \usepackage{pxfonts} 60 | 61 | % Page margins 62 | \usepackage[left=2.0cm, right=1.5cm]{geometry} 63 | 64 | % Hyperref 65 | \usepackage[colorlinks=true,linkcolor=black,citecolor=black,urlcolor=black]{hyperref} 66 | %\usepackage[hidelinks]{hyperref} 67 | \hypersetup{pdftitle={\doctitle}} 68 | \hypersetup{pdfsubject={\docsubject}} 69 | \hypersetup{pdfauthor={\docauthor}} 70 | 71 | % Setspace 72 | \usepackage{setspace} 73 | \onehalfspacing 74 | %\numberwithin{equation}{section} 75 | % Alter some LaTeX defaults for better treatment of figures: 76 | % See p.105 of "TeX Unbound" for suggested values. 77 | % See pp. 199-200 of Lamport's "LaTeX" book for details. 78 | % General parameters, for ALL pages: 79 | \renewcommand{\topfraction}{0.9} % max fraction of floats at top 80 | \renewcommand{\bottomfraction}{0.8} % max fraction of floats at bottom 81 | % Parameters for TEXT pages (not float pages): 82 | \setcounter{topnumber}{2} 83 | \setcounter{bottomnumber}{2} 84 | \setcounter{totalnumber}{4} % 2 may work better 85 | \setcounter{dbltopnumber}{2} % for 2-column pages 86 | \renewcommand{\dbltopfraction}{0.9} % fit big float above 2-col. text 87 | \renewcommand{\textfraction}{0.07} % allow minimal text w. figs 88 | % Parameters for FLOAT pages (not text pages): 89 | \renewcommand{\floatpagefraction}{0.7} % require fuller float pages 90 | % N.B.: floatpagefraction MUST be less than topfraction !! 91 | \renewcommand{\dblfloatpagefraction}{0.7} % require fuller float pages 92 | 93 | % remember to use [htp] or [htpb] for placement 94 | 95 | % Title 96 | \title{ 97 | \HRule \\ 98 | \textsc{\doctitle} \\ 99 | \small{\textsl{\docsubtitle}} 100 | \HRule 101 | } 102 | \author{\docauthor\\\small{\docplace}} 103 | \date{\docdate} 104 | 105 | % Fancyheader : http://mirrors.dotsrc.org/ctan/macros/latex/contrib/fancyhdr/fancyhdr.pdf 106 | \usepackage{fancyhdr} 107 | \pagestyle{fancy} 108 | \fancyhf{} 109 | %\fancyhead[RO]{\docauthor \hfill \doctitle \hfill\thepage} 110 | \fancyhead[RO]{\doctitle \hfill \docauthor \hfill \thepage /\ref{TotPages}} 111 | % Get rid of annoying error messages 112 | \setlength{\headheight}{14.5pt} 113 | \usepackage{totpages} 114 | \usepackage{sectsty} 115 | \allsectionsfont{\scshape} 116 | \begin{document} 117 | \section*{Exercise 3} 118 | \subsection*{Chosen-plaintext attack(CPA)} 119 | Enigma was broken using both Chosen-plaintext attacks and known-plaintext attacks. We will describe the usage of Chosen-plaintext attacks. The british used gardening, arranging mine laying missions and letting the germans know on purpose. That way, they knew what the germans would send messages about, and therefore "choosing" the plaintext themselves. (Read about on wikipedia and $http://www.princeton.edu/~achaney/tmve/wiki100k/docs/Chosen-plaintext_attack.html$) 120 | \subsection*{Known-plaintext attack(KPA)} 121 | The A5/1 algorithm was broken using known-plaintext attacks. The breakers only had to know a few seconds of conversation to break the key. Found and read about at $http://en.wikipedia.org/wiki/A5/1$ 122 | \newpage 123 | \section*{Exercise 5} 124 | \begin{verbatim} 125 | import time 126 | 127 | def encrypt(plaintext, key): 128 | cipher = ['0'] * len(plaintext) 129 | for x in xrange(0, len(plaintext)): 130 | cipher[x] = str(ord(plaintext[x]) ^ ord(key[x])) 131 | return cipher 132 | 133 | def bruteforce(plaintext, cip): 134 | cntr = 1 135 | brute_key = ['A'] * len(key) 136 | lostKey=[65]*16 137 | while True: 138 | for x in range(0,len(plaintext)): 139 | brute_key[x]=chr(lostKey[x]) 140 | newCiph = encrypt(plaintext, brute_key) 141 | if newCiph == cip: 142 | print "Plaintext is: "+ ''.join(plaintext)+" the bruteforce text is: "+ ' '.join(newCiph) 143 | print "I ran: %d Times"%cntr 144 | break 145 | index = 15; 146 | lostKey[index]=lostKey[index]+1 147 | while index >= 0 and lostKey[index] >= 123: 148 | lostKey[index] = 65 149 | index=index-1 150 | if index < 0: 151 | break 152 | lostKey[index]=lostKey[index]+1 153 | cntr = cntr +1 154 | 155 | 156 | if __name__ == '__main__': 157 | start = time.clock() 158 | key = ['A','A','A','A','A','A','A','A','A','A','A','A','A','z','A','A'] 159 | plaintext = ['h','e','j','h','e','j','h','e','j','h','e','j','h','e','j','h'] 160 | cip = encrypt(plaintext, key) 161 | bruteforce(plaintext, cip) 162 | stop = time.clock() 163 | print "Took", (stop - start), "sec" 164 | \end{verbatim} 165 | We had a faster implementation in Java, but rewrote it in Python to make it shorter and trying to reach the 1 page limit. I will use our data from Java in the calculations. If you would like to see the Java program instead, let us know.\\ 166 | We only used characters from A-z in our key/plaintext\\ 167 | The program checked around 780000 keys each second. That gives us 2808000000 keys checked each hour. That gives us around $2^{44.5}$ keys checked in a year.\\ 168 | If we have a bot net of 1 million computers, we would be able to check $780000 \cdot 1*10^6 = 2^{39}$ keys each second, $2^{51}$ each hour and $2^{64}$ each year. Given our key is 16 long, with 52 possible characters at each spot, there is around $2^{91}$ possible combinations. That makes it possible to break keys up to 88 bits. Given that we could'nt break our 128 bit key with a million computers in a year, and that is if we have both plaintext and cipher. 169 | \section*{Exercise 6} 170 | The unicity distance is calculated based on a simple substitution cipher, using english letters only. We see captial and lowercase as the same. The unicity distance is calculated by using following equation: 171 | \begin{equation} 172 | |UD| = \frac{log_2(|K|)}{R_L \cdot log_2(|P|)} 173 | \end{equation} 174 | We use the following:\\ 175 | $ |K| = 26!$\\ 176 | $ |P| = 26$\\ 177 | $ R_L = 0.7$\\ 178 | \begin{equation} 179 | UD=\frac{log_2(26!)}{0.7 \cdot log_2(26)}= \frac{88.39}{0.7 \cdot 4.7} = 26.8 180 | \end{equation} 181 | So the average number of ciphertext characters required to eliminate alle spurious keys is around 27. 182 | \section*{Exercise 9} 183 | The $ \chi^2 $ test is performed on the given data. The four pairs of bit should occour an equal ammount of times, if the random number generator is perfect. But as it's a quite small sample size, there will be fluctations. The following data is given: 184 | \begin{align*} 185 | k_1("11") = 228 \quad e_1("11") =250 \quad k_2("10") = 270 \quad e_2("10") =250 \\ \quad k_3("01") = 271 \quad e_3("01") =250 \quad k_4("00") = 231\quad e_4("00") =250 186 | \end{align*} 187 | The following equation is used: 188 | \begin{equation} 189 | \chi^2 = \frac{(o_1 - e_1)^2}{e_1}+\frac{(o_2 - e_2)^2}{e_2}+ \ldots \frac{(o_k - e_k)^2}{e_k} 190 | \end{equation} 191 | \begin{align*} 192 | \chi^2 = \frac{(228 - 250)^2}{250}+\frac{(270 - 250)^2}{250}+\frac{(271 - 250)^2}{250}+\frac{(231 - 250)^2}{250}=6.744 193 | \end{align*} 194 | Since the degree of freedom is 3 in our example, the probability value is: 195 | \begin{equation} 196 | P=\frac{1}{\Gamma \left( \frac{3}{2} \right)}\cdot \Gamma \left( \frac{3}{2}, \frac{6.744}{2} \right) = 0.08 = 8\% 197 | \end{equation} 198 | A P-value of 0.05 or less is regarded as statistically significant. Therefore our example is regarded as non significant. 199 | \newpage 200 | \section*{Exercise 11} 201 | I've made a encryption tool: 202 | \begin{verbatim} 203 | int initVector; 204 | int key[] = { 13, 4, 3, 12, 1, 0, 8, 10, 14, 6, 9, 15, 11, 2, 5, 7 }; 205 | int plaintext[] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }; 206 | int cipher[16]; 207 | int bitSize = 16; 208 | 209 | void encrypt(int *plainText, int initVector){ 210 | 211 | cipher[0] = key[initVector ^ plainText[0]]; 212 | 213 | for (int i = 1; i < bitSize; i++) { 214 | cipher[i] = key[cipher[i - 1] ^ plainText[i]]; 215 | } 216 | } 217 | 218 | int main(int argc, const char * argv[]) 219 | { 220 | 221 | for (int i = 0; i < bitSize; i++) { 222 | initVector = i; 223 | 224 | encrypt(plaintext, initVector); 225 | printf("InitVector: %d Cipher: ", initVector); 226 | for (int j = 0; j < bitSize; j++) { 227 | printf("%d ", cipher[j]); 228 | } 229 | printf("\n"); 230 | } 231 | 232 | } 233 | \end{verbatim} 234 | \newpage 235 | The tool encrypts the plaintext, using every 4-bit initialisation vector. The following console output is given: 236 | \begin{verbatim} 237 | InitVector: 0 Cipher: 12 7 1 3 13 5 8 15 11 14 2 4 10 6 0 12 238 | InitVector: 1 Cipher: 3 13 5 8 15 11 14 2 4 10 6 0 12 7 1 3 239 | InitVector: 2 Cipher: 4 10 6 0 12 7 1 3 13 5 8 15 11 14 2 4 240 | InitVector: 3 Cipher: 13 5 8 15 11 14 2 4 10 6 0 12 7 1 3 13 241 | InitVector: 4 Cipher: 10 6 0 12 7 1 3 13 5 8 15 11 14 2 4 10 242 | InitVector: 5 Cipher: 8 15 11 14 2 4 10 6 0 12 7 1 3 13 5 8 243 | InitVector: 6 Cipher: 0 12 7 1 3 13 5 8 15 11 14 2 4 10 6 0 244 | InitVector: 7 Cipher: 1 3 13 5 8 15 11 14 2 4 10 6 0 12 7 1 245 | InitVector: 8 Cipher: 15 11 14 2 4 10 6 0 12 7 1 3 13 5 8 15 246 | InitVector: 9 Cipher: 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 247 | InitVector: 10 Cipher: 6 0 12 7 1 3 13 5 8 15 11 14 2 4 10 6 248 | InitVector: 11 Cipher: 14 2 4 10 6 0 12 7 1 3 13 5 8 15 11 14 249 | InitVector: 12 Cipher: 7 1 3 13 5 8 15 11 14 2 4 10 6 0 12 7 250 | InitVector: 13 Cipher: 5 8 15 11 14 2 4 10 6 0 12 7 1 3 13 5 251 | InitVector: 14 Cipher: 2 4 10 6 0 12 7 1 3 13 5 8 15 11 14 2 252 | InitVector: 15 Cipher: 11 14 2 4 10 6 0 12 7 1 3 13 5 8 15 11 253 | \end{verbatim} 254 | We see that every unique initialisation vector, produces a different output of the cipher. We also see that, when the initialisation vector is 9 every number in the cipher text is also 9. This is expected, as 3 XOR 9 = 10 and a p = 10 produces a c = 9 creating a loop. 255 | \end{document} -------------------------------------------------------------------------------- /worksheet2/exercise14/graph.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | A=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] 4 | 5 | B=[13,14,3,4,5,6,0,15,10,11,16,1,18,2,7,8,17,19,9,12] 6 | 7 | C=[0]*20 8 | 9 | x=1 10 | curPos =0 11 | temp = 0 12 | modVal = 0 13 | a=input ('Enter reduction size: ') 14 | while x len(A): 20 | temp = 0 21 | if A in C: 22 | break 23 | C[x]=B[temp] 24 | print "%d ->"%C[x], 25 | curPos=B[temp] 26 | x=x+1 -------------------------------------------------------------------------------- /worksheet2/exercise15/Exercise15.py.lprof: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfaerevaag/cryptanalysis/c44a14c812c8e99e2ffdf9e0c413f7c5592eccb9/worksheet2/exercise15/Exercise15.py.lprof -------------------------------------------------------------------------------- /worksheet2/exercise15/README.md: -------------------------------------------------------------------------------- 1 | Exercise 15 2 | =========== 3 | 4 | By using a MD5 reduction function `f`, outputting a key-size of 20 bits, we 5 | have generated a Hallman's table with `2^16` chains, each with a length 6 | of `2^8`. That is, by iterating the reduction function 256 times. 7 | 8 | f = Min 20 bits of MD5(s) 9 | 10 | ## Coverage 11 | 12 | In total our implementation covers ca. **300000** of the total 13 | ca. **1000000** (2^20), which gives us about **30 %** coverage. 14 | 15 | ## Count vs *i* 16 | 17 | We have kept track of how many points of the total key-space we 18 | actually have covered after *i* calls to the reduction function `f`: 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 |
Coveredi
0255
500095089
10000130121
15000155724
20000176160
25000193557
30000208845
35000222276
40000234321
45000245930
50000255963
55000265776
60000274964
65000283572
83 |
84 | 85 | These results can be found in `covered-points.csv` 86 | 87 | Here is a graph showing the results: 88 | 89 |
90 | ![Count vs i](graph.png) 91 |
92 | -------------------------------------------------------------------------------- /worksheet2/exercise15/covered-points.csv: -------------------------------------------------------------------------------- 1 | count;i 2 | 0;255 3 | 5000;95089 4 | 10000;130121 5 | 15000;155724 6 | 20000;176160 7 | 25000;193557 8 | 30000;208845 9 | 35000;222276 10 | 40000;234321 11 | 45000;245930 12 | 50000;255963 13 | 55000;265776 14 | 60000;274964 15 | 65000;283572 16 | -------------------------------------------------------------------------------- /worksheet2/exercise15/exercise15.py: -------------------------------------------------------------------------------- 1 | # 2 | # Exercise 15 3 | # Worksheet 2 4 | # 5 | # 01435 Practiacal Cryptanalysis 6 | # Technical University of Denmark 7 | 8 | # Markus Faerevaag (s123692@student.dtu.dk) 9 | # Christian Mathias Rohde Kiaer (s123812@student.dtu.dk) 10 | # Jonathan Becktor (s123094@student.dtu.dk) 11 | # 12 | 13 | import time, csv, md5, random 14 | 15 | BIT_SIZE = 20 16 | NUM_CHAINS = 2**16 17 | CHAIN_LEN = 2**8 18 | TABLE_NAME = "table.csv" 19 | LOG_FREQ = 5000 20 | 21 | 22 | def md5_redux(s): 23 | """MD5 reduction function. 24 | Throws away all exceeding output bits from MD5 digest""" 25 | return '0x' + md5.new(str(s)).hexdigest()[:BIT_SIZE/4] 26 | 27 | def generate_list(): 28 | """Generates a rainbow table""" 29 | dict = {} 30 | order = [] 31 | keys_checked = [] 32 | counter = 0 33 | 34 | for i in xrange(0, NUM_CHAINS - 1): 35 | red = hex(random.getrandbits(BIT_SIZE))[:-1] 36 | red_start_point = red 37 | 38 | for x in xrange(0, CHAIN_LEN - 1): 39 | red = md5_redux(red) 40 | keys_checked.append(red) 41 | 42 | red_end_point = red 43 | 44 | if i % LOG_FREQ == 0: 45 | print "Took i calls: %d and the unique keys checked is: %d" % (i, len(set(keys_checked))) 46 | 47 | order.append(red_start_point) 48 | dict[red_start_point] = red_end_point 49 | counter += 1 50 | 51 | print len(set(keys_checked)) 52 | print len(keys_checked) 53 | 54 | write_to_csv(dict, order) 55 | 56 | 57 | def write_to_csv(dict, order): 58 | """Writes the rainbow table to a .csv file""" 59 | w = csv.writer(open(TABLE_NAME, 'w')) 60 | for key in order: 61 | value = dict[key] 62 | w.writerow([key, value]) 63 | 64 | 65 | def main(): 66 | start = time.clock() 67 | 68 | generate_list() 69 | 70 | end = time.clock() 71 | print "Took: ", (end - start), " s" 72 | 73 | 74 | if __name__ == '__main__': 75 | main() 76 | -------------------------------------------------------------------------------- /worksheet2/exercise15/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfaerevaag/cryptanalysis/c44a14c812c8e99e2ffdf9e0c413f7c5592eccb9/worksheet2/exercise15/graph.png -------------------------------------------------------------------------------- /worksheet2/exercise16.md: -------------------------------------------------------------------------------- 1 | Exercise 16 2 | =========== 3 | 4 | ## Hellman's vs Rainbow tables 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 |
Hellman'sRainbow
Memory2^85.32^85.3
Offline comp2^1282^128
Online comp2^85.32^85.3
Online search2^85.32^42.67
33 | 34 | as the best values 35 | 36 | l = m = t = 2^(11/3)t = 2^42.67 37 | -------------------------------------------------------------------------------- /worksheet2/exercise17/README.md: -------------------------------------------------------------------------------- 1 | Exercise 17 2 | =========== 3 | 4 | By using a MD5 reduction function `f`, outputting a key-size of 20 bits, we 5 | have generated a Rainbow table with `2^16` chains, each with a length 6 | of `2^8`. That is, by iterating the reduction function 256 times. 7 | 8 | f = Min 20 bits of (MD5(s) ^ i) 9 | 10 | ## Coverage 11 | 12 | In total our implementation covers ca. **1034904** of the total 13 | ca. **1048576** (2^20), which gives us about **98.8 %** coverage. 14 | This is a phenomenal improvement from the Hellman's at around 30 %! 15 | 16 | ## Count vs *i* 17 | 18 | We have kept track of how many points of the total key-space we 19 | actually have covered after *i* calls to the reduction function `f`: 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 |
Coveredi
0255
5000645180
10000836326
15000916822
20000959115
25000983192
30000999148
350001009589
400001017355
450001023006
500001027086
550001030204
600001032709
650001034740
84 |
85 | 86 | These results can be found in `covered-points.csv` 87 | 88 | Here is a graph showing the results: 89 | 90 |
91 | ![Count vs i](graph.png) 92 |
93 | -------------------------------------------------------------------------------- /worksheet2/exercise17/covered-keys.csv: -------------------------------------------------------------------------------- 1 | 0;255 2 | 5000;645180 3 | 10000;836326 4 | 15000;916822 5 | 20000;959115 6 | 25000;983192 7 | 30000;999148 8 | 35000;1009589 9 | 40000;1017355 10 | 45000;1023006 11 | 50000;1027086 12 | 55000;1030204 13 | 60000;1032709 14 | 65000;1034740 -------------------------------------------------------------------------------- /worksheet2/exercise17/exercise17.py: -------------------------------------------------------------------------------- 1 | # 2 | # Exercise 17 3 | # Worksheet 2 4 | # 5 | # 01435 Practiacal Cryptanalysis 6 | # Technical University of Denmark 7 | 8 | # Markus Faerevaag (s123692@student.dtu.dk) 9 | # Christian Mathias Rohde Kiaer (s123812@student.dtu.dk) 10 | # Jonathan Becktor (s123094@student.dtu.dk) 11 | # 12 | 13 | import md5, random, time, csv 14 | 15 | BIT_SIZE = 20 16 | NUM_CHAINS = 2**16 17 | CHAIN_LEN = 2**8 18 | TABLE_NAME = "table.csv" 19 | LOG_FREQ = 5000 20 | 21 | def md5_redux(s, i): 22 | """MD5 reduction function xor'ed with i. 23 | Throws away all exceeding output bits from MD5 digest""" 24 | digest = int(md5.new(str(s)).hexdigest()[:BIT_SIZE/4], 16) 25 | result = digest ^ i 26 | return '0x' + str(result) 27 | 28 | 29 | def generate_table(): 30 | """Generates a rainbow table""" 31 | dict = {} 32 | order = [] 33 | counter = 0 34 | keys_checked = [] 35 | 36 | for i in xrange(0, NUM_CHAINS - 1): 37 | red = hex(random.getrandbits(20))[:-1] 38 | red_start_point = red 39 | 40 | for x in xrange(0, CHAIN_LEN - 1): 41 | red = md5_redux(red, x) 42 | keys_checked.append(red) 43 | 44 | red_end_point = red 45 | 46 | if counter % LOG_FREQ == 0: 47 | print "Took i calls: %d and the unique keys checked is: %d" % (i, len(set(keys_checked))) 48 | 49 | order.append(red_start_point) 50 | dict[red_start_point] = red_end_point 51 | counter += 1 52 | 53 | print len(set(keys_checked)) 54 | print len(keys_checked) 55 | 56 | write_to_csv(dict, order) 57 | 58 | 59 | def write_to_csv(dict, order): 60 | """Writes the rainbow table to a .csv file""" 61 | w = csv.writer(open(TABLE_NAME, 'w')) 62 | for key in order: 63 | value = dict[key] 64 | w.writerow([key, value]) 65 | 66 | 67 | def main(): 68 | start = time.clock() 69 | 70 | generate_table() 71 | 72 | end = time.clock() 73 | print "Took: ", (end - start), " s" 74 | 75 | 76 | if __name__ == '__main__': 77 | main() 78 | 79 | -------------------------------------------------------------------------------- /worksheet2/exercise17/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mfaerevaag/cryptanalysis/c44a14c812c8e99e2ffdf9e0c413f7c5592eccb9/worksheet2/exercise17/graph.png -------------------------------------------------------------------------------- /worksheet3/Entropy.py: -------------------------------------------------------------------------------- 1 | # 2 | # Project 2 3 | # 4 | # 01435 Practiacal Cryptanalysis 5 | # Technical University of Denmark 6 | 7 | # Markus Faerevaag (s123692@student.dtu.dk) 8 | # Christian Mathias Rohde Kiaer (s123812@student.dtu.dk) 9 | # Jonathan Becktor (s123094@student.dtu.dk) 10 | # 11 | 12 | import math 13 | 14 | LETTERS = ['A','B','C','D','E', 15 | 'F','G','H','I','J', 16 | 'K','L','M','N','O', 17 | 'P','Q','R','S','T', 18 | 'U','V','W','X','Y','Z'] 19 | PERC = [0.082, 0.015, 0.028, 0.043, 0.127, 20 | 0.022, 0.02, 0.061, 0.07, 0.002, 21 | 0.008, 0.04, 0.024, 0.067, 0.075, 22 | 0.019, 0.001, 0.060, 0.063, 0.091, 23 | 0.028, 0.01, 0.023, 0.001, 0.02, 0.001] 24 | 25 | 26 | def calc_entropy(letter): 27 | """Calculates entropy for given letter""" 28 | P = PERC[LETTERS.index(letter.upper())] 29 | return P * math.log(1/P)/math.log(2) 30 | 31 | 32 | def main(): 33 | # Sum entropy for each letter 34 | sum = 0 35 | for letter in LETTERS: 36 | entropy = calc_entropy(letter) 37 | sum += entropy 38 | print "%s: %.3f" % (letter, entropy) 39 | 40 | print "The average number of bits: %f" % sum 41 | 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /worksheet3/README.md: -------------------------------------------------------------------------------- 1 | Worksheet 3 2 | =========== 3 | 4 | Script for calculating the average number of bits required to store one letter of British English if perfect compression. 5 | 6 | 7 | ## Usage 8 | 9 | Simply: 10 | 11 | $ python Entropy.py 12 | 13 | 14 | ## Logic 15 | 16 | Sum the entropy of each character in the alphabet using the given 17 | probability in the slides. 18 | 19 | 20 | ## Results 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 |
LetterProbabilityEntropy
A0.0820.296
B0.0150.091
C0.0280.144
D0.0430.195
E0.1270.378
F0.0220.121
G0.020.113
H0.0610.246
I0.07,0.269
J0.0020.018
K0.0080.056
L0.040.186
M0.0240.129
N0.0670.261
O0.0750.280
P0.0190.109
Q0.0010.010
R0.0600.244
S0.0630.251
T0.0910.315
U0.0280.144
V0.010.066
W0.0230.125
X0.0010.010
Y0.020.113
Z0.0010.010
Total4.180245
165 |
166 | 167 | Results can be found in `results.csv`. 168 | 169 | 170 | ## Further Help 171 | 172 | For further help or explanation please contact one of us by mail and 173 | we'll be happy to help: 174 | 175 | * Markus Faerevaag [s123692@student.dtu.dk](mailto:s123692@student.dtu.dk) 176 | * Christian Mathias Rohde Kiaer [s123812@student.dtu.dk](mailto:s123812@student.dtu.dk) 177 | * Jonathan Becktor [s123094@student.dtu.dk](mailto:s123094@student.dtu.dk) 178 | -------------------------------------------------------------------------------- /worksheet3/results.csv: -------------------------------------------------------------------------------- 1 | A,0.296 2 | B,0.091 3 | C,0.144 4 | D,0.195 5 | E,0.378 6 | F,0.121 7 | G,0.113 8 | H,0.246 9 | I,0.269 10 | J,0.018 11 | K,0.056 12 | L,0.186 13 | M,0.129 14 | N,0.261 15 | O,0.280 16 | P,0.109 17 | Q,0.010 18 | R,0.244 19 | S,0.251 20 | T,0.315 21 | U,0.144 22 | V,0.066 23 | W,0.125 24 | X,0.010 25 | Y,0.113 26 | Z,0.010 --------------------------------------------------------------------------------