ruby-des 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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