otherinbox-crypt19 1.2.1

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,73 @@
1
+ # RC6 symmetric key block cipher
2
+ # RC6 is a patented encryption algorithm (U.S. Patent 5,724,428 and U.S. Patent 5,835,600)
3
+ # Ported by Alexey Lapitsky <lex.public@gmail.com> (2009)
4
+
5
+ require 'crypt/cbc'
6
+
7
+ module Crypt
8
+ class RC6
9
+ include Crypt::CBC
10
+
11
+ def block_size
12
+ return 16
13
+ end
14
+
15
+ def lrotate(d,s)
16
+ d = d & 0xffffffff
17
+ ((d)<<(s&(31))) | ((d)>>(32-(s&(31))))
18
+ end
19
+ def rrotate(d,s)
20
+ d = d & 0xffffffff
21
+ ((d)>>(s&(31))) | ((d)<<(32-(s&(31))))
22
+ end
23
+
24
+ def initialize(key)
25
+ @rounds, @sbox, @key = 20, [0xB7E15163], []
26
+ key = key.bytes.to_a if key.class == String
27
+ raise("Wrong key length") unless [32,24,16].include?(key.size)
28
+ (key.size-1).downto(0){|i| @key[i/4] = ((@key[i/4]||0) << 8) + key[i]}
29
+
30
+ (@rounds * 2 + 3).times{|i| @sbox << (@sbox.last + 0x9E3779B9 & 0xffffffff)}
31
+ a = b = i = j = 0
32
+ (3 * (2 * @rounds + 4)).times do
33
+ a = @sbox[i] = lrotate(@sbox[i] + a + b, 3)
34
+ b = @key[j] = lrotate(@key[j] + a + b, a + b)
35
+ i = (i + 1).divmod(2 * @rounds + 4).last
36
+ j = (j + 1).divmod(@key.size).last
37
+ end
38
+ end
39
+
40
+ def encrypt_block(data)
41
+ a, b, c, d = *data.unpack('N*')
42
+ b += @sbox[0]
43
+ d += @sbox[1]
44
+ 1.upto @rounds do |i|
45
+ t = lrotate((b * (2 * b + 1)), 5)
46
+ u = lrotate((d * (2 * d + 1)), 5)
47
+ a = lrotate((a ^ t), u) + @sbox[2 * i]
48
+ c = lrotate((c ^ u), t) + @sbox[2 * i + 1]
49
+ a, b, c, d = b, c, d, a
50
+ end
51
+ a += @sbox[2 * @rounds + 2]
52
+ c += @sbox[2 * @rounds + 3]
53
+ [a, b, c, d].map{|i| i & 0xffffffff}.pack('N*')
54
+ end
55
+
56
+ def decrypt_block(data)
57
+ a, b, c, d = *data.unpack('N*')
58
+ c -= @sbox[2 * @rounds + 3]
59
+ a -= @sbox[2 * @rounds + 2]
60
+ @rounds.downto 1 do |i|
61
+ a, b, c, d = d, a, b, c
62
+ u = lrotate((d * (2 * d + 1)), 5)
63
+ t = lrotate((b * (2 * b + 1)), 5)
64
+ c = rrotate((c - @sbox[2 * i + 1]), t) ^ u
65
+ a = rrotate((a - @sbox[2 * i]), u) ^ t
66
+ end
67
+ d -= @sbox[1]
68
+ b -= @sbox[0]
69
+ [a, b, c, d].map{|i| i & 0xffffffff}.pack('N*')
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,115 @@
1
+ module Crypt
2
+ module RijndaelTables
3
+
4
+ LogTable = [
5
+ 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 223, 3,
6
+ 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200, 248, 105, 28, 193,
7
+ 125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 166, 114, 154, 201, 9, 120,
8
+ 101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69, 53, 147, 218, 142,
9
+ 150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210, 241, 64, 70, 131, 56,
10
+ 102, 221, 253, 48, 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16,
11
+ 126, 110, 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
12
+ 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115, 167, 87,
13
+ 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 231, 230, 173, 232,
14
+ 44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 95, 176, 156, 169, 81, 160,
15
+ 127, 12, 246, 111, 23, 196, 73, 236, 216, 67, 31, 45, 164, 118, 123, 183,
16
+ 204, 187, 62, 90, 251, 96, 177, 134, 59, 82, 161, 108, 170, 85, 41, 157,
17
+ 151, 178, 135, 144, 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209,
18
+ 83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
19
+ 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 227, 165,
20
+ 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128, 192, 247, 112, 7
21
+ ]
22
+
23
+ AlogTable = [
24
+ 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
25
+ 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
26
+ 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
27
+ 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
28
+ 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
29
+ 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
30
+ 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
31
+ 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
32
+ 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
33
+ 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
34
+ 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
35
+ 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
36
+ 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
37
+ 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
38
+ 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
39
+ 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
40
+ ]
41
+
42
+ S = [
43
+ 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
44
+ 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
45
+ 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
46
+ 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
47
+ 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
48
+ 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
49
+ 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
50
+ 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
51
+ 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
52
+ 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
53
+ 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
54
+ 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
55
+ 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
56
+ 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
57
+ 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
58
+ 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22
59
+ ]
60
+
61
+ Si = [
62
+ 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251,
63
+ 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203,
64
+ 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78,
65
+ 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37,
66
+ 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
67
+ 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132,
68
+ 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6,
69
+ 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107,
70
+ 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115,
71
+ 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
72
+ 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27,
73
+ 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244,
74
+ 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95,
75
+ 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239,
76
+ 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
77
+ 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125,
78
+ ]
79
+
80
+ IG = [
81
+ [0x0e, 0x09, 0x0d, 0x0b],
82
+ [0x0b, 0x0e, 0x09, 0x0d],
83
+ [0x0d, 0x0b, 0x0e, 0x09],
84
+ [0x09, 0x0d, 0x0b, 0x0e]
85
+ ]
86
+
87
+ Rcon = [
88
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
89
+ 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
90
+ 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
91
+ 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
92
+ 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
93
+ ]
94
+
95
+ Shifts = [
96
+ [
97
+ [0, 0],
98
+ [1, 3],
99
+ [2, 2],
100
+ [3, 1]
101
+ ], [
102
+ [0, 0],
103
+ [1, 5],
104
+ [2, 4],
105
+ [3, 3]
106
+ ], [
107
+ [0, 0],
108
+ [1, 7],
109
+ [3, 5],
110
+ [4, 4]
111
+ ]
112
+ ]
113
+
114
+ end
115
+ end
@@ -0,0 +1,267 @@
1
+ # Adapted from the reference C implementation:
2
+ # rijndael-alg-ref.c v2.2 March 2002
3
+ # Reference ANSI C code by Paulo Barreto and Vincent Rijmen
4
+
5
+ require 'crypt/cbc'
6
+ require 'crypt/rijndael-tables'
7
+ require 'crypt/bytes-compat'
8
+
9
+ module Crypt
10
+ class Rijndael
11
+
12
+ include Crypt::CBC
13
+ include Crypt::RijndaelTables
14
+
15
+
16
+ def initialize(user_key, key_bits = 256, block_bits = 128)
17
+ case key_bits
18
+ when 128
19
+ @key_words = 4
20
+ when 192
21
+ @key_words = 6
22
+ when 256
23
+ @key_words = 8
24
+ else raise "The key must be 128, 192, or 256 bits long."
25
+ end
26
+
27
+ case (key_bits >= block_bits) ? key_bits : block_bits
28
+ when 128
29
+ @rounds = 10
30
+ when 192
31
+ @rounds = 12
32
+ when 256
33
+ @rounds = 14
34
+ else raise "The key and block sizes must be 128, 192, or 256 bits long."
35
+ end
36
+
37
+ case block_bits
38
+ when 128
39
+ @block_size = 16
40
+ @block_words = 4
41
+ @shift_index = 0
42
+ when 192
43
+ @block_size = 24
44
+ @block_words = 6
45
+ @shift_index = 1
46
+ when 256
47
+ @block_size = 32
48
+ @block_words = 8
49
+ @shift_index = 2
50
+ else raise "The block size must be 128, 192, or 256 bits long."
51
+ end
52
+
53
+ uk = user_key.unpack('C'*user_key.length)
54
+ max_useful_size_of_user_key = (key_bits/8)
55
+ uk = uk[0..max_useful_size_of_user_key-1] # truncate
56
+ padding = 0
57
+ if (user_key.length < key_bits/8)
58
+ shortfall_in_user_key = (key_bits/8 - user_key.length)
59
+ shortfall_in_user_key.times { uk << padding }
60
+ end
61
+ @key = [[], [], [], []]
62
+ 0.upto(uk.length-1) { |pos|
63
+ @key[pos % 4][pos / 4] = uk[pos]
64
+ }
65
+ @round_keys = generate_key_schedule(@key, key_bits, block_bits)
66
+ end
67
+
68
+
69
+ def block_size
70
+ return(@block_size) # needed for CBC
71
+ end
72
+
73
+
74
+ def mul(a, b)
75
+ if ((a ==0) | (b == 0))
76
+ result = 0
77
+ else
78
+ result = AlogTable[(LogTable[a] + LogTable[b]) % 255]
79
+ end
80
+ return(result)
81
+ end
82
+
83
+
84
+ def add_round_key(block_array, round_key)
85
+ 0.upto(3) { |i|
86
+ 0.upto(@block_words) { |j|
87
+ block_array[i][j] ^= round_key[i][j]
88
+ }
89
+ }
90
+ return(block_array)
91
+ end
92
+
93
+
94
+ def shift_rows(block_array, direction)
95
+ tmp = []
96
+ 1.upto(3) { |i| # row zero remains unchanged
97
+ 0.upto(@block_words-1) { |j|
98
+ tmp[j] = block_array[i][(j + Shifts[@shift_index][i][direction]) % @block_words]
99
+ }
100
+ 0.upto(@block_words-1) { |j|
101
+ block_array[i][j] = tmp[j]
102
+ }
103
+ }
104
+ return(block_array)
105
+ end
106
+
107
+
108
+ def substitution(block_array, sBox)
109
+ # replace every byte of the input with the byte at that position in the S-box
110
+ 0.upto(3) { |i|
111
+ 0.upto(@block_words-1) { |j|
112
+ block_array[i][j] = sBox[block_array[i][j]]
113
+ }
114
+ }
115
+ return(block_array)
116
+ end
117
+
118
+
119
+ def mix_columns(block_array)
120
+ mixed = [[], [], [], []]
121
+ 0.upto(@block_words-1) { |j|
122
+ 0.upto(3) { |i|
123
+ mixed[i][j] = mul(2,block_array[i][j]) ^
124
+ mul(3,block_array[(i + 1) % 4][j]) ^
125
+ block_array[(i + 2) % 4][j] ^
126
+ block_array[(i + 3) % 4][j]
127
+ }
128
+ }
129
+ return(mixed)
130
+ end
131
+
132
+
133
+ def inverse_mix_columns(block_array)
134
+ unmixed = [[], [], [], []]
135
+ 0.upto(@block_words-1) { |j|
136
+ 0.upto(3) { |i|
137
+ unmixed[i][j] = mul(0xe, block_array[i][j]) ^
138
+ mul(0xb, block_array[(i + 1) % 4][j]) ^
139
+ mul(0xd, block_array[(i + 2) % 4][j]) ^
140
+ mul(0x9, block_array[(i + 3) % 4][j])
141
+ }
142
+ }
143
+ return(unmixed)
144
+ end
145
+
146
+
147
+ def generate_key_schedule(k, key_bits, block_bits)
148
+ tk = k[0..3][0..@key_words-1] # using slice to get a copy instead of a reference
149
+ key_sched = []
150
+ (@rounds + 1).times { key_sched << [[], [], [], []] }
151
+ t = 0
152
+ j = 0
153
+ while ((j < @key_words) && (t < (@rounds+1)*@block_words))
154
+ 0.upto(3) { |i|
155
+ key_sched[t / @block_words][i][t % @block_words] = tk[i][j]
156
+ }
157
+ j += 1
158
+ t += 1
159
+ end
160
+ # while not enough round key material collected, calculate new values
161
+ rcon_index = 0
162
+ while (t < (@rounds+1)*@block_words)
163
+ 0.upto(3) { |i|
164
+ tk[i][0] ^= S[tk[(i + 1) % 4][@key_words - 1]]
165
+ }
166
+ tk[0][0] ^= Rcon[rcon_index]
167
+ rcon_index = rcon_index.next
168
+ if (@key_words != 8)
169
+ 1.upto(@key_words - 1) { |j|
170
+ 0.upto(3) { |i|
171
+ tk[i][j] ^= tk[i][j-1];
172
+ }
173
+ }
174
+ else
175
+ 1.upto(@key_words/2 - 1) { |j|
176
+ 0.upto(3) { |i|
177
+ tk[i][j] ^= tk[i][j-1]
178
+ }
179
+ }
180
+ 0.upto(3) { |i|
181
+ tk[i][@key_words/2] ^= S[tk[i][@key_words/2 - 1]]
182
+ }
183
+ (@key_words/2 + 1).upto(@key_words - 1) { |j|
184
+ 0.upto(3) { |i|
185
+ tk[i][j] ^= tk[i][j-1]
186
+ }
187
+ }
188
+ end
189
+ j = 0
190
+ while ((j < @key_words) && (t < (@rounds+1) * @block_words))
191
+ 0.upto(3) { |i|
192
+ key_sched[t / @block_words][i][t % @block_words] = tk[i][j]
193
+ }
194
+ j += 1
195
+ t += 1
196
+ end
197
+ end
198
+ return(key_sched)
199
+ end
200
+
201
+
202
+ def encrypt_byte_array(block_array)
203
+ block_array = add_round_key(block_array, @round_keys[0])
204
+ 1.upto(@rounds - 1) { |round|
205
+ block_array = substitution(block_array, S)
206
+ block_array = shift_rows(block_array, 0)
207
+ block_array = mix_columns(block_array)
208
+ block_array = add_round_key(block_array, @round_keys[round])
209
+ }
210
+ # special round without mix_columns
211
+ block_array = substitution(block_array,S)
212
+ block_array = shift_rows(block_array,0)
213
+ block_array = add_round_key(block_array, @round_keys[@rounds])
214
+ return(block_array)
215
+ end
216
+
217
+
218
+ def encrypt_block(block)
219
+ raise "block must be #{@block_size} bytes long" if (block.length() != @block_size)
220
+ block_array = [[], [], [], []]
221
+ block_bytes = block.bytes.to_a
222
+ 0.upto(@block_size - 1) { |pos|
223
+ block_array[pos % 4][pos / 4] = block_bytes[pos]
224
+ }
225
+ encrypted_block = encrypt_byte_array(block_array)
226
+ encrypted = ""
227
+ 0.upto(@block_size - 1) { |pos|
228
+ encrypted << encrypted_block[pos % 4][pos / 4]
229
+ }
230
+ return(encrypted)
231
+ end
232
+
233
+
234
+ def decrypt_byte_array(block_array)
235
+ # first special round without inverse_mix_columns
236
+ # add_round_key is an involution - applying it a second time returns the original result
237
+ block_array = add_round_key(block_array, @round_keys[@rounds])
238
+ block_array = substitution(block_array,Si) # using inverse S-box
239
+ block_array = shift_rows(block_array,1)
240
+ (@rounds-1).downto(1) { |round|
241
+ block_array = add_round_key(block_array, @round_keys[round])
242
+ block_array = inverse_mix_columns(block_array)
243
+ block_array = substitution(block_array, Si)
244
+ block_array = shift_rows(block_array, 1)
245
+ }
246
+ block_array = add_round_key(block_array, @round_keys[0])
247
+ return(block_array)
248
+ end
249
+
250
+
251
+ def decrypt_block(block)
252
+ raise "block must be #{@block_size} bytes long" if (block.length() != @block_size)
253
+ block_array = [[], [], [], []]
254
+ block_bytes = block.bytes.to_a
255
+ 0.upto(@block_size - 1) { |pos|
256
+ block_array[pos % 4][pos / 4] = block_bytes[pos]
257
+ }
258
+ decrypted_block = decrypt_byte_array(block_array)
259
+ decrypted = ""
260
+ 0.upto(@block_size - 1) { |pos|
261
+ decrypted << decrypted_block[pos % 4][pos / 4]
262
+ }
263
+ return(decrypted)
264
+ end
265
+
266
+ end
267
+ end