BASIC ENCRYPTION We show how to encrypt and decrypt text strings using a simple text to number translation scheme from Tom Davis' notes. The encryption algorithm is basic: multiply by a mod N to encrypt, multiply by the multiplicative inverse of a to decrypt. In the examle below, we set a = 17, N = 10000, and b = 2353, where ab = 1 mod N. The text to number code is at the end of these notes (see tdavis.py). >>> from isolve import * >>> a = 17 >>> N = 10000 >>> isolve(a,N,1) [2353, -4] >>> b = 2353 >>> f = lambda x: a*x % N >>> g = lambda x: b*x % N Check that g is the inverse function of f: >>> g(f(5)) 5 Import utilities to convert strings to blocks of integers and vice versa >>> from tdavis import * >>> s2b('hello',2) [4441, 4848, 5171] >>> b2s(_) 'hello@' Thus s2b and b2s are almost inverse functions. Padding is added if the length of the string is not a multiple of the block size. EXAMPLE. We encrpt the message hello. >>> s2b("hello",2) [4441, 4848, 5171] >>> map(f,_) [5497, 2416, 7907] >>> b2s(_) 'r7NF+\xc8' Thus "hello" is encrypted as "r7NF+\xc8". EXAMPLE. We decrypt the text "r7NF+\xc8". >>> s2b("r7NF+\xc8",2) [5497, 2416, 7907] >>> map(g,_) [4441, 4848, 5171] >>> b2s(_) 'hello@' --------------------------------------------------------------------- tdavis.py: ############################################# # # dict # reverselookup(D,key) # charlist2str(L) # # s2v, v2s -- convert between strings and vector of 2-digit integers according to dict # incb(v,s): increase block size in list of integers v from 2 to 2b # decb(b): decrease block size -- convert 2b block of integers to list of 2-digit integers # s2b, b2s -- converst between strings and vectors of 2b-digit integers # ############################################# # dict is Tom Davis' character dictionary, except that # we have put arbitrary characters in positions 0 -- 9 # where Davis has put "X" from random import randint dict = { '\xc1':0, '\xc2':1, '\xc3':2, '\xc4':3, '\xc5':4, '\xc6':5, '\xc7':6, '\xc8':7, '\xc9':8, '\xca':9, ' ':10, 'A':11, 'B':12, 'C':13, 'D':14, 'E':15, 'F':16, 'G': 17, 'H':18, 'I':19, 'J':20, 'K':21, 'L':22, 'M':23, 'N':24, 'O':25, 'P':26, 'Q':27, 'R':28, 'S':29, 'T':30, 'U':31, 'V':32, 'W':33, 'X':34, 'Y':35, 'Z':36, 'a':37, 'b':38, 'c':39, 'd':40, 'e':41, 'f':42, 'g':43, 'h':44, 'i':45, 'j':46, 'k':47, 'l':48, 'm':49, 'n':50, 'o':51, 'p':52, 'q':53, 'r':54, 's':55, 't':56, 'u':57, 'v':58, 'w':59, 'x':60, 'y':61, 'z':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, '0':90, '1':91, '2':92, '3':93, '4':94, '5':95, '6':96, '7':97, '8':98, '9':99 } def reverselookup(D,key): for item in D: if D[item] == key: break return item def charlist2str( L ): """charlist2str(L): convert list of characters into a string""" s = '' for c in L: s = s+c return s ########################################################################## # s2v("ABC") = [11, 12, 13] # v2s(s2v("ABC")) = "ABC" s2v = lambda s: map( lambda x: dict[x], s) v2s = lambda v: charlist2str(map( lambda x: reverselookup(dict,x), v)) ########################################################################## def incb(v,b): """increase block size from 2 digits to 2b digits""" r = len(v) % b if r > 0: for k in range(0,b-r): v.append(0) L = [] N = 0 p10 = 1 j = len(v)-1 while j >= 0: N = N + p10*v[j] p10 = 100*p10 if j % b == 0: L = [N] + L p10 = 1 N = 0 j = j - 1 return L def decb(b): """decb: decrease block size to two digits b2v(12345678) = [12, 34, 56, 78]""" v = [] while b > 0: v = [b % 100] + v b = b//100 return v ######################################################################### def b2s(B): block2s = lambda b: v2s(decb(b)) bb2s = lambda blockList: map(block2s, blockList) strings = bb2s(B) output = '' for string in strings: output = output + string return output s2b = lambda s, b: incb(s2v(pad(s,b)),b) def pad(s,b): """return t, where t = s+x, s+x has kb characters""" n = len(s) r = n % b if r > 0: padding = "@"+randstring(b-r-1) else: padding="" return s + padding def randstring(k): """return random string of k characters""" s = "" if k <= 0: return "" alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'] na = len(alphabet) for j in range(0,k): rn = randint(0,na-1) s = s+alphabet[rn] return s def concatlist(L): s = "" for k in range(0,len(L)): s = s+`L[k]` return s #####################################################################