""" Module with useful functions to experiment with public key cryptography. To use in sage, apply the load() function. """ def to_number(message): """ Maps the lower case letters from 'a' to 'z' to the numbers 1 to 26, the space is mapped to 0. With this map, the message gets converted to one big number, and the number is returned. """ alphabet = [chr(k) for k in range(ord('a'), ord('z')+1)] alphabet.insert(0, ' ') numbvals = [n for n in range(0, 27)] items = [t for t in zip(alphabet, numbvals)] str2num = dict(items) vals = [str2num[c] for c in message] return ZZ(list(reversed(vals)), base=100) def to_string(number): """ Given a positive number, returns the corresponding string of characters, inverting the to_number: to_string(to_number(message)) == message. """ alphabet = [chr(k) for k in range(ord('a'), ord('z')+1)] alphabet.insert(0, ' ') numbvals = [n for n in range(0, 27)] items = [t for t in zip(numbvals, alphabet)] num2str = dict(items) vals = ZZ(number).digits(base=100) # letters = [num2str[x] for x in vals] letters = [] for val in vals: try: letters.append(num2str[val]) except KeyError: letters.append('?') letters.reverse() return ''.join(letters) def modexp(message, expkey, modkey): """ Applies modular exponentiation on the numerical message, using exponent expkey modulo the modkey. """ result = 0 wrk = message shift = 1 while wrk > 0: rest = wrk % modkey result = power_mod(rest, expkey, modkey)*shift + result wrk = (wrk - rest)/modkey shift = shift*modkey return result