def blum(p, q, m): # your code here if not isinstance(m, int): print('Error(blum): Invalid value of m', end='') return '' if m <= 0: print('Error(blum): Invalid value of m', end='') return '' if not isinstance(p, int) or not isinstance(q, int): print('Error(blum): Invalid values of p,q', end='') return '' if mod.residue(p, 4) != 3 or mod.residue(q, 4) != 3: print('Error(blum): Invalid values of p,q', end='') return '' n = p * q p_file = open(primeFile, 'r') primes = p_file.read().split('\n') temp = n seed = int(primes[temp - 1]) while mod.gcd(seed, n) != 1: temp += 1 seed = int(primes[temp - 1]) bitStream = '' x = mod.residue(seed**2, n) for i in range(m): x = mod.residue(x**2, n) bitStream += str(mod.residue(x, 2)) return bitStream
def d_mathCipher(ciphertext, key): # your code here if not isinstance(ciphertext, str) or len(ciphertext) == 0: print('Error(d_mathCipher): invalid ciphertext', end='') return '' if not isValidKey_mathCipher(key): print('Error(d_mathCipher): Invalid key', end='') return '' baseString = key[0] m = len(baseString) a = key[1][0] a_inv = mod.mul_inv(a, m) b = key[1][1] b_inv = mod.mul_inv(b, m) c_key = key[1][2] plaintext = '' for c in ciphertext: if c.lower() in baseString: y = baseString.index(c.lower()) x = a_inv * ((y + c_key) * b_inv - b) x = mod.residue(x, m) plainChar = baseString[x] plaintext += plainChar.upper() if c.isupper() else plainChar else: plaintext += c return plaintext
def e_mathCipher(plaintext, key): # your code here if not isinstance(plaintext, str) or len(plaintext) == 0: print('Error(e_mathCipher): invalid plaintext', end='') return '' if not isValidKey_mathCipher(key): print('Error(e_mathCipher): Invalid key', end='') return '' baseString = key[0] m = len(baseString) a = key[1][0] b = key[1][1] c = key[1][2] ciphertext = '' for p in plaintext: if p.lower() in baseString: x = baseString.index(p.lower()) y = b * (a * x + b) - c y = mod.residue(y, m) cipherChar = baseString[y] ciphertext += cipherChar.upper() if p.isupper() else cipherChar else: ciphertext += p return ciphertext
def d_decimation(ciphertext, key): # your code here if not isinstance(key, tuple): print('Error (d_decimation): Invalid key') return '' if not isinstance(key[0], str) or not isinstance(key[1], int): print('Error (d_decimation): Invalid key') return '' baseString = key[0] m = len(baseString) k = key[1] if not mod.has_mul_inv(k, m): print('Error (d_decimation): Invalid key') return '' m_i_k = mod.mul_inv(k, m) plaintext = '' for c in ciphertext: if c.lower() in baseString: y = baseString.index(c.lower()) x = mod.residue(m_i_k * y, m) plainChar = baseString[x] plaintext += plainChar.upper() if c.isupper() else plainChar else: plaintext += c return plaintext
def e_decimation(plaintext, key): # your code here if not isinstance(key, tuple): print('Error (e_decimation): Invalid key') return '' if not isinstance(key[0], str) or not isinstance(key[1], int): print('Error (e_decimation): Invalid key') return '' baseString = key[0] m = len(baseString) k = key[1] if not mod.has_mul_inv(k, m): print('Error (e_decimation): Invalid key') return '' ciphertext = '' for p in plaintext: if p.lower() in baseString: x = baseString.index(p.lower()) y = mod.residue(k * x, m) cipherChar = baseString[y] ciphertext += cipherChar.upper() if p.isupper() else cipherChar else: ciphertext += p return ciphertext
def d_affine(ciphertext, key): # your code here if not isinstance(key, tuple): print('Error (e_affine): Invalid key') return '' if not isinstance(key[0], str) or not isinstance(key[1], list): print('Error (e_affine): Invalid key') return '' if not isinstance(key[1][0], int) or not isinstance(key[1][1], int): print('Error (e_affine): Invalid key') return '' baseString = key[0] m = len(baseString) alpha = key[1][0] beta = key[1][1] if not mod.has_mul_inv(alpha, m): print('Error (e_affine): Invalid key') return '' m_i_alpha = mod.mul_inv(alpha, m) plaintext = '' for c in ciphertext: if c.lower() in baseString: y = baseString.index(c.lower()) x = mod.residue((y - beta) * m_i_alpha, m) plainChar = baseString[x] plaintext += plainChar.upper() if c.isupper() else plainChar else: plaintext += c return plaintext
def blum(p,q,m): if m <= 0: print('Error(blum): Invalid value of m',end ='') return '' elif not isinstance(p, int) or not isinstance(q, int) or not mod.is_congruent(p,3,4) or not mod.is_congruent(q,3,4): print('Error(blum): Invalid values of p,q',end ='') return '' else: n = p*q prime = open(primeFile, 'r') lines = prime.readlines() pn = lines[n-1] while not mod.is_relatively_prime(pn,n): # print(n, pn) pn = lines[n-1] n+=1 # print(n, pn) seed = int(pn) bitStream = "" for x in range(m): seed = (seed**2)%n bitStream+= str(mod.residue((seed**2),n)%2) prime.close() return bitStream
def inverse(A, m): # your code here if not isinstance(m, int) or m <= 0: return 'Error(inverse): invalid mod' if not is_matrix(A): return 'Error(inverse): invalid input' if get_rowCount(A) == 0: return 'Error(inverse): invalid input' if not is_square(A): return 'Error(inverse): matrix is not invertible' else: if get_rowCount(A) == 2: if mod.gcd(det(A), m) != 1: return 'Error(inverse): matrix is not invertible' else: return 'Error(inverse): Unsupported matrix size' delta = mod.residue(det(A), m) m_i_delta = mod.mul_inv(delta, m) new = new_matrix(2, 2, 0) new[0][0] = A[1][1] new[0][1] = 0 - A[0][1] new[1][0] = 0 - A[1][0] new[1][1] = A[0][0] return matrix_mod(scalar_mul(m_i_delta, new), m)
def LRM(b, e, m): # your code here binary = utilities.dec_to_bin(e, 100) i = binary.find('1') binary = binary[i:] x = mod.residue(b, m) first = True for bit in binary: if first: first = False else: x = mod.residue(x**2, m) if bit == '1': x = mod.residue(x * b, m) x = mod.residue(x, m) return x
def matrix_mod(A, m): # your code here if not is_matrix(A): return 'Error(matrix_mod): invalid input' if get_rowCount(A) == 0: return 'Error(matrix_mod): invalid input' if not isinstance(m, int) or m <= 0: return 'Error(matrix_mod): invalid mod' C = new_matrix(get_rowCount(A), get_columnCount(A), 0) if get_rowCount(A) == 1: for i in range(len(A)): C[i] = mod.residue(A[i], m) else: for i in range(len(A)): for j in range(len(A[0])): C[i][j] = mod.residue(A[i][j], m) return C
def e_decimation(plaintext,key): ciphertext = "" sample = [] text = key[0] dec_key = mod.has_mul_inv(key[1],len(key[0])) if not dec_key: print('Error (e_decimation): Invalid key') return else: dec_key = mod.mul_inv(key[1], len(text)) val = key[1] for i in plaintext: if i.lower() in text: if i.isupper(): sample.append([mod.residue(text.index(i.lower())*val,len(key[0])),1]) else: sample.append([mod.residue(text.index(i.lower())*val,len(key[0])),0]) # if 65<=ord(i)<=90: # sample.append([mod.residue((ord(i)-65)*val,len(key[0])),1]) # elif 97<=ord(i)<=122: # sample.append([mod.residue((ord(i)-97)*val,len(key[0])),0]) # else: # sample.append([mod.residue((ord(i)-97)*val,len(key[0])),0]) else: sample.append([ord(i),2]) for j in sample: if j[1] == 1: ciphertext+=text[j[0]].upper() elif j[1]==0: ciphertext+=text[j[0]] else: ciphertext += chr(j[0]) return ciphertext
def d_decimation(ciphertext,key): plaintext = "" sample = [] text = key[0] val = key[1] if val > len(text): val = mod.residue(val, len(text)) dec_key = mod.has_mul_inv(val,len(text)) if not dec_key: print('Error (d_decimation): Invalid key') return else: dec_key = mod.mul_inv(key[1], len(text)) for i in ciphertext: if i.lower() in text: if i.isupper(): plaintext+= text[(mod.residue(text.index(i.lower())*dec_key,len(text)))].upper() else: plaintext+=text[(mod.residue(text.index(i.lower())*dec_key,len(text)))] # if 65<=ord(i)<=90: # sample.append([mod.residue((ord(i)-65)*dec_key,26),1]) # elif 97<=ord(i)<=122: # sample.append([mod.residue((ord(i)-97)*dec_key,26),0]) else: plaintext+=i # for j in sample: # if j[1] == 1: # plaintext+=chr(j[0]+65).upper() # elif j[1]==0: # plaintext+=chr(j[0]+97) # else: # plaintext+= chr(j[0]) return plaintext
def analyze_mathCipher(baseString): # your code here total = 0 illegal = 0 noCipher = 0 decimation = 0 valid = 0 # total m = len(baseString) total = m**3 # illegal legal = 0 m_i_table = mod.mul_inv_table(m) for mi in m_i_table[1]: if mi != 'NA': legal += 1 legal *= legal legal *= m illegal = total - legal # noCipher for mi1 in m_i_table[0]: if m_i_table[1][mi1] != 'NA': for mi2 in m_i_table[0]: if m_i_table[1][mi2] != 'NA': for c in range(m): if mod.residue(mi2**2 - c, m) == 0: if mod.residue(mi1 * mi2, m) == 1: noCipher += 1 else: decimation += 1 valid = legal - decimation - noCipher return [total, illegal, noCipher, decimation, valid]
def cryptanalysis_mathCipher(ciphertext): # your code here baseString = utilities.get_baseString() length = len(baseString) dictList = utilities.load_dictionary('engmix.txt') sub_baseString = [] for j in range(25, length): sub_baseString.append(baseString[:j + 1]) attempts = 0 for n_s in sub_baseString: m = len(n_s) m_i_table = mod.mul_inv_table(m) for mi1 in m_i_table[0]: if m_i_table[1][mi1] != 'NA': for mi2 in m_i_table[0]: if m_i_table[1][mi2] != 'NA': for c in range(m): if mod.residue(mi2**2 - c, m) != 0: k = [mi1, mi2, c] key = (n_s, k) plaintext = d_mathCipher(ciphertext, key) attempts += 1 if len(utilities.remove_nonalpha( plaintext)) < len(plaintext) / 2: continue if utilities.is_plaintext( plaintext, dictList, 0.90): print('key found after ' + str(attempts) + ' attempts') return plaintext, key return '', ''
def test_q1(): print("-------------------------------------------") print("Testing Q1: Modular Arithmetic Library") filename = 'q1_solution.txt' outFile = open(filename, 'w') print() outFile.write('1- Testing residue_set:\n') outFile.write('residue_set({}) = {}\n'.format(10, mod.residue_set(10))) outFile.write('residue_set({}) = {}\n'.format(1, mod.residue_set(1))) outFile.write('residue_set({}) = '.format(-5)) outFile.write('{}\n'.format(mod.residue_set(-5))) outFile.write('residue_set({}) = '.format([5])) outFile.write('{}\n'.format(mod.residue_set([5]))) outFile.write('\n') outFile.write('2- Testing residue:\n') outFile.write('residue({},{}) = {}\n'.format(17, 5, mod.residue(17, 5))) outFile.write('residue({},{}) = '.format(3.4, 5)) outFile.write('{}\n'.format(mod.residue(3.4, 5))) outFile.write('residue({},{}) = '.format(13, -5)) outFile.write('{}\n'.format(mod.residue(13, -5))) outFile.write('\n') outFile.write('3- Testing is_congruent:\n') outFile.write('is_congruent({},{},{})= {}\n'.format( 22, 33, 11, mod.is_congruent(22, 33, 11))) outFile.write('is_congruent({},{},{}) = {}\n'.format( 7, 9, 3, mod.is_congruent(7, 9, 3))) outFile.write('is_congruent({},{},{})= '.format(3.4, 5, 9)) outFile.write('{}\n'.format(mod.is_congruent(3.4, 5, 9))) outFile.write('is_congruent({},{},{}) = '.format(3, 5, -9)) outFile.write('{}\n'.format(mod.is_congruent(3, 5, -9))) outFile.write('\n') outFile.write('4- Testing add:\n') outFile.write('add({},{},{}) = {}\n'.format(17, 23, 7, mod.add(17, 23, 7))) outFile.write('add({},{},{}) = {}\n'.format(-17, 23, 7, mod.add(-17, 23, 7))) outFile.write('add({},{},{}) = {}\n'.format(17, -23, 7, mod.add(17, -23, 7))) outFile.write('add({},{},{}) = '.format(9, 17, 0)) outFile.write('{}\n'.format(mod.add(9, 17, 0))) outFile.write('add({},{},{}) = '.format([9], 17, 7)) outFile.write('{}\n'.format(mod.add([9], 17, 7))) outFile.write('add({},{},{}) = '.format(9, 17.1, 8)) outFile.write('{}\n'.format(mod.add(9, 17.1, 8))) outFile.write('\n') outFile.write('5- Testing sub:\n') outFile.write('sub({},{},{}) = {}\n'.format(17, 23, 7, mod.sub(17, 23, 7))) outFile.write('sub({},{},{}) = {}\n'.format(-17, 23, 7, mod.sub(-17, 23, 7))) outFile.write('sub({},{},{}) = {}\n'.format(17, -23, 7, mod.sub(17, -23, 7))) outFile.write('sub({},{},{}) = '.format(9, 17, 0)) outFile.write('{}\n'.format(mod.sub(9, 17, 0))) outFile.write('sub({},{},{}) = '.format([9], 17, 7)) outFile.write('{}\n'.format(mod.sub([9], 17, 7))) outFile.write('sub({},{},{}) = '.format(9, 17.1, 8)) outFile.write('{}\n'.format(mod.sub(9, 17.1, 8))) outFile.write('\n') outFile.write('6- Testing additive inverse:\n') outFile.write('add_inv({},{}) = {}\n'.format(3, 5, mod.add_inv(3, 5))) outFile.write('add_inv({},{}) = {}\n'.format(6, 1, mod.add_inv(6, 1))) outFile.write('add_inv({},{})= {}\n'.format(22, 10, mod.add_inv(22, 10))) outFile.write('add_inv({},{}) = '.format(6, -1)) outFile.write('{}\n'.format(mod.add_inv(6, -1))) outFile.write('add_inv({},{}) = '.format(6.2, 6)) outFile.write('{}\n'.format(mod.add_inv(6.2, 6))) a = 4 b = 2 m = 5 result = mod.sub(a, b, m) == mod.add(a, mod.add_inv(b, m), m) outFile.write( 'sub({0},{1},{2}) == add({0},add_inv({1},{2}),{2})? = {3}\n'.format( a, b, m, result)) outFile.write('\n') outFile.write('7- Testing Addition Table:\n') outFile.write('Addition Table for mode {} =\n'.format(5)) addTab = mod.add_table(5) for i in range(len(addTab)): outFile.write(str(addTab[i])) outFile.write('\n') outFile.write('Addition Table for mode {} =\n'.format(8)) addTab = mod.add_table(8) for i in range(len(addTab)): outFile.write(str(addTab[i])) outFile.write('\n') outFile.write('Addition Table for mode {} =\n'.format(0)) outFile.write(mod.add_table(0)) outFile.write('\n') outFile.write('\n') outFile.write('8- Testing Subtraction Table:\n') outFile.write('Subtraction Table for mode {} =\n'.format(5)) subTab = mod.sub_table(5) for i in range(len(subTab)): outFile.write(str(subTab[i])) outFile.write('\n') outFile.write('Subtraction Table for mode {} =\n'.format(8)) subTab = mod.sub_table(8) for i in range(len(subTab)): outFile.write(str(subTab[i])) outFile.write('\n') outFile.write('Subtraction Table for mode {} =\n'.format([5])) outFile.write(mod.sub_table([5])) outFile.write('\n') outFile.write('\n') outFile.write('9- Testing Addition Inverse Table:\n') outFile.write('Addition Inverse Table for mode {} =\n'.format(5)) addInvTab = mod.add_inv_table(5) outFile.write(str(addInvTab[0])) outFile.write('\n') outFile.write(str(addInvTab[1])) outFile.write('\n') outFile.write('Addition Inverse Table for mode {} =\n'.format(26)) addInvTab = mod.add_inv_table(26) outFile.write(str(addInvTab[0])) outFile.write('\n') outFile.write(str(addInvTab[1])) outFile.write('\n') outFile.write('Addition Inverse Table for mode {} =\n'.format(-2)) outFile.write(mod.add_inv_table(-2)) outFile.write('\n') outFile.write('\n') outFile.write('10- Testing mul:\n') outFile.write('mul({},{},{}) = {}\n'.format(3, 5, 5, mod.mul(3, 5, 5))) outFile.write('mul({},{},{}) = {}\n'.format(8, 3, 7, mod.mul(8, 3, 7))) outFile.write('mul({},{},{})= {}\n'.format(17, -3, 7, mod.mul(17, -3, 7))) outFile.write('mul({},{},{}) = '.format(9, 17, 0)) outFile.write('{}\n'.format(mod.mul(9, 17, 0))) outFile.write('mul({},{},{}) = '.format([9], 17, 7)) outFile.write('{}\n'.format(mod.mul([9], 17, 7))) outFile.write('mul({},{},{}) = '.format(9, 17.1, 8)) outFile.write('{}\n'.format(mod.mul(9, 17.1, 8))) outFile.write('\n') outFile.write('11- Testing Multiplication Table:\n') outFile.write('Multiplication Table for mode {} =\n'.format(4)) mulTab = mod.mul_table(4) for i in range(len(mulTab)): outFile.write(str(mulTab[i])) outFile.write('\n') outFile.write('Multiplication Table for mode {} =\n'.format(5)) mulTab = mod.mul_table(5) for i in range(len(mulTab)): outFile.write(str(mulTab[i])) outFile.write('\n') outFile.write('Multiplication Table for mode {} =\n'.format(-5)) outFile.write(mod.mul_table(-5)) outFile.write('\n') outFile.write('\n') outFile.write('12- Testing is_prime:\n') outFile.write('is_prime({}) = {}\n'.format(97, mod.is_prime(97))) outFile.write('is_prime({}) = {}\n'.format(479, mod.is_prime(479))) outFile.write('is_prime({})= {}\n'.format(1044, mod.is_prime(1044))) outFile.write('is_prime({}) = {}\n'.format(0, mod.is_prime(0))) outFile.write('is_prime({}) = {}\n'.format(-17, mod.is_prime(-17))) outFile.write('\n') outFile.write('13- Testing gcd:\n') outFile.write('gcd({},{}) = {}\n'.format(629, 357, mod.gcd(629, 357))) outFile.write('gcd({},{}) = {}\n'.format(440, 700, mod.gcd(440, 700))) outFile.write('gcd({},{}) = {}\n'.format(-30, 700, mod.gcd(-30, 700))) outFile.write('gcd({},{}) = {}\n'.format(540, -539, mod.gcd(540, -539))) outFile.write('gcd({},{}) = '.format(711, 0)) outFile.write(mod.gcd(711, 0)) outFile.write('\n') outFile.write('gcd({},{}) = '.format(0, 311)) outFile.write(mod.gcd(0, 311)) outFile.write('\n') outFile.write('gcd({},{}) = '.format([9], 27)) outFile.write(mod.gcd([9], 27)) outFile.write('\n') outFile.write('\n') outFile.write('14- Testing is_relatively_prime:\n') outFile.write('is_relatively_prime({},{}) = {}\n'.format( 4, 5, mod.is_relatively_prime(4, 5))) outFile.write('is_relatively_prime({},{})= {}\n'.format( 540, 539, mod.is_relatively_prime(540, 539))) outFile.write('is_relatively_prime({},{}) = {}\n'.format( 18, 26, mod.is_relatively_prime(18, 26))) outFile.write('is_relatively_prime({},{}) = {}\n'.format( 0, 26, mod.is_relatively_prime(0, 26))) outFile.write('is_relatively_prime({},{}) = '.format([1], 26)) outFile.write(mod.is_relatively_prime([1], 26)) outFile.write('\n') outFile.write('\n') outFile.write('15- Testing has_mul_inv:\n') outFile.write('has_mul_inv({},{}) = {}\n'.format( 4, 5, mod.has_mul_inv(4, 5))) outFile.write('has_mul_inv({},{}) = {}\n'.format(17, 26, mod.has_mul_inv(17, 26))) outFile.write('has_mul_inv({},{}) = {}\n'.format(18, 26, mod.has_mul_inv(18, 26))) outFile.write('has_mul_inv({},{}) = {}\n'.format( 0, 26, mod.has_mul_inv(0, 26))) outFile.write('has_mul_inv({},{}) = '.format([1], 26)) outFile.write(mod.has_mul_inv([1], 26)) outFile.write('\n') outFile.write('\n') outFile.write('16- Testing EEA:\n') outFile.write('eea({},{}) = {}\n'.format(700, 440, mod.eea(700, 440))) outFile.write('eea({},{}) = {}\n'.format(88, 35, mod.eea(88, 35))) outFile.write('eea({},{}) = {}\n'.format(35, 88, mod.eea(35, 88))) outFile.write('eea({},{}) = {}\n'.format(-88, 35, mod.eea(-88, 35))) outFile.write('eea({},{}) = {}\n'.format(88, -35, mod.eea(88, -35))) outFile.write('eea({},{}) = '.format(0, 777)) outFile.write(mod.eea(0, 777)) outFile.write('\n') outFile.write('\n') outFile.write('17- Testing mul_inv:\n') outFile.write('mul_inv({},{}) = {}\n'.format(23, 26, mod.mul_inv(23, 26))) outFile.write('mul_inv({},{}) = {}\n'.format(5, 6, mod.mul_inv(5, 6))) outFile.write('mul_inv({},{}) = {}\n'.format(24, 26, mod.mul_inv(24, 26))) outFile.write('mul_inv({},{}) = {}\n'.format(700, 440, mod.mul_inv(700, 440))) outFile.write('mul_inv({},{}) = {}\n'.format(0, 777, mod.mul_inv(700, 440))) outFile.write('mul_inv({},{}) = '.format(1, [99])) outFile.write(mod.mul_inv(1, [99])) outFile.write('\n') outFile.write('mul_inv({},{}) = '.format([1], 99)) outFile.write(mod.mul_inv([1], 99)) outFile.write('\n') outFile.write('\n') outFile.write('18- Testing Multiplicative Inverse Table:\n') outFile.write('Multiplicative Inverse Table for mode {} =\n'.format(5)) mulInvTab = mod.mul_inv_table(5) outFile.write(str(mulInvTab[0])) outFile.write('\n') outFile.write(str(mulInvTab[1])) outFile.write('\n') outFile.write('Multiplicative Inverse Table for mode {} =\n'.format(26)) mulInvTab = mod.mul_inv_table(26) outFile.write(str(mulInvTab[0])) outFile.write('\n') outFile.write(str(mulInvTab[1])) outFile.write('\n') outFile.write('Multiplicative Inverse Table for mode {} =\n'.format(-2)) outFile.write(mod.mul_inv_table(-2)) outFile.write('\n') outFile.write('\n') outFile.close() print('Comparing q1_solution with q1_sample:') print(utilities_A4.compare_files('q1_solution.txt', 'q1_sample.txt')) print() print("-------------------------------------------") return