ruby-des 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ .DS_Store
2
+ *.swp
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009 Robert Sosinski (http://www.robertsosinski.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ RubyDES
2
+ =======
3
+
4
+ RubyDES is a full Ruby implementation of the Data Encryption Standard. The purpose of this
5
+ project was to allow Ruby programmers interested in cryptography a glimpse of how a robust
6
+ cryptographic algorithm functions in a language they understand.
7
+
8
+ The best way to understand the RubyDES source code is by following along with a FIPS 46,
9
+ which you can find at http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
10
+
11
+ NOTE: DES is deprecated, and as such, you should not use this implementation in any project you
12
+ are developing. I highly recommend the AES, TwoFish or Serpent algorithms through the OpenSSL
13
+ library instead.
14
+
15
+ Running RubyDES
16
+ ===============
17
+
18
+ Using RubyDES is pretty easy. First, construct a new data and key block.
19
+
20
+ data = RubyDES::Block.new('mysecret')
21
+ key = RubyDES::Block.new('hushhush')
22
+
23
+ Then, build a new `RubyDES::Ctx` object and supply the data and key block.
24
+
25
+ des = RubyDES::Ctx.new(data, key)
26
+
27
+ Finally, let it go.
28
+
29
+ encrypted_data = des.encrypt
30
+
31
+ You will then be returned a DES encrypted block that is completely secure against eavesdropping
32
+ (if it were still 1997).
33
+
34
+ To decrypt an encrypted data block, just build a new `RubyDES::Ctx` object in similar
35
+ fashion as before.
36
+
37
+ un_des = RubyDES::Ctx.new(encrypted_data, key)
38
+
39
+ And run the DES with the key schedule reversed.
40
+
41
+ decrypted_data = un_des.decrypt
42
+
43
+ You can then check to see if it all worked.
44
+
45
+ data.bit_array.eql?(decrypted_data.bit_array)
46
+
47
+ Enjoy!
48
+
49
+ Feedback
50
+ ========
51
+
52
+ If you have any questions, comments or just want to talk shop about crypto, feel free to reach me
53
+ through my website at http://www.robertsosinski.com.
@@ -0,0 +1,9 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << "test"
6
+ t.test_files = FileList['test/*_test.rb']
7
+ end
8
+
9
+ task :default => ["test"]
@@ -0,0 +1,91 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ require 'ruby-des/feistel'
4
+ require 'ruby-des/key_schedule'
5
+ require 'ruby-des/xor'
6
+
7
+ module RubyDES
8
+ IP_L = [0x3a, 0x32, 0x2a, 0x22, 0x1a, 0x12, 0x0a, 0x02,
9
+ 0x3c, 0x34, 0x2c, 0x24, 0x1c, 0x14, 0x0c, 0x04,
10
+ 0x3e, 0x36, 0x2e, 0x26, 0x1e, 0x16, 0x0e, 0x06,
11
+ 0x40, 0x38, 0x30, 0x28, 0x20, 0x18, 0x10, 0x08]
12
+
13
+ IP_R = [0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09, 0x01,
14
+ 0x3b, 0x33, 0x2b, 0x23, 0x1b, 0x13, 0x0b, 0x03,
15
+ 0x3d, 0x35, 0x2d, 0x25, 0x1d, 0x15, 0x0d, 0x05,
16
+ 0x3f, 0x37, 0x2f, 0x27, 0x1f, 0x17, 0x0f, 0x07]
17
+
18
+ FP = [0x28, 0x08, 0x30, 0x10, 0x38, 0x18, 0x40, 0x20,
19
+ 0x27, 0x07, 0x2f, 0x0f, 0x37, 0x17, 0x3f, 0x1f,
20
+ 0x26, 0x06, 0x2e, 0x0e, 0x36, 0x16, 0x3e, 0x1e,
21
+ 0x25, 0x05, 0x2d, 0x0d, 0x35, 0x15, 0x3d, 0x1d,
22
+ 0x24, 0x04, 0x2c, 0x0c, 0x34, 0x14, 0x3c, 0x1c,
23
+ 0x23, 0x03, 0x2b, 0x0b, 0x33, 0x13, 0x3b, 0x1b,
24
+ 0x22, 0x02, 0x2a, 0x0a, 0x32, 0x12, 0x3a, 0x1a,
25
+ 0x21, 0x01, 0x29, 0x09, 0x31, 0x11, 0x39, 0x19]
26
+
27
+ class Ctx
28
+ attr_reader :data, :key
29
+
30
+ def initialize(data, key)
31
+ unless data.is_a?(RubyDES::Block) and key.is_a?(RubyDES::Block)
32
+ raise "RubyDES::InvalidBlockFormat: Data and key must be a Block object."
33
+ end
34
+
35
+ @data = data
36
+ @key = key
37
+ end
38
+
39
+ def encrypt
40
+ self.run(:encrypt)
41
+ end
42
+
43
+ def decrypt
44
+ self.run(:decrypt)
45
+ end
46
+
47
+ protected
48
+
49
+ def run(operation)
50
+ l = [] # l[0] is the IP_1_L permutation of the data block, l[1..16] are the results of each round of encryption.
51
+ r = [] # r[0] is the IP_1_R permutation of the data block, r[1..16] are the results of each round of encryption.
52
+
53
+ l << IP_L.collect{|p| data.bit_array[p - 1]}
54
+ r << IP_R.collect{|p| data.bit_array[p - 1]}
55
+
56
+ case operation
57
+ when :encrypt
58
+ k = KeySchedule.new(key.bit_array).sub_keys
59
+ when :decrypt
60
+ k = KeySchedule.new(key.bit_array).sub_keys.reverse
61
+ end
62
+
63
+ 16.times do |i|
64
+ l << r[i]
65
+ r << XOR.run(Feistel.run(r[i], k[i]), l[i])
66
+ end
67
+
68
+ return RubyDES::Block.new(FP.collect{|p| (r.last + l.last)[p - 1]})
69
+ end
70
+ end
71
+
72
+ class Block
73
+ attr_reader :string, :bit_array
74
+
75
+ def initialize(input)
76
+ if input.is_a?(String)
77
+ raise "RubyDES::InvalidStringLength: Input String must contain (8) characters." unless input.length.eql?(8)
78
+
79
+ @string = input
80
+ @bit_array = input.unpack('B*').join.split('').collect{|b| b.to_i}
81
+ elsif input.is_a?(Array)
82
+ raise "RubyDES::InvalidArraySize: Input Array must contain (64) bits." unless input.size.eql?(64)
83
+
84
+ @string = input.join.to_a.pack('B*')
85
+ @bit_array = input
86
+ else
87
+ raise "RubyDES::InvalidFormat: Input must be a String or an Array."
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,89 @@
1
+ module Feistel
2
+ E = [0x20, 0x01, 0x02, 0x03, 0x04, 0x05,
3
+ 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
4
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
5
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
6
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
7
+ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
8
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
9
+ 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x01]
10
+
11
+ P = [0x10, 0x07, 0x14, 0x15,
12
+ 0x1d, 0x0c, 0x1c, 0x11,
13
+ 0x01, 0x0f, 0x17, 0x1a,
14
+ 0x05, 0x12, 0x1f, 0x0a,
15
+ 0x02, 0x08, 0x18, 0x0e,
16
+ 0x20, 0x1b, 0x03, 0x09,
17
+ 0x13, 0x0d, 0x1e, 0x06,
18
+ 0x16, 0x0b, 0x04, 0x19]
19
+
20
+ S1 = [0x0e, 0x04, 0x0d, 0x01, 0x02, 0x0f, 0x0b, 0x08, 0x03, 0x0a, 0x06, 0x0c, 0x05, 0x09, 0x00, 0x07,
21
+ 0x00, 0x0f, 0x07, 0x04, 0x0e, 0x02, 0x0d, 0x01, 0x0a, 0x06, 0x0c, 0x0b, 0x09, 0x05, 0x03, 0x08,
22
+ 0x04, 0x01, 0x0e, 0x08, 0x0d, 0x06, 0x02, 0x0b, 0x0f, 0x0c, 0x09, 0x07, 0x03, 0x0a, 0x05, 0x00,
23
+ 0x0f, 0x0c, 0x08, 0x02, 0x04, 0x09, 0x01, 0x07, 0x05, 0x0b, 0x03, 0x0e, 0x0a, 0x00, 0x06, 0x0d]
24
+
25
+ S2 = [0x0f, 0x01, 0x08, 0x0e, 0x06, 0x0b, 0x03, 0x04, 0x09, 0x07, 0x02, 0x0d, 0x0c, 0x00, 0x05, 0x0a,
26
+ 0x03, 0x0d, 0x04, 0x07, 0x0f, 0x02, 0x08, 0x0e, 0x0c, 0x00, 0x01, 0x0a, 0x06, 0x09, 0x0b, 0x05,
27
+ 0x00, 0x0e, 0x07, 0x0b, 0x0a, 0x04, 0x0d, 0x01, 0x05, 0x08, 0x0c, 0x06, 0x09, 0x03, 0x02, 0x0f,
28
+ 0x0d, 0x08, 0x0a, 0x01, 0x03, 0x0f, 0x04, 0x02, 0x0b, 0x06, 0x07, 0x0c, 0x00, 0x05, 0x0e, 0x09]
29
+
30
+ S3 = [0x0a, 0x00, 0x09, 0x0e, 0x06, 0x03, 0x0f, 0x05, 0x01, 0x0d, 0x0c, 0x07, 0x0b, 0x04, 0x02, 0x08,
31
+ 0x0d, 0x07, 0x00, 0x09, 0x03, 0x04, 0x06, 0x0a, 0x02, 0x08, 0x05, 0x0e, 0x0c, 0x0b, 0x0f, 0x01,
32
+ 0x0d, 0x06, 0x04, 0x09, 0x08, 0x0f, 0x03, 0x00, 0x0b, 0x01, 0x02, 0x0c, 0x05, 0x0a, 0x0e, 0x07,
33
+ 0x01, 0x0a, 0x0d, 0x00, 0x06, 0x09, 0x08, 0x07, 0x04, 0x0f, 0x0e, 0x03, 0x0b, 0x05, 0x02, 0x0c]
34
+
35
+ S4 = [0x07, 0x0d, 0x0e, 0x03, 0x00, 0x06, 0x09, 0x0a, 0x01, 0x02, 0x08, 0x05, 0x0b, 0x0c, 0x04, 0x0f,
36
+ 0x0d, 0x08, 0x0b, 0x05, 0x06, 0x0f, 0x00, 0x03, 0x04, 0x07, 0x02, 0x0c, 0x01, 0x0a, 0x0e, 0x09,
37
+ 0x0a, 0x06, 0x09, 0x00, 0x0c, 0x0b, 0x07, 0x0d, 0x0f, 0x01, 0x03, 0x0e, 0x05, 0x02, 0x08, 0x04,
38
+ 0x03, 0x0f, 0x00, 0x06, 0x0a, 0x01, 0x0d, 0x08, 0x09, 0x04, 0x05, 0x0b, 0x0c, 0x07, 0x02, 0x0e]
39
+
40
+ S5 = [0x02, 0x0c, 0x04, 0x01, 0x07, 0x0a, 0x0b, 0x06, 0x08, 0x05, 0x03, 0x0f, 0x0d, 0x00, 0x0e, 0x09,
41
+ 0x0e, 0x0b, 0x02, 0x0c, 0x04, 0x07, 0x0d, 0x01, 0x05, 0x00, 0x0f, 0x0a, 0x03, 0x09, 0x08, 0x06,
42
+ 0x04, 0x02, 0x01, 0x0b, 0x0a, 0x0d, 0x07, 0x08, 0x0f, 0x09, 0x0c, 0x05, 0x06, 0x03, 0x00, 0x0e,
43
+ 0x0b, 0x08, 0x0c, 0x07, 0x01, 0x0e, 0x02, 0x0d, 0x06, 0x0f, 0x00, 0x09, 0x0a, 0x04, 0x05, 0x03]
44
+
45
+ S6 = [0x0c, 0x01, 0x0a, 0x0f, 0x09, 0x02, 0x06, 0x08, 0x00, 0x0d, 0x03, 0x04, 0x0e, 0x07, 0x05, 0x0b,
46
+ 0x0a, 0x0f, 0x04, 0x02, 0x07, 0x0c, 0x09, 0x05, 0x06, 0x01, 0x0d, 0x0e, 0x00, 0x0b, 0x03, 0x08,
47
+ 0x09, 0x0e, 0x0f, 0x05, 0x02, 0x08, 0x0c, 0x03, 0x07, 0x00, 0x04, 0x0a, 0x01, 0x0d, 0x0b, 0x06,
48
+ 0x04, 0x03, 0x02, 0x0c, 0x09, 0x05, 0x0f, 0x0a, 0x0b, 0x0e, 0x01, 0x07, 0x06, 0x00, 0x08, 0x0d]
49
+
50
+ S7 = [0x04, 0x0b, 0x02, 0x0e, 0x0f, 0x00, 0x08, 0x0d, 0x03, 0x0c, 0x09, 0x07, 0x05, 0x0a, 0x06, 0x01,
51
+ 0x0d, 0x00, 0x0b, 0x07, 0x04, 0x09, 0x01, 0x0a, 0x0e, 0x03, 0x05, 0x0c, 0x02, 0x0f, 0x08, 0x06,
52
+ 0x01, 0x04, 0x0b, 0x0d, 0x0c, 0x03, 0x07, 0x0e, 0x0a, 0x0f, 0x06, 0x08, 0x00, 0x05, 0x09, 0x02,
53
+ 0x06, 0x0b, 0x0d, 0x08, 0x01, 0x04, 0x0a, 0x07, 0x09, 0x05, 0x00, 0x0f, 0x0e, 0x02, 0x03, 0x0c]
54
+
55
+ S8 = [0x0d, 0x02, 0x08, 0x04, 0x06, 0x0f, 0x0b, 0x01, 0x0a, 0x09, 0x03, 0x0e, 0x05, 0x00, 0x0c, 0x07,
56
+ 0x01, 0x0f, 0x0d, 0x08, 0x0a, 0x03, 0x07, 0x04, 0x0c, 0x05, 0x06, 0x0b, 0x00, 0x0e, 0x09, 0x02,
57
+ 0x07, 0x0b, 0x04, 0x01, 0x09, 0x0c, 0x0e, 0x02, 0x00, 0x06, 0x0a, 0x0d, 0x0f, 0x03, 0x05, 0x08,
58
+ 0x02, 0x01, 0x0e, 0x07, 0x04, 0x0a, 0x08, 0x0d, 0x0f, 0x0c, 0x09, 0x00, 0x03, 0x05, 0x06, 0x0b]
59
+
60
+ S = [S1, S2, S3, S4, S5, S6, S7, S8]
61
+
62
+ def self.run(r, k)
63
+ b = [] # b[0..7] is e_xor_k prepped as 8 6-bit arrays for s-box substitution.
64
+ m = [] # m[0..7] is the row of the value when performing a s-box lookup.
65
+ n = [] # n[0..7] is the column of the value when performing a s-box lookup.
66
+
67
+ e = E.collect{|p| r[p - 1]} # Expand r (right half data block) using E.
68
+
69
+ e_xor_k = XOR.run(e, k) # X-or e (expanded r) with k (the sub key).
70
+
71
+ # Break e_xor_k into 8 6-bit arrays and find both m (s-box row) and n (s-box column) for the s-box lookup.
72
+ 8.times do |i|
73
+ b << []
74
+ 6.times do
75
+ b[i] << e_xor_k.shift
76
+ end
77
+
78
+ m << [b[i].first, b[i].last].join.to_i(2) * 16 # [1, 0, 1, 0, 1, 0] => [1, 0] => 2 => 32 => 3rd row.
79
+ n << b[i][1..4].join.to_i(2) # [1, 0, 1, 0, 1, 0] => [0, 1, 0, 1] => 5 => 6th column.
80
+ end
81
+
82
+ # Substitute every 6-bit array with the 4-bit array specified by the appropriate s-box.
83
+ 8.times do |i|
84
+ b[i] = S[i][m[i] + n[i]].to_s(2).rjust(4, '0').split('').collect{|bit| bit.to_i}
85
+ end
86
+
87
+ return P.collect{|p| b.flatten[p - 1]}
88
+ end
89
+ end
@@ -0,0 +1,51 @@
1
+ class KeySchedule
2
+ attr_accessor :sub_keys
3
+ attr_reader :key
4
+
5
+ PC_1_L = [0x39, 0x31, 0x29, 0x21, 0x19, 0x11, 0x09,
6
+ 0x01, 0x3a, 0x32, 0x2a, 0x22, 0x1a, 0x12,
7
+ 0x0a, 0x02, 0x3b, 0x33, 0x2b, 0x23, 0x1b,
8
+ 0x13, 0x0b, 0x03, 0x3c, 0x34, 0x2c, 0x24]
9
+
10
+ PC_1_R = [0x3f, 0x37, 0x2f, 0x27, 0x1f, 0x17, 0x0f,
11
+ 0x07, 0x3e, 0x36, 0x2e, 0x26, 0x1e, 0x16,
12
+ 0x0e, 0x06, 0x3d, 0x35, 0x2d, 0x25, 0x1d,
13
+ 0x15, 0x0d, 0x05, 0x1c, 0x14, 0x0c, 0x04]
14
+
15
+ PC_2 = [0x0e, 0x11, 0x0b, 0x18, 0x01, 0x05,
16
+ 0x03, 0x1c, 0x0f, 0x06, 0x15, 0x0a,
17
+ 0x17, 0x13, 0x0c, 0x04, 0x1a, 0x08,
18
+ 0x10, 0x07, 0x1b, 0x14, 0x0d, 0x02,
19
+ 0x29, 0x34, 0x1f, 0x25, 0x2f, 0x37,
20
+ 0x1e, 0x28, 0x33, 0x2d, 0x21, 0x30,
21
+ 0x2c, 0x31, 0x27, 0x38, 0x22, 0x35,
22
+ 0x2e, 0x2a, 0x32, 0x24, 0x1d, 0x20]
23
+
24
+ ROTATIONS = [1, 1, 2, 2, 2, 2, 2, 2,
25
+ 1, 2, 2, 2, 2, 2, 2, 1]
26
+
27
+ def initialize(key)
28
+ @key = key
29
+
30
+ c = [] # c[0] is the PC_1_L permutation of the key, c[1..16] are the results of each left shift.
31
+ d = [] # d[0] is the PC_1_R permutation of the key, d[1..16] are the results of each left shift.
32
+ k = [] # k[0..15] are the sub keys created by combining c[i] and d[i] and permuting with PC_2.
33
+
34
+ c << PC_1_L.collect{|p| key[p - 1]}
35
+ d << PC_1_R.collect{|p| key[p - 1]}
36
+
37
+ 16.times do |i|
38
+ c << c[i]
39
+ d << d[i]
40
+
41
+ ROTATIONS[i].times do
42
+ c[i + 1] << c[i + 1].shift
43
+ d[i + 1] << d[i + 1].shift
44
+ end
45
+
46
+ k << PC_2.collect{|p| (c[i + 1] + d[i + 1])[p - 1]}
47
+ end
48
+
49
+ @sub_keys = k
50
+ end
51
+ end
@@ -0,0 +1,11 @@
1
+ module XOR
2
+ def self.run(x, y)
3
+ output = []
4
+
5
+ x.size.times do |i|
6
+ output << (x[i] ^ y[i])
7
+ end
8
+
9
+ return output
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ decrypted_bit_array: [0, 1, 1, 1, 0, 0, 1, 1,
2
+ 0, 1, 1, 0, 0, 1, 0, 1,
3
+ 0, 1, 1, 0, 0, 0, 1, 1,
4
+ 0, 1, 1, 1, 0, 1, 0, 1,
5
+ 0, 1, 1, 1, 0, 0, 1, 0,
6
+ 0, 1, 1, 0, 1, 0, 0, 1,
7
+ 0, 1, 1, 1, 0, 1, 0, 0,
8
+ 0, 1, 1, 1, 1, 0, 0, 1]
9
+
10
+ encrypted_bit_array: [0, 0, 0, 0, 1, 0, 1, 0,
11
+ 1, 1, 0, 1, 1, 1, 1, 0,
12
+ 0, 1, 0, 1, 0, 0, 1, 0,
13
+ 1, 0, 1, 0, 0, 1, 0, 0,
14
+ 0, 1, 1, 1, 0, 0, 1, 0,
15
+ 0, 0, 0, 0, 0, 1, 0, 1,
16
+ 0, 0, 0, 0, 0, 0, 1, 0,
17
+ 0, 1, 0, 1, 0, 0, 0, 1]
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ class CtxTest < Test::Unit::TestCase
4
+ fixtures :ctx
5
+
6
+ def setup
7
+ @data = RubyDES::Block.new('security')
8
+ @key = RubyDES::Block.new('ruby-des')
9
+ end
10
+
11
+ def test_run
12
+ encrypted_data = RubyDES::Ctx.new(@data, @key).encrypt
13
+
14
+ assert_equal ctx(:encrypted_bit_array), encrypted_data.bit_array
15
+
16
+ decrypted_data = RubyDES::Ctx.new(encrypted_data, @key).decrypt
17
+
18
+ assert_equal ctx(:decrypted_bit_array), decrypted_data.bit_array
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ half_block: [0, 0, 0, 0, 0, 0, 0, 0,
2
+ 1, 1, 1, 1, 1, 1, 1, 1,
3
+ 1, 0, 1, 0, 0, 0, 0, 0,
4
+ 0, 0, 0, 1, 0, 1, 0, 1]
5
+
6
+ sub_key: [1, 0, 1, 0, 1, 1,
7
+ 0, 1, 1, 1, 0, 1,
8
+ 1, 0, 1, 1, 0, 1,
9
+ 1, 1, 1, 1, 1, 1,
10
+ 1, 1, 1, 0, 1, 0,
11
+ 0, 0, 0, 1, 0, 0,
12
+ 0, 0, 0, 1, 1, 0,
13
+ 1, 0, 1, 1, 1, 1]
14
+
15
+ output: [1, 0, 0, 1, 1, 1, 0, 0,
16
+ 0, 1, 1, 0, 0, 1, 0, 0,
17
+ 0, 1, 0, 1, 1, 1, 1, 0,
18
+ 1, 0, 1, 1, 0, 0, 0, 0]
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class FeistelTest < Test::Unit::TestCase
4
+ fixtures :feistel
5
+
6
+ def test_run
7
+ assert_equal feistel(:output), Feistel.run(feistel(:half_block), feistel(:sub_key))
8
+ end
9
+ end
@@ -0,0 +1,152 @@
1
+ test_key: [1, 1, 1, 0, 0, 1, 0, 1,
2
+ 1, 1, 1, 0, 1, 0, 1, 0,
3
+ 1, 1, 0, 0, 0, 1, 0, 0,
4
+ 1, 1, 1, 1, 0, 0, 1, 0,
5
+ 0, 1, 0, 1, 1, 0, 1, 1,
6
+ 1, 1, 0, 0, 1, 0, 0, 0,
7
+ 1, 1, 0, 0, 1, 0, 1, 1,
8
+ 1, 1, 1, 0, 0, 1, 1, 0]
9
+
10
+ sub_key_1: [1, 0, 1, 0, 1, 1,
11
+ 0, 1, 1, 1, 0, 1,
12
+ 1, 0, 1, 1, 0, 1,
13
+ 1, 1, 1, 1, 1, 1,
14
+ 1, 1, 1, 0, 1, 0,
15
+ 0, 0, 0, 1, 0, 0,
16
+ 0, 0, 0, 1, 1, 0,
17
+ 1, 0, 1, 1, 1, 1]
18
+
19
+ sub_key_2: [1, 0, 1, 0, 1, 1,
20
+ 1, 1, 1, 1, 1, 1,
21
+ 0, 1, 1, 1, 1, 1,
22
+ 0, 1, 1, 0, 1, 0,
23
+ 0, 0, 1, 0, 0, 1,
24
+ 1, 1, 1, 1, 1, 0,
25
+ 1, 1, 0, 1, 0, 0,
26
+ 1, 1, 0, 0, 0, 0]
27
+
28
+ sub_key_3: [0, 1, 1, 1, 1, 1,
29
+ 1, 0, 0, 1, 0, 1,
30
+ 0, 1, 1, 1, 1, 1,
31
+ 0, 1, 1, 1, 1, 1,
32
+ 0, 0, 1, 0, 1, 0,
33
+ 0, 1, 0, 0, 1, 0,
34
+ 1, 1, 0, 1, 0, 1,
35
+ 0, 1, 0, 0, 1, 0]
36
+
37
+ sub_key_4: [0, 1, 1, 1, 1, 1,
38
+ 1, 1, 1, 1, 0, 1,
39
+ 1, 0, 0, 1, 0, 1,
40
+ 0, 1, 1, 0, 0, 1,
41
+ 1, 1, 1, 0, 1, 1,
42
+ 0, 1, 1, 1, 0, 0,
43
+ 0, 0, 0, 0, 0, 0,
44
+ 0, 1, 0, 1, 1, 0]
45
+
46
+ sub_key_5: [0, 0, 0, 0, 1, 1,
47
+ 1, 1, 1, 1, 1, 0,
48
+ 1, 0, 0, 1, 1, 1,
49
+ 1, 1, 1, 1, 1, 1,
50
+ 0, 1, 0, 0, 0, 1,
51
+ 0, 1, 0, 1, 0, 0,
52
+ 0, 1, 1, 0, 1, 1,
53
+ 0, 0, 1, 1, 1, 0]
54
+
55
+ sub_key_6: [1, 0, 1, 1, 1, 1,
56
+ 1, 1, 0, 1, 1, 0,
57
+ 1, 1, 0, 1, 1, 0,
58
+ 0, 1, 1, 1, 1, 1,
59
+ 1, 0, 0, 1, 1, 1,
60
+ 0, 0, 1, 0, 0, 1,
61
+ 0, 0, 0, 0, 1, 1,
62
+ 0, 0, 1, 1, 0, 1]
63
+
64
+ sub_key_7: [0, 1, 1, 1, 1, 1,
65
+ 1, 1, 0, 0, 1, 0,
66
+ 1, 1, 1, 1, 1, 0,
67
+ 1, 0, 1, 0, 0, 1,
68
+ 1, 0, 0, 0, 0, 0,
69
+ 1, 0, 1, 1, 0, 1,
70
+ 0, 1, 1, 0, 1, 1,
71
+ 1, 0, 0, 1, 0, 1]
72
+
73
+ sub_key_8: [1, 1, 0, 1, 1, 0,
74
+ 1, 1, 1, 0, 1, 1,
75
+ 1, 1, 0, 0, 1, 0,
76
+ 1, 1, 1, 1, 0, 1,
77
+ 0, 0, 0, 1, 1, 0,
78
+ 1, 0, 1, 0, 1, 0,
79
+ 1, 1, 1, 1, 1, 0,
80
+ 1, 0, 0, 0, 0, 1]
81
+
82
+ sub_key_9: [1, 0, 0, 1, 1, 0,
83
+ 0, 1, 1, 1, 1, 0,
84
+ 1, 1, 0, 0, 1, 1,
85
+ 1, 0, 1, 1, 1, 1,
86
+ 0, 0, 1, 0, 0, 1,
87
+ 0, 0, 0, 1, 1, 1,
88
+ 0, 0, 0, 0, 0, 0,
89
+ 1, 1, 1, 1, 1, 1]
90
+
91
+ sub_key_10: [1, 1, 1, 1, 0, 0,
92
+ 0, 1, 0, 1, 1, 0,
93
+ 1, 1, 1, 1, 1, 0,
94
+ 1, 1, 1, 1, 1, 0,
95
+ 1, 0, 1, 0, 0, 1,
96
+ 1, 1, 0, 0, 0, 1,
97
+ 1, 0, 0, 0, 1, 1,
98
+ 1, 0, 0, 1, 1, 0]
99
+
100
+ sub_key_11: [1, 1, 1, 1, 0, 1,
101
+ 0, 0, 1, 0, 1, 1,
102
+ 1, 1, 1, 1, 1, 0,
103
+ 1, 0, 0, 1, 0, 1,
104
+ 1, 0, 0, 0, 0, 1,
105
+ 0, 0, 1, 0, 0, 0,
106
+ 1, 0, 1, 1, 1, 1,
107
+ 1, 1, 0, 0, 1, 1]
108
+
109
+ sub_key_12: [1, 1, 0, 1, 0, 0,
110
+ 1, 1, 1, 0, 1, 1,
111
+ 1, 1, 1, 0, 0, 1,
112
+ 1, 1, 0, 1, 1, 1,
113
+ 0, 0, 0, 1, 0, 1,
114
+ 1, 1, 1, 0, 0, 0,
115
+ 1, 1, 1, 0, 0, 1,
116
+ 0, 1, 0, 1, 0, 1]
117
+
118
+ sub_key_13: [1, 1, 1, 0, 1, 1,
119
+ 0, 1, 1, 1, 1, 1,
120
+ 0, 1, 1, 0, 1, 1,
121
+ 1, 1, 0, 1, 1, 0,
122
+ 0, 1, 0, 1, 1, 0,
123
+ 1, 1, 1, 0, 0, 0,
124
+ 0, 1, 0, 1, 1, 1,
125
+ 0, 1, 0, 0, 0, 0]
126
+
127
+ sub_key_14: [1, 1, 1, 1, 0, 1,
128
+ 1, 0, 1, 1, 0, 1,
129
+ 0, 1, 1, 1, 1, 1,
130
+ 1, 0, 1, 1, 1, 0,
131
+ 0, 0, 0, 0, 1, 0,
132
+ 0, 1, 1, 1, 1, 0,
133
+ 0, 1, 0, 1, 0, 0,
134
+ 0, 0, 1, 1, 0, 1]
135
+
136
+ sub_key_15: [1, 1, 1, 1, 1, 0,
137
+ 1, 0, 1, 1, 0, 1,
138
+ 0, 0, 1, 1, 0, 1,
139
+ 1, 1, 0, 0, 1, 1,
140
+ 0, 1, 1, 0, 1, 0,
141
+ 1, 0, 0, 1, 1, 1,
142
+ 0, 1, 0, 0, 1, 0,
143
+ 0, 0, 0, 1, 0, 0]
144
+
145
+ sub_key_16: [1, 1, 1, 1, 1, 1,
146
+ 1, 1, 1, 1, 1, 1,
147
+ 1, 0, 1, 0, 0, 1,
148
+ 1, 1, 0, 0, 1, 1,
149
+ 0, 0, 0, 1, 1, 0,
150
+ 1, 0, 1, 0, 1, 1,
151
+ 1, 0, 0, 0, 0, 1,
152
+ 1, 1, 0, 0, 1, 1]
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+
3
+ class KeyScheduleTest < Test::Unit::TestCase
4
+ fixtures :key_schedule
5
+
6
+ def setup
7
+ @key_schedule = KeySchedule.new(key_schedule(:test_key))
8
+ end
9
+
10
+ def test_class
11
+ assert_kind_of KeySchedule, @key_schedule
12
+ end
13
+
14
+ def test_test_key
15
+ assert_kind_of Array, @key_schedule.key
16
+ assert_equal key_schedule(:test_key), @key_schedule.key
17
+ end
18
+
19
+ def test_sub_keys
20
+ assert_kind_of Array, @key_schedule.sub_keys
21
+ assert_equal key_schedule(:sub_key_1), @key_schedule.sub_keys[0]
22
+ assert_equal key_schedule(:sub_key_2), @key_schedule.sub_keys[1]
23
+ assert_equal key_schedule(:sub_key_3), @key_schedule.sub_keys[2]
24
+ assert_equal key_schedule(:sub_key_4), @key_schedule.sub_keys[3]
25
+ assert_equal key_schedule(:sub_key_5), @key_schedule.sub_keys[4]
26
+ assert_equal key_schedule(:sub_key_6), @key_schedule.sub_keys[5]
27
+ assert_equal key_schedule(:sub_key_7), @key_schedule.sub_keys[6]
28
+ assert_equal key_schedule(:sub_key_8), @key_schedule.sub_keys[7]
29
+ assert_equal key_schedule(:sub_key_9), @key_schedule.sub_keys[8]
30
+ assert_equal key_schedule(:sub_key_10), @key_schedule.sub_keys[9]
31
+ assert_equal key_schedule(:sub_key_11), @key_schedule.sub_keys[10]
32
+ assert_equal key_schedule(:sub_key_12), @key_schedule.sub_keys[11]
33
+ assert_equal key_schedule(:sub_key_13), @key_schedule.sub_keys[12]
34
+ assert_equal key_schedule(:sub_key_14), @key_schedule.sub_keys[13]
35
+ assert_equal key_schedule(:sub_key_15), @key_schedule.sub_keys[14]
36
+ assert_equal key_schedule(:sub_key_16), @key_schedule.sub_keys[15]
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ $:.unshift(File.dirname(__FILE__) + "../lib")
2
+
3
+ require 'test/unit'
4
+ require 'yaml'
5
+ require 'ruby-des'
6
+
7
+ class Test::Unit::TestCase
8
+ @@fixtures = {}
9
+ def self.fixtures(*list)
10
+ list.each do |fixture|
11
+ self.class_eval do
12
+ define_method(fixture) do |item|
13
+ @@fixtures[fixture] ||= File.exists?("#{fixture.to_s}.yml") ? YAML::load_file("#{fixture.to_s}.yml") : YAML::load_file("test/#{fixture.to_s}.yml")
14
+ @@fixtures[fixture][item.to_s]
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ e: [1, 0, 0, 0, 0, 0,
2
+ 0, 0, 0, 0, 0, 1,
3
+ 0, 1, 1, 1, 1, 1,
4
+ 1, 1, 1, 1, 1, 1,
5
+ 1, 1, 0, 1, 0, 0,
6
+ 0, 0, 0, 0, 0, 0,
7
+ 0, 0, 0, 0, 1, 0,
8
+ 1, 0, 1, 0, 1, 0]
9
+
10
+ sub_key: [1, 0, 1, 0, 1, 1,
11
+ 0, 1, 1, 1, 0, 1,
12
+ 1, 0, 1, 1, 0, 1,
13
+ 1, 1, 1, 1, 1, 1,
14
+ 1, 1, 1, 0, 1, 0,
15
+ 0, 0, 0, 1, 0, 0,
16
+ 0, 0, 0, 1, 1, 0,
17
+ 1, 0, 1, 1, 1, 1]
18
+
19
+ e_xor_sub_key: [0, 0, 1, 0, 1, 1,
20
+ 0, 1, 1, 1, 0, 0,
21
+ 1, 1, 0, 0, 1, 0,
22
+ 0, 0, 0, 0, 0, 0,
23
+ 0, 0, 1, 1, 1, 0,
24
+ 0, 0, 0, 1, 0, 0,
25
+ 0, 0, 0, 1, 0, 0,
26
+ 0, 0, 0, 1, 0, 1]
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class XORTest < Test::Unit::TestCase
4
+ fixtures :xor
5
+
6
+ def test_run
7
+ assert_equal xor(:e_xor_sub_key), XOR.run(xor(:e), xor(:sub_key))
8
+ end
9
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-des
3
+ version: !ruby/object:Gem::Version
4
+ hash: 15
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ version: "1.0"
10
+ platform: ruby
11
+ authors:
12
+ - Robert Sosinski
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-06-04 00:00:00 +08:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description:
22
+ email:
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - .gitignore
31
+ - MIT-LICENSE
32
+ - README.markdown
33
+ - Rakefile
34
+ - lib/ruby-des.rb
35
+ - lib/ruby-des/feistel.rb
36
+ - lib/ruby-des/key_schedule.rb
37
+ - lib/ruby-des/xor.rb
38
+ - test/ctx.yml
39
+ - test/ctx_test.rb
40
+ - test/feistel.yml
41
+ - test/feistel_test.rb
42
+ - test/key_schedule.yml
43
+ - test/key_schedule_test.rb
44
+ - test/test_helper.rb
45
+ - test/xor.yml
46
+ - test/xor_test.rb
47
+ has_rdoc: true
48
+ homepage:
49
+ licenses: []
50
+
51
+ post_install_message:
52
+ rdoc_options: []
53
+
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ hash: 3
71
+ segments:
72
+ - 0
73
+ version: "0"
74
+ requirements: []
75
+
76
+ rubyforge_project: ruby-des
77
+ rubygems_version: 1.6.2
78
+ signing_key:
79
+ specification_version: 3
80
+ summary: This gem make use DES Data Encryption.
81
+ test_files:
82
+ - test/ctx.yml
83
+ - test/ctx_test.rb
84
+ - test/feistel.yml
85
+ - test/feistel_test.rb
86
+ - test/key_schedule.yml
87
+ - test/key_schedule_test.rb
88
+ - test/test_helper.rb
89
+ - test/xor.yml
90
+ - test/xor_test.rb