Skip to content

Instantly share code, notes, and snippets.

Created May 31, 2016 07:27
Show Gist options
  • Save anonymous/756a1ff2a5de9c6babfa989e6d090341 to your computer and use it in GitHub Desktop.
Save anonymous/756a1ff2a5de9c6babfa989e6d090341 to your computer and use it in GitHub Desktop.
Ruby 8 bit S-DES encryption
# 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