RSA code
RSA code is used to encode secret messages. The advantage of this type of encryption is that you can distribute the number "n" and "e" (which make up the encryption key) to everyone. The decryption key "d" is kept secret, so only you and a select few can read the encrypted plaintext. The process by which this is done is that a message, for example "Hello World" is converted to numbers (a=01,b=02,...,z=26). This yields 2 blocks of numbers, generally referred to as "numerical plaintext", or "P". For this example, "Hello World" would be [805121215, 2315181204]. The ciphertext, C, is then computed by taking each block of P, and computing C ≡ P^e mod(n). Similarly, to decode, one computes P ≡ C^d mod(n).
To generate a key, one finds 2 (large) primes p and q. the value "n" is simply: n = p*q. One must then choose an "e" such that gcd(e, (p-1)*(q-1) ) = 1. That is to say, e and (p-1)*(q-1) are relatively prime to each other. The decryption value d is then found by solving d*e ≡ 1 mod((p-1)*(q-1))
It is important to note that a numerical plaintext block cannot be greater than the value of "n", else decryption will not find the correct values due to the presence of the mod(n). Also important is that the security of the code is based off the secrecy of the decryption exponent "d", and therefor is based off the difficulty in factoring "n".
J
<lang j>NB. keys N=: 2537x E=: 13x D=: 937x
NB. blocks letters=: 'abcdefghijklmnopqrstuvwxyz,.!? ' base=: 1+#letters blocksize=: base <.@^. N pad=: base ?@#~ blocksize | -@# txt2num=: ((-blocksize) base&#.\ 1x + letters&i. , pad) :.num2txt num2txt=: ((' ',letters) {~ ,@:#:~&(blocksize#base) ) :.txt2num
NB. RSA algorithm cypher=: N&|@^ encrypt=: cypher&E@txt2num decrypt=: num2txt@:cypher&D</lang>
Example use:
<lang j> encrypt 'hi there' 695 153 2377 260
decrypt 695 153 2377 260
hi there</lang>
Python
This code will open up a simple Tkinter window which has space to type a message. That message can then be encrypted by pressing the button labeled "encrypt". It will then print an output of ciphertext blocks, separated by commas. To decrypt a message, simply press the decrypt button. All ciphertext data must be entered with each block separated by commas. The ciphertext always goes (and appears) in the bottom box, while plaintext goes (and appears) in the topmost box.
This code was made just for fun, feel free to suggest anything to make it better. The key given here is a toy key, it is easily broken. --Erasmus 04:23, 24 March 2011 (UTC) <lang python>
from tkinter import * import random import time
letter = ["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",",",".","!","?",' ']
number = ["01","02","03","04","05","06","07","08","09","10","11","12","13",
"14","15","16","17","18","19","20","21","22","23","24","25","26","27", "28","29","30",'31']
n = 2537 e = 13 d = 937 def decrypt(F,d):
# performs the decryption function on an block of ciphertext if d == 0: return 1 if d == 1: return F w,r = divmod(d,2) if r == 1: return decrypt(F*F%n,w)*F%n else: return decrypt(F*F%n,w)
def correct():
# Ensures that there are no orphaned letters at the end of a plaintext message by padding with random letters. for i in range(len(D)): if len(str(P[i]))%2 !=0: y = str(0)+str(P[i]) P.remove(str(P[i])) P.insert(i,y)
def cipher(b,e):
# Performs the Encryption function on a block of ciphertext if e == 0: return 1 if e == 1: return b w,r = divmod(e,2) if r == 1: return cipher(b*b%n,w)*b%n else: return cipher(b*b%n,w)
def group(j,h,z):
# Places the plaintext numbers into blocks for encryption for i in range(int(j)): y = 0 for n in range(h): y += int(numP[(h*i)+n])*(10**(z-2*n)) X.append(int(y))
class App:
# Makes a nice frame, for ease of use def __init__(self, master):
frame = Frame(master) frame.grid()
quitbutton = Button(frame, text = "quit", fg ="red", command = root.quit, width = 10) quitbutton.grid(row = 0, column =3)
entry = Entry(frame, width = 100) entry.grid(row = 0, column = 0)
self.contents = StringVar() self.contents.set("Type message here") entry["textvariable"] = self.contents #entry.bind('<Key-Return>',self.Encrypt)
decrypt = Button(frame,text = "Decrypt", fg = "blue", command = self.Decrypt) decrypt.grid(row = 2, column = 1)
label = Label(frame, text = "# of blocks") label.grid(row = 1, column = 1)
encrypt = Button(frame, text="Encrypt", fg = "blue", command = self.Encrypt) encrypt.grid(row =0, column =1)
nbox = Entry(frame, width = 100) nbox.grid(row = 3, column = 0)
self.n = StringVar() self.n.set(n) nbox["textvar"] = self.n nbox.bind('<Key-Return>', self.set_n)
nlabel = Label(frame, text = "the value of 'n'") nlabel.grid(row = 3, column = 1)
ebox = Entry(frame, width = 100) ebox.grid(row = 4, column = 0)
self.e = StringVar() self.e.set(e) ebox["textvar"] = self.e ebox.bind('<Key-Return>', self.set_e)
elabel = Label(frame, text = "the value of 'e'") elabel.grid(row = 4, column = 1)
dbox = Entry(frame, width = 100) dbox.grid(row =5, column = 0)
self.d = StringVar() self.d.set(d) dbox["textvar"] = self.d dbox.bind('<Key-Return>', self.set_d)
dlabel = Label(frame, text = "the value of 'd'") dlabel.grid(row = 5, column =1)
blocks = Label(frame, width = 100) blocks.grid(row = 1, column =0)
self.block = StringVar() self.block.set("number of blocks") blocks["textvar"] = self.block output = Entry(frame, width = 100) output.grid(row = 2, column = 0)
self.answer = StringVar() self.answer.set("Ciphertext") output["textvar"] = self.answer
def set_n(self,event): global n n = int(self.n.get()) print("n set to", n)
def set_e(self, event): global e e = int(self.e.get()) print("e set to",e)
def set_d(self,event): global d d = int(self.d.get()) print("d set to", d) def Decrypt(self): #decrypts an encoded message global m,P,D,x,h,p,Text,y,w,PText P = [] D = str(self.answer.get()) D = D.lstrip('[') D = D.rstrip(']') D = D.split(',') for i in range(len(D)): x = decrypt(int(D[i]),d) P.append(str(x)) correct() #print(P) h = len(P[0]) p = [] for i in range(len(D)): for n in range(int(h/2)): p.append(str(P[i][(2*n):((2*n)+2)])) Text = [] for i in range(len(p)): for j in range(len(letter)): if str(p[i]) == number[j]: Text.append(letter[j]) PText = str() for i in range(len(Text)): PText = PText + str(Text[i]) self.contents.set(str(PText))
def Encrypt(self): #encrypts a plaintext message using the current key global plaintext,numP,q,j,z,X,C plaintext = self.contents.get() plaintext = plaintext.lower() numP = [] for i in range(len(plaintext)): for j in range(len(letter)): if plaintext[i] == letter[j]: numP.append(number[j]) #print("Number of letters in message:",len(numP)) #print("Max block length:",len(str(n))/2) #h = int(input("Desired block length:")) h = (len(str(n))//2)-1 q = len(numP)%h for i in range(h-q): numP.append(number[random.randint(0,25)]) j = len(numP) / h #print(numP) X = [] z = 0 for m in range(h-1): z+=2 group(j,h,z) k = len(X) C = [] for i in range(k): b = X[i] r = cipher(b,e) C.append(r) self.answer.set(C) self.block.set(len(C))
root = Tk()
app = App(root)
root.mainloop() root.destroy()