Professional Documents
Culture Documents
l
implementation
of Ron's Cipher
#4 (AKA RC4).
Follows form of a `Programming Praxis exercise`_.
.. _Programming Praxis exercise:
http://programmingpraxis.com/2009/09/04/rons-cipher-4/
:author: Christopher D. Leary <cdleary@gmail.com>
"""
import textwrap
try:
import readline
except ImportError: # Only available on POSIX, but no big deal.
pass
def initialize(key):
"""Produce a 256-entry list based on `key` (a sequence of
numbers)
as the first step in RC4.
Note: indices in key greater than 255 will be ignored.
"""
k = range(256)
j = 0
for i in range(256):
j = (j + k[i] + key[i % len(key)]) % 256
k[i], k[j] = k[j], k[i]
return k
def gen_random_bytes(k):
"""Yield a pseudo-random stream of bytes based on 256-byte array
`k`."""
i = 0
j = 0
while True:
i = (i + 1) % 256
j = (j + k[i]) % 256
k[i], k[j] = k[j], k[i]
yield k[(k[i] + k[j]) % 256]
def loop_user_query(k):
"""Raises EOFError when the user uses an EOT escape sequence
(i.e. ^D)."""
quotes = "'\""
while True:
text = raw_input('Enter plain or cipher text: ')
if text[0] == text[-1] and text[0] in quotes:
# Unescape presumed ciphertext.
print 'Unescaping ciphertext...'
text = text[1:-1].decode('string_escape')
k_copy = list(k)
print 'Your RC4 text is:', repr(run_rc4(k_copy, text))
print
def print_prologue():
title = 'RC4 Utility'
print '=' * len(title)
print title
print '=' * len(title)
explanation = """The output values are valid Python strings. They
may
contain escape characters of the form \\xhh to avoid confusing your
terminal
emulator. Only the first 256 characters of the encryption key are
used."""
for line in textwrap.wrap(explanation, width=79):
print line
print
def main():
"""Present a command-line interface to the cipher."""
print_prologue()
# Acquire initial cipher values.
key = raw_input('Enter an encryption key: ')
print
key = [ord(char) for char in key]
k = initialize(key)
# Perform cipher until exit.
try:
loop_user_query(k)
except EOFError:
print
print 'Have a pleasant day!'
if __name__ == '__main__':
main()
#Initia
l
IP = [58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17, 9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7]
#Final
FP = [40,8,48,16,56,24,64,32,
39,7,47,15,55,23,63,31,
38,6,46,14,54,22,62,30,
37,5,45,13,53,21,61,29,
36,4,44,12,52,20,60,28,
35,3,43,11,51,19,59,27,
34,2,42,10,50,18,58,26,
33,1,41, 9,49,17,57,25]
#Expansion Function E
EP = [32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9,10,11,12,13,
12,13,14,15,16,17,
16,17,18,19,20,21,
20,21,22,23,24,25,
24,25,26,27,28,29,
28,29,30,31,32, 1]
#Permutation P in expansion
RP = [16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25]
S1 = [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5,
3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10,
5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0,
6, 13]
#PC-1
PC1 = [ 57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4]
#PC-2
PC2 = [14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32]
def permute(x,y,p_table):
for character in p_table :
y+=x[character-1]
return y
#Rotate
def rotateright(x, n,bits):
mask = (2**n) - 1
mask_bits = x & mask
return (x >> n) | (mask_bits << (bits - n))
def sbox(bits,sbox):
x = bin(bits[1:5])[2:].zfill(4)
y = bin(bits[0]+bits[5])[2:].zfill(2)
return sbox[int(x,2)+int(y,2)*16]
def ffunction(input_bin_r_expan,pc1_key_ff):
input_bin_r_expan_int=int(("".join(input_bin_r_expan)),2)
pc1_key_ff1 = []
permute(pc1_key_ff,pc1_key_ff1,EP)
pc1_key_ff_int=int(("".join(pc1_key_ff1)),2)
x=list(bin(input_bin_r_expan_int ^ pc1_key_ff_int))
z=[]
for i in range(0,8,1):
if i > 0 :
z += sbox(x[6*i-1][0:6],SBOX[i])
z += sbox(x[6*i][0:6],SBOX[i])
return int(("".join(z)),2)
print("")
cipher = "1111111111111111111111111110000000000000000000011111111000000111"
cipher1 = []
#decrypt use FP inverse
permute(cipher,cipher1,IP)
#key = input()
leftbit = cipher[28:]
rightbit = cipher[0:28]
leftbit1 = int(("".join(leftbit)),2)
rightbit1 = int(("".join(rightbit)),2)
key = "1111111111111111000000000000000011111111111100000000001111111111"
key1 = []
permute(key,key1,PC1)
print(type(key))
print(type(key1))
key1 = "".join(key1)
key1_c = key1[0:28]
key1_d = key1[28:]
key1left=int(("".join(key1_c)),2)
key1right=int(("".join(key1_d)),2)
sumbit=[]
for i in range(16, 1, -1):
if i < 16 :
key1 = bin(rotateright(key1left, SHIFT[i-1], 28))[2:].zfill(28)
+ bin(rotateright(key1right, SHIFT[i-1], 28))[2:].zfill(28)
key2 = []
permute(key1,key2,PC2)
tmp = rightbit1
rightbit1 = leftbit1
leftbit1_bin = bin(leftbit1)[2:].zfill(32)
#!/usr/bin/en
v python
# -*- coding: utf-8 -*-
#
# DES.py
#
# Author: Overxfl0w13
import binascii
def header():
print """
____ _____ ____ ____ ______ ______ _____
| _ \| ____/ ___| / ___| _ \ \ / / _ \_ _|
| | | | _| \___ \ | | | |_) \ V /| |_) || |
| |_| | |___ ___) | | |___| _ < | | | __/ | |
|____/|_____|____/ \____|_| \_\|_| |_| |_|
"""
### UTILS ###
def leftRotate(b,n):
for shift in xrange(n): b = b[1:len(b)] + b[0]
return b
def addPadding(s):
while len(s)%64!=0: s += "0"
return s
def split64blocks(s):
blocks,i = [],0
while (i*64)<len(s):
blocks.append(s[64*i:64*(i+1)])
i += 1
return blocks
def computeSBox(block6,sBox):
row,col = int(block6[0]+block6[len(block6)-
1],2),int(block6[1:len(block6)-1],2)
r = bin(sBox[row][col])[2:]
while len(r)!=4: r = "0"+r
return r
def make16keys(c0,d0,shiftsSchedule,pc2):
cc0,cd0,keys = c0,d0,[(c0+d0)]
for i in xrange(16):
cc0,cd0 =
leftRotate(cc0,shiftsSchedule[i]),leftRotate(cd0,shiftsSchedule[i])
keys.append(makePermutation(cc0+cd0,pc2))
return keys
def computeF(r,k,expansionTable):
eR = makePermutation(r,expansionTable)
eRxK = xor(k,eR)
print "ER:",eR
print "Key:",k
print "Result:",xor(k,eR)
blocks6 = blocks6Bits(eRxK)
sBoxed,i = [],0
for SBOX in SBOXES:
sBoxed.append(computeSBox(blocks6[i],SBOX)) ; i+=1
sBoxed = "".join(sBoxed)
print "SBoxed: ",sBoxed
sBoxed = makePermutation(sBoxed,P)
print "Permuted: ",sBoxed
return sBoxed
def blocks6Bits(s):
blocks,i = [],6
while i<=len(s): blocks.append(s[i-6:i]); i+=6
return blocks
### DES ###
S2 = [[15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10],
[3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5],
[0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15],
[13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9]]
S3 = [[10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8],
[13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1],
[13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7],
[1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12] ]
S4 = [[7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15],
[13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9],
[10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4],
[3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14]]
S5 = [[2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9],
[14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6],
[4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14],
[11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3]]
S6 = [[12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11],
[10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8],
[9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6],
[4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13]]
S7 = [[4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1],
[13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6],
[1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2],
[6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12]]
S8 = [[13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7],
[1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2],
[7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8],
[2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11]]
SBOXES = [S1,S2,S3,S4,S5,S6,S7,S8]
expansionTable = [ 32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9,10, 11, 12,13,
12, 13,14, 15, 16,17,
16, 17,18, 19, 20,21,
20, 21,22, 23, 24,25,
24, 25,26, 27, 28,29,
28, 29,30, 31, 32, 1 ]
shiftsSchedule = [1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1]
P = [16,7,20,21,
29,12,28,17,
1,15,23,26,
5,18,31,10,
2,8,24,14,
32,27,3,9,
19,13,30,6,
22,11,4,25]
INVIP = [ 40,8,48,16,56,24,64,32
,39,7,47,15,55,23,63,31
,38,6,46,14,54,22,62,30
,37,5,45,13,53,21,61,29
,36,4,44,12,52,20,60,28
,35,3,43,11,51,19,59,27
,34,2,42,10,50,18,58,26
,33,1,41,9,49,17,57,25 ]
if __name__ == '__main__':
header()
pt = getBitString(raw_input("Msg> "))
print "\n\n ***** MSG ANALYSIS ***** \n\n"
print "Plain text:",pt,"\n"
pt = addPadding(pt)
print "Plain text padded:",pt,"\n"
blocks64 = split64blocks(pt)
print "64 bit blocks:",blocks64,"\n"
key = getBitString(raw_input("Key> ")) # 64 bits key, else key
will be padded ******* #
print "\n\n ***** KEY ANALYSIS ***** \n\n"
print "Key:",key,"\n"
key = addPadding(key)
print "Key padded:",key,"\n"
key = makePermutation(key,PC1)
print "Permuted key with PC1:",key
hKey = halved(key)
print "Halved key:",hKey,"\n\n\n"
keys = make16keys(hKey[0],hKey[1],shiftsSchedule,PC2)
print "Generated keys:",keys,"\n\n"
print "\n\n ****** Initialize encryption *****\n\n"
ciphered,auxCiph = "",""
for i in xrange(len(blocks64)):
print "\n ***** BLOCK,",i,"*****\n"
IP = makePermutation(blocks64[i],IPR)
print "Initial permutation (IP):",IP,"\n"
hIP = halved(IP)
L0,R0 = hIP[0],hIP[1]
actL,actR,antL,antR = L0,R0,L0,R0
print "Halved IP:",hIP[0],"-",hIP[1],"\n"
## 16 stages ##
for i in xrange(1,17):
print "\n\n ***** STAGE",i,"***** \n\n"
antL,antR = actL,actR
actL,actR =
antR,xor(antL,computeF(antR,keys[i],expansionTable))
print "AntL="+antL,"\nAntR="+antR,"\n"
print "ActL="+actL,"\nActR="+actR,"\n"
auxCiph = makePermutation(actR+actL,INVIP)
ciphered += hex(int(auxCiph,2))[2:-1]
print "Ciphered:",ciphered.upper()