ruby-aes-unroll2 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,599 @@
1
+ =begin
2
+ This file is a part of ruby-aes <http://rubyforge.org/projects/ruby-aes>
3
+ Written by Alex Boussinet <alex.boussinet@gmail.com>
4
+
5
+ This version is derived from the Optimised ANSI C code
6
+ Authors of C version:
7
+ Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
8
+ Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
9
+ Paulo Barreto <paulo.barreto@terra.com.br>
10
+
11
+ Table look up improvements
12
+ =end
13
+
14
+ require 'ruby-aes/aes_cons'
15
+
16
+ class AesAlg
17
+ include AesCons
18
+
19
+ def encryption_key_schedule(key)
20
+ i = 0
21
+ @ek = []
22
+ @ek[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]
23
+ @ek[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7]
24
+ @ek[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11]
25
+ @ek[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15]
26
+ if @kl == 128
27
+ j = 0
28
+ loop do
29
+ temp = @ek[3+j]
30
+ @ek[4+j] = @ek[0+j] ^
31
+ (S3[(temp >> 16) & 0xff]) ^
32
+ (S2[(temp >> 8) & 0xff]) ^
33
+ (S1[(temp) & 0xff]) ^
34
+ (S0[(temp >> 24)]) ^ RCON[i]
35
+ @ek[5+j] = @ek[1+j] ^ @ek[4+j]
36
+ @ek[6+j] = @ek[2+j] ^ @ek[5+j]
37
+ @ek[7+j] = @ek[3+j] ^ @ek[6+j]
38
+ i += 1
39
+ return if (i == 10)
40
+ j += 4
41
+ end
42
+ end
43
+ @ek[4] = key[16] << 24 | key[17] << 16 | key[18] << 8 | key[19]
44
+ @ek[5] = key[20] << 24 | key[21] << 16 | key[22] << 8 | key[23]
45
+ if (@kl == 192)
46
+ j = 0
47
+ loop do
48
+ temp = @ek[ 5+j]
49
+ @ek[ 6+j] = @ek[ 0+j] ^
50
+ (S3[(temp >> 16) & 0xff]) ^
51
+ (S2[(temp >> 8) & 0xff]) ^
52
+ (S1[(temp) & 0xff]) ^
53
+ (S0[(temp >> 24)]) ^ RCON[i]
54
+ @ek[ 7+j] = @ek[ 1+j] ^ @ek[ 6+j]
55
+ @ek[ 8+j] = @ek[ 2+j] ^ @ek[ 7+j]
56
+ @ek[ 9+j] = @ek[ 3+j] ^ @ek[ 8+j]
57
+ i += 1
58
+ return if (i == 8)
59
+ @ek[10+j] = @ek[ 4+j] ^ @ek[ 9+j]
60
+ @ek[11+j] = @ek[ 5+j] ^ @ek[10+j]
61
+ j += 6
62
+ end
63
+ end
64
+ @ek[6] = key[24] << 24 | key[25] << 16 | key[26] << 8 | key[27]
65
+ @ek[7] = key[28] << 24 | key[29] << 16 | key[30] << 8 | key[31]
66
+ if (@kl == 256)
67
+ j = 0
68
+ loop do
69
+ temp = @ek[ 7+j]
70
+ @ek[ 8+j] = @ek[ 0+j] ^
71
+ (S3[(temp >> 16) & 0xff]) ^
72
+ (S2[(temp >> 8) & 0xff]) ^
73
+ (S1[(temp) & 0xff]) ^
74
+ (S0[(temp >> 24)]) ^ RCON[i]
75
+ @ek[ 9+j] = @ek[ 1+j] ^ @ek[ 8+j]
76
+ @ek[10+j] = @ek[ 2+j] ^ @ek[ 9+j]
77
+ @ek[11+j] = @ek[ 3+j] ^ @ek[10+j]
78
+ i += 1
79
+ return if (i == 7)
80
+ temp = @ek[11+j]
81
+ @ek[12+j] = @ek[ 4+j] ^
82
+ (S3[(temp >> 24)]) ^
83
+ (S2[(temp >> 16) & 0xff]) ^
84
+ (S1[(temp >> 8) & 0xff]) ^
85
+ (S0[(temp) & 0xff])
86
+ @ek[13+j] = @ek[ 5+j] ^ @ek[12+j]
87
+ @ek[14+j] = @ek[ 6+j] ^ @ek[13+j]
88
+ @ek[15+j] = @ek[ 7+j] ^ @ek[14+j]
89
+ j += 8
90
+ end
91
+ end
92
+ end
93
+ protected :encryption_key_schedule
94
+
95
+ def decryption_key_schedule(key)
96
+ # expand the cipher key:
97
+ encryption_key_schedule(key)
98
+ @dk = @ek.dup
99
+ # invert the order of the round keys:
100
+ j = 4 * @nr
101
+ i = 0
102
+ loop do
103
+ break if i >= j
104
+ temp = @dk[i]
105
+ @dk[i] = @dk[j]
106
+ @dk[j] = temp
107
+ temp = @dk[i + 1]
108
+ @dk[i + 1] = @dk[j + 1]
109
+ @dk[j + 1] = temp
110
+ temp = @dk[i + 2]
111
+ @dk[i + 2] = @dk[j + 2]
112
+ @dk[j + 2] = temp
113
+ temp = @dk[i + 3]
114
+ @dk[i + 3] = @dk[j + 3]
115
+ @dk[j + 3] = temp
116
+ i += 4
117
+ j -= 4
118
+ end
119
+ # apply the inverse MixColumn transform
120
+ # to all round keys but the first and the last:
121
+ j = 0
122
+ 1.upto(@nr-1) do |i|
123
+ j += 4
124
+ w0= @dk[j]
125
+ w1 = @dk[j+1]
126
+ w2 = @dk[j+2]
127
+ w3 = @dk[j+3]
128
+ @dk[0+j] =
129
+ Td0[S0[(w0 >> 24)] ]^
130
+ Td1[S0[(w0 >> 16) & 0xff] ] ^
131
+ Td2[S0[(w0 >> 8) & 0xff] ] ^
132
+ Td3[S0[(w0) & 0xff] ]
133
+ @dk[1+j] =
134
+ Td0[S0[(w1 >> 24)] ] ^
135
+ Td1[S0[(w1 >> 16) & 0xff] ] ^
136
+ Td2[S0[(w1 >> 8) & 0xff] ] ^
137
+ Td3[S0[(w1) & 0xff] ]
138
+ @dk[2+j] =
139
+ Td0[S0[(w2 >> 24)] ] ^
140
+ Td1[S0[(w2 >> 16) & 0xff] ] ^
141
+ Td2[S0[(w2 >> 8) & 0xff] ] ^
142
+ Td3[S0[(w2) & 0xff] ]
143
+ @dk[3+j] =
144
+ Td0[S0[(w3 >> 24)] ] ^
145
+ Td1[S0[(w3 >> 16) & 0xff] ] ^
146
+ Td2[S0[(w3 >> 8) & 0xff] ] ^
147
+ Td3[S0[(w3) & 0xff] ]
148
+ end
149
+ end
150
+ protected :decryption_key_schedule
151
+
152
+ def _encrypt_block(pt)
153
+ #
154
+ # map byte array block to cipher state and add initial round key:
155
+ #
156
+ s0 = (pt[ 0] << 24 | pt[ 1] << 16 | pt[ 2] << 8 | pt[ 3]) ^ @ek[0]
157
+ s1 = (pt[ 4] << 24 | pt[ 5] << 16 | pt[ 6] << 8 | pt[ 7]) ^ @ek[1]
158
+ s2 = (pt[ 8] << 24 | pt[ 9] << 16 | pt[10] << 8 | pt[11]) ^ @ek[2]
159
+ s3 = (pt[12] << 24 | pt[13] << 16 | pt[14] << 8 | pt[15]) ^ @ek[3]
160
+ # round 1:
161
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
162
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ @ek[ 4]
163
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
164
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ @ek[ 5]
165
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
166
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ @ek[ 6]
167
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
168
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ @ek[ 7]
169
+ # round 2:
170
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
171
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ @ek[ 8]
172
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
173
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ @ek[ 9]
174
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
175
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ @ek[10]
176
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
177
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ @ek[11]
178
+ # round 3:
179
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
180
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ @ek[12]
181
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
182
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ @ek[13]
183
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
184
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ @ek[14]
185
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
186
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ @ek[15]
187
+ # round 4:
188
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
189
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ @ek[16]
190
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
191
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ @ek[17]
192
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
193
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ @ek[18]
194
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
195
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ @ek[19]
196
+ # round 5:
197
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
198
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ @ek[20]
199
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
200
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ @ek[21]
201
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
202
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ @ek[22]
203
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
204
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ @ek[23]
205
+ # round 6:
206
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
207
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ @ek[24]
208
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
209
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ @ek[25]
210
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
211
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ @ek[26]
212
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
213
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ @ek[27]
214
+ # round 7:
215
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
216
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ @ek[28]
217
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
218
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ @ek[29]
219
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
220
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ @ek[30]
221
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
222
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ @ek[31]
223
+ # round 8:
224
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
225
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ @ek[32]
226
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
227
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ @ek[33]
228
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
229
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ @ek[34]
230
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
231
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ @ek[35]
232
+ # round 9:
233
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
234
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ @ek[36]
235
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
236
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ @ek[37]
237
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
238
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ @ek[38]
239
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
240
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ @ek[39]
241
+ if (@nr > 10)
242
+ # round 10:
243
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
244
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ @ek[40]
245
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
246
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ @ek[41]
247
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
248
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ @ek[42]
249
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
250
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ @ek[43]
251
+ # round 11:
252
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
253
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ @ek[44]
254
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
255
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ @ek[45]
256
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
257
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ @ek[46]
258
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
259
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ @ek[47]
260
+ if (@nr > 12)
261
+ # round 12:
262
+ s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^
263
+ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ @ek[48]
264
+ s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^
265
+ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ @ek[49]
266
+ s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^
267
+ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ @ek[50]
268
+ s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^
269
+ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ @ek[51]
270
+ # round 13:
271
+ t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^
272
+ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ @ek[52]
273
+ t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^
274
+ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ @ek[53]
275
+ t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^
276
+ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ @ek[54]
277
+ t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^
278
+ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ @ek[55]
279
+ end
280
+ end
281
+ j = @nr << 2
282
+ #
283
+ # apply last round and map cipher state to byte array block:
284
+ #
285
+ s0 =
286
+ (S3[(t0 >> 24)]) ^
287
+ (S2[(t1 >> 16) & 0xff]) ^
288
+ (S1[(t2 >> 8) & 0xff]) ^
289
+ (S0[(t3) & 0xff]) ^ @ek[0+j]
290
+ s1 =
291
+ (S3[(t1 >> 24)]) ^
292
+ (S2[(t2 >> 16) & 0xff]) ^
293
+ (S1[(t3 >> 8) & 0xff]) ^
294
+ (S0[(t0) & 0xff]) ^ @ek[1+j]
295
+ s2 =
296
+ (S3[(t2 >> 24)]) ^
297
+ (S2[(t3 >> 16) & 0xff]) ^
298
+ (S1[(t0 >> 8) & 0xff]) ^
299
+ (S0[(t1) & 0xff]) ^ @ek[2+j]
300
+ s3 =
301
+ (S3[(t3 >> 24)]) ^
302
+ (S2[(t0 >> 16) & 0xff]) ^
303
+ (S1[(t1 >> 8) & 0xff]) ^
304
+ (S0[(t2) & 0xff]) ^ @ek[3+j]
305
+ [("%08x%08x%08x%08x" % [s0, s1, s2, s3])].pack("H*")
306
+ end
307
+ protected :_encrypt_block
308
+
309
+ def _decrypt_block(ct)
310
+ #
311
+ # map byte array block to cipher state and add initial round key:
312
+ #
313
+ s0 = (ct[ 0] << 24 | ct[ 1] << 16 | ct[ 2] << 8 | ct[ 3]) ^ @dk[0]
314
+ s1 = (ct[ 4] << 24 | ct[ 5] << 16 | ct[ 6] << 8 | ct[ 7]) ^ @dk[1]
315
+ s2 = (ct[ 8] << 24 | ct[ 9] << 16 | ct[10] << 8 | ct[11]) ^ @dk[2]
316
+ s3 = (ct[12] << 24 | ct[13] << 16 | ct[14] << 8 | ct[15]) ^ @dk[3]
317
+ # round 1:
318
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
319
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ @dk[ 4]
320
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
321
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ @dk[ 5]
322
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
323
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ @dk[ 6]
324
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
325
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ @dk[ 7]
326
+ # round 2:
327
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
328
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ @dk[ 8]
329
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
330
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ @dk[ 9]
331
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
332
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ @dk[10]
333
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
334
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ @dk[11]
335
+ # round 3:
336
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
337
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ @dk[12]
338
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
339
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ @dk[13]
340
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
341
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ @dk[14]
342
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
343
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ @dk[15]
344
+ # round 4:
345
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
346
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ @dk[16]
347
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
348
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ @dk[17]
349
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
350
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ @dk[18]
351
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
352
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ @dk[19]
353
+ # round 5:
354
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
355
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ @dk[20]
356
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
357
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ @dk[21]
358
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
359
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ @dk[22]
360
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
361
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ @dk[23]
362
+ # round 6:
363
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
364
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ @dk[24]
365
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
366
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ @dk[25]
367
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
368
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ @dk[26]
369
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
370
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ @dk[27]
371
+ # round 7:
372
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
373
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ @dk[28]
374
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
375
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ @dk[29]
376
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
377
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ @dk[30]
378
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
379
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ @dk[31]
380
+ # round 8:
381
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
382
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ @dk[32]
383
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
384
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ @dk[33]
385
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
386
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ @dk[34]
387
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
388
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ @dk[35]
389
+ # round 9:
390
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
391
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ @dk[36]
392
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
393
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ @dk[37]
394
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
395
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ @dk[38]
396
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
397
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ @dk[39]
398
+ if (@nr > 10)
399
+ # round 10:
400
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
401
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ @dk[40]
402
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
403
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ @dk[41]
404
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
405
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ @dk[42]
406
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
407
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ @dk[43]
408
+ # round 11:
409
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
410
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ @dk[44]
411
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
412
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ @dk[45]
413
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
414
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ @dk[46]
415
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
416
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ @dk[47]
417
+ if (@nr > 12)
418
+ # round 12:
419
+ s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^
420
+ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ @dk[48]
421
+ s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^
422
+ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ @dk[49]
423
+ s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^
424
+ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ @dk[50]
425
+ s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^
426
+ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ @dk[51]
427
+ # round 13:
428
+ t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^
429
+ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ @dk[52]
430
+ t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^
431
+ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ @dk[53]
432
+ t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^
433
+ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ @dk[54]
434
+ t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^
435
+ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ @dk[55]
436
+ end
437
+ end
438
+ j = @nr << 2
439
+ #
440
+ # apply last round and map cipher state to byte array block:
441
+ #
442
+ s0 =
443
+ (Si3[(t0 >> 24)]) ^
444
+ (Si2[(t3 >> 16) & 0xff]) ^
445
+ (Si1[(t2 >> 8) & 0xff]) ^
446
+ (Si0[(t1) & 0xff]) ^ @dk[0+j]
447
+ s1 =
448
+ (Si3[(t1 >> 24)]) ^
449
+ (Si2[(t0 >> 16) & 0xff]) ^
450
+ (Si1[(t3 >> 8) & 0xff]) ^
451
+ (Si0[(t2) & 0xff]) ^ @dk[1+j]
452
+ s2 =
453
+ (Si3[(t2 >> 24)]) ^
454
+ (Si2[(t1 >> 16) & 0xff]) ^
455
+ (Si1[(t0 >> 8) & 0xff]) ^
456
+ (Si0[(t3) & 0xff]) ^ @dk[2+j]
457
+ s3 =
458
+ (Si3[(t3 >> 24)]) ^
459
+ (Si2[(t2 >> 16) & 0xff]) ^
460
+ (Si1[(t1 >> 8) & 0xff]) ^
461
+ (Si0[(t0) & 0xff]) ^ @dk[3+j]
462
+ [("%08x%08x%08x%08x" % [s0, s1, s2, s3])].pack("H*")
463
+ end
464
+ protected :_decrypt_block
465
+
466
+ def xor(a,b)
467
+ c = ""
468
+ 16.times do |i|
469
+ c << (a[i] ^ b[i]).chr
470
+ end
471
+ c
472
+ end
473
+ protected :xor
474
+
475
+ def encrypt_block(block)
476
+ case @mode
477
+ when 'ECB'
478
+ _encrypt_block(block)
479
+ when 'CBC'
480
+ @iv = _encrypt_block(xor(block, @iv))
481
+ when 'OFB'
482
+ @iv = _encrypt_block(@iv)
483
+ xor(@iv, block)
484
+ when 'CFB'
485
+ @iv = xor(_encrypt_block(@iv), block)
486
+ end
487
+ end
488
+
489
+ def decrypt_block(block)
490
+ case @mode
491
+ when 'ECB'
492
+ _decrypt_block(block)
493
+ when 'CBC'
494
+ o = xor(_decrypt_block(block), @iv)
495
+ @iv = block
496
+ o
497
+ when 'OFB'
498
+ @iv = _encrypt_block(@iv)
499
+ xor(@iv, block)
500
+ when 'CFB'
501
+ o = xor(_encrypt_block(@iv), block)
502
+ @iv = block
503
+ o
504
+ end
505
+ end
506
+
507
+ def encrypt_blocks(buffer)
508
+ raise "Bad block length" unless (buffer.length % 16).zero?
509
+ ct = ""
510
+ block = ""
511
+ buffer.each_byte do |char|
512
+ block << char
513
+ if block.length == 16
514
+ ct << encrypt_block(block)
515
+ block = ""
516
+ end
517
+ end
518
+ end
519
+
520
+ def decrypt_blocks(buffer)
521
+ raise "Bad block length" unless (buffer.length % 16).zero?
522
+ pt = ""
523
+ block = ""
524
+ buffer.each_byte do |char|
525
+ block << char
526
+ if block.length == 16
527
+ pt << decrypt_block(block)
528
+ block = ""
529
+ end
530
+ end
531
+ end
532
+
533
+ def encrypt_buffer(buffer)
534
+ ct = ""
535
+ block = ""
536
+ buffer.each_byte do |char|
537
+ block << char
538
+ if block.length == 16
539
+ ct << encrypt_block(block)
540
+ block = ""
541
+ end
542
+ end
543
+ m = 16 - block.length % 16
544
+ ct << (m == 16 ? 0 : encrypt_block(block << m.chr * m))
545
+ end
546
+
547
+ def decrypt_buffer(buffer)
548
+ pt = ""
549
+ block = ""
550
+ buffer.each_byte do |char|
551
+ block << char
552
+ if block.length == 16
553
+ pt << decrypt_block(block)
554
+ block = ""
555
+ end
556
+ end
557
+ if block.length == 0
558
+ c = pt[-1]
559
+ c.chr * c == pt[-c..-1] ? pt[0..-(c+1)] : (raise "Bad Block Padding")
560
+ else
561
+ pt
562
+ end
563
+ end
564
+
565
+ def init(key_length, mode, key, iv = nil)
566
+ @nb = 4
567
+ @ek = []
568
+ @dk = []
569
+ @state = nil
570
+ @iv = "\000" * 16
571
+ @iv = iv if iv
572
+ case key_length
573
+ when 128
574
+ @nk = 4
575
+ @nr = 10
576
+ when 192
577
+ @nk = 6
578
+ @nr = 12
579
+ when 256
580
+ @nk = 8
581
+ @nr = 14
582
+ else
583
+ raise 'Bad Key length'
584
+ end
585
+ @kl = key_length
586
+ case mode
587
+ when 'ECB', 'CBC', 'OFB', 'CFB'
588
+ @mode = mode
589
+ else
590
+ raise 'Bad AES mode'
591
+ end
592
+ decryption_key_schedule(key)
593
+ end
594
+
595
+ def initialize(key_length, mode, key, iv = nil)
596
+ init(key_length, mode, key, iv)
597
+ end
598
+
599
+ end # AesAlg