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