Skip to content
Browse files

working and tested, time to refactor and cleanup

  • Loading branch information...
1 parent b10da4a commit 9066b940c9937d88154e6d22b98cbc4061cf0183 Robert Sosinski committed
Showing with 79 additions and 44 deletions.
  1. +15 −24 lib/ruby-des.rb
  2. +18 −18 lib/ruby-des/feistel.rb
  3. +5 −0 lib/ruby-des/key_schedule.rb
  4. +26 −0 test/ctx.yml
  5. +13 −0 test/ctx_test.rb
  6. +1 −1 test/feistel_test.rb
  7. +1 −1 test/xor_test.rb
View
39 lib/ruby-des.rb
@@ -24,26 +24,6 @@ module RubyDES
0x22, 0x02, 0x2a, 0x0a, 0x32, 0x12, 0x3a, 0x1a,
0x21, 0x01, 0x29, 0x09, 0x31, 0x11, 0x39, 0x19]
- # The 8-bit binary representation of "security"
- TEST_MESSAGE = [0, 1, 1, 1, 0, 0, 1, 1,
- 0, 1, 1, 0, 0, 1, 0, 1,
- 0, 1, 1, 0, 0, 0, 1, 1,
- 0, 1, 1, 1, 0, 1, 0, 1,
- 0, 1, 1, 1, 0, 0, 1, 0,
- 0, 1, 1, 0, 1, 0, 0, 1,
- 0, 1, 1 ,1, 0, 1, 0, 0,
- 0, 1, 1, 1, 1, 0, 0, 1]
-
- # The 7-bit binary representation of "ruby-des" with proper parity."
- TEST_KEY = [1, 1, 1, 0, 0, 1, 0, 1,
- 1, 1, 1, 0, 1, 0, 1, 0,
- 1, 1, 0, 0, 0, 1, 0, 0,
- 1, 1, 1, 1, 0, 0, 1, 0,
- 0, 1, 0, 1, 1, 0, 1, 1,
- 1, 1, 0, 0, 1, 0, 0, 0,
- 1, 1, 0, 0, 1, 0, 1, 1,
- 1, 1, 1, 0, 0, 1, 1, 0]
-
class Ctx
attr_reader :block, :key
@@ -63,16 +43,27 @@ def encrypt
16.times do |i|
l << r[i]
- r << XOR.run(Feistel.run(r[i], k[i], i), l[i])
+ r << XOR.run(Feistel.run(r[i], k[i]), l[i])
end
- k << PC_2.collect{|p| (c[i + 1] + d[i + 1])[p - 1]}
-
- output = FP.collect{|p| (l.last + r.last)[p - 1]}
+ return FP.collect{|p| (r.last + l.last)[p - 1]}
end
def decrypt
+ l = [] # l[0] is the IP_1_L permutation of the block, l[1..16] are the results of each round of encryption.
+ r = [] # r[0] is the IP_1_R permutation of the block, r[1..16] are the results of each round of encryption.
+
+ l << IP_L.collect{|p| block[p - 1]}
+ r << IP_R.collect{|p| block[p - 1]}
+
+ k = KeySchedule.new(key).sub_keys.reverse
+
+ 16.times do |i|
+ l << r[i]
+ r << XOR.run(Feistel.run(r[i], k[i]), l[i])
+ end
+ return FP.collect{|p| (r.last + l.last)[p - 1]}
end
end
end
View
36 lib/ruby-des/feistel.rb
@@ -56,32 +56,31 @@ module Feistel
0x01, 0x0f, 0x0d, 0x08, 0x0a, 0x03, 0x07, 0x04, 0x0c, 0x05, 0x06, 0x0b, 0x00, 0x0e, 0x09, 0x02,
0x07, 0x0b, 0x04, 0x01, 0x09, 0x0c, 0x0e, 0x02, 0x00, 0x06, 0x0a, 0x0d, 0x0f, 0x03, 0x05, 0x08,
0x02, 0x01, 0x0e, 0x07, 0x04, 0x0a, 0x08, 0x0d, 0x0f, 0x0c, 0x09, 0x00, 0x03, 0x05, 0x06, 0x0b]
-
- S = [S1, S2, S3, S4, S5, S6, S7, S8]
- # Some test data
- #
- # half_block = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1]
- # k = [1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1]
-
- def self.run(half_block, k)
- b = [] # b[0..7] is e_xor_k prepped as 8 6-bit arrays for sbox substitution.
- m = [] #
- n = []
+ def self.run(r, k)
+ b = [] # b[0..7] is e_xor_k prepped as 8 6-bit arrays for sbox substitution.
+ m = [] # m[0..7] is the row of the value when performing a s-box lookup.
+ n = [] # n[0..7] is the column of the value when performing a s-box lookup.
+
+ # Expand the half block using E.
+ e = E.collect{|p| r[p - 1]}
- e = E.collect{|p| half_block[p - 1]}
- e_xor_k = XOR.run(e, k)
+ # X-or the expanded half block with k (the sub key).
+ e_xor_k = XOR.run(e, k)
- 8.times do |i|
+ # Break e_xor_k into 8 6-bit arrays and find both m and m for the s-box lookup.
+ 8.times do |j|
b << []
6.times do
- b[i] << e_xor_k.shift
+ b[j] << e_xor_k.shift
end
- m << (b[i].first.to_s + b[i].last.to_s).to_i(2) * 16
- n << b[i][1..4].to_s.to_i(2)
+ # If given the bit array [1, 0, 1, 0, 1, 0]
+ m << (b[j].first.to_s + b[j].last.to_s).to_i(2) * 16 # => [1, 0]
+ n << b[j][1..4].to_s.to_i(2) # => [0, 1, 0, 1]
end
+ # Substitute every 6-bit array with a 4-bit array by using the correct s-box.
b[0] = S1[m[0] + n[0]].to_s(2).rjust(4, '0').split('').collect{|bit| bit.to_i}
b[1] = S2[m[1] + n[1]].to_s(2).rjust(4, '0').split('').collect{|bit| bit.to_i}
b[2] = S3[m[2] + n[2]].to_s(2).rjust(4, '0').split('').collect{|bit| bit.to_i}
@@ -90,7 +89,8 @@ def self.run(half_block, k)
b[5] = S6[m[5] + n[5]].to_s(2).rjust(4, '0').split('').collect{|bit| bit.to_i}
b[6] = S7[m[6] + n[6]].to_s(2).rjust(4, '0').split('').collect{|bit| bit.to_i}
b[7] = S8[m[7] + n[7]].to_s(2).rjust(4, '0').split('').collect{|bit| bit.to_i}
-
+
+ # Permute the flattened array with P
return P.collect{|p| b.flatten[p - 1]}
end
end
View
5 lib/ruby-des/key_schedule.rb
@@ -31,19 +31,24 @@ def initialize(key)
d = [] # d[0] is the PC_1_R permutation of the key, d[1..16] are the results of each left shift.
k = [] # k[0..15] are the sub keys created by combining c[i] and d[i] and permuting with PC_2.
+ # Get c[0] and d[0] by permuting the key with PC_1_L and PC_1_R.
c << PC_1_L.collect{|p| key[p - 1]}
d << PC_1_R.collect{|p| key[p - 1]}
+ # Generate 16 sub keys with left-wise rotations and PC_2.
16.times do |i|
+ # Create two new arrays of bits from the previous arrays of bits.
c << c[i]
d << d[i]
+ # Rotate the new arrays of bits left one or two times.
ROTATIONS[i].times do
c[i + 1] << c[i + 1].shift
d[i + 1] << d[i + 1].shift
end
+ # Combine the new c and d arrays and permute the result with PC_2.
k << PC_2.collect{|p| (c[i + 1] + d[i + 1])[p - 1]}
end
View
26 test/ctx.yml
@@ -0,0 +1,26 @@
+key: [1, 1, 1, 0, 0, 1, 0, 1,
+ 1, 1, 1, 0, 1, 0, 1, 0,
+ 1, 1, 0, 0, 0, 1, 0, 0,
+ 1, 1, 1, 1, 0, 0, 1, 0,
+ 0, 1, 0, 1, 1, 0, 1, 1,
+ 1, 1, 0, 0, 1, 0, 0, 0,
+ 1, 1, 0, 0, 1, 0, 1, 1,
+ 1, 1, 1, 0, 0, 1, 1, 0]
+
+plain_text: [0, 1, 1, 1, 0, 0, 1, 1,
+ 0, 1, 1, 0, 0, 1, 0, 1,
+ 0, 1, 1, 0, 0, 0, 1, 1,
+ 0, 1, 1, 1, 0, 1, 0, 1,
+ 0, 1, 1, 1, 0, 0, 1, 0,
+ 0, 1, 1, 0, 1, 0, 0, 1,
+ 0, 1, 1, 1, 0, 1, 0, 0,
+ 0, 1, 1, 1, 1, 0, 0, 1]
+
+cipher_text: [0, 1, 0, 1, 1, 1, 1, 0,
+ 1, 1, 1, 0, 1, 1, 0, 0,
+ 1, 0, 1, 0, 1, 1, 1, 0,
+ 0, 0, 1, 0, 1, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 1,
+ 0, 1, 0, 0, 1, 1, 0, 0,
+ 0, 1, 0, 1, 0, 0, 1, 0]
View
13 test/ctx_test.rb
@@ -0,0 +1,13 @@
+require 'test_helper'
+
+class CtxTest < Test::Unit::TestCase
+ fixtures :ctx
+
+ def test_encypt
+ assert_equal ctx(:cipher_text), RubyDES::Ctx.new(ctx(:plain_text), ctx(:key)).encrypt
+ end
+
+ def test_decrypt
+ assert_equal ctx(:plain_text), RubyDES::Ctx.new(ctx(:cipher_text), ctx(:key)).decrypt
+ end
+end
View
2 test/feistel_test.rb
@@ -1,6 +1,6 @@
require 'test_helper'
-class FeistelTest < Test::Unit::TestCase
+class FeistelTest < Test::Unit::TestCase
fixtures :feistel
def test_run
View
2 test/xor_test.rb
@@ -1,6 +1,6 @@
require 'test_helper'
-class XORTest < Test::Unit::TestCase
+class XORTest < Test::Unit::TestCase
fixtures :xor
def test_run

0 comments on commit 9066b94

Please sign in to comment.
Something went wrong with that request. Please try again.