Created
May 31, 2016 07:27
-
-
Save anonymous/756a1ff2a5de9c6babfa989e6d090341 to your computer and use it in GitHub Desktop.
Ruby 8 bit S-DES encryption
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Ruby_Encryption.rb | |
#Shifts each half of number left one | |
def shift(number) | |
first_perm = "" | |
second_perm = "" | |
for i in 0..3 | |
first_perm += number[i + 1] | |
second_perm += number[i + 6] | |
end | |
first_perm += number[0] | |
second_perm += number[5] | |
finish = first_perm | |
finish += second_perm | |
return finish | |
end | |
#Creates an 8 digit key out of 4 digits | |
def ep(permute) | |
change = [3,0,1,2,1,2,3,0] | |
finish = "" | |
for i in 0..7 | |
finish += permute[change[i]] | |
end | |
return finish | |
end | |
#Uses a premade permutation to change the order of the input | |
def p10(number) | |
change = [2,4,1,6,3,9,0,8,7,5] | |
finish = "" | |
for i in 0..9 | |
finish += number[change[i]] | |
end | |
return finish | |
end | |
#Pulls in 10 bits, changes order and cuts out the first two bits | |
def p8(number) | |
change = [5,2,6,3,7,4,9,8] | |
finish = "" | |
for i in 0..7 | |
finish += number[change[i]] | |
end | |
return finish | |
end | |
#Uses a premade permutation to change the order of the input | |
def p4(number) | |
change = [1,3,2,0] | |
finish = "" | |
for i in 0..3 | |
finish += number[change[i]] | |
end | |
return finish | |
end | |
#Uses a premade permutation to change the order of the input | |
def ip(plaintext) | |
change = [1,5,2,0,3,7,4,6] | |
finish = "" | |
for i in 0..7 | |
finish += plaintext[change[i]] | |
end | |
return finish | |
end | |
#Uses a premade permutation to change the order of the input | |
def ip1(number) | |
change = [3,0,2,4,6,1,7,5] | |
finish = "" | |
for i in 0..7 | |
finish += number[change[i]] | |
end | |
return finish | |
end | |
#Switches the first half and last half of an 8 bit sequence | |
def sw(number) | |
finish = " " | |
for i in 0..3 | |
finish[i] = (number[i + 4]) | |
finish += number[i] | |
end | |
return finish | |
end | |
def s0(plaintext) | |
array = [[1,0,3,2], | |
[3,2,1,0], | |
[0,2,1,3], | |
[3,1,3,2]] | |
t_row = plaintext[0] | |
t_row += plaintext[3] | |
t_col = plaintext[1] | |
t_col += plaintext[2] | |
hold = array[t_row.to_i(2)][t_col.to_i(2)] | |
if hold == 0 | |
hold = "00" | |
elsif hold == 1 | |
hold = "01" | |
else | |
hold = hold.to_s(2) | |
end | |
return hold | |
end | |
def s1(plaintext) | |
array = [[0,1,2,3], | |
[2,0,1,3], | |
[3,0,1,0], | |
[2,1,0,3]] | |
t_row = plaintext[0] | |
t_row += plaintext[3] | |
t_col = plaintext[1] | |
t_col += plaintext[2] | |
hold = array[t_row.to_i(2)][t_col.to_i(2)] | |
if hold == 0 | |
hold = "00" | |
elsif hold == 1 | |
hold = "01" | |
else | |
hold = hold.to_s(2) | |
end | |
return hold | |
end | |
def exor(plaintext, primekey) | |
count = plaintext.length | |
finish = "" | |
for i in 0...count | |
if plaintext[i] == primekey[i] | |
finish += "0" | |
else | |
finish += "1" | |
end | |
end | |
return finish | |
end | |
def encrypt(plaintext, number) | |
newplaintext = ip(plaintext) | |
fk = "" | |
permute = "" | |
permute1 = "" | |
permutehold = "" | |
#Getting two keys | |
key1 = p10(number) | |
key1 = shift(key1) | |
key2 = key1 | |
key1 = p8(key1) | |
key2 = shift(key2) | |
key2 = shift(key2) | |
key2 = p8(key2) | |
for i in 0..3 | |
fk += newplaintext[i] | |
permute += newplaintext[i + 4] | |
permutehold += newplaintext[i + 4] | |
end | |
newplaintext = ep(permute) | |
newplaintext = exor(newplaintext, key1) | |
for i in 0..3 | |
permute1 += newplaintext[i] | |
permute[i] = newplaintext[i + 4] | |
end | |
byte = s1(permute) | |
byte1 = s0(permute1) | |
byte1 += byte | |
byte = p4(byte1) | |
newplaintext = exor(fk, byte) | |
newplaintext += permutehold | |
newplaintext = sw(newplaintext) | |
#Process repeats with second key and an ip1 call at the end | |
for i in 0..3 | |
fk[i] = newplaintext[i] | |
permute[i] = newplaintext[i + 4] | |
permutehold[i] = newplaintext[i + 4] | |
end | |
newplaintext = ep(permute) | |
newplaintext = exor(newplaintext, key2) | |
for i in 0..3 | |
permute1[i] = newplaintext[i] | |
permute[i] = newplaintext[i + 4] | |
end | |
byte = s1(permute) | |
byte1 = s0(permute1) | |
byte1 += byte | |
byte = p4(byte1) | |
newplaintext = exor(fk, byte) | |
newplaintext += permutehold | |
newplaintext = ip1(newplaintext) | |
return newplaintext | |
end | |
def decrypt(ciphertext, number) | |
newciphertext = ip(ciphertext) | |
fk = "" | |
permute = "" | |
permute1 = "" | |
permutehold = "" | |
#Getting two keys | |
key1 = p10(number) | |
key1 = shift(key1) | |
key2 = key1 | |
key1 = p8(key1) | |
key2 = shift(key2) | |
key2 = shift(key2) | |
key2 = p8(key2) | |
for i in 0..3 | |
fk += newciphertext[i] | |
permute += newciphertext[i + 4] | |
permutehold += newciphertext[i + 4] | |
end | |
newciphertext = ep(permute) | |
newciphertext = exor(newciphertext, key2) | |
for i in 0..3 | |
permute1 += newciphertext[i] | |
permute[i] = newciphertext[i + 4] | |
end | |
byte = s1(permute) | |
byte1 = s0(permute1) | |
byte1 += byte | |
byte = p4(byte1) | |
newciphertext = exor(fk, byte) | |
newciphertext += permutehold | |
newciphertext = sw(newciphertext) | |
#Process repeats with second key and an ip1 call at the end | |
for i in 0..3 | |
fk[i] = newciphertext[i] | |
permute[i] = newciphertext[i + 4] | |
permutehold[i] = newciphertext[i + 4] | |
end | |
newciphertext = ep(permute) | |
newciphertext = exor(newciphertext, key1) | |
for i in 0..3 | |
permute1[i] = newciphertext[i] | |
permute[i] = newciphertext[i + 4] | |
end | |
byte = s1(permute) | |
byte1 = s0(permute1) | |
byte1 += byte | |
byte = p4(byte1) | |
newciphertext = exor(fk, byte) | |
newciphertext += permutehold | |
newciphertext = ip1(newciphertext) | |
return newciphertext | |
end | |
# 65% of original code size | |
key = "1000110101" | |
passed = false | |
while passed == false | |
print "Encrypt or Decrypt: " | |
choice = gets.chomp | |
if choice == "Encrypt" | |
output = "" | |
File.open('Ruby_Plaintext.txt', 'r') do |text| | |
read_in = text.read.split(" ") | |
read_in.each do |plaintext| | |
ciphertext = encrypt(plaintext, key) | |
output += ciphertext + " " | |
end | |
end | |
print "Encrypted" | |
File.open('Ruby_Ciphertext.txt', 'w') { |file| file.write(output) } | |
passed = true | |
elsif choice == "Decrypt" | |
output = "" | |
File.open('Ruby_Ciphertext.txt', 'r') do |text| | |
read_in = text.read.split(" ") | |
read_in.each do |ciphertext| | |
plaintext = decrypt(ciphertext, key) | |
output += plaintext + " " | |
end | |
end | |
print "Decrypted" | |
File.open('Ruby_Decrypt.txt', 'w') { |file| file.write(output) } | |
passed = true | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment