des 1.03

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: