RSA code: Difference between revisions

From Rosetta Code
Content added Content deleted
(J: simplify)
m (J: use space instead of DEL for irrelevant character)
Line 15: Line 15:
pad=: base ?@#~ blocksize | -@#
pad=: base ?@#~ blocksize | -@#
txt2num=: ((-blocksize) base&#.\ 1x + letters&i. , pad) :.num2txt
txt2num=: ((-blocksize) base&#.\ 1x + letters&i. , pad) :.num2txt
num2txt=: ((DEL,letters) {~ ,@:#:~&(blocksize#base) ) :.txt2num
num2txt=: ((' ',letters) {~ ,@:#:~&(blocksize#base) ) :.txt2num


NB. RSA algorithm
NB. RSA algorithm

Revision as of 17:15, 25 March 2011

RSA code is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

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.

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 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()