des 1.03

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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7510ef2176a3d24c508f769686a9431b2ea5c6d6
4
+ data.tar.gz: bbdc24272bd2ae1021d176e9533d93b9f85912a9
5
+ SHA512:
6
+ metadata.gz: c50ab8d64bc1c39f5de8ef51e9f94b77475fb8a44ee227f7e4d1e2d1b4e078125831bc9760ad2ea09dc970ba592bfbe79c2de26b36dd2597896481e1e20aac81
7
+ data.tar.gz: 319cbb98911b7fdb1a9544bebf76119e0af458fd44ec330cdec6210484b0090a2eb30d3fb270eb7f699692ff9c77c6686924c4212708fc81d04d327be0d64912
@@ -0,0 +1,111 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ require 'des/feistel'
4
+ require 'des/key_schedule'
5
+
6
+ module DES
7
+ IP_L = [58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8]
8
+ IP_R = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7]
9
+ FP = [40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
10
+ 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25]
11
+
12
+ class ::Array
13
+ # @param [Array] another_ary
14
+ # @return [Array]
15
+ def xor(another_ary)
16
+ self.map.with_index { |obj, i| (obj ^ another_ary[i]) }
17
+ end
18
+ end
19
+
20
+ class Ctx
21
+ attr_reader :data, :key
22
+
23
+ def initialize(data, key)
24
+ unless data.is_a?(DES::Block) and key.is_a?(DES::Block)
25
+ raise 'DES::InvalidBlockFormat: Data and key must be a Block object.'
26
+ end
27
+
28
+ @data = data
29
+ @key = key
30
+ end
31
+
32
+ def encrypt
33
+ self.run(:encrypt)
34
+ end
35
+
36
+ def decrypt
37
+ self.run(:decrypt)
38
+ end
39
+
40
+ protected
41
+
42
+ # @param [Symbol] operation
43
+ def run(operation)
44
+ # l[0] is the IP_1_L permutation of the data block, l[1..16] are the results of each round of encryption
45
+ l = []
46
+ # r[0] is the IP_1_R permutation of the data block, r[1..16] are the results of each round of encryption
47
+ r = []
48
+
49
+ l << IP_L.collect { |p| data.bit_array[p - 1] }
50
+ r << IP_R.collect { |p| data.bit_array[p - 1] }
51
+
52
+ case operation
53
+ when :encrypt
54
+ k = KeySchedule.new(key.bit_array).sub_keys
55
+ when :decrypt
56
+ k = KeySchedule.new(key.bit_array).sub_keys.reverse
57
+ else
58
+ raise "Unknown operation - #{operation}"
59
+ end
60
+
61
+ 16.times do |i|
62
+ l << r[i]
63
+ r << Feistel.run(r[i], k[i]).xor(l[i])
64
+ end
65
+
66
+ DES::Block.new(FP.collect { |p| (r.last + l.last)[p - 1] })
67
+ end
68
+ end
69
+
70
+ class Block
71
+ attr_reader :string, :bit_array
72
+
73
+ alias_method :to_s, :string
74
+ alias_method :to_a, :bit_array
75
+
76
+ # @param [String, Array] input
77
+ # @return [NilClass]
78
+ def initialize(input)
79
+ if input.is_a?(String)
80
+ raise "DES::InvalidStringLength: Input String '#{input}' must contain (8) characters." unless input.length.eql?(8)
81
+
82
+ @string = input
83
+ @bit_array = input.unpack('B*').join.split('').collect { |b| b.to_i }
84
+ elsif input.is_a?(Array)
85
+ raise 'DES::InvalidArraySize: Input Array must contain (64) bits.' unless input.size.eql?(64)
86
+
87
+ @string = input.join.lines.to_a.pack('B*')
88
+ @bit_array = input
89
+ else
90
+ raise 'DES::InvalidFormat: Input must be a String or an Array.'
91
+ end
92
+ end
93
+ end
94
+
95
+ # @param [String, Array] data
96
+ # @param [String, Array] key
97
+ def self.encrypt(data, key)
98
+ data_block = DES::Block.new(data)
99
+ key_block = DES::Block.new(key)
100
+
101
+ DES::Ctx.new(data_block, key_block).encrypt
102
+ end
103
+
104
+ # @param [DES::Block] data_block
105
+ # @param [String] key
106
+ def self.decrypt(data_block, key)
107
+ key_block = DES::Block.new(key)
108
+ DES::Ctx.new(data_block, key_block).decrypt
109
+ end
110
+
111
+ end
@@ -0,0 +1,70 @@
1
+ module Feistel
2
+ E = [32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20,
3
+ 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1]
4
+
5
+ P = [16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11,
6
+ 4, 25]
7
+
8
+ S1 = [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 4,
9
+ 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]
10
+
11
+ S2 = [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, 0,
12
+ 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]
13
+
14
+ S3 = [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, 13,
15
+ 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]
16
+
17
+ S4 = [7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, 10,
18
+ 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]
19
+
20
+ S5 = [2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, 4,
21
+ 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]
22
+
23
+ S6 = [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, 9,
24
+ 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]
25
+
26
+ S7 = [4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, 1,
27
+ 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]
28
+
29
+ S8 = [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, 7,
30
+ 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]
31
+
32
+ S = [S1, S2, S3, S4, S5, S6, S7, S8]
33
+
34
+ # @param [Array] r
35
+ # @param [Array] k
36
+ def self.run(r, k)
37
+ # b[0..7] is e_xor_k prepped as 8 6-bit arrays for s-box substitution
38
+ b = []
39
+ # m[0..7] is the row of the value when performing a s-box lookup
40
+ m = []
41
+ # n[0..7] is the column of the value when performing a s-box lookup
42
+ n = []
43
+
44
+ # Expand r (right half data block) using E
45
+ e = E.collect { |p| r[p - 1] }
46
+
47
+ # X-or e (expanded r) with k (the sub key)
48
+ e_xor_k = e.xor(k)
49
+
50
+ # 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
51
+ 8.times do |i|
52
+ b << []
53
+ 6.times do
54
+ b[i] << e_xor_k.shift
55
+ end
56
+
57
+ # [1, 0, 1, 0, 1, 0] => [1, 0] => 2 => 32 => 3rd row
58
+ m << [b[i].first, b[i].last].join.to_i(2) * 16
59
+ # [1, 0, 1, 0, 1, 0] => [0, 1, 0, 1] => 5 => 6th column
60
+ n << b[i][1..4].join.to_i(2)
61
+ end
62
+
63
+ # Substitute every 6-bit array with the 4-bit array specified by the appropriate s-box
64
+ 8.times do |i|
65
+ b[i] = S[i][m[i] + n[i]].to_s(2).rjust(4, '0').split('').collect { |bit| bit.to_i }
66
+ end
67
+
68
+ P.collect { |p| b.flatten[p - 1] }
69
+ end
70
+ end
@@ -0,0 +1,40 @@
1
+ class KeySchedule
2
+ attr_accessor :sub_keys
3
+ attr_reader :key
4
+
5
+ PC_1_L = [57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36]
6
+ PC_1_R = [63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4]
7
+ PC_2 = [14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47,
8
+ 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32]
9
+
10
+ ROTATIONS = [1, 1, 2, 2, 2, 2, 2, 2,
11
+ 1, 2, 2, 2, 2, 2, 2, 1]
12
+
13
+ def initialize(key)
14
+ @key = key
15
+
16
+ # c[0] is the PC_1_L permutation of the key, c[1..16] are the results of each left shift.
17
+ c = []
18
+ # d[0] is the PC_1_R permutation of the key, d[1..16] are the results of each left shift.
19
+ d = []
20
+ # k[0..15] are the sub keys created by combining c[i] and d[i] and permuting with PC_2.
21
+ k = []
22
+
23
+ c << PC_1_L.collect { |p| key[p - 1] }
24
+ d << PC_1_R.collect { |p| key[p - 1] }
25
+
26
+ 16.times do |i|
27
+ c << c[i]
28
+ d << d[i]
29
+
30
+ ROTATIONS[i].times do
31
+ c[i + 1] << c[i + 1].shift
32
+ d[i + 1] << d[i + 1].shift
33
+ end
34
+
35
+ k << PC_2.collect { |p| (c[i + 1] + d[i + 1])[p - 1] }
36
+ end
37
+
38
+ @sub_keys = k
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: des
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.03'
5
+ platform: ruby
6
+ authors:
7
+ - Robert Sosinski
8
+ - Arthur Karganyan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-06-03 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: This gem make use DES Data Encryption.
15
+ email: dondenegocios@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/des.rb
21
+ - lib/des/feistel.rb
22
+ - lib/des/key_schedule.rb
23
+ homepage: https://github.com/dondenegocios/des
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.2.2
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: This gem make use DES Data Encryption.
47
+ test_files: []
48
+ has_rdoc: