ruby-aes-optimized 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,208 @@
1
+
2
+ body {
3
+ font-family: Verdana,Arial,Helvetica,sans-serif;
4
+ font-size: 90%;
5
+ margin: 0;
6
+ margin-left: 40px;
7
+ padding: 0;
8
+ background: white;
9
+ }
10
+
11
+ h1,h2,h3,h4 { margin: 0; color: #efefef; background: transparent; }
12
+ h1 { font-size: 150%; }
13
+ h2,h3,h4 { margin-top: 1em; }
14
+
15
+ a { background: #eef; color: #039; text-decoration: none; }
16
+ a:hover { background: #039; color: #eef; }
17
+
18
+ /* Override the base stylesheet's Anchor inside a table cell */
19
+ td > a {
20
+ background: transparent;
21
+ color: #039;
22
+ text-decoration: none;
23
+ }
24
+
25
+ /* and inside a section title */
26
+ .section-title > a {
27
+ background: transparent;
28
+ color: #eee;
29
+ text-decoration: none;
30
+ }
31
+
32
+ /* === Structural elements =================================== */
33
+
34
+ div#index {
35
+ margin: 0;
36
+ margin-left: -40px;
37
+ padding: 0;
38
+ font-size: 90%;
39
+ }
40
+
41
+
42
+ div#index a {
43
+ margin-left: 0.7em;
44
+ }
45
+
46
+ div#index .section-bar {
47
+ margin-left: 0px;
48
+ padding-left: 0.7em;
49
+ background: #ccc;
50
+ font-size: small;
51
+ }
52
+
53
+
54
+ div#classHeader, div#fileHeader {
55
+ width: auto;
56
+ color: white;
57
+ padding: 0.5em 1.5em 0.5em 1.5em;
58
+ margin: 0;
59
+ margin-left: -40px;
60
+ border-bottom: 3px solid #006;
61
+ }
62
+
63
+ div#classHeader a, div#fileHeader a {
64
+ background: inherit;
65
+ color: white;
66
+ }
67
+
68
+ div#classHeader td, div#fileHeader td {
69
+ background: inherit;
70
+ color: white;
71
+ }
72
+
73
+
74
+ div#fileHeader {
75
+ background: #057;
76
+ }
77
+
78
+ div#classHeader {
79
+ background: #048;
80
+ }
81
+
82
+
83
+ .class-name-in-header {
84
+ font-size: 180%;
85
+ font-weight: bold;
86
+ }
87
+
88
+
89
+ div#bodyContent {
90
+ padding: 0 1.5em 0 1.5em;
91
+ }
92
+
93
+ div#description {
94
+ padding: 0.5em 1.5em;
95
+ background: #efefef;
96
+ border: 1px dotted #999;
97
+ }
98
+
99
+ div#description h1,h2,h3,h4,h5,h6 {
100
+ color: #125;;
101
+ background: transparent;
102
+ }
103
+
104
+ div#validator-badges {
105
+ text-align: center;
106
+ }
107
+ div#validator-badges img { border: 0; }
108
+
109
+ div#copyright {
110
+ color: #333;
111
+ background: #efefef;
112
+ font: 0.75em sans-serif;
113
+ margin-top: 5em;
114
+ margin-bottom: 0;
115
+ padding: 0.5em 2em;
116
+ }
117
+
118
+
119
+ /* === Classes =================================== */
120
+
121
+ table.header-table {
122
+ color: white;
123
+ font-size: small;
124
+ }
125
+
126
+ .type-note {
127
+ font-size: small;
128
+ color: #DEDEDE;
129
+ }
130
+
131
+ .xxsection-bar {
132
+ background: #eee;
133
+ color: #333;
134
+ padding: 3px;
135
+ }
136
+
137
+ .section-bar {
138
+ color: #333;
139
+ border-bottom: 1px solid #999;
140
+ margin-left: -20px;
141
+ }
142
+
143
+
144
+ .section-title {
145
+ background: #79a;
146
+ color: #eee;
147
+ padding: 3px;
148
+ margin-top: 2em;
149
+ margin-left: -30px;
150
+ border: 1px solid #999;
151
+ }
152
+
153
+ .top-aligned-row { vertical-align: top }
154
+ .bottom-aligned-row { vertical-align: bottom }
155
+
156
+ /* --- Context section classes ----------------------- */
157
+
158
+ .context-row { }
159
+ .context-item-name { font-family: monospace; font-weight: bold; color: black; }
160
+ .context-item-value { font-size: small; color: #448; }
161
+ .context-item-desc { color: #333; padding-left: 2em; }
162
+
163
+ /* --- Method classes -------------------------- */
164
+ .method-detail {
165
+ background: #efefef;
166
+ padding: 0;
167
+ margin-top: 0.5em;
168
+ margin-bottom: 1em;
169
+ border: 1px dotted #ccc;
170
+ }
171
+ .method-heading {
172
+ color: black;
173
+ background: #ccc;
174
+ border-bottom: 1px solid #666;
175
+ padding: 0.2em 0.5em 0 0.5em;
176
+ }
177
+ .method-signature { color: black; background: inherit; }
178
+ .method-name { font-weight: bold; }
179
+ .method-args { font-style: italic; }
180
+ .method-description { padding: 0 0.5em 0 0.5em; }
181
+
182
+ /* --- Source code sections -------------------- */
183
+
184
+ a.source-toggle { font-size: 90%; }
185
+ div.method-source-code {
186
+ background: #262626;
187
+ color: #ffdead;
188
+ margin: 1em;
189
+ padding: 0.5em;
190
+ border: 1px dashed #999;
191
+ overflow: hidden;
192
+ }
193
+
194
+ div.method-source-code pre { color: #ffdead; overflow: hidden; }
195
+
196
+ /* --- Ruby keyword styles --------------------- */
197
+
198
+ .standalone-code { background: #221111; color: #ffdead; overflow: hidden; }
199
+
200
+ .ruby-constant { color: #7fffd4; background: transparent; }
201
+ .ruby-keyword { color: #00ffff; background: transparent; }
202
+ .ruby-ivar { color: #eedd82; background: transparent; }
203
+ .ruby-operator { color: #00ffee; background: transparent; }
204
+ .ruby-identifier { color: #ffdead; background: transparent; }
205
+ .ruby-node { color: #ffa07a; background: transparent; }
206
+ .ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
207
+ .ruby-regexp { color: #ffa07a; background: transparent; }
208
+ .ruby-value { color: #7fffd4; background: transparent; }
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ruby-aes'
4
+ require 'example_helper'
5
+
6
+ class RubyAES_block
7
+
8
+ include RubyAES_helper
9
+
10
+ def initialize
11
+ setup
12
+ pt = "0123467890ABCDEF"
13
+ puts "Using #{@kl}-#{@mode} encryption/decryption"
14
+ puts "Plaintext is: #{pt} (a block should be 16 octets)"
15
+ ct = Aes.encrypt_block(@kl, @mode, @keys[@kl], @iv, pt)
16
+ puts "Ciphertext (unpacked) is: #{ct.unpack("H*").first}"
17
+ npt = Aes.decrypt_block(@kl, @mode, @keys[@kl], @iv, ct)
18
+ puts "Decrypted ciphertext is: #{npt} (should be: #{pt})"
19
+ end
20
+
21
+ end
22
+ RubyAES_block.new
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ruby-aes'
4
+ require 'example_helper'
5
+
6
+ class RubyAES_buffer
7
+
8
+ include RubyAES_helper
9
+
10
+ def initialize
11
+ setup
12
+ puts "Using #{@kl}-#{@mode} encryption/decryption"
13
+ pt = "The quick brown fox jumps over the lazy dog"
14
+ puts "Plaintext is: '#{pt}'"
15
+ puts "(a buffer will be padded so that its length will be a multiple of 16)"
16
+ ct = Aes.encrypt_buffer(@kl, @mode, @keys[@kl], @iv, pt)
17
+ puts "Ciphertext (unpacked) is: #{ct.unpack("H*").first}"
18
+ npt = Aes.decrypt_buffer(@kl, @mode, @keys[@kl], @iv, ct)
19
+ puts "Decrypted ciphertext is: '#{npt}'"
20
+ puts "(should be: '#{pt}')"
21
+ end
22
+
23
+ end
24
+ RubyAES_buffer.new
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ruby-aes'
4
+ require 'example_helper'
5
+ require 'fileutils'
6
+
7
+ class RubyAES_stream
8
+
9
+ include RubyAES_helper
10
+
11
+ def initialize
12
+ setup
13
+ puts "Using #{@kl}-#{@mode} encryption/decryption"
14
+ file = "_ruby-aes_encrypt_stream_"
15
+
16
+ sin = File.open(file, "w+b")
17
+ sin.puts "The quick brown fox jumps over the lazy dog"
18
+ sin.rewind
19
+ sout = File.open("#{file}.aes", "w+b")
20
+ Aes.encrypt_stream(@kl, @mode, @keys[@kl], @iv, sin, sout)
21
+ sin.close
22
+ sout.close
23
+
24
+ sin = File.open("#{file}.aes", "rb")
25
+ sout = File.open("#{file}.plain", "w+b")
26
+ Aes.decrypt_stream(@kl, @mode, @keys[@kl], @iv, sin, sout)
27
+ sin.close
28
+ sout.close
29
+
30
+ if IO.read(file) == IO.read("#{file}.plain")
31
+ puts "The decrypted file is exactly the same as the original one"
32
+ else
33
+ puts "The decrypted file differs from the orginal one"
34
+ end
35
+ FileUtils.rm_f [ file, "#{file}.aes", "#{file}.plain" ]
36
+ end
37
+
38
+ end
39
+ RubyAES_stream.new
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ module RubyAES_helper
4
+
5
+ KEY_LENGTH = [128,192,256].freeze
6
+ MODES = ['ECB','CBC','OFB','CFB'].freeze
7
+
8
+ def random_fill(n, buffer)
9
+ n.times do
10
+ buffer << rand(256).chr
11
+ end
12
+ end
13
+
14
+ def setup
15
+ @keys = {}
16
+ KEY_LENGTH.each do |kl|
17
+ @keys[kl] = ""
18
+ random_fill(kl/8, @keys[kl])
19
+ end
20
+
21
+ @iv = ""; random_fill(16, @iv)
22
+ @pt = ""; random_fill(64, @pt)
23
+ @kl = KEY_LENGTH[(rand * KEY_LENGTH.length).to_i]
24
+ @mode = MODES[(rand * MODES.length).to_i]
25
+ end
26
+
27
+ end
@@ -0,0 +1,280 @@
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
+ ruby-aes (optimized version)
6
+ Based on "Normal" code
7
+ Adapted from the Rijndael Specifications (dfips-AES.pdf)
8
+ =end
9
+
10
+ require 'ruby-aes/aes_cons'
11
+
12
+ class AesAlg
13
+ include AesCons
14
+
15
+ def mixColumns
16
+ t = ""
17
+ 4.times do |j| i = j*4
18
+ t << (G2X[@state[i]] ^ G3X[@state[i+1]] ^ @state[i+2] ^ @state[i+3])
19
+ t << (@state[i] ^ G2X[@state[i+1]] ^ G3X[@state[i+2]] ^ @state[i+3])
20
+ t << (@state[i] ^ @state[i+1] ^ G2X[@state[i+2]] ^ G3X[@state[i+3]])
21
+ t << (G3X[@state[i]] ^ @state[i+1] ^ @state[i+2] ^ G2X[@state[i+3]])
22
+ end
23
+ @state = t
24
+ end
25
+ protected :mixColumns
26
+
27
+ def imixColumns
28
+ t = ""
29
+ 4.times do |j| i = j*4
30
+ t << (GEX[@state[i]] ^ GBX[@state[i+1]] ^ GDX[@state[i+2]] ^ G9X[@state[i+3]])
31
+ t << (G9X[@state[i]] ^ GEX[@state[i+1]] ^ GBX[@state[i+2]] ^ GDX[@state[i+3]])
32
+ t << (GDX[@state[i]] ^ G9X[@state[i+1]] ^ GEX[@state[i+2]] ^ GBX[@state[i+3]])
33
+ t << (GBX[@state[i]] ^ GDX[@state[i+1]] ^ G9X[@state[i+2]] ^ GEX[@state[i+3]])
34
+ end
35
+ @state = t
36
+ end
37
+ protected :imixColumns
38
+
39
+ # Combine -- shiftRows, subBytes -- as one method
40
+ def subShiftRows
41
+ @state[0], @state[4], @state[8], @state[12] =
42
+ S_BOX[@state[0]], S_BOX[@state[4]], S_BOX[@state[8]], S_BOX[@state[12]]
43
+ @state[1], @state[5], @state[9], @state[13] =
44
+ S_BOX[@state[5]], S_BOX[@state[9]], S_BOX[@state[13]], S_BOX[@state[1]]
45
+ @state[2], @state[6], @state[10], @state[14] =
46
+ S_BOX[@state[10]], S_BOX[@state[14]], S_BOX[@state[2]], S_BOX[@state[6]]
47
+ @state[3], @state[7], @state[11], @state[15] =
48
+ S_BOX[@state[15]], S_BOX[@state[3]], S_BOX[@state[7]], S_BOX[@state[11]]
49
+ end
50
+ protected :subShiftRows
51
+
52
+ # Combine -- shiftRows, subBytes, addRoundkey -- as one method
53
+ def lastEncryptRound
54
+ i = 16*@nr
55
+ @state[0], @state[4], @state[8], @state[12] =
56
+ S_BOX[@state[0]] ^ @w[i], S_BOX[@state[4]] ^ @w[i+4],
57
+ S_BOX[@state[8]] ^ @w[i+8], S_BOX[@state[12]] ^ @w[i+12]
58
+ @state[1], @state[5], @state[9], @state[13] =
59
+ S_BOX[@state[5]] ^ @w[i+1], S_BOX[@state[9]] ^ @w[i+5],
60
+ S_BOX[@state[13]] ^ @w[i+9], S_BOX[@state[1]] ^ @w[i+13]
61
+ @state[2], @state[6], @state[10], @state[14] =
62
+ S_BOX[@state[10]] ^ @w[i+2], S_BOX[@state[14]] ^ @w[i+6],
63
+ S_BOX[@state[2]] ^ @w[i+10], S_BOX[@state[6]] ^ @w[i+14]
64
+ @state[3], @state[7], @state[11], @state[15] =
65
+ S_BOX[@state[15]] ^ @w[i+3], S_BOX[@state[3]] ^ @w[i+7],
66
+ S_BOX[@state[7]] ^ @w[i+11], S_BOX[@state[11]] ^ @w[i+15]
67
+ end
68
+ protected :lastEncryptRound
69
+
70
+ # Combine -- ishiftRows, isubBytes, addRoundkey -- as one method
71
+ def decryptSubRound(n)
72
+ i = 16*n
73
+ @state[0], @state[4], @state[8], @state[12] =
74
+ IS_BOX[@state[0]] ^ @w[i], IS_BOX[@state[4]] ^ @w[i+4],
75
+ IS_BOX[@state[8]] ^ @w[i+8], IS_BOX[@state[12]] ^ @w[i+12]
76
+ @state[1], @state[5], @state[9], @state[13] =
77
+ IS_BOX[@state[13]] ^ @w[i+1], IS_BOX[@state[1]] ^ @w[i+5],
78
+ IS_BOX[@state[5]] ^ @w[i+9], IS_BOX[@state[9]] ^ @w[i+13]
79
+ @state[2], @state[6], @state[10], @state[14] =
80
+ IS_BOX[@state[10]] ^ @w[i+2], IS_BOX[@state[14]] ^ @w[i+6],
81
+ IS_BOX[@state[2]] ^ @w[i+10], IS_BOX[@state[6]] ^ @w[i+14]
82
+ @state[3], @state[7], @state[11], @state[15] =
83
+ IS_BOX[@state[7]] ^ @w[i+3], IS_BOX[@state[11]] ^ @w[i+7],
84
+ IS_BOX[@state[15]] ^ @w[i+11], IS_BOX[@state[3]] ^@w[i+15]
85
+ end
86
+ protected :decryptSubRound
87
+
88
+ def addRoundKey(n)
89
+ j = n*16
90
+ 16.times do |i|
91
+ @state[i] ^= @w[i+j]
92
+ end
93
+ end
94
+ protected :addRoundKey
95
+
96
+ def key_expansion(key)
97
+ 0.upto(@nk*4-1) do
98
+ |i| @w[i] = key[i]
99
+ end
100
+ @nk.upto(@nb*(@nr+1)-1) do |i|
101
+ j = i*4
102
+ k = j-(@nk*4)
103
+ t0, t1, t2, t3 = @w[j-4], @w[j-3], @w[j-2], @w[j-1]
104
+ if (i % @nk == 0)
105
+ t0, t1, t2, t3 =
106
+ S_BOX[t1] ^ RCON[i/@nk - 1], S_BOX[t2], S_BOX[t3], S_BOX[t0]
107
+ elsif (@nk > 6) && (i % @nk == 4)
108
+ t0, t1, t2, t3 = S_BOX[t0], S_BOX[t1], S_BOX[t2], S_BOX[t3]
109
+ end
110
+ @w[j], @w[j+1], @w[j+2], @w[j+3] =
111
+ @w[k] ^ t0, @w[k+1] ^ t1, @w[k+2] ^ t2, @w[k+3] ^ t3
112
+ end
113
+ end
114
+ protected :key_expansion
115
+
116
+ def _encrypt_block
117
+ addRoundKey 0
118
+ 1.upto(@nr-1) do |n|
119
+ subShiftRows
120
+ mixColumns
121
+ addRoundKey n
122
+ end
123
+ lastEncryptRound
124
+ @state
125
+ end
126
+ protected :_encrypt_block
127
+
128
+ def _decrypt_block
129
+ addRoundKey @nr
130
+ (@nr-1).downto(1) do |n|
131
+ decryptSubRound n
132
+ imixColumns
133
+ end
134
+ decryptSubRound 0
135
+ @state
136
+ end
137
+ protected :_decrypt_block
138
+
139
+ def xor(a,b)
140
+ c = ""
141
+ 16.times do |i|
142
+ c << (a[i] ^ b[i]).chr
143
+ end
144
+ c
145
+ end
146
+ protected :xor
147
+
148
+ def encrypt_block(block)
149
+ @state = block.dup
150
+ case @mode
151
+ when 'ECB'
152
+ _encrypt_block
153
+ when 'CBC'
154
+ @state = xor(block, @iv)
155
+ @iv = _encrypt_block
156
+ when 'OFB'
157
+ @state = @iv.dup
158
+ @iv = _encrypt_block
159
+ xor(@iv, block)
160
+ when 'CFB'
161
+ @state = @iv.dup
162
+ @iv = xor(_encrypt_block, block)
163
+ end
164
+ end
165
+
166
+ def decrypt_block(block)
167
+ @state = block.dup
168
+ case @mode
169
+ when 'ECB'
170
+ _decrypt_block
171
+ when 'CBC'
172
+ o = xor(_decrypt_block, @iv)
173
+ @iv = block
174
+ o
175
+ when 'OFB'
176
+ @state = @iv.dup
177
+ @iv = _encrypt_block
178
+ xor(@iv, block)
179
+ when 'CFB'
180
+ @state = @iv.dup
181
+ o = xor(_encrypt_block, block)
182
+ @iv = block
183
+ o
184
+ end
185
+ end
186
+
187
+ def encrypt_blocks(buffer)
188
+ raise "Bad block length" unless (buffer.length % 16).zero?
189
+ ct = ""
190
+ block = ""
191
+ buffer.each_byte do |char|
192
+ block << char
193
+ if block.length == 16
194
+ ct << encrypt_block(block)
195
+ block = ""
196
+ end
197
+ end
198
+ end
199
+
200
+ def decrypt_blocks(buffer)
201
+ raise "Bad block length" unless (buffer.length % 16).zero?
202
+ pt = ""
203
+ block = ""
204
+ buffer.each_byte do |char|
205
+ block << char
206
+ if block.length == 16
207
+ pt << decrypt_block(block)
208
+ block = ""
209
+ end
210
+ end
211
+ end
212
+
213
+ def encrypt_buffer(buffer)
214
+ ct = ""
215
+ block = ""
216
+ buffer.each_byte do |char|
217
+ block << char
218
+ if block.length == 16
219
+ ct << encrypt_block(block)
220
+ block = ""
221
+ end
222
+ end
223
+ m = 16 - block.length % 16
224
+ ct << (m == 16 ? 0 : encrypt_block(block << m.chr * m))
225
+ end
226
+
227
+ def decrypt_buffer(buffer)
228
+ pt = ""
229
+ block = ""
230
+ buffer.each_byte do |char|
231
+ block << char
232
+ if block.length == 16
233
+ pt << decrypt_block(block)
234
+ block = ""
235
+ end
236
+ end
237
+ if block.length == 0
238
+ c = pt[-1]
239
+ c.chr * c == pt[-c..-1] ? pt[0..-(c+1)] : (raise "Bad Block Padding")
240
+ else
241
+ pt
242
+ end
243
+ end
244
+
245
+ def init(key_length, mode, key, iv = nil)
246
+ @iv = "\000" * 16
247
+ @iv = iv if iv
248
+ @nb = 4
249
+ @nk = 4
250
+ @nr = 10
251
+ @mode = 'ECB'
252
+ @state = nil
253
+ @w = []
254
+ case key_length
255
+ when 128
256
+ @nk = 4
257
+ @nr = 10
258
+ when 192
259
+ @nk = 6
260
+ @nr = 12
261
+ when 256
262
+ @nk = 8
263
+ @nr = 14
264
+ else
265
+ raise 'Bad Key length'
266
+ end
267
+ case mode
268
+ when 'ECB', 'CBC', 'OFB', 'CFB'
269
+ @mode = mode
270
+ else
271
+ raise 'Bad AES mode'
272
+ end
273
+ key_expansion key
274
+ end
275
+
276
+ def initialize(key_length, mode, key, iv = nil)
277
+ init(key_length, mode, key, iv)
278
+ end
279
+
280
+ end # class aes