def decryptVigenere(charList, keyString): """ (list, str) -> str Decrypt the passed ciphertext list charList, encrypted with the Vigenere cipher using the passed key keyString. >>> decryptVigenere(['X', 'S', 'F', 'J', 'D', 'J', 'M', 'N', 'R', 'F', 'R', 'U', 'D', 'J', 'V', 'L', 'M', 'Y', 'F', 'T', 'G', 'W', 'W', 'H', 'P', 'T', 'U', 'D', 'I', 'A', 'H', 'W', 'R', 'M', 'S', 'X', 'X', 'A', 'H', 'J', 'D', 'N', 'B', 'R', 'H', 'Q', 'T', 'O', 'F', 'F', 'N', 'W', 'F', 'G', 'H', 'G', 'L', 'D', 'J', 'J', 'A', 'T', 'Q', 'W', 'H', 'U', 'E', 'Q', 'E', 'M', 'D', 'M', 'H', 'R', 'H', 'L', 'M', 'C', 'G', 'L', 'Z', 'A', 'Y', 'B', 'T', 'H', 'U', 'W', 'I', 'C', 'M', 'H', 'D', 'J', 'I', 'C', 'G', 'F', 'V', 'Z', 'T', 'J', 'H', 'W', 'R', 'F', 'Y', 'B', 'X', 'B', 'H', 'T', 'T', 'L', 'X', 'A', 'H', 'F', 'L', 'Y', 'M', 'H', 'D', 'K', 'M', 'Z', 'K', 'T', 'P', 'S', 'S', 'U', 'M', 'R', 'H', 'F', 'H', 'L', 'R', 'U', 'W', 'A', 'T', 'H', 'U', 'J', 'V', 'L', 'T', 'Q', 'L', 'Z', 'S', 'G', 'S', 'N', 'A', 'F', 'W', 'L', 'W', 'U', 'G', 'X', 'D', 'U', 'Y', 'C', 'H', 'S', 'W', 'Z', 'J', 'W', 'H', 'S', 'I', 'A', 'I', 'Y', 'G', 'Y', 'L', 'S', 'Q', 'C', 'M', 'D', 'D', 'F', 'I', 'M', 'X', 'H', 'X', 'J', 'N', 'N', 'R', 'Y', 'R', 'E', 'F', 'E', 'X', 'N', 'W', 'H', 'T', 'M', 'L', 'N', 'E', 'D', 'J', 'C', 'Y', 'D', 'R', 'M', 'H', 'I', 'G', 'X', 'L', 'V', 'J', 'L', 'X', 'Q', 'H', 'U', 'Y', 'L', 'H', 'S', 'L', 'U', 'Y', 'L', 'T', 'S', 'V', 'S', 'H', 'N', 'B', 'T', 'Q', 'K', 'F', 'H', 'W', 'T', 'Q', 'D', 'N', 'H', 'X', 'U', 'D', 'Q', 'R', 'Y', 'G', 'Y', 'V', 'S', 'Q', 'F', 'M', 'M', 'R', 'K', 'J', 'Q', 'H', 'Z', 'O', 'V', 'S', 'I', 'M', 'G', 'H', 'H', 'T', 'M', 'L', 'N', 'E', 'D', 'J', 'Q', 'B', 'Y', 'K', 'G', 'Z', 'N', 'X', 'S', 'F', 'J', 'D', 'J', 'M', 'N', 'R', 'F', 'X', 'U', 'B', 'I', 'G', 'J', 'R', 'U', 'K', 'P', 'P', 'S', 'S', 'O', 'E', 'N', 'V', 'S', 'X', 'Y', 'G', 'N', 'R', 'J', 'Q', 'Y', 'V', 'Y', 'X', 'J', 'J', 'L', 'B', 'S', 'F', 'J', 'D', 'J', 'M', 'T', 'J', 'J', 'F', 'J', 'A', 'D', 'D', 'L', 'Y', 'B', 'X', 'Z', 'Q', 'A', 'A', 'Y', 'K', 'X', 'L', 'L', 'D', 'I', 'Y', 'X', 'X', 'J', 'W', 'Y', 'R', 'F', 'W', 'A', 'Y', 'M', 'L', 'N', 'P', 'H', 'Q', 'Y', 'L', 'Y', 'H', 'F', 'H', 'L', 'R', 'U', 'W', 'A', 'T', 'H', 'B', 'X', 'D', 'D', 'Q', 'U', 'U', 'T', 'X', 'L', 'Y', 'L', 'T', 'S', 'V', 'X', 'T', 'L', 'F', 'N', 'Q', 'Y', 'N', 'H', 'M', 'J', 'O', 'D', 'N', 'A', 'B', 'G', 'O', 'W', 'S', 'O', 'F', 'G', 'H', 'J', 'X', 'I', 'K', 'Y', 'H', 'P', 'Y', 'M', 'H', 'Z', 'Q', 'V', 'X', 'U', 'G', 'I', 'L', 'E', 'F', 'A', 'X', 'X', 'L', 'F', 'Y', 'I', 'T', 'X', 'W', 'J', 'J', 'U', 'F', 'T', 'I', 'F', 'T', 'H', 'L', 'J', 'Q', 'K', 'J', 'N', 'A', 'J', 'U', 'W', 'F', 'L', 'X', 'R', 'D', 'F', 'D', 'G', 'T', 'S', 'B', 'O', 'F', 'S', 'L', 'Y', 'R', 'H', 'J', 'L', 'Y', 'T', 'U', 'E', 'Y', 'B', 'T', 'Y', 'W', 'J', 'F', 'H', 'L', 'K', 'R', 'J', 'R', 'U', 'M', 'N', 'R', 'F', 'X', 'I', 'F', 'J', 'V', 'L', 'W', 'U', 'B', 'L', 'K', 'L', 'K', 'I', 'K', 'B', 'D', 'J', 'I', 'U', 'G', 'I', 'V', 'G', 'R', 'Y', 'O', 'J', 'U', 'Q', 'H', 'I', 'F', 'U', 'O', 'W', 'C', 'G', 'H', 'X', 'W', 'A', 'S', 'P', 'H', 'Q', 'Y', 'W', 'X', 'Q', 'T', 'U', 'S', 'A', 'S', 'A', 'E', 'J', 'W', 'L', 'J', 'L', 'L', 'K', 'R', 'J', 'S', 'O', 'F', 'G', 'H', 'J', 'X', 'U', 'G', 'I', 'X', 'K', 'J', 'G', 'T', 'Y', 'K', 'K', 'Y', 'I', 'W', 'T', 'W', 'Z', 'J', 'N', 'K', 'F', 'Q', 'K', 'K', 'I', 'K', 'R', 'D', 'L', 'N', 'I', 'G', 'M', 'R', 'O', 'J', 'P', 'X', 'W', 'Q', 'G', 'R', 'U', 'M', 'Y', 'H', 'J', 'B', 'B', 'B', 'H', 'K', 'E', 'J', 'N', 'A', 'T', 'G', 'A', 'X', 'O', 'L', 'J', 'G', 'L', 'M', 'Y', 'K', 'J', 'V', 'M', 'Q', 'N', 'B', 'S', 'J', 'K', 'H', 'L', 'T', 'R', 'E', 'D', 'J', 'X', 'W', 'F', 'W', 'S', 'X', 'N', 'K', 'J', 'D', 'E', 'X', 'B', 'H', 'Z', 'O', 'V', 'L', 'C', 'O', 'J', 'Q', 'G', 'M', 'C', 'G', 'Y', 'V', 'S', 'G', 'I', 'N', 'Y', 'K', 'G', 'B', 'C', 'M', 'B', 'D', 'K', 'J', 'H', 'V', 'W', 'B', 'H', 'Y', 'Y', 'W', 'I', 'X', 'J', 'N', 'H', 'Z', 'B', 'R', 'J', 'Q', 'X', 'P', 'F', 'U', 'A', 'N', 'N', 'A', 'J', 'D', 'D', 'Q', 'C', 'X', 'X', 'V', 'U', 'T', 'L', 'X', 'I', 'V', 'G', 'R', 'Y', 'G', 'T', 'W', 'S', 'G', 'F', 'X', 'A', 'L', 'U', 'Y', 'I', 'K', 'N', 'H', 'K', 'F', 'A', 'T', 'N', 'Q', 'K', 'Y', 'N', 'A', 'J', 'J', 'W', 'W', 'G', 'T', 'S', 'V', 'T', 'J', 'W', 'T', 'Z', 'V', 'W', 'Y', 'B', 'X', 'N', 'U', 'W', 'S', 'W', 'K', 'D', 'S', 'L', 'N', 'I', 'G', 'X', 'B', 'K', 'Y', 'Y', 'F', 'X', 'G', 'A', 'I', 'H', 'H', 'Y', 'V', 'M', 'K', 'Z', 'B', 'H', 'L', 'W', 'S', 'N', 'E', 'D', 'V', 'U', 'W', 'U', 'F', 'G', 'O', 'W', 'R', 'Y', 'L', 'X', 'D', 'Y', 'J', 'M', 'K', 'N', 'J', 'G', 'W', 'I', 'N', 'X', 'P', 'S', 'Y', 'B', 'X', 'R', 'D', 'L', 'N', 'W', 'T', 'Q', 'D', 'F', 'F', 'F', 'R', 'X', 'L', 'K', 'G', 'S', 'T', 'Q', 'O', 'A', 'J', 'X', 'V', 'T', 'G', 'W', 'H', 'L', 'T', 'H', 'N', 'W', 'W', 'M', 'E', 'F', 'L', 'V', 'G', 'U', 'K', 'J', 'S', 'S', 'Y', 'N', 'X', 'W', 'Q', 'K', 'M', 'C', 'W', 'I', 'H', 'F', 'B', 'C', 'M', 'M', 'L', 'F', 'Y', 'B', 'X', 'R', 'H', 'K', 'X', 'U', 'Z', 'J', 'V', 'S', 'S', 'X', 'N', 'X', 'H', 'V', 'Y', 'B', 'X', 'R', 'W', 'G', 'W', 'Y', 'V', 'W', 'H', 'S', 'Y', 'Y', 'M', 'M', 'H', 'E', 'F', 'W', 'A', 'N', 'Q', 'W', 'Z', 'M', 'X', 'I', 'W', 'G', 'J', 'H', 'V', 'W', 'B', 'H', 'Y', 'N', 'A', 'J', 'P', 'L', 'M', 'I', 'L', 'J', 'F', 'G', 'I', 'Y', 'L', 'W', 'H', 'N', 'T', 'F', 'O', 'J', 'G', 'S', 'W', 'I', 'N', 'S', 'G', 'L', 'M', 'Y', 'N', 'X', 'H', 'G', 'K', 'M', 'X', 'H', 'U', 'W', 'Y', 'E', 'X', 'D', 'V', 'L', 'M', 'U', 'M', 'B', 'H', 'J', 'J', 'M', 'A', 'F', 'U', 'W', 'I', 'U', 'F', 'T', 'Q', 'Y', 'Y', 'B', 'H', 'X', 'H', 'O', 'M', 'I', 'G', 'J', 'H', 'V', 'J', 'X', 'M', 'T', 'F', 'G', 'R', 'G', 'N', 'S', 'L', 'U', 'F', 'N', 'X', 'X', 'H', 'U', 'Z', 'L', 'X', 'Q', 'B', 'L', 'M', 'Y', 'L', 'J', 'D', 'J', 'J', 'E', 'G', 'T', 'Z', 'F', 'F', 'M', 'L', 'D', 'P', 'E', 'J', 'N', 'K', 'N', 'F', 'W', 'S', 'W', 'K', 'D', 'S', 'L', 'N', 'I', 'G', 'X', 'B', 'K', 'Y', 'Y', 'F', 'X', 'D', 'F', 'I', 'B', 'T', 'A', 'H', 'S', 'B', 'Y', 'T', 'P', 'Q', 'W', 'X', 'M', 'B', 'S', 'W', 'Z', 'F', 'N', 'X', 'A', 'H', 'J', 'D', 'I', 'G', 'J', 'L', 'F', 'A', 'I', 'E', 'A', 'H', 'V', 'M', 'U', 'L', 'Y', 'R', 'H', 'T', 'M', 'L', 'J', 'V', 'K', 'Y', 'B', 'X', 'X', 'D', 'E', 'J', 'M', 'X', 'Y', 'R', 'X', 'X', 'Y', 'V', 'W', 'H', 'L', 'P', 'Y', 'R', 'X'], 'SECRET') encryptionmakesthemodernworldgoroundeverytimeyoumakeamobilephonecallbuysomethingwithacreditcardinashoporontheweborevengetcashfromanatmencryptionbestowsuponthattransactiontheconfidentialityandsecuritytomakeitpossibleifyouconsiderelectronictransactionsandonlinepaymentsallthosewouldnotbepossiblewithoutencryptionsaiddrmarkmanulisaseniorlecturerincryptographyattheuniversityofsurreyatitssimplestencryptionisallabouttransformingintelligiblenumbersortextsoundsandimagesintoastreamofnonsensetherearemanymanywaystoperformthattransformationsomestraightforwardandsomeverycomplexmostinvolveswappinglettersfornumbersandusemathstodothetransformationhowevernomatterwhichmethodisusedtheresultingscrambleddatastreamshouldgivenohintsabouthowitwasencryptedduringworldwariithealliesscoredsomenotablevictoriesagainstthegermansbecausetheirencryptionsystemsdidnotsufficientlyscramblemessagesrigorousmathematicalanalysisbyalliedcodecrackerslaidbarepatternshiddenwithinthemessagesandusedthemtorecreatethemachineusedtoencryptthemthosecodesrevolvedaroundtheuseofsecretkeysthatweresharedamongthosewhoneededtocommunicatesecurelytheseareknownassymmetricencryptionsystemsandhaveaweaknessinthateveryoneinvolvedhastopossessthesamesetofsecretkeys """ keyString = keyString.upper() keyLength = len(keyString) decryptedCharList = [] subKeyIndex = 0 for char in charList: subKeyLetter = keyString[subKeyIndex] subKey = cipher_utils.cipherLetterToOrdinal(subKeyLetter) + 1 cipherOrdinal = cipher_utils.cipherLetterToOrdinal(char) plainTextOrdinal = (cipherOrdinal - subKey) % 26 plainTextLetter = cipher_utils.ordinalToClearLetter(plainTextOrdinal) decryptedCharList.append(plainTextLetter) subKeyIndex += 1 logger.debug( 'SubKey %s (%s - %s):\tcipher char: %s (%s)\tplaintext char: %s (%s)' % (subKeyIndex, subKey, subKeyLetter, char, cipherOrdinal + 1, plainTextLetter, plainTextOrdinal + 1)) if subKeyIndex == keyLength: subKeyIndex = 0 return ''.join(decryptedCharList)
def matrixMult(keyMatrix, colVector): m = n = len(keyMatrix) letterBlock = [] for i in range(n): productElement = 0 for j in range(m): keyLetter = keyMatrix[i][j] keyOrd = cipher_utils.cipherLetterToOrdinal(keyLetter) letter = colVector[j] letterOrd = cipher_utils.cipherLetterToOrdinal(letter) productElement += keyOrd * letterOrd cipherOrd = (productElement) % 26 cipherLetter = cipher_utils.integerToChr(cipherOrd) logger.debug( '%s (%s) x %s (%s) = %s (%s)' % (keyLetter, keyOrd, letter, letterOrd, cipherOrd, cipherLetter)) letterBlock.append(cipherLetter) return ''.join(letterBlock)
def deriveVigenereKeyPhraseFromCrib(cipherChars, crib): # Derive a possible Vigenere keyphrase from the most frequently occurring letter for each sub key """ (str, str) -> str Derive a possible Vigenere keyphrase from a section of the cipher, with a guessed crib >>> deriveVigenereKeyPhrase('HTPEG', 'MARTIN') 'MARTIN' """ keyPhrase = [] index = 0 for cipherChar in cipherChars: cipherCharOrdinal = cipher_utils.cipherLetterToOrdinal(cipherChar) caesarShift = (cipherCharOrdinal - cipher_utils.cipherLetterToOrdinal( crib[index]) - 1) % 26 keyChar = cipher_utils.ordinalToClearLetter(caesarShift).upper() keyPhrase.append(keyChar) logger.info( 'Cipher character %s (%s) should be %s (%s),\tCaesar Shift for sub key = %s,\tkeyChar = %s' % (cipherChar, cipherCharOrdinal + 1, crib[index], cipherLetterToOrdinal(crib[index]) + 1, caesarShift + 1, keyChar)) index += 1 return ''.join(keyPhrase)
def deriveVigenereKeyPhrase(frequentChars): # Derive a possible Vigenere keyphrase from the most frequently occurring letter for each sub key """ (str) -> str Derive a possible Vigenere keyphrase from the most frequently occurring letter for each sub key Please note, the key length should be known, or at least correctly guessed, for this function to produce meaningful results. >>> deriveVigenereKeyPhrase('XJHJDY') 'SECRET' """ keyPhrase = [] for frequentChar in frequentChars: frequentCharOrdinal = cipher_utils.cipherLetterToOrdinal(frequentChar) caesarShift = (frequentCharOrdinal - 5) % 26 # 'E' = 5 keyChar = cipher_utils.ordinalToClearLetter(caesarShift).upper() keyPhrase.append(keyChar) logger.info( 'Frequent character %s (%s) should be E (5),\tCaesar Shift for sub key = %s,\tkeyChar = %s' % (frequentChar, frequentCharOrdinal + 1, caesarShift + 1, keyChar)) return ''.join(keyPhrase)
def decryptSimpleSubstitutionCipher(charList, keyString, dummy=None): """ (list, str, str) -> str Decrypt the passed ciphertext list charList, encrypted with simple substitution cipher using the passed key keyString. Dummy characters are defined by the argument dummy, which, if set, will simply display the ciphertext character >>> decryptSimpleSubstitutionCipher(['A', 'B', 'C', ' ', 'Z'], 'KEYABCDFGHIJLMNOPQRSTUVWX.', dummy='.') 'key Z' """ decryptedCharList = [] logger.debug('Cipher\tPlain') for char in charList: cipherOrdinal = cipher_utils.cipherLetterToOrdinal(char) if cipherOrdinal in range(len(keyString)): plainTextLetter = keyString[cipherOrdinal].lower() if plainTextLetter == dummy: plainTextLetter = char else: plainTextLetter = char decryptedCharList.append(plainTextLetter) logger.debug('%s\t%s' % (char, plainTextLetter)) return ''.join(decryptedCharList)
def getMatrixInverse(keyMatrix): # calc inv matrix # Only proven to work on a 2x2 matrix (4 letter keyword) for now # First, find the determinant det K of keyMatrix K det = 0 m = n = p = len(keyMatrix) for i in range(m // 2): for j in range(n): subDet = cipher_utils.cipherLetterToOrdinal( keyMatrix[i][j]) * cipher_utils.cipherLetterToOrdinal( keyMatrix[m - 1][n - 1]) if i == j: det += subDet else: det -= subDet logger.debug( 'determinant=%s, i=%s, j=%s, m=%s, n=%s, keyL=%s, keyR=%s' % (det, i, j, m, n, cipher_utils.cipherLetterToOrdinal(keyMatrix[i][j]), cipher_utils.cipherLetterToOrdinal(keyMatrix[m - 1][n - 1]))) n -= 1 n = p m -= 1 det = det % 26 logger.debug('determinant = %s' % (det)) # Next, find the multiplicative inverse of the determinant det K di = 0 for x in range(26): if (det * x) % 26 == 1: di = x if di == 0: print('could not invert, try different key') return None logger.debug( 'multiplicative inverse K**-1 of the determinant det K (such that (det * x) mod 26 = 1 : %s' % (di)) keyInverseMatrix = [] m = n = p = len(keyMatrix) for i in range(p): row = [] for j in range(p): if i == j: inverse = di * cipher_utils.cipherLetterToOrdinal( keyMatrix[m - 1][n - 1]) logger.debug('m=%s, n=%s row[%s][%s] = %s (mod 26)' % (m - 1, n - 1, i, j, inverse)) else: inverse = -1 * di * cipher_utils.cipherLetterToOrdinal( keyMatrix[i][j]) logger.debug('i=%s, j=%s row[%s][%s] = %s (mod 26)' % (i, j, i, j, inverse)) inverse = inverse % 26 row.append(inverse) logger.debug('row[%s][%s] = %s' % (i, j, inverse)) n -= 1 keyInverseMatrix.append(row) n = p m -= 1 logger.debug('keyInverseMatrix = %s' % (keyInverseMatrix)) return keyInverseMatrix