ruby-aes-cext 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,118 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+ This file is a part of ruby-aes <http://rubyforge.org/projects/ruby-aes>
5
+ Written by Alex Boussinet <alex.boussinet@gmail.com>
6
+
7
+ This script generates the constant arrays needed by ruby-aes
8
+ =end
9
+
10
+ module AesCons
11
+
12
+ ALOG = []
13
+ LOG = []
14
+ j = 1
15
+ 256.times do |i|
16
+ ALOG[i] = ALOG[i+255] = j
17
+ LOG[j] = i
18
+ j = (j ^ (j << 1) ^ (j & 0x80 != 0 ? 0x01b : 0)) & 0xff
19
+ end
20
+ LOG[1] = 0
21
+
22
+ def self.mul(a, b)
23
+ (a.zero? || b.zero?) ? 0 : ALOG[LOG[a] + LOG[b]]
24
+ end
25
+
26
+ RCON = []
27
+ j = 1
28
+ 10.times do |i|
29
+ RCON[i] = j << 24 & 0xff000000
30
+ j = mul(2, j)
31
+ end
32
+
33
+ S = []
34
+ Si = []
35
+ 256.times do |i|
36
+ x = (i != 0) ? ALOG[255 - LOG[i]] : 0
37
+ x ^= (x << 1) ^ (x << 2) ^ (x << 3) ^ (x << 4)
38
+ x = 0x63 ^ (x ^ (x >> 8))
39
+ S[i] = x & 0xff
40
+ Si[x & 0xff] = i
41
+ end
42
+
43
+ def self.mul4(a, b)
44
+ return 0 if (a.zero?)
45
+ a = LOG[a & 0xFF]
46
+ a0 = (b[0] != 0) ? ALOG[(a + LOG[b[0] & 0xff]) % 255] & 0xff : 0
47
+ a1 = (b[1] != 0) ? ALOG[(a + LOG[b[1] & 0xff]) % 255] & 0xff : 0
48
+ a2 = (b[2] != 0) ? ALOG[(a + LOG[b[2] & 0xff]) % 255] & 0xff : 0
49
+ a3 = (b[3] != 0) ? ALOG[(a + LOG[b[3] & 0xff]) % 255] & 0xff : 0
50
+ return a0 << 24 | a1 << 16 | a2 << 8 | a3
51
+ end
52
+
53
+ G = [
54
+ [2, 1, 1, 3],[3, 2, 1, 1],[1, 3, 2, 1],[1, 1, 3, 2],
55
+ [0, 0, 0, 1],[0, 0, 1, 0],[0, 1, 0, 0],[1, 0, 0, 0]
56
+ ]
57
+ Gi = [
58
+ [14, 9, 13, 11], [11, 14, 9, 13], [13, 11, 14, 9],[9, 13, 11, 14],
59
+ [0, 0, 0, 1],[0, 0, 1, 0],[0, 1, 0, 0],[1, 0, 0, 0]
60
+ ]
61
+ Te0, Te1, Te2, Te3 = [], [], [], []
62
+ S0, S1, S2, S3 = [], [], [], []
63
+ Td0, Td1, Td2, Td3 = [], [], [], []
64
+ Si0, Si1, Si2, Si3 = [], [], [], []
65
+ 256.times do |t|
66
+ s = S[t]
67
+ Te0[t] = mul4(s, G[0])
68
+ Te1[t] = mul4(s, G[1])
69
+ Te2[t] = mul4(s, G[2])
70
+ Te3[t] = mul4(s, G[3])
71
+ S0[t] = mul4(s, G[4])
72
+ S1[t] = mul4(s, G[5])
73
+ S2[t] = mul4(s, G[6])
74
+ S3[t] = mul4(s, G[7])
75
+ s = Si[t]
76
+ Td0[t] = mul4(s, Gi[0])
77
+ Td1[t] = mul4(s, Gi[1])
78
+ Td2[t] = mul4(s, Gi[2])
79
+ Td3[t] = mul4(s, Gi[3])
80
+ Si0[t] = mul4(s, Gi[4])
81
+ Si1[t] = mul4(s, Gi[5])
82
+ Si2[t] = mul4(s, Gi[6])
83
+ Si3[t] = mul4(s, Gi[7])
84
+ end
85
+
86
+ File.open("aes_cons.h" , "w+") do |f|
87
+ f.write <<-STOP
88
+ /*
89
+ * This file is a part of ruby-aes <http://rubyforge.org/projects/ruby-aes>
90
+ * Written by Alex Boussinet <alex.boussinet@gmail.com>
91
+ *
92
+ * aes_cons.h - AES Constant Arrays for ruby-aes
93
+ */
94
+
95
+ #ifndef __AES_CONS__
96
+ #define __AES_CONS__
97
+
98
+ STOP
99
+ ["RCON", "Te0", "Te1", "Te2", "Te3", "S0", "S1", "S2", "S3",
100
+ "Td0", "Td1", "Td2", "Td3", "Si0", "Si1", "Si2", "Si3"].each do |x|
101
+ f.write "uint " + x + "[] = {\n"
102
+ line = " " * 4
103
+ module_eval(x).each do |y|
104
+ z = "0x%08x" % y
105
+ line << ", " if line.length > 4
106
+ if (line.length + z.length) > 79
107
+ f.write line.chop + "\n"
108
+ line = " " * 4
109
+ end
110
+ line << z
111
+ end
112
+ f.write line unless line.length == 4
113
+ f.write "\n};\n\n"
114
+ end
115
+ f.write "#endif\n"
116
+ end
117
+
118
+ end # AesCons
@@ -0,0 +1,7 @@
1
+ require 'mkmf'
2
+
3
+ dir_config('aes_alg')
4
+ have_library('c', 'main')
5
+ have_header('aes_cons.h')
6
+
7
+ create_makefile('aes_alg')
data/lib/ruby-aes.rb ADDED
@@ -0,0 +1,162 @@
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
+ ==Valid modes are:
6
+ * ECB (Electronic Code Book)
7
+ * CBC (Cipher Block Chaining)
8
+ * OFB (Output Feedback)
9
+ * CFB (Cipher Feedback)
10
+
11
+ ==Valid key length:
12
+ * 128 bits
13
+ * 192 bits
14
+ * 256 bits
15
+
16
+ ==API calls:
17
+ Default key_length: 128
18
+ Default mode: 'ECB'
19
+ Default IV: 16 null chars ("00" * 16 in hex format)
20
+ Default key: 16 null chars ("00" * 16 in hex format)
21
+ Default input text: "PLAINTEXT"
22
+
23
+ Aes.check_key(key_string, key_length)
24
+ Aes.check_iv(iv_string)
25
+ Aes.check_kl(key_length)
26
+ Aes.check_mode(mode)
27
+ Aes.init(key_length, mode, key, iv)
28
+ Aes.encrypt_block(key_length, mode, key, iv, block) # no padding
29
+ Aes.decrypt_block(key_length, mode, key, iv, block) # no padding
30
+ Aes.encrypt_buffer(key_length, mode, key, iv, block) # padding
31
+ Aes.decrypt_buffer(key_length, mode, key, iv, block) # padding
32
+ Aes.encrypt_stream(key_length, mode, key, iv, sin, sout)
33
+ Aes.decrypt_stream(key_length, mode, key, iv, sin, sout)
34
+ Aes.bs() # block size for read operations (stream)
35
+ Aes.bs=(bs)
36
+ =end
37
+
38
+ module Aes
39
+
40
+ require 'ruby-aes/aes_alg'
41
+
42
+ @@aes = nil
43
+ @@bs = 4096
44
+
45
+ def Aes.bs(); return @@bs end
46
+ def Aes.bs=(bs); @@bs = bs.to_i; @@bs==0 ? 4096 : @@bs = @@bs - @@bs%16 end
47
+
48
+ def Aes.check_key(key_string, kl = 128)
49
+ kl = Aes.check_kl(kl)
50
+ k = key_string.length
51
+ raise "Bad key string or bad key length" if (k != kl/8) && (k != kl/4)
52
+ hex = (key_string =~ /[a-f0-9A-F]{#{k}}/) == 0 && (k == kl/4)
53
+ bin = ! hex
54
+ if ! (([32, 48, 64].include?(k) && hex) ||
55
+ ([16, 24, 32].include?(k) && bin))
56
+ raise "Bad key string"
57
+ end
58
+ hex ? [key_string].pack("H*") : key_string
59
+ end
60
+
61
+ def Aes.check_iv(iv_string)
62
+ k = iv_string.length
63
+ hex = (iv_string =~ /[a-f0-9A-F]{#{k}}/) == 0
64
+ bin = ! hex
65
+ if k == 32 && hex
66
+ return [iv_string].pack("H*")
67
+ elsif k == 16 && bin
68
+ return iv_string
69
+ else
70
+ raise "Bad IV string"
71
+ end
72
+ end
73
+
74
+ def Aes.check_mode (mode)
75
+ case mode
76
+ when 'ECB', 'CBC', 'OFB', 'CFB'
77
+ else raise "Bad cipher mode"
78
+ end
79
+ mode
80
+ end
81
+
82
+ def Aes.check_kl(key_length)
83
+ case key_length
84
+ when 128, 192, 256
85
+ else raise "Bad key length"
86
+ end
87
+ key_length
88
+ end
89
+
90
+ def Aes.init(keyl, mode, key, iv)
91
+ unless @@aes
92
+ @@aes = AesAlg.new(Aes.check_kl(keyl), Aes.check_mode(mode),
93
+ Aes.check_key(key, keyl), iv ? Aes.check_iv(iv) : nil)
94
+ else
95
+ @@aes.init(Aes.check_kl(keyl), Aes.check_mode(mode),
96
+ Aes.check_key(key, keyl), iv ? Aes.check_iv(iv) : nil)
97
+ end
98
+ end
99
+
100
+ def Aes.encrypt_block(keyl, mode, key, iv, block = "DEFAULT PLAINTXT")
101
+ raise "Bad Block size" if block.length < 16 || block.length > 16
102
+ Aes.init(keyl, mode, key, iv)
103
+ @@aes.encrypt_block(block)
104
+ end
105
+
106
+ def Aes.decrypt_block(keyl, mode, key, iv, block = "DEFAULT PLAINTXT")
107
+ Aes.init(keyl, mode, key, iv)
108
+ @@aes.decrypt_block(block)
109
+ end
110
+
111
+ def Aes.encrypt_buffer(keyl, mode, key, iv, buffer = "PLAINTEXT")
112
+ Aes.init(keyl, mode, key, iv)
113
+ @@aes.encrypt_buffer(buffer)
114
+ end
115
+
116
+ def Aes.decrypt_buffer(keyl, mode, key, iv, buffer = "DEFAULT PLAINTXT")
117
+ raise "Bad Block size" if buffer.length < 16
118
+ Aes.init(keyl, mode, key, iv)
119
+ @@aes.decrypt_buffer(buffer)
120
+ end
121
+
122
+ def Aes.encrypt_stream(keyl, mode, key, iv, sin = STDIN, sout = STDOUT)
123
+ Aes.init(keyl, mode, key, iv)
124
+ case sout
125
+ when String, Array, IO
126
+ else
127
+ raise "Bad output stream (String, Array, IO)"
128
+ end
129
+ case sin
130
+ when String
131
+ sout << @@aes.encrypt_buffer(sin)
132
+ when IO
133
+ while buf = sin.read(@@bs)
134
+ sout << ((buf.length % 16).zero? ? @@aes.encrypt_blocks(buf) :
135
+ @@aes.encrypt_buffer(buf))
136
+ end
137
+ else
138
+ raise "Bad input stream (String, IO)"
139
+ end
140
+ end
141
+
142
+ def Aes.decrypt_stream(keyl, mode, key, iv, sin = STDIN, sout = STDOUT)
143
+ Aes.init(keyl, mode, key, iv)
144
+ case sout
145
+ when String, Array, IO
146
+ else
147
+ raise "Bad output stream (String, Array, IO)"
148
+ end
149
+ case sin
150
+ when String
151
+ sout << @@aes.decrypt_buffer(sin)
152
+ when IO
153
+ while buf = sin.read(@@bs)
154
+ sout << (sin.eof? ? @@aes.decrypt_buffer(buf) :
155
+ @@aes.decrypt_blocks(buf))
156
+ end
157
+ else
158
+ raise "Bad input stream (String, IO)"
159
+ end
160
+ end
161
+
162
+ end # end Aes
@@ -0,0 +1,386 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ =begin
4
+ This file is a part of ruby-aes <http://rubyforge.org/projects/ruby-aes>
5
+ Written by Alex Boussinet <alex.boussinet@gmail.com>
6
+
7
+ KAT Tests and MCT tests according to katmct.pdf file.
8
+ <http://csrc.nist.gov/encryption/aes/katmct/katmct.htm>
9
+ See rijndael-vals.zip
10
+ =end
11
+
12
+ require File.dirname(__FILE__) + '/../test_helper.rb'
13
+
14
+ def cbc_decrypt_mct(output)
15
+ output.write <<EOT
16
+
17
+ =========================
18
+
19
+ FILENAME: "cbc_d_m.txt"
20
+
21
+ Cipher Block Chaining (CBC) Mode - DECRYPTION
22
+ Monte Carlo Test
23
+
24
+ Algorithm Name: Rijndael
25
+
26
+ ==========
27
+
28
+ EOT
29
+ [128, 192, 256].each { |kl|
30
+ output.write "KEYSIZE=#{kl}\n\n"
31
+ key = "0" * (kl/4)
32
+ ct = iv = "0" * 32
33
+ opt = pt = nil
34
+ 400.times { |i|
35
+ output.write "I=#{i}\nKEY=#{key}\nIV=#{iv}\nCT=#{ct}\n"
36
+ 10000.times { |j|
37
+ opt = pt
38
+ pt = Aes.decrypt_block(kl, 'ECB', key, iv,
39
+ [ct].pack("H*")).unpack("H*")[0]
40
+ pt = "%032X" % (pt.hex ^ iv.hex)
41
+ iv = ct
42
+ ct = pt
43
+ }
44
+ case kl
45
+ when 128
46
+ npt = pt
47
+ when 192, 256
48
+ x = -(kl/4-32)
49
+ npt = opt[x..-1] + pt
50
+ end
51
+ key = "%0#{kl/4}X" % (key.hex ^ npt.hex)
52
+ output.write "PT=#{pt}\n\n"
53
+ }
54
+ output.write "=========================\n\n"
55
+ }
56
+ end
57
+
58
+ def cbc_encrypt_mct(output)
59
+ output.write <<EOT
60
+
61
+ =========================
62
+
63
+ FILENAME: "cbc_e_m.txt"
64
+
65
+ Cipher Block Chaining (CBC) Mode - ENCRYPTION
66
+ Monte Carlo Test
67
+
68
+ Algorithm Name: Rijndael
69
+
70
+ ==========
71
+
72
+ EOT
73
+ [128, 192, 256].each { |kl|
74
+ output.write "KEYSIZE=#{kl}\n\n"
75
+ key = "0" * (kl/4)
76
+ pt = iv = "0" * 32
77
+ oct = ct = nil
78
+ 400.times { |i|
79
+ output.write "I=#{i}\nKEY=#{key}\nIV=#{iv}\nPT=#{pt}\n"
80
+ 10000.times { |j|
81
+ oct = ct
82
+ pt = "%032X" % (pt.hex ^ iv.hex)
83
+ ct = Aes.encrypt_block(kl, 'ECB', key, iv,
84
+ [pt].pack("H*")).unpack("H*")[0]
85
+ if j == 0 then pt = iv else pt = oct end
86
+ iv = ct
87
+ }
88
+ case kl
89
+ when 128
90
+ nct = ct
91
+ when 192, 256
92
+ x = -(kl/4-32)
93
+ nct = oct[x..-1] + ct
94
+ end
95
+ key = "%0#{kl/4}X" % (key.hex ^ nct.hex)
96
+ output.write "CT=#{ct}\n\n"
97
+ }
98
+ output.write "=========================\n\n"
99
+ }
100
+ end
101
+
102
+ def ecb_decrypt_mct(output)
103
+ output.write <<EOT
104
+
105
+ =========================
106
+
107
+ FILENAME: "ecb_d_m.txt"
108
+
109
+ Electronic Codebook (ECB) Mode - DECRYPTION
110
+ Monte Carlo Test
111
+
112
+ Algorithm Name: Rijndael
113
+
114
+ =========================
115
+
116
+ EOT
117
+ [128, 192, 256].each { |kl|
118
+ output.write "KEYSIZE=#{kl}\n\n"
119
+ key = "0" * (kl/4)
120
+ ct = "0" * 32
121
+ opt = pt = nil
122
+ 400.times { |i|
123
+ output.write "I=#{i}\nKEY=#{key}\nCT=#{ct}\n"
124
+ 10000.times { |j|
125
+ opt = pt
126
+ pt = Aes.decrypt_block(kl, 'ECB', key, nil,
127
+ [ct].pack("H*")).unpack("H*")[0]
128
+ ct = pt
129
+ }
130
+ case kl
131
+ when 128
132
+ npt = pt
133
+ when 192, 256
134
+ x = -(kl/4-32)
135
+ npt = opt[x..-1] + pt
136
+ end
137
+ key = "%0#{kl/4}X" % (key.hex ^ npt.hex)
138
+ ct = pt
139
+ output.write "PT=#{pt}\n\n"
140
+ }
141
+ output.write "=========================\n\n"
142
+ }
143
+ end
144
+
145
+ def ecb_encrypt_mct(output)
146
+ output.write <<EOT
147
+
148
+ =========================
149
+
150
+ FILENAME: "ecb_e_m.txt"
151
+
152
+ Electronic Codebook (ECB) Mode - ENCRYPTION
153
+ Monte Carlo Test
154
+
155
+ Algorithm Name: Rijndael
156
+
157
+ =========================
158
+
159
+ EOT
160
+ [128, 192, 256].each { |kl|
161
+ output.write "KEYSIZE=#{kl}\n\n"
162
+ key = "0" * (kl/4)
163
+ pt = "0" * 32
164
+ oct = ct = nil
165
+ 400.times { |i|
166
+ output.write "I=#{i}\nKEY=#{key}\nPT=#{pt}\n"
167
+ 10000.times { |j|
168
+ oct = ct
169
+ ct = Aes.encrypt_block(kl, 'ECB', key, nil,
170
+ [pt].pack("H*")).unpack("H*")[0]
171
+ pt = ct
172
+ }
173
+ case kl
174
+ when 128
175
+ nct = ct
176
+ when 192, 256
177
+ x = -(kl/4-32)
178
+ nct = oct[x..-1] + ct
179
+ end
180
+ key = "%0#{kl/4}X" % (key.hex ^ nct.hex)
181
+ pt = ct
182
+ output.write "CT=#{ct}\n\n"
183
+ }
184
+ output.write "=========================\n\n"
185
+ }
186
+ end
187
+
188
+ def ecb_iv(output)
189
+ output.write <<EOT
190
+
191
+ =========================
192
+
193
+ FILENAME: "ecb_iv.txt"
194
+
195
+ Electronic Codebook (ECB) Mode
196
+ Intermediate Value Known Answer Tests
197
+
198
+ Algorithm Name: Rijndael
199
+
200
+ ==========
201
+
202
+ EOT
203
+ if (AesAlg.respond_to? :c_extension)
204
+ @output.write <<EOT
205
+ Not Implemented
206
+
207
+ ==========
208
+
209
+ EOT
210
+ else
211
+ $output = output
212
+ AesAlg.class_eval do
213
+ alias :encrypt_block_original :_encrypt_block
214
+ alias :decrypt_original_block :_decrypt_block
215
+ def _encrypt_block
216
+ addRoundKey 0
217
+ 1.upto(@nr) { |n|
218
+ subBytes
219
+ shiftRows
220
+ mixColumns unless n == @nr
221
+ addRoundKey n
222
+ $output.puts "CT#{n}=#{@state.unpack("H*")[0]}" unless (@nr-n).zero?
223
+ }
224
+ @state
225
+ end
226
+ def _decrypt_block
227
+ addRoundKey @nr
228
+ (@nr-1).downto(0) { |n|
229
+ ishiftRows
230
+ isubBytes
231
+ $output.puts "PT#{@nr-n}=#{@state.unpack("H*")[0]}" unless n.zero?
232
+ addRoundKey n
233
+ imixColumns unless n == 0
234
+ }
235
+ @state
236
+ end
237
+ end
238
+ [128, 192, 256].each { |kl|
239
+ output.write "KEYSIZE=#{kl}\n"
240
+ key = ""
241
+ (kl/8).times do |n| key << n.chr end
242
+ output.write "KEY=#{key.unpack("H*")[0]}\n\n"
243
+ output.write "Intermediate Ciphertext Values (Encryption)\n\n"
244
+ pt = ""
245
+ 16.times do |n| pt << n.chr end
246
+ output.write "PT=#{pt.unpack("H*")[0]}\n"
247
+ ct = Aes.encrypt_block(kl, 'ECB', key, nil, pt)
248
+ output.write "CT=#{ct.unpack("H*")[0]}\n\n"
249
+
250
+ output.write "Intermediate Ciphertext Values (Decryption)\n\n"
251
+ output.write "CT=#{ct.unpack("H*")[0]}\n"
252
+ npt = Aes.decrypt_block(kl, 'ECB', key, nil, ct)
253
+ output.write "PT=#{npt.unpack("H*")[0]}\n\n"
254
+
255
+ output.write "==========\n\n"
256
+ }
257
+ AesAlg.class_eval do
258
+ alias :_block_encrypt :encrypt_block_original
259
+ alias :_block_decrypt :decrypt_block_original
260
+ end
261
+ end
262
+ end
263
+
264
+ def ecb_tbl(output)
265
+ output.write <<EOT
266
+
267
+ =========================
268
+
269
+ FILENAME: "ecb_tbl.txt"
270
+
271
+ Electronic Codebook (ECB) Mode
272
+ Tables Known Answer Tests
273
+
274
+ Algorithm Name: Rijndael
275
+ Tables tested: S, Si, LOG, ALOG, RCON, Te0-4 Td0-4
276
+
277
+ ==========
278
+
279
+ EOT
280
+ [128, 192, 256].each { |kl|
281
+ output.write "KEYSIZE=#{kl}\n\n"
282
+ File.open("table.#{kl}", "r") { |f|
283
+ begin
284
+ 1.upto(64) { |i|
285
+ key, *pt = f.readline.split(" ")
286
+ pt = pt.join
287
+ ct = Aes.encrypt_block(kl, 'ECB', key, nil, [pt].pack("H*"))
288
+ output.write "I=#{i}\nKEY=#{key}\nPT=#{pt}\nCT=#{ct.unpack("H*")[0]}\n\n"
289
+ }
290
+ 65.upto(128) { |i|
291
+ key, *ct = f.readline.split(" ")
292
+ ct = ct.join
293
+ pt = Aes.encrypt_block(kl, 'ECB', key, nil, [ct].pack("H*"))
294
+ output.write "I=#{i}\nKEY=#{key}\nPT=#{pt.unpack("H*")[0]}\nCT=#{ct}\n\n"
295
+ }
296
+ rescue
297
+ raise "Bad Table File"
298
+ end
299
+ }
300
+ output.write "==========\n\n"
301
+ }
302
+ end
303
+
304
+ def ecb_vt(output)
305
+ output.write <<EOT
306
+
307
+ =========================
308
+
309
+ FILENAME: "ecb_vt.txt"
310
+
311
+ Electronic Codebook (ECB) Mode
312
+ Variable Text Known Answer Tests
313
+
314
+ Algorithm Name: Rijndael
315
+
316
+ ==========
317
+
318
+ EOT
319
+ [128, 192, 256].each { |kl|
320
+ key = "0" * (kl/4)
321
+ output.write "KEYSIZE=#{kl}\n\nKEY=#{key}\n\n"
322
+ (127).downto(0) { |b|
323
+ i = 128 - b
324
+ pt = "%032X" % (1 << b)
325
+ ct = Aes.encrypt_block(kl, 'ECB', key, nil, [pt].pack("H*"))
326
+ output.write "I=#{i}\nPT=#{pt}\nCT=#{ct.unpack("H*")[0]}\n\n"
327
+ }
328
+ output.write "==========\n\n"
329
+ }
330
+ end
331
+
332
+ def ecb_vk(output)
333
+ pt = "00000000000000000000000000000000"
334
+ output.write <<EOT
335
+
336
+ =========================
337
+
338
+ FILENAME: "ecb_vk.txt"
339
+
340
+ Electronic Codebook (ECB) Mode
341
+ Variable Key Known Answer Tests
342
+
343
+ Algorithm Name: Rijndael
344
+
345
+ ==========
346
+ EOT
347
+ [128, 192, 256].each { |kl|
348
+ output.write "KEYSIZE=#{kl}\n\nPT=#{pt}\n\n"
349
+ (kl-1).downto(0) { |b|
350
+ i = kl - b
351
+ key = "%0#{kl/4}X" % (1 << b)
352
+ ct = Aes.encrypt_block(kl, 'ECB', key, nil, [pt].pack("H*"))
353
+ output.write "I=#{i}\nKEY=#{key}\nCT=#{ct.unpack("H*")[0]}\n\n"
354
+ }
355
+ output.write "==========\n\n"
356
+ }
357
+ end
358
+
359
+ def kat_tests
360
+ puts "Writing ecb_vk.txt..."
361
+ File.open("ecb_vk.txt") { |f| ecb_vk f }
362
+ puts "Writing ecb_vt.txt..."
363
+ File.open("ecb_vt.txt") { |f| ecb_vt f }
364
+ puts "Writing ecb_tbl.txt..."
365
+ File.open("ecb_tbl.txt") { |f| ecb_tbl f }
366
+ puts "Writing ecb_iv.txt..."
367
+ File.open("ecb_iv.txt") { |f| ecb_iv f }
368
+ end
369
+
370
+ def mct_tests
371
+ puts "Writing ecb_e_m.txt..."
372
+ File.open("ecb_e_m.txt") { |f| ecb_encrypt_mct f }
373
+ puts "Writing ecb_d_m.txt..."
374
+ File.open("ecb_d_m.txt") { |f| ecb_decrypt_mct f }
375
+ puts "Writing cbc_e_m.txt..."
376
+ File.open("cbc_e_m.txt") { |f| cbc_encrypt_mct f }
377
+ puts "Writing cbc_d_m.txt..."
378
+ File.open("cbc_d_m.txt") { |f| cbc_decrypt_mct f }
379
+ end
380
+
381
+ if __FILE__ == $0
382
+ puts "Performing KAT Tests..."
383
+ kat_tests
384
+ puts "Performing MCT Tests... VERY time consuming !"
385
+ mct_tests
386
+ end
Binary file