raptcha 0.0.1 → 2.0.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.
Files changed (63) hide show
  1. data/README +0 -88
  2. data/Rakefile +364 -0
  3. data/image.sh +24 -0
  4. data/images/raptcha.png +0 -0
  5. data/lib/raptcha.rb +377 -2063
  6. metadata +56 -128
  7. data/bin/raptcha +0 -2225
  8. data/gemspec.rb +0 -28
  9. data/install.rb +0 -210
  10. data/out +0 -0
  11. data/rails/README +0 -182
  12. data/rails/Rakefile +0 -10
  13. data/rails/app/controllers/application.rb +0 -7
  14. data/rails/app/controllers/raptcha_controller.rb +0 -43
  15. data/rails/app/helpers/application_helper.rb +0 -3
  16. data/rails/config/boot.rb +0 -45
  17. data/rails/config/database.yml +0 -36
  18. data/rails/config/environment.rb +0 -62
  19. data/rails/config/environments/development.rb +0 -21
  20. data/rails/config/environments/production.rb +0 -18
  21. data/rails/config/environments/test.rb +0 -19
  22. data/rails/config/lighttpd.conf +0 -54
  23. data/rails/config/routes.rb +0 -23
  24. data/rails/doc/README_FOR_APP +0 -2
  25. data/rails/lib/raptcha.rb +0 -2225
  26. data/rails/log/development.log +0 -16
  27. data/rails/log/fastcgi.crash.log +0 -4
  28. data/rails/log/lighttpd.access.log +0 -2
  29. data/rails/log/lighttpd.error.log +0 -3
  30. data/rails/log/production.log +0 -0
  31. data/rails/log/server.log +0 -0
  32. data/rails/log/test.log +0 -0
  33. data/rails/public/404.html +0 -30
  34. data/rails/public/500.html +0 -30
  35. data/rails/public/dispatch.cgi +0 -10
  36. data/rails/public/dispatch.fcgi +0 -24
  37. data/rails/public/dispatch.rb +0 -10
  38. data/rails/public/favicon.ico +0 -0
  39. data/rails/public/images/rails.png +0 -0
  40. data/rails/public/index.html +0 -277
  41. data/rails/public/javascripts/application.js +0 -2
  42. data/rails/public/javascripts/controls.js +0 -833
  43. data/rails/public/javascripts/dragdrop.js +0 -942
  44. data/rails/public/javascripts/effects.js +0 -1088
  45. data/rails/public/javascripts/prototype.js +0 -2515
  46. data/rails/public/robots.txt +0 -1
  47. data/rails/script/about +0 -3
  48. data/rails/script/breakpointer +0 -3
  49. data/rails/script/console +0 -3
  50. data/rails/script/destroy +0 -3
  51. data/rails/script/generate +0 -3
  52. data/rails/script/performance/benchmarker +0 -3
  53. data/rails/script/performance/profiler +0 -3
  54. data/rails/script/plugin +0 -3
  55. data/rails/script/process/inspector +0 -3
  56. data/rails/script/process/reaper +0 -3
  57. data/rails/script/process/spawner +0 -3
  58. data/rails/script/runner +0 -3
  59. data/rails/script/server +0 -3
  60. data/rails/test/test_helper.rb +0 -28
  61. data/rails/tmp/sessions/ruby_sess.04085f44b9141c9d +0 -0
  62. data/raptcha-0.0.1.gem +0 -0
  63. data/samples.rb +0 -19
metadata CHANGED
@@ -1,143 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
3
- specification_version: 1
4
2
  name: raptcha
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.0.1
7
- date: 2007-07-06 00:00:00 -06:00
8
- summary: raptcha
9
- require_paths:
10
- - lib
11
- email: ara.t.howard@gmail.com
12
- homepage: http://codeforpeople.com/lib/ruby/raptcha/
13
- rubyforge_project:
14
- description:
15
- autorequire: raptcha
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: false
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ hash: 15
5
+ prerelease: false
6
+ segments:
7
+ - 2
8
+ - 0
9
+ - 0
10
+ version: 2.0.0
25
11
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
12
  authors:
30
13
  - Ara T. Howard
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-01-12 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: "description: raptcha kicks the ass"
23
+ email: ara.t.howard@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
31
30
  files:
32
- - bin
33
- - bin/raptcha
34
- - gemspec.rb
35
- - install.rb
36
- - lib
31
+ - image.sh
32
+ - images/raptcha.png
37
33
  - lib/raptcha.rb
38
- - out
39
- - rails
40
- - rails/app
41
- - rails/app/controllers
42
- - rails/app/controllers/application.rb
43
- - rails/app/controllers/raptcha_controller.rb
44
- - rails/app/helpers
45
- - rails/app/helpers/application_helper.rb
46
- - rails/app/models
47
- - rails/app/views
48
- - rails/app/views/layouts
49
- - rails/components
50
- - rails/config
51
- - rails/config/boot.rb
52
- - rails/config/database.yml
53
- - rails/config/environment.rb
54
- - rails/config/environments
55
- - rails/config/environments/development.rb
56
- - rails/config/environments/production.rb
57
- - rails/config/environments/test.rb
58
- - rails/config/lighttpd.conf
59
- - rails/config/routes.rb
60
- - rails/db
61
- - rails/doc
62
- - rails/doc/README_FOR_APP
63
- - rails/lib
64
- - rails/lib/raptcha.rb
65
- - rails/lib/tasks
66
- - rails/log
67
- - rails/log/development.log
68
- - rails/log/fastcgi.crash.log
69
- - rails/log/lighttpd.access.log
70
- - rails/log/lighttpd.error.log
71
- - rails/log/production.log
72
- - rails/log/server.log
73
- - rails/log/test.log
74
- - rails/public
75
- - rails/public/404.html
76
- - rails/public/500.html
77
- - rails/public/dispatch.cgi
78
- - rails/public/dispatch.fcgi
79
- - rails/public/dispatch.rb
80
- - rails/public/favicon.ico
81
- - rails/public/images
82
- - rails/public/images/rails.png
83
- - rails/public/index.html
84
- - rails/public/javascripts
85
- - rails/public/javascripts/application.js
86
- - rails/public/javascripts/controls.js
87
- - rails/public/javascripts/dragdrop.js
88
- - rails/public/javascripts/effects.js
89
- - rails/public/javascripts/prototype.js
90
- - rails/public/robots.txt
91
- - rails/public/stylesheets
92
- - rails/Rakefile
93
- - rails/README
94
- - rails/script
95
- - rails/script/about
96
- - rails/script/breakpointer
97
- - rails/script/console
98
- - rails/script/destroy
99
- - rails/script/generate
100
- - rails/script/performance
101
- - rails/script/performance/benchmarker
102
- - rails/script/performance/profiler
103
- - rails/script/plugin
104
- - rails/script/process
105
- - rails/script/process/inspector
106
- - rails/script/process/reaper
107
- - rails/script/process/spawner
108
- - rails/script/runner
109
- - rails/script/server
110
- - rails/test
111
- - rails/test/fixtures
112
- - rails/test/functional
113
- - rails/test/integration
114
- - rails/test/mocks
115
- - rails/test/mocks/development
116
- - rails/test/mocks/test
117
- - rails/test/test_helper.rb
118
- - rails/test/unit
119
- - rails/tmp
120
- - rails/tmp/cache
121
- - rails/tmp/pids
122
- - rails/tmp/sessions
123
- - rails/tmp/sessions/ruby_sess.04085f44b9141c9d
124
- - rails/tmp/sockets
125
- - rails/vendor
126
- - rails/vendor/plugins
127
- - raptcha-0.0.1.gem
34
+ - Rakefile
128
35
  - README
129
- - samples.rb
130
- test_files: []
36
+ has_rdoc: true
37
+ homepage: http://github.com/ahoward/raptcha/tree/master
38
+ licenses: []
131
39
 
40
+ post_install_message:
132
41
  rdoc_options: []
133
42
 
134
- extra_rdoc_files: []
135
-
136
- executables:
137
- - raptcha
138
- extensions: []
139
-
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ hash: 3
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
140
63
  requirements: []
141
64
 
142
- dependencies: []
65
+ rubyforge_project: codeforpeople
66
+ rubygems_version: 1.3.7
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: raptcha
70
+ test_files: []
143
71
 
@@ -1,2225 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- module Raptcha
4
- #--{{{
5
- VERSION = '0.0.1' unless defined? Raptcha::VERSION
6
- def self.version() VERSION end
7
-
8
- require 'base64'
9
- require 'socket'
10
-
11
- begin
12
- require 'rubygems'
13
- rescue LoadError
14
- nil
15
- end
16
-
17
- begin
18
- require 'RMagick'
19
- rescue LoadError
20
- begin
21
- require 'Rmagick'
22
- rescue LoadError
23
- require 'rmagick'
24
- end
25
- end
26
-
27
- =begin
28
- #--{{{
29
- # all of this in inlined in the BEGIN block below...
30
-
31
- libdir = __FILE__.gsub %r'\.rb$', '/'
32
- begin
33
- $:.unshift libdir
34
- require 'pervasives'
35
- require 'attributes'
36
- require 'crypt/blowfish'
37
- ensure
38
- $:.shift
39
- end
40
- #--}}}
41
- =end
42
-
43
- module Image
44
- #--{{{
45
- singleton_class =
46
- class << self
47
- self
48
- end
49
-
50
- singleton_class.module_eval do
51
- attribute('key'){ "--img--#{ Raptcha.mac_address }--#{ Raptcha.hostname }--"[0,56] }
52
-
53
- attribute('distort'){ Hash[
54
- :low => [0, 100],
55
- :medium => [3, 50],
56
- :high => [5, 30],
57
- ] }
58
-
59
- attribute('default'){ Hash[
60
- :width => 142,
61
- :height => 30,
62
- :distort => :medium,
63
- #:background => 'black',
64
- #:foreground => 'springgreen',
65
- :background => 'white',
66
- :foreground => 'springgreen3',
67
- :format => 'png',
68
- :font_family => 'monoco',
69
- :pointsize => 22,
70
- :implode => 0.2,
71
- ] }
72
-
73
-
74
- def create kw = {}
75
- kw = default.update kw.to_options
76
-
77
- word = kw[:word]
78
- encrypted = kw[:encrypted] || kw[:e]
79
- word ||= Raptcha.decrypt(encrypted, :key => key) if encrypted
80
- word ||= Raptcha.word
81
- word = word.split(%r"").join(" ")
82
-
83
- kw[:width] = kw[:width].to_i
84
- kw[:height] = kw[:height].to_i
85
- kw[:implode] = kw[:implode].to_f
86
-
87
- img = Magick::Image.new(kw[:width], kw[:height]) do |i|
88
- i.background_color = kw[:background]
89
- i.format = kw[:format]
90
- end
91
-
92
- draw = Magick::Draw.new
93
-
94
- # text
95
- draw.stroke = kw[:foreground]
96
- draw.stroke_width = 0
97
- draw.font_family = kw[:font_family]
98
- draw.pointsize = kw[:pointsize]
99
- #draw.pointsize = kw[:height] * 0.75
100
- draw.fill = kw[:foreground]
101
- draw.gravity = Magick::NorthGravity
102
- draw.annotate img, 0, 0, 5, 5, word
103
-
104
- # line
105
- draw.stroke = kw[:foreground]
106
- draw.stroke_width = 1
107
- #draw.line 5, kw[:height]*0.33, kw[:width]-5, kw[:height]*0.33
108
- #draw.line 5, kw[:height]*0.66, kw[:width]-5, kw[:height]*0.66
109
- draw.line 5, kw[:height]*0.65, kw[:width]-5, kw[:height]*0.65
110
-
111
- draw.draw img
112
-
113
- img = img.wave *distort[kw[:distort]]
114
- img = img.implode kw[:implode]
115
-
116
- img.to_blob
117
- end
118
-
119
- def inline kw ={}
120
- Base64.encode64(create(kw))
121
- end
122
- end
123
- #--}}}
124
- end
125
-
126
- class Error < ::StandardError; end
127
- class NoInput < Error; end
128
- class BadInput < Error; end
129
- class Expired < Error; end
130
-
131
- singleton_class =
132
- class << self
133
- self
134
- end
135
-
136
- singleton_class.module_eval do
137
- attribute('key'){ "--key--#{ mac_address }--#{ hostname }--"[0,56] }
138
- attribute('src'){ '/raptcha' }
139
- attribute('gravity'){ 'west' }
140
- attribute('hostname'){ Socket.gethostname }
141
- attribute('user'){ ENV['USER'] || ENV['LOGNAME'] || 'raptcha' }
142
- attribute('alphabet'){ ('A' .. 'Z').to_a }
143
- attribute('ttl'){ 30 * 60 }
144
-
145
- attribute('close_enough'){ Hash[
146
- '0OoQ' => '0',
147
- '1l' => '1',
148
- '2zZ' => '2',
149
- '5sS' => '5',
150
- 'kKxX' => 'x',
151
- ] }
152
-
153
- def valid? params
154
- #--{{{
155
- begin
156
- validate! params
157
- rescue NoInput
158
- nil
159
- rescue BadInput
160
- false
161
- rescue Expired
162
- false
163
- end
164
- #--}}}
165
- end
166
-
167
- def validate! params
168
- #--{{{
169
- if params.has_key? 'raptcha'
170
- raptcha = params['raptcha']
171
-
172
- textarea = raptcha['t']
173
- word = raptcha['w']
174
- timebomb = raptcha['b']
175
-
176
- raise NoInput unless textarea and word and timebomb
177
-
178
- word = decrypt word
179
- timebomb = decrypt timebomb
180
-
181
- begin
182
- timebomb = Integer timebomb
183
- timebomb = Time.at(timebomb).utc
184
- now = Time.now.utc
185
- raise Expired unless now < timebomb
186
- rescue
187
- raise Expired
188
- end
189
-
190
- raise BadInput unless fuzzy(word) == fuzzy(textarea)
191
-
192
- textarea
193
- else
194
- validate! 'raptcha' => params
195
- end
196
- #--}}}
197
- end
198
-
199
- def fuzzy word
200
- #--{{{
201
- result = word.to_s.downcase
202
- close_enough.each do |charset, replace|
203
- result.gsub! %r"[#{ charset }]", replace
204
- end
205
- result
206
- #--}}}
207
- end
208
-
209
- attribute 'input_north'
210
- attribute 'input_south'
211
- attribute 'input_east'
212
- attribute 'input_west'
213
-
214
- def input kw = {}
215
- #--{{{
216
- kw.to_options!
217
-
218
- kw[:src] ||= Raptcha.src
219
- kw[:word] ||= Raptcha.word
220
- kw[:timebomb] ||= Raptcha.timebomb
221
- kw[:gravity] ||= Raptcha.gravity
222
-
223
- encrypted_word = encrypt kw[:word], :key => Raptcha.key
224
- encrypted_timebomb = encrypt kw[:timebomb], :key => Raptcha.key
225
-
226
- west = north = east = south = nil
227
- case gravity.to_s
228
- when /w(est)?/
229
- west = Raptcha.img(kw)
230
- when /n(orth)?/
231
- north = Raptcha.img(kw) + '<br>'
232
- when /e(ast)?/
233
- east = Raptcha.img(kw)
234
- when /s(outh)?/
235
- south = '<br>' + Raptcha.img(kw)
236
- end
237
-
238
- <<-html
239
- <div class="raptcha">
240
- #{ input_north }#{ input_west }
241
- #{ north } #{ west }
242
- <input type="textarea" name="raptcha[t]" value="" class="raptcha_t"/>
243
- <input type="hidden" name="raptcha[w]" value="#{ encrypted_word }" class="raptcha_w"/>
244
- <input type="hidden" name="raptcha[b]" value="#{ encrypted_timebomb }" class="raptcha_b"/>
245
- #{ east } #{ south }
246
- #{ input_east } #{ input_south }
247
- </div>
248
- html
249
-
250
- #--}}}
251
- end
252
- alias_method "tag", "input"
253
-
254
- def img kw = {}
255
- #--{{{
256
- kw.to_options!
257
- return(inline(kw)) if kw[:inline]
258
- src = kw[:src] || Raptcha.src
259
- word = kw[:word] || Raptcha.word
260
- encrypted_word = encrypt word, :key => Image.key
261
- <<-html
262
- <img src="#{ src }?e=#{ CGI.escape encrypted_word }" alt="raptcha.png" class="raptcha_i"/>
263
- html
264
- #--}}}
265
- end
266
-
267
- def inline kw = {}
268
- #--{{{
269
- <<-html
270
- <img src="data:image/png;base64,#{ Image.inline kw }" alt="raptcha.png" class="raptcha_i"/>
271
- html
272
- #--}}}
273
- end
274
-
275
- def timebomb
276
- #--{{{
277
- Time.now.utc.to_i + Raptcha.ttl
278
- #--}}}
279
- end
280
-
281
- def word size = 6
282
- #--{{{
283
- w = '' and size.times{ w << alphabet[rand(alphabet.size - 1)]} and w
284
- #--}}}
285
- end
286
-
287
- def image *a, &b
288
- #--{{{
289
- Raptcha::Image.create *a, &b
290
- #--}}}
291
- end
292
-
293
- def mac_address
294
- #--{{{
295
- return @mac_address if defined? @mac_address
296
- re = %r/[^:\-](?:[0-9A-F][0-9A-F][:\-]){5}[0-9A-F][0-9A-F][^:\-]/io
297
- cmds = '/sbin/ifconfig', '/bin/ifconfig', 'ifconfig', 'ipconfig /all'
298
-
299
- null = test(?e, '/dev/null') ? '/dev/null' : 'NUL'
300
-
301
- lines = nil
302
- cmds.each do |cmd|
303
- stdout = IO.popen("#{ cmd } 2> #{ null }"){|fd| fd.readlines} rescue next
304
- next unless stdout and stdout.size > 0
305
- lines = stdout and break
306
- end
307
- raise "all of #{ cmds.join ' ' } failed" unless lines
308
-
309
- candidates = lines.select{|line| line =~ re}
310
- raise 'no mac address candidates' unless candidates.first
311
- candidates.map!{|c| c[re]}
312
-
313
- maddr = candidates.first
314
- raise 'no mac address found' unless maddr
315
-
316
- maddr.strip!
317
- maddr.instance_eval{ @list = candidates; def list() @list end }
318
-
319
- @mac_address = maddr
320
- #--}}}
321
- end
322
-
323
- def blowfish
324
- #--{{{
325
- @blowfish ||= Hash.new{|h,k| h[k] = Crypt::Blowfish.new(k)}
326
- #--}}}
327
- end
328
-
329
- def encrypt string, kw = {}
330
- #--{{{
331
- kw.to_options!
332
- k = kw[:key] || key
333
- Base64.encode64(blowfish[k].encrypt_string(string.to_s)).chop # kill "\n"
334
- #--}}}
335
- end
336
-
337
- def decrypt string, kw = {}
338
- #--{{{
339
- kw.to_options!
340
- k = kw[:key] || key
341
- blowfish[k].decrypt_string(Base64.decode64("#{ string }\n")).strip
342
- #--}}}
343
- end
344
-
345
-
346
- def render controller, params
347
- #--{{{
348
- controller.instance_eval do
349
- send_data Raptcha.image(params), :type => 'image/png', :disposition => 'inline', :filename => 'raptcha.png'
350
- end
351
- #--}}}
352
- end
353
- end
354
- #--}}}
355
- end
356
-
357
-
358
- if $0 == __FILE__
359
- #--{{{
360
- (( Main = Object.new )).instance_eval do
361
- def run
362
- @argv = ARGV.dup
363
- mode = @argv.detect{|arg| arg !~ %r"[=:]"} || 'raptcha'
364
- @argv.delete mode
365
- send mode
366
- end
367
-
368
- def raptcha
369
- kw = {}
370
- @argv.each{|kv| k, v = kv.split(%r"[=:]").map{|x| x.strip}; kw.update k => v}
371
- STDOUT.write Raptcha.image(kw)
372
- end
373
-
374
- def generate
375
- what = @argv.shift
376
- send "generate_#{ what }"
377
- end
378
-
379
- def generate_controller
380
- src = DATA.read
381
- if test ?d, 'app'
382
- path = File.join 'app', 'controllers', 'raptcha_controller.rb'
383
- if test ?e, path
384
- puts "exists #{ path }"
385
- exit 1
386
- end
387
- open path, 'w' do |fd|
388
- fd.puts src
389
- end
390
- puts "#{ path }"
391
- else
392
- puts "generated #{ src }"
393
- end
394
- end
395
-
396
- def generate_lib
397
- src = IO.read(__FILE__)
398
- if test ?d, 'app'
399
- path = File.join 'lib', 'raptcha.rb'
400
- if test ?e, path
401
- puts "exists #{ path }"
402
- exit 1
403
- end
404
- open path, 'w' do |fd|
405
- fd.puts src
406
- end
407
- puts "#{ path }"
408
- else
409
- puts "generated #{ src }"
410
- end
411
- end
412
- end
413
- Main.run
414
- #--}}}
415
- end
416
-
417
- BEGIN {
418
- #--{{{
419
- unless Hash.new.respond_to? 'to_options' #--{{{
420
- def to_options
421
- inject(Hash.new){|h, kv| h.update kv.first.to_s.to_sym => kv.last}
422
- end
423
- def to_options!
424
- h = to_options
425
- clear
426
- update h
427
- end
428
- end #--}}}
429
-
430
- module Pervasives #--{{{
431
- VERSION = "1.0.0" unless defined? Pervasives::VERSION
432
- def self.version() VERSION end
433
- class ::Class
434
- def __pervasive__ m, *a, &b
435
- (( Class.instance_method(m) rescue Module.instance_method(m) rescue Object.instance_method(m) )).bind(self).call(*a, &b)
436
- end
437
- end
438
- class ::Module
439
- def __pervasive__ m, *a, &b
440
- (( Module.instance_method(m) rescue Object.instance_method(m) )).bind(self).call(*a, &b)
441
- end
442
- end
443
- class ::Object
444
- def __pervasive__ m, *a, &b
445
- (( Object.instance_method(m) )).bind(self).call(*a, &b)
446
- end
447
- end
448
-
449
- class Proxy
450
- instance_methods.each{|m| undef_method m unless m[%r/__/]}
451
- def initialize obj
452
- @obj = obj
453
- end
454
- def method_missing m, *a, &b
455
- @obj.__pervasive__ m, *a, &b
456
- end
457
- def __obj__
458
- @obj
459
- end
460
- end
461
- end #--}}}
462
-
463
- module Attributes #--{{{
464
- VERSION = '3.5.0'
465
- def self.version() VERSION end
466
-
467
- def attributes *a, &b
468
- unless a.empty?
469
- hashes, names = a.partition{|x| Hash === x}
470
-
471
- names_and_defaults = {}
472
- hashes.each{|h| names_and_defaults.update h}
473
- names.flatten.compact.each{|name| names_and_defaults.update name => nil}
474
-
475
- names_and_defaults.each do |name, default|
476
- init = b || lambda { default }
477
- ivar, getter, setter, query, banger =
478
- "@#{ name }", "#{ name }", "#{ name }=", "#{ name }?", "#{ name }!"
479
-
480
- define_method(setter) do |value|
481
- __pervasive__('instance_variable_set', ivar, value)
482
- end
483
-
484
- define_method(getter) do |*value|
485
- unless value.empty?
486
- __pervasive__('send', setter, value.shift)
487
- else
488
- defined = __pervasive__('instance_eval', "defined? #{ ivar }")
489
- __pervasive__('send', setter, __pervasive__('instance_eval', &init)) unless defined
490
- __pervasive__('instance_variable_get', ivar)
491
- end
492
- end
493
-
494
- define_method(banger) do
495
- __pervasive__('send', setter, __pervasive__('instance_eval', &init))
496
- __pervasive__('instance_variable_get', ivar)
497
- end
498
-
499
- alias_method query, getter
500
-
501
- (attributes << name.to_s).uniq!
502
- attributes
503
- end
504
- else
505
- begin
506
- __attribute_list__
507
- rescue NameError
508
- singleton_class =
509
- class << self
510
- self
511
- end
512
- klass = self
513
- singleton_class.module_eval do
514
- attribute_list = []
515
- define_method('attribute_list'){ klass == self ? attribute_list : raise(NameError) }
516
- alias_method '__attribute_list__', 'attribute_list'
517
- end
518
- __attribute_list__
519
- end
520
- end
521
- end
522
-
523
- %w( __attributes__ __attribute__ attribute ).each{|dst| alias_method dst, 'attributes'}
524
- end
525
-
526
- class Object
527
- def attributes *a, &b
528
- sc =
529
- class << self
530
- self
531
- end
532
- sc.attributes *a, &b
533
- end
534
- %w( __attributes__ __attribute__ attribute ).each{|dst| alias_method dst, 'attributes'}
535
- end
536
-
537
- class Module
538
- include Attributes
539
- end #--}}}
540
-
541
- # cbc.rb Richard Kernahan <kernighan_rich@rubyforge.org>
542
- module Crypt #--{{{
543
- module CBC
544
-
545
- require 'stringio'
546
- #require 'crypt/stringxor'
547
-
548
- ULONG = 0x100000000
549
-
550
- # When this module is mixed in with an encryption class, the class
551
- # must provide three methods: encrypt_block(block) and decrypt_block(block)
552
- # and block_size()
553
-
554
-
555
- def generate_initialization_vector(words)
556
- srand(Time.now.to_i)
557
- vector = ""
558
- words.times {
559
- vector << [rand(ULONG)].pack('N')
560
- }
561
- return(vector)
562
- end
563
-
564
-
565
- def encrypt_stream(plainStream, cryptStream)
566
- # Cypher-block-chain mode
567
-
568
- initVector = generate_initialization_vector(block_size() / 4)
569
- chain = encrypt_block(initVector)
570
- cryptStream.write(chain)
571
-
572
- while ((block = plainStream.read(block_size())) && (block.length == block_size()))
573
- block = block ^ chain
574
- encrypted = encrypt_block(block)
575
- cryptStream.write(encrypted)
576
- chain = encrypted
577
- end
578
-
579
- # write the final block
580
- # At most block_size()-1 bytes can be part of the message.
581
- # That means the final byte can be used to store the number of meaningful
582
- # bytes in the final block
583
- block = '' if block.nil?
584
- buffer = block.split('')
585
- remainingMessageBytes = buffer.length
586
- # we use 7-bit characters to avoid possible strange behavior on the Mac
587
- remainingMessageBytes.upto(block_size()-2) { buffer << rand(128).chr }
588
- buffer << remainingMessageBytes.chr
589
- block = buffer.join('')
590
- block = block ^ chain
591
- encrypted = encrypt_block(block)
592
- cryptStream.write(encrypted)
593
- end
594
-
595
-
596
- def decrypt_stream(cryptStream, plainStream)
597
- # Cypher-block-chain mode
598
- chain = cryptStream.read(block_size())
599
-
600
- while (block = cryptStream.read(block_size()))
601
- decrypted = decrypt_block(block)
602
- plainText = decrypted ^ chain
603
- plainStream.write(plainText) unless cryptStream.eof?
604
- chain = block
605
- end
606
-
607
- # write the final block, omitting the padding
608
- buffer = plainText.split('')
609
- remainingMessageBytes = buffer.last.unpack('C').first
610
- remainingMessageBytes.times { plainStream.write(buffer.shift) }
611
- end
612
-
613
-
614
- def carefully_open_file(filename, mode)
615
- begin
616
- aFile = File.new(filename, mode)
617
- rescue
618
- puts "Sorry. There was a problem opening the file <#{filename}>."
619
- aFile.close() unless aFile.nil?
620
- raise
621
- end
622
- return(aFile)
623
- end
624
-
625
-
626
- def encrypt_file(plainFilename, cryptFilename)
627
- plainFile = carefully_open_file(plainFilename, 'rb')
628
- cryptFile = carefully_open_file(cryptFilename, 'wb+')
629
- encrypt_stream(plainFile, cryptFile)
630
- plainFile.close unless plainFile.closed?
631
- cryptFile.close unless cryptFile.closed?
632
- end
633
-
634
-
635
- def decrypt_file(cryptFilename, plainFilename)
636
- cryptFile = carefully_open_file(cryptFilename, 'rb')
637
- plainFile = carefully_open_file(plainFilename, 'wb+')
638
- decrypt_stream(cryptFile, plainFile)
639
- cryptFile.close unless cryptFile.closed?
640
- plainFile.close unless plainFile.closed?
641
- end
642
-
643
-
644
- def encrypt_string(plainText)
645
- plainStream = StringIO.new(plainText)
646
- cryptStream = StringIO.new('')
647
- encrypt_stream(plainStream, cryptStream)
648
- cryptText = cryptStream.string
649
- return(cryptText)
650
- end
651
-
652
-
653
- def decrypt_string(cryptText)
654
- cryptStream = StringIO.new(cryptText)
655
- plainStream = StringIO.new('')
656
- decrypt_stream(cryptStream, plainStream)
657
- plainText = plainStream.string
658
- return(plainText)
659
- end
660
-
661
- end
662
- end #--}}}
663
-
664
- # blowfish-tables.rb Richard Kernahan <kernighan_rich@rubyforge.org>
665
- module Crypt #--{{{
666
- module BlowfishTables
667
-
668
- INITIALPARRAY = [
669
- 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
670
- 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
671
- 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
672
- ]
673
-
674
- INITIALSBOXES = [[
675
- 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
676
- 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
677
- 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
678
- 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
679
- 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
680
- 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
681
- 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
682
- 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
683
- 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
684
- 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
685
- 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
686
- 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
687
- 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
688
- 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
689
- 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
690
- 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
691
- 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
692
- 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
693
- 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
694
- 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
695
- 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
696
- 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
697
- 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
698
- 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
699
- 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
700
- 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
701
- 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
702
- 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
703
- 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
704
- 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
705
- 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
706
- 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
707
- 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
708
- 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
709
- 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
710
- 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
711
- 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
712
- 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
713
- 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
714
- 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
715
- 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
716
- 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
717
- 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a], [
718
- 0x4b7a70e9, 0xb5b32944,
719
- 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
720
- 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29,
721
- 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
722
- 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26,
723
- 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
724
- 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c,
725
- 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
726
- 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6,
727
- 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
728
- 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f,
729
- 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
730
- 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810,
731
- 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
732
- 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa,
733
- 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
734
- 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55,
735
- 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
736
- 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1,
737
- 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
738
- 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78,
739
- 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
740
- 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883,
741
- 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
742
- 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170,
743
- 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
744
- 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7,
745
- 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
746
- 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099,
747
- 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
748
- 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263,
749
- 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
750
- 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3,
751
- 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
752
- 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7,
753
- 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
754
- 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d,
755
- 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
756
- 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460,
757
- 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
758
- 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484,
759
- 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
760
- 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a,
761
- 0xe6e39f2b, 0xdb83adf7], [
762
- 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
763
- 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a,
764
- 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
765
- 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785,
766
- 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
767
- 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900,
768
- 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
769
- 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9,
770
- 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
771
- 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397,
772
- 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
773
- 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9,
774
- 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
775
- 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f,
776
- 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
777
- 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e,
778
- 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
779
- 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd,
780
- 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
781
- 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8,
782
- 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
783
- 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c,
784
- 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
785
- 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b,
786
- 0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
787
- 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386,
788
- 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
789
- 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0,
790
- 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
791
- 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2,
792
- 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
793
- 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770,
794
- 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
795
- 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c,
796
- 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
797
- 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa,
798
- 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
799
- 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63,
800
- 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
801
- 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9,
802
- 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
803
- 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4,
804
- 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0], [
805
- 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
806
- 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
807
- 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
808
- 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
809
- 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
810
- 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
811
- 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
812
- 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
813
- 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
814
- 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
815
- 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
816
- 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
817
- 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
818
- 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
819
- 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
820
- 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
821
- 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
822
- 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
823
- 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
824
- 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
825
- 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
826
- 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
827
- 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
828
- 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
829
- 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
830
- 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
831
- 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
832
- 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
833
- 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
834
- 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
835
- 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
836
- 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
837
- 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
838
- 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
839
- 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
840
- 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
841
- 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
842
- 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
843
- 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
844
- 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
845
- 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
846
- 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
847
- 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6]
848
- ]
849
-
850
-
851
- end
852
- end #--}}}
853
-
854
- # blowfish.rb Richard Kernahan <kernighan_rich@rubyforge.org>
855
- #
856
- # Blowfish algorithm by Bruce Schneider
857
- # Ported by Richard Kernahan from the reference C code
858
- module Crypt #--{{{
859
- class Blowfish
860
-
861
- #require 'crypt/cbc'
862
- include Crypt::CBC
863
-
864
- #require 'crypt/blowfish-tables'
865
- include Crypt::BlowfishTables
866
-
867
- ULONG = 0x100000000
868
-
869
- def block_size
870
- return(8)
871
- end
872
-
873
-
874
- def initialize(key)
875
- @key = key
876
- raise "Bad key length: the key must be 1-56 bytes." unless (key.length.between?(1,56))
877
- @pArray = []
878
- @sBoxes = []
879
- setup_blowfish()
880
- end
881
-
882
-
883
- def f(x)
884
- a, b, c, d = [x].pack('N').unpack('CCCC')
885
- y = (@sBoxes[0][a] + @sBoxes[1][b]) % ULONG
886
- y = (y ^ @sBoxes[2][c]) % ULONG
887
- y = (y + @sBoxes[3][d]) % ULONG
888
- return(y)
889
- end
890
-
891
-
892
- def setup_blowfish()
893
- @sBoxes = Array.new(4) { |i| INITIALSBOXES[i].clone }
894
- @pArray = INITIALPARRAY.clone
895
- keypos = 0
896
- 0.upto(17) { |i|
897
- data = 0
898
- 4.times {
899
- data = ((data << 8) | @key[keypos]) % ULONG
900
- keypos = (keypos.next) % @key.length
901
- }
902
- @pArray[i] = (@pArray[i] ^ data) % ULONG
903
- }
904
- l = 0
905
- r = 0
906
- 0.step(17, 2) { |i|
907
- l, r = encrypt_pair(l, r)
908
- @pArray[i] = l
909
- @pArray[i+1] = r
910
- }
911
- 0.upto(3) { |i|
912
- 0.step(255, 2) { |j|
913
- l, r = encrypt_pair(l, r)
914
- @sBoxes[i][j] = l
915
- @sBoxes[i][j+1] = r
916
- }
917
- }
918
- end
919
-
920
- def encrypt_pair(xl, xr)
921
- 0.upto(15) { |i|
922
- xl = (xl ^ @pArray[i]) % ULONG
923
- xr = (xr ^ f(xl)) % ULONG
924
- xl, xr = [xl, xr].reverse
925
- }
926
- xl, xr = [xl, xr].reverse
927
- xr = (xr ^ @pArray[16]) % ULONG
928
- xl = (xl ^ @pArray[17]) % ULONG
929
- return([xl, xr])
930
- end
931
-
932
-
933
- def decrypt_pair(xl, xr)
934
- 17.downto(2) { |i|
935
- xl = (xl ^ @pArray[i]) % ULONG
936
- xr = (xr ^ f(xl)) % ULONG
937
- xl, xr = [xl, xr].reverse
938
- }
939
- xl, xr = [xl, xr].reverse
940
- xr = (xr ^ @pArray[1]) % ULONG
941
- xl = (xl ^ @pArray[0]) % ULONG
942
- return([xl, xr])
943
- end
944
-
945
-
946
- def encrypt_block(block)
947
- xl, xr = block.unpack('NN')
948
- xl, xr = encrypt_pair(xl, xr)
949
- encrypted = [xl, xr].pack('NN')
950
- return(encrypted)
951
- end
952
-
953
-
954
- def decrypt_block(block)
955
- xl, xr = block.unpack('NN')
956
- xl, xr = decrypt_pair(xl, xr)
957
- decrypted = [xl, xr].pack('NN')
958
- return(decrypted)
959
- end
960
-
961
- end
962
- end #--}}}
963
-
964
- # gost.rb
965
- # Adapted by Richard Kernahan <kernighan_rich@rubyforge.org>
966
- # from C++ code written by Wei Dai
967
- # of the Crypto++ project http://www.eskimo.com/~weidai/cryptlib.html
968
- module Crypt #--{{{
969
- class Gost
970
-
971
- #require 'crypt/cbc'
972
- include CBC
973
-
974
- ULONG = 0x100000000
975
-
976
- def block_size
977
- return(8)
978
- end
979
-
980
-
981
- def initialize(userKey)
982
-
983
- # These are the S-boxes given in Applied Cryptography 2nd Ed., p. 333
984
- @sBox = [
985
- [4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3],
986
- [14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9],
987
- [5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11],
988
- [7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3],
989
- [6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2],
990
- [4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14],
991
- [13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12],
992
- [1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12]
993
- ]
994
-
995
- # These are the S-boxes given in the GOST source code listing in Applied
996
- # Cryptography 2nd Ed., p. 644. They appear to be from the DES S-boxes
997
- # [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 ],
998
- # [ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 ],
999
- # [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 ],
1000
- # [ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 ],
1001
- # [ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 ],
1002
- # [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 ],
1003
- # [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 ],
1004
- # [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 ]
1005
-
1006
- # precalculate the S table
1007
- @sTable = precalculate_S_table()
1008
-
1009
- # derive the 32-byte key from the user-supplied key
1010
- userKeyLength = userKey.length
1011
- @key = userKey[0..31].unpack('C'*32)
1012
- if (userKeyLength < 32)
1013
- userKeyLength.upto(31) { @key << 0 }
1014
- end
1015
- end
1016
-
1017
-
1018
- def precalculate_S_table()
1019
- sTable = [[], [], [], []]
1020
- 0.upto(3) { |i|
1021
- 0.upto(255) { |j|
1022
- t = @sBox[2*i][j % 16] | (@sBox[2*i+1][j/16] << 4)
1023
- u = (8*i + 11) % 32
1024
- v = (t << u) | (t >> (32-u))
1025
- sTable[i][j] = (v % ULONG)
1026
- }
1027
- }
1028
- return(sTable)
1029
- end
1030
-
1031
-
1032
- def f(longWord)
1033
- longWord = longWord % ULONG
1034
- a, b, c, d = [longWord].pack('L').unpack('CCCC')
1035
- return(@sTable[3][d] ^ @sTable[2][c] ^ @sTable[1][b] ^ @sTable[0][a])
1036
- end
1037
-
1038
-
1039
- def encrypt_pair(xl, xr)
1040
- 3.times {
1041
- xr ^= f(xl+@key[0])
1042
- xl ^= f(xr+@key[1])
1043
- xr ^= f(xl+@key[2])
1044
- xl ^= f(xr+@key[3])
1045
- xr ^= f(xl+@key[4])
1046
- xl ^= f(xr+@key[5])
1047
- xr ^= f(xl+@key[6])
1048
- xl ^= f(xr+@key[7])
1049
- }
1050
- xr ^= f(xl+@key[7])
1051
- xl ^= f(xr+@key[6])
1052
- xr ^= f(xl+@key[5])
1053
- xl ^= f(xr+@key[4])
1054
- xr ^= f(xl+@key[3])
1055
- xl ^= f(xr+@key[2])
1056
- xr ^= f(xl+@key[1])
1057
- xl ^= f(xr+@key[0])
1058
- return([xr, xl])
1059
- end
1060
-
1061
-
1062
- def decrypt_pair(xl, xr)
1063
- xr ^= f(xl+@key[0])
1064
- xl ^= f(xr+@key[1])
1065
- xr ^= f(xl+@key[2])
1066
- xl ^= f(xr+@key[3])
1067
- xr ^= f(xl+@key[4])
1068
- xl ^= f(xr+@key[5])
1069
- xr ^= f(xl+@key[6])
1070
- xl ^= f(xr+@key[7])
1071
- 3.times {
1072
- xr ^= f(xl+@key[7])
1073
- xl ^= f(xr+@key[6])
1074
- xr ^= f(xl+@key[5])
1075
- xl ^= f(xr+@key[4])
1076
- xr ^= f(xl+@key[3])
1077
- xl ^= f(xr+@key[2])
1078
- xr ^= f(xl+@key[1])
1079
- xl ^= f(xr+@key[0])
1080
- }
1081
- return([xr, xl])
1082
- end
1083
-
1084
-
1085
- def encrypt_block(block)
1086
- xl, xr = block.unpack('NN')
1087
- xl, xr = encrypt_pair(xl, xr)
1088
- encrypted = [xl, xr].pack('NN')
1089
- return(encrypted)
1090
- end
1091
-
1092
-
1093
- def decrypt_block(block)
1094
- xl, xr = block.unpack('NN')
1095
- xl, xr = decrypt_pair(xl, xr)
1096
- decrypted = [xl, xr].pack('NN')
1097
- return(decrypted)
1098
- end
1099
-
1100
-
1101
- end
1102
- end #--}}}
1103
-
1104
- # idea.rb Richard Kernahan <kernighan_rich@rubyforge.org>
1105
- # IDEA (International Data Encryption Algorithm) by
1106
- # Xuejia Lai and James Massey (1992). Refer to license info at end.
1107
- # Ported by Richard Kernahan 2005
1108
- module Crypt #--{{{
1109
- class IDEA
1110
-
1111
- #require 'crypt/cbc'
1112
- include Crypt::CBC
1113
-
1114
- require 'digest/md5'
1115
-
1116
- ULONG = 0x100000000
1117
- USHORT = 0x10000
1118
-
1119
- ENCRYPT = 0
1120
- DECRYPT = 1
1121
-
1122
-
1123
- def block_size
1124
- return(8)
1125
- end
1126
-
1127
-
1128
- def initialize(key128, mode)
1129
- # IDEA is subject to attack unless the key is sufficiently random, so we
1130
- # take an MD5 digest of a variable-length passphrase to ensure a solid key
1131
- if (key128.class == String)
1132
- digest = Digest::MD5.new(key128).digest
1133
- key128 = digest.unpack('n'*8)
1134
- end
1135
- raise "Key must be 128 bits (8 words)" unless (key128.class == Array) && (key128.length == 8)
1136
- raise "Mode must be IDEA::ENCRYPT or IDEA::DECRYPT" unless ((mode == ENCRYPT) | (mode == DECRYPT))
1137
- if (mode == ENCRYPT)
1138
- @subkeys = generate_encryption_subkeys(key128)
1139
- else (mode == DECRYPT)
1140
- @subkeys = generate_decryption_subkeys(key128)
1141
- end
1142
- end
1143
-
1144
-
1145
- def mul(a, b)
1146
- modulus = 0x10001
1147
- return((1 - b) % USHORT) if (a == 0)
1148
- return((1 - a) % USHORT) if (b == 0)
1149
- return((a * b) % modulus)
1150
- end
1151
-
1152
-
1153
- def mulInv(x)
1154
- modulus = 0x10001
1155
- x = x.to_i % USHORT
1156
- return(x) if (x <= 1)
1157
- t1 = USHORT / x
1158
- y = modulus % x
1159
- if (y == 1)
1160
- inv = (1 - t1) & 0xFFFF
1161
- return(inv)
1162
- end
1163
- t0 = 1
1164
- while (y != 1)
1165
- q = x / y
1166
- x = x % y
1167
- t0 = t0 + (q * t1)
1168
- return(t0) if (x == 1)
1169
- q = y / x
1170
- y = y % x
1171
- t1 = t1 + (q * t0)
1172
- end
1173
- inv = (1 - t1) & 0xFFFF
1174
- return(inv)
1175
- end
1176
-
1177
-
1178
- def generate_encryption_subkeys(key)
1179
- encrypt_keys = []
1180
- encrypt_keys[0..7] = key.dup
1181
- 8.upto(51) { |i|
1182
- a = ((i + 1) % 8 > 0) ? (i-7) : (i-15)
1183
- b = ((i + 2) % 8 < 2) ? (i-14) : (i-6)
1184
- encrypt_keys[i] = ((encrypt_keys[a] << 9) | (encrypt_keys[b] >> 7)) % USHORT
1185
- }
1186
- return(encrypt_keys)
1187
- end
1188
-
1189
-
1190
- def generate_decryption_subkeys(key)
1191
- encrypt_keys = generate_encryption_subkeys(key)
1192
- decrypt_keys = []
1193
- decrypt_keys[48] = mulInv(encrypt_keys.shift)
1194
- decrypt_keys[49] = (-encrypt_keys.shift) % USHORT
1195
- decrypt_keys[50] = (-encrypt_keys.shift) % USHORT
1196
- decrypt_keys[51] = mulInv(encrypt_keys.shift)
1197
- 42.step(0, -6) { |i|
1198
- decrypt_keys[i+4] = encrypt_keys.shift % USHORT
1199
- decrypt_keys[i+5] = encrypt_keys.shift % USHORT
1200
- decrypt_keys[i] = mulInv(encrypt_keys.shift)
1201
- if (i ==0)
1202
- decrypt_keys[1] = (-encrypt_keys.shift) % USHORT
1203
- decrypt_keys[2] = (-encrypt_keys.shift) % USHORT
1204
- else
1205
- decrypt_keys[i+2] = (-encrypt_keys.shift) % USHORT
1206
- decrypt_keys[i+1] = (-encrypt_keys.shift) % USHORT
1207
- end
1208
- decrypt_keys[i+3] = mulInv(encrypt_keys.shift)
1209
- }
1210
- return(decrypt_keys)
1211
- end
1212
-
1213
-
1214
- def crypt_pair(l, r)
1215
- word = [l, r].pack('NN').unpack('nnnn')
1216
- k = @subkeys[0..51]
1217
- 8.downto(1) { |i|
1218
- word[0] = mul(word[0], k.shift)
1219
- word[1] = (word[1] + k.shift) % USHORT
1220
- word[2] = (word[2] + k.shift) % USHORT
1221
- word[3] = mul(word[3], k.shift)
1222
- t2 = word[0] ^ word[2]
1223
- t2 = mul(t2, k.shift)
1224
- t1 = (t2 + (word[1] ^ word[3])) % USHORT
1225
- t1 = mul(t1, k.shift)
1226
- t2 = (t1 + t2) % USHORT
1227
- word[0] ^= t1
1228
- word[3] ^= t2
1229
- t2 ^= word[1]
1230
- word[1] = word[2] ^ t1
1231
- word[2] = t2
1232
- }
1233
- result = []
1234
- result << mul(word[0], k.shift)
1235
- result << (word[2] + k.shift) % USHORT
1236
- result << (word[1] + k.shift) % USHORT
1237
- result << mul(word[3], k.shift)
1238
- twoLongs = result.pack('nnnn').unpack('NN')
1239
- return(twoLongs)
1240
- end
1241
-
1242
- def encrypt_block(block)
1243
- xl, xr = block.unpack('NN')
1244
- xl, xr = crypt_pair(xl, xr)
1245
- encrypted = [xl, xr].pack('NN')
1246
- return(encrypted)
1247
- end
1248
-
1249
-
1250
- def decrypt_block(block)
1251
- xl, xr = block.unpack('NN')
1252
- xl, xr = crypt_pair(xl, xr)
1253
- decrypted = [xl, xr].pack('NN')
1254
- return(decrypted)
1255
- end
1256
-
1257
-
1258
- end
1259
- end #--}}}
1260
-
1261
- # LICENSE INFORMATION
1262
- #
1263
- # This software product contains the IDEA algorithm as described and claimed in
1264
- # US patent 5,214,703, EPO patent 0482154 (covering Austria, France, Germany,
1265
- # Italy, the Netherlands, Spain, Sweden, Switzerland, and the UK), and Japanese
1266
- # patent application 508119/1991, "Device for the conversion of a digital block
1267
- # and use of same" (hereinafter referred to as "the algorithm"). Any use of
1268
- # the algorithm for commercial purposes is thus subject to a license from Ascom
1269
- # Systec Ltd. of CH-5506 Maegenwil (Switzerland), being the patentee and sole
1270
- # owner of all rights, including the trademark IDEA.
1271
- #
1272
- # Commercial purposes shall mean any revenue generating purpose including but
1273
- # not limited to:
1274
- #
1275
- # i) Using the algorithm for company internal purposes (subject to a site
1276
- # license).
1277
- #
1278
- # ii) Incorporating the algorithm into any software and distributing such
1279
- # software and/or providing services relating thereto to others (subject to
1280
- # a product license).
1281
- #
1282
- # iii) Using a product containing the algorithm not covered by an IDEA license
1283
- # (subject to an end user license).
1284
- #
1285
- # All such end user license agreements are available exclusively from Ascom
1286
- # Systec Ltd and may be requested via the WWW at http://www.ascom.ch/systec or
1287
- # by email to idea@ascom.ch.
1288
- #
1289
- # Use other than for commercial purposes is strictly limited to non-revenue
1290
- # generating data transfer between private individuals. The use by government
1291
- # agencies, non-profit organizations, etc is considered as use for commercial
1292
- # purposes but may be subject to special conditions. Any misuse will be
1293
- # prosecuted.
1294
-
1295
- # crypt/rattle.rb Richard Kernahan <kernighan_rich@rubyforge.org>
1296
-
1297
- # add_noise - take a message and intersperse noise to make a new noisy message of given byte-length
1298
- # remove_noise - take a noisy message and extract the message
1299
- module Crypt #--{{{
1300
- module Noise
1301
-
1302
- def add_noise(newLength)
1303
- message = self
1304
- usableNoisyMessageLength = newLength / 9 * 8
1305
- bitmapSize = newLength / 9
1306
- remainingBytes = newLength - usableNoisyMessageLength - bitmapSize
1307
- if (message.length > usableNoisyMessageLength)
1308
- minimumNewLength = (message.length / 8.0).ceil * 9
1309
- puts "For a clear text of #{message.length} bytes, the minimum obscured length"
1310
- puts "is #{minimumNewLength} bytes which allows for no noise in the message."
1311
- puts "You should choose an obscured length of at least double the clear text"
1312
- puts "length, such as #{message.length / 8 * 32} bytes"
1313
- raise "Insufficient length for noisy message"
1314
- end
1315
- bitmap = []
1316
- usableNoisyMessageLength.times { bitmap << false }
1317
- srand(Time.now.to_i)
1318
- positionsSelected = 0
1319
- while (positionsSelected < message.length)
1320
- positionTaken = rand(usableNoisyMessageLength)
1321
- if bitmap[positionTaken]
1322
- next
1323
- else
1324
- bitmap[positionTaken] = true
1325
- positionsSelected = positionsSelected.next
1326
- end
1327
- end
1328
-
1329
- noisyMessage = ""
1330
- 0.upto(bitmapSize-1) { |byte|
1331
- c = 0
1332
- 0.upto(7) { |bit|
1333
- c = c + (1<<bit) if bitmap[byte * 8 + bit]
1334
- }
1335
- noisyMessage << c.chr
1336
- }
1337
- posInMessage = 0
1338
- 0.upto(usableNoisyMessageLength-1) { |pos|
1339
- if bitmap[pos]
1340
- meaningfulByte = message[posInMessage]
1341
- noisyMessage << meaningfulByte
1342
- posInMessage = posInMessage.next
1343
- else
1344
- noiseByte = rand(256).chr
1345
- noisyMessage << noiseByte
1346
- end
1347
- }
1348
- remainingBytes.times {
1349
- noiseByte = rand(256).chr
1350
- noisyMessage << noiseByte
1351
- }
1352
- return(noisyMessage)
1353
- end
1354
-
1355
-
1356
- def remove_noise
1357
- noisyMessage = self
1358
- bitmapSize = noisyMessage.length / 9
1359
- actualMessageLength = bitmapSize * 8
1360
-
1361
- actualMessageStart = bitmapSize
1362
- actualMessageFinish = bitmapSize + actualMessageLength - 1
1363
- actualMessage = noisyMessage[actualMessageStart..actualMessageFinish]
1364
-
1365
- bitmap = []
1366
- 0.upto(bitmapSize - 1) { |byte|
1367
- c = noisyMessage[byte]
1368
- 0.upto(7) { |bit|
1369
- bitmap[byte * 8 + bit] = (c[bit] == 1)
1370
- }
1371
- }
1372
- clearMessage = ""
1373
- 0.upto(actualMessageLength) { |pos|
1374
- meaningful = bitmap[pos]
1375
- if meaningful
1376
- clearMessage << actualMessage[pos]
1377
- end
1378
- }
1379
- return(clearMessage)
1380
- end
1381
-
1382
- end
1383
- end
1384
-
1385
- class String
1386
- include Crypt::Noise
1387
- end #--}}}
1388
-
1389
-
1390
- # Thanks to Binky DaClown who wrote this pure-ruby implementation
1391
- # http://rubyforge.org/projects/prstringio/
1392
- # Apparently CBC does not work well with the C-based stringio
1393
- module Crypt #--{{{
1394
- class PureRubyStringIO
1395
-
1396
- include Enumerable
1397
-
1398
- SEEK_CUR = IO::SEEK_CUR
1399
- SEEK_END = IO::SEEK_END
1400
- SEEK_SET = IO::SEEK_SET
1401
-
1402
- @@relayMethods = [:<<, :all?, :any?, :binmode, :close, :close_read, :close_write, :closed?, :closed_read?,
1403
- :closed_write?, :collect, :detect, :each, :each_byte, :each_line, :each_with_index,
1404
- :entries, :eof, :eof?, :fcntl, :fileno, :find, :find_all, :flush, :fsync, :getc, :gets,
1405
- :grep, :include?, :inject, :isatty, :length, :lineno, :lineno=, :map, :max, :member?,
1406
- :min, :partition, :path, :pid, :pos, :pos=, :print, :printf, :putc, :puts, :read,
1407
- :readchar, :readline, :readlines, :reject, :rewind, :seek, :select, :size, :sort,
1408
- :sort_by, :string, :string=, :sync, :sync=, :sysread, :syswrite, :tell, :truncate, :tty?,
1409
- :ungetc, :write, :zip]
1410
-
1411
- def self.open(string="", mode="r+")
1412
- if block_given? then
1413
- sio = new(string, mode)
1414
- rc = yield(sio)
1415
- sio.close
1416
- rc
1417
- else
1418
- new(string, mode)
1419
- end
1420
- end
1421
-
1422
- def <<(obj)
1423
- requireWritable
1424
- write obj
1425
- self
1426
- end
1427
-
1428
- def binmode
1429
- self
1430
- end
1431
-
1432
- def close
1433
- requireOpen
1434
- @sio_closed_read = true
1435
- @sio_closed_write = true
1436
- self
1437
- end
1438
-
1439
- def close_read
1440
- raise IOError, "closing non-duplex IO for reading", caller if closed_read?
1441
- @sio_closed_read = true
1442
- self
1443
- end
1444
-
1445
- def close_write
1446
- raise IOError, "closing non-duplex IO for writing", caller if closed_write?
1447
- @sio_closed_read = true
1448
- self
1449
- end
1450
-
1451
- def closed?
1452
- closed_read? && closed_write?
1453
- end
1454
-
1455
- def closed_read?
1456
- @sio_closed_read
1457
- end
1458
-
1459
- def closed_write?
1460
- @sio_closed_write
1461
- end
1462
-
1463
- def each(sep_string=$/, &block)
1464
- requireReadable
1465
- @sio_string.each(sep_string, &block)
1466
- @sio_pos = @sio_string.length
1467
- end
1468
-
1469
- def each_byte(&block)
1470
- requireReadable
1471
- @sio_string.each_byte(&block)
1472
- @sio_pos = @sio_string.length
1473
- end
1474
-
1475
- def eof
1476
- requireReadable { @sio_pos >= @sio_string.length }
1477
- end
1478
-
1479
- def fcntl(integer_cmd, arg)
1480
- raise NotImplementedError, "The fcntl() function is unimplemented on this machine", caller
1481
- end
1482
-
1483
- def fileno
1484
- nil
1485
- end
1486
-
1487
- def flush
1488
- self
1489
- end
1490
-
1491
- def fsync
1492
- 0
1493
- end
1494
-
1495
- def getc
1496
- requireReadable
1497
- char = @sio_string[@sio_pos]
1498
- @sio_pos += 1 unless char.nil?
1499
- char
1500
- end
1501
-
1502
- def gets(sep_string=$/)
1503
- requireReadable
1504
- @sio_lineno += 1
1505
- pstart = @sio_pos
1506
- @sio_pos = @sio_string.index(sep_string, @sio_pos) || [@sio_string.length, @sio_pos].max
1507
- @sio_string[pstart..@sio_pos]
1508
- end
1509
-
1510
- def initialize(string="", mode="r+")
1511
- @sio_string = string.to_s
1512
- @sio_lineno = 0
1513
- @mode = mode
1514
- @relay = nil
1515
- case mode.delete("b")
1516
- when "r"
1517
- @sio_closed_read = false
1518
- @sio_closed_write = true
1519
- @sio_pos = 0
1520
- when "r+"
1521
- @sio_closed_read = false
1522
- @sio_closed_write = false
1523
- @sio_pos = 0
1524
- when "w"
1525
- @sio_closed_read = true
1526
- @sio_closed_write = false
1527
- @sio_pos = 0
1528
- @sio_string.replace("")
1529
- when "w+"
1530
- @sio_closed_read = false
1531
- @sio_closed_write = false
1532
- @sio_pos = 0
1533
- @sio_string.replace("")
1534
- when "a"
1535
- @sio_closed_read = true
1536
- @sio_closed_write = false
1537
- @sio_pos = @sio_string.length
1538
- when "a+"
1539
- @sio_closed_read = false
1540
- @sio_closed_write = false
1541
- @sio_pos = @sio_string.length
1542
- else
1543
- raise ArgumentError, "illegal access mode #{mode}", caller
1544
- end
1545
- end
1546
-
1547
- def isatty
1548
- flase
1549
- end
1550
-
1551
- def length
1552
- @sio_string.length
1553
- end
1554
-
1555
- def lineno
1556
- @sio_lineno
1557
- end
1558
-
1559
- def lineno=(integer)
1560
- @sio_lineno = integer
1561
- end
1562
-
1563
- def path
1564
- nil
1565
- end
1566
-
1567
- def pid
1568
- nil
1569
- end
1570
-
1571
- def pos
1572
- @sio_pos
1573
- end
1574
-
1575
- def pos=(integer)
1576
- raise Errno::EINVAL, "Invalid argument", caller if integer < 0
1577
- @sio_pos = integer
1578
- end
1579
-
1580
- def print(*args)
1581
- requireWritable
1582
- args.unshift($_) if args.empty
1583
- args.each { |obj| write(obj) }
1584
- write($\) unless $\.nil?
1585
- nil
1586
- end
1587
-
1588
- def printf(format_string, *args)
1589
- requireWritable
1590
- write format(format_string, *args)
1591
- nil
1592
- end
1593
-
1594
- def putc(obj)
1595
- requireWritable
1596
- write(obj.is_a?(Numeric) ? sprintf("%c", obj) : obj.to_s[0..0])
1597
- obj
1598
- end
1599
-
1600
- def puts(*args)
1601
- requireWritable
1602
- args.unshift("") if args.empty?
1603
- args.each { |obj|
1604
- write obj
1605
- write $/
1606
- }
1607
- nil
1608
- end
1609
-
1610
- def read(length=nil, buffer=nil)
1611
- requireReadable
1612
- len = length || [@sio_string.length - @sio_pos, 0].max
1613
- raise ArgumentError, "negative length #{len} given", caller if len < 0
1614
- buffer ||= ""
1615
- pstart = @sio_pos
1616
- @sio_pos += len
1617
- buffer.replace(@sio_string[pstart..@sio_pos])
1618
- buffer.empty? && !length.nil? ? nil : buffer
1619
- end
1620
-
1621
- def readchar
1622
- requireReadable
1623
- raise EOFError, "End of file reached", caller if eof?
1624
- getc
1625
- end
1626
-
1627
- def readline
1628
- requireReadable
1629
- raise EOFError, "End of file reached", caller if eof?
1630
- gets
1631
- end
1632
-
1633
- def readlines(sep_string=$/)
1634
- requireReadable
1635
- raise EOFError, "End of file reached", caller if eof?
1636
- rc = []
1637
- until eof
1638
- rc << gets(sep_string)
1639
- end
1640
- rc
1641
- end
1642
-
1643
- def reopen(string, mode=nil)
1644
- if string.is_a?(self.class) then
1645
- raise ArgumentError, "wrong number of arguments (2 for 1)", caller if !mode.nil?
1646
- @relay = string
1647
- instance_eval(%Q{
1648
- class << self
1649
- @@relayMethods.each { |name|
1650
- define_method(name, ObjectSpace._id2ref(#{@relay.object_id}).method(("original_" + name.to_s).to_sym).to_proc)
1651
- }
1652
- end
1653
- })
1654
- else
1655
- raise ArgumentError, "wrong number of arguments (1 for 2)", caller if mode.nil?
1656
- class << self
1657
- @@relayMethods.each { |name|
1658
- alias_method(name, "original_#{name}".to_sym)
1659
- public name
1660
- }
1661
- @relay = nil
1662
- end unless @relay.nil?
1663
- @sio_string = string.to_s
1664
- @mode = mode
1665
- end
1666
- end
1667
-
1668
- def rewind
1669
- @sio_pos = 0
1670
- @sio_lineno = 0
1671
- end
1672
-
1673
- def seek(amount, whence=SEEK_SET)
1674
- if whence == SEEK_CUR then
1675
- offset += @sio_pos
1676
- elsif whence == SEEK_END then
1677
- offset += size
1678
- end
1679
- @sio_pos = offset
1680
- end
1681
-
1682
- def string
1683
- @sio_string
1684
- end
1685
-
1686
- def string=(newstring)
1687
- @sio_string = newstring
1688
- end
1689
-
1690
- def sync
1691
- true
1692
- end
1693
-
1694
- def sync=(boolean)
1695
- boolean
1696
- end
1697
-
1698
- def sysread(length=nil, buffer=nil)
1699
- requireReadable
1700
- raise EOFError, "End of file reached", caller if eof?
1701
- read(length, buffer)
1702
- end
1703
-
1704
- def syswrite(string)
1705
- requireWritable
1706
- addition = "\000" * (@sio_string.length - @sio_pos) + string.to_s
1707
- @sio_string[@sio_pos..(addition.length - 1)] = addition
1708
- @sio_pos += addition.size
1709
- addition.size
1710
- end
1711
-
1712
- #In ruby 1.8.4 truncate differs from the docs in two ways.
1713
- #First, if an integer greater that the length is given then the string is expanded to the new integer
1714
- #length. As this expansion seems to contain junk characters instead of nulls I suspect this may be a
1715
- #flaw in the C code which could cause a core dump if abused/used.
1716
- #Second, the documentation states that truncate returns 0. It returns the integer instead.
1717
- #This implementation follows the documentation in the first instance as I suspect this will be fixed
1718
- #in the C code. In the second instance, it follows the actions of the C code instead of the docs.
1719
- #This was decided as it causes no immedeate harm and this ruby implentation is to be as compatable
1720
- #as possible with the C version. Should the C version change to match the docs the ruby version
1721
- #will be simple to update as well.
1722
- def truncate(integer)
1723
- requireWritable
1724
- raise Errno::EINVAL, "Invalid argument - negative length", caller if integer < 0
1725
- @sio_string[[integer, @sio_string.length].max..-1] = ""
1726
- integer
1727
- end
1728
-
1729
- def ungetc(integer)
1730
- requireWritable
1731
- if @sio_pos > 0 then
1732
- @sio_pos -= 1
1733
- putc(integer)
1734
- @sio_pos -= 1
1735
- end
1736
- end
1737
-
1738
- alias :each_line :each
1739
- alias :eof? :eof
1740
- alias :size :length
1741
- alias :tty? :isatty
1742
- alias :tell :pos
1743
- alias :write :syswrite
1744
-
1745
- protected
1746
- @@relayMethods.each { |name|
1747
- alias_method("original_#{name}".to_sym, name)
1748
- protected "original_#{name}".to_sym
1749
- }
1750
-
1751
- private
1752
-
1753
- def requireReadable
1754
- raise IOError, "not opened for reading", caller[1..-1] if @sio_closed_read
1755
- end
1756
-
1757
- def requireWritable
1758
- raise IOError, "not opened for writing", caller[1..-1] if @sio_closed_write
1759
- end
1760
-
1761
- def requireOpen
1762
- raise IOError, "closed stream", caller[1..-1] if @sio_closed_read && @sio_closed_write
1763
- end
1764
-
1765
- end
1766
- end #--}}}
1767
-
1768
- # rijndael-tables.rb Richard Kernahan <kernighan_rich@rubyforge.org>
1769
- module Crypt #--{{{
1770
- module RijndaelTables
1771
-
1772
- LogTable = [
1773
- 0, 0, 25, 1, 50, 2, 26, 198, 75, 199, 27, 104, 51, 238, 223, 3,
1774
- 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8, 200, 248, 105, 28, 193,
1775
- 125, 194, 29, 181, 249, 185, 39, 106, 77, 228, 166, 114, 154, 201, 9, 120,
1776
- 101, 47, 138, 5, 33, 15, 225, 36, 18, 240, 130, 69, 53, 147, 218, 142,
1777
- 150, 143, 219, 189, 54, 208, 206, 148, 19, 92, 210, 241, 64, 70, 131, 56,
1778
- 102, 221, 253, 48, 191, 6, 139, 98, 179, 37, 226, 152, 34, 136, 145, 16,
1779
- 126, 110, 72, 195, 163, 182, 30, 66, 58, 107, 40, 84, 250, 133, 61, 186,
1780
- 43, 121, 10, 21, 155, 159, 94, 202, 78, 212, 172, 229, 243, 115, 167, 87,
1781
- 175, 88, 168, 80, 244, 234, 214, 116, 79, 174, 233, 213, 231, 230, 173, 232,
1782
- 44, 215, 117, 122, 235, 22, 11, 245, 89, 203, 95, 176, 156, 169, 81, 160,
1783
- 127, 12, 246, 111, 23, 196, 73, 236, 216, 67, 31, 45, 164, 118, 123, 183,
1784
- 204, 187, 62, 90, 251, 96, 177, 134, 59, 82, 161, 108, 170, 85, 41, 157,
1785
- 151, 178, 135, 144, 97, 190, 220, 252, 188, 149, 207, 205, 55, 63, 91, 209,
1786
- 83, 57, 132, 60, 65, 162, 109, 71, 20, 42, 158, 93, 86, 242, 211, 171,
1787
- 68, 17, 146, 217, 35, 32, 46, 137, 180, 124, 184, 38, 119, 153, 227, 165,
1788
- 103, 74, 237, 222, 197, 49, 254, 24, 13, 99, 140, 128, 192, 247, 112, 7
1789
- ]
1790
-
1791
- AlogTable = [
1792
- 1, 3, 5, 15, 17, 51, 85, 255, 26, 46, 114, 150, 161, 248, 19, 53,
1793
- 95, 225, 56, 72, 216, 115, 149, 164, 247, 2, 6, 10, 30, 34, 102, 170,
1794
- 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217, 112, 144, 171, 230, 49,
1795
- 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104, 184, 211, 110, 178, 205,
1796
- 76, 212, 103, 169, 224, 59, 77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
1797
- 131, 158, 185, 208, 107, 189, 220, 127, 129, 152, 179, 206, 73, 219, 118, 154,
1798
- 181, 196, 87, 249, 16, 48, 80, 240, 11, 29, 39, 105, 187, 214, 97, 163,
1799
- 254, 25, 43, 125, 135, 146, 173, 236, 47, 113, 147, 174, 233, 32, 96, 160,
1800
- 251, 22, 58, 78, 210, 109, 183, 194, 93, 231, 50, 86, 250, 21, 63, 65,
1801
- 195, 94, 226, 61, 71, 201, 64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
1802
- 159, 186, 213, 100, 172, 239, 42, 126, 130, 157, 188, 223, 122, 142, 137, 128,
1803
- 155, 182, 193, 88, 232, 35, 101, 175, 234, 37, 111, 177, 200, 67, 197, 84,
1804
- 252, 31, 33, 99, 165, 244, 7, 9, 27, 45, 119, 153, 176, 203, 70, 202,
1805
- 69, 207, 74, 222, 121, 139, 134, 145, 168, 227, 62, 66, 198, 81, 243, 14,
1806
- 18, 54, 90, 238, 41, 123, 141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
1807
- 57, 75, 221, 124, 132, 151, 162, 253, 28, 36, 108, 180, 199, 82, 246, 1
1808
- ]
1809
-
1810
- S = [
1811
- 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
1812
- 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
1813
- 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
1814
- 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
1815
- 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
1816
- 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
1817
- 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
1818
- 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
1819
- 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
1820
- 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
1821
- 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
1822
- 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
1823
- 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
1824
- 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
1825
- 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
1826
- 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22
1827
- ]
1828
-
1829
- Si = [
1830
- 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215, 251,
1831
- 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222, 233, 203,
1832
- 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66, 250, 195, 78,
1833
- 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73, 109, 139, 209, 37,
1834
- 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
1835
- 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70, 87, 167, 141, 157, 132,
1836
- 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88, 5, 184, 179, 69, 6,
1837
- 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1, 19, 138, 107,
1838
- 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230, 115,
1839
- 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
1840
- 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27,
1841
- 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244,
1842
- 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95,
1843
- 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239,
1844
- 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
1845
- 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12, 125,
1846
- ]
1847
-
1848
- IG = [
1849
- [0x0e, 0x09, 0x0d, 0x0b],
1850
- [0x0b, 0x0e, 0x09, 0x0d],
1851
- [0x0d, 0x0b, 0x0e, 0x09],
1852
- [0x09, 0x0d, 0x0b, 0x0e]
1853
- ]
1854
-
1855
- Rcon = [
1856
- 0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
1857
- 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
1858
- 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
1859
- 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
1860
- 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
1861
- ]
1862
-
1863
- Shifts = [
1864
- [
1865
- [0, 0],
1866
- [1, 3],
1867
- [2, 2],
1868
- [3, 1]
1869
- ], [
1870
- [0, 0],
1871
- [1, 5],
1872
- [2, 4],
1873
- [3, 3]
1874
- ], [
1875
- [0, 0],
1876
- [1, 7],
1877
- [3, 5],
1878
- [4, 4]
1879
- ]
1880
- ]
1881
-
1882
- end
1883
- end #--}}}
1884
-
1885
- # rijndael.rb Richard Kernahan <kernighan_rich@rubyforge.org>
1886
- # Adapted from the reference C implementation:
1887
- # rijndael-alg-ref.c v2.2 March 2002
1888
- # Reference ANSI C code
1889
- # authors: Paulo Barreto and Vincent Rijmen
1890
- # This code is placed in the public domain.
1891
- module Crypt #--{{{
1892
- class Rijndael
1893
-
1894
- #require 'crypt/cbc'
1895
- include Crypt::CBC
1896
-
1897
- #require 'crypt/rijndael-tables'
1898
- include Crypt::RijndaelTables
1899
-
1900
-
1901
- def initialize(userKey, keyBits = 256, blockBits = 128)
1902
- case keyBits
1903
- when 128
1904
- @keyWords = 4
1905
- when 192
1906
- @keyWords = 6
1907
- when 256
1908
- @keyWords = 8
1909
- else raise "The key must be 128, 192, or 256 bits long."
1910
- end
1911
-
1912
- case (keyBits >= blockBits) ? keyBits : blockBits
1913
- when 128
1914
- @rounds = 10
1915
- when 192
1916
- @rounds = 12
1917
- when 256
1918
- @rounds = 14
1919
- else raise "The key and block sizes must be 128, 192, or 256 bits long."
1920
- end
1921
-
1922
- case blockBits
1923
- when 128
1924
- @blockSize = 16
1925
- @blockWords = 4
1926
- @shiftIndex = 0
1927
- when 192
1928
- @blockSize = 24
1929
- @blockWords = 6
1930
- @shiftIndex = 1
1931
- when 256
1932
- @blockSize = 32
1933
- @blockWords = 8
1934
- @shiftIndex = 2
1935
- else raise "The block size must be 128, 192, or 256 bits long."
1936
- end
1937
-
1938
- uk = userKey.unpack('C'*userKey.length)
1939
- maxUsefulSizeOfUserKey = (keyBits/8)
1940
- uk = uk[0..maxUsefulSizeOfUserKey-1] # truncate
1941
- padding = 0
1942
- if (userKey.length < keyBits/8)
1943
- shortfallInUserKey = (keyBits/8 - userKey.length)
1944
- shortfallInUserKey.times { uk << padding }
1945
- end
1946
- @key = [[], [], [], []]
1947
- 0.upto(uk.length-1) { |pos|
1948
- @key[pos % 4][pos / 4] = uk[pos]
1949
- }
1950
- @roundKeys = generate_key_schedule(@key, keyBits, blockBits)
1951
- end
1952
-
1953
-
1954
- def block_size
1955
- return(@blockSize) # needed for CBC
1956
- end
1957
-
1958
-
1959
- def mul(a, b)
1960
- if ((a ==0) | (b == 0))
1961
- result = 0
1962
- else
1963
- result = AlogTable[(LogTable[a] + LogTable[b]) % 255]
1964
- end
1965
- return(result)
1966
- end
1967
-
1968
-
1969
- def add_round_key(blockArray, roundKey)
1970
- 0.upto(3) { |i|
1971
- 0.upto(@blockWords) { |j|
1972
- blockArray[i][j] ^= roundKey[i][j]
1973
- }
1974
- }
1975
- return(blockArray)
1976
- end
1977
-
1978
-
1979
- def shift_rows(blockArray, direction)
1980
- tmp = []
1981
- 1.upto(3) { |i| # row zero remains unchanged
1982
- 0.upto(@blockWords-1) { |j|
1983
- tmp[j] = blockArray[i][(j + Shifts[@shiftIndex][i][direction]) % @blockWords]
1984
- }
1985
- 0.upto(@blockWords-1) { |j|
1986
- blockArray[i][j] = tmp[j]
1987
- }
1988
- }
1989
- return(blockArray)
1990
- end
1991
-
1992
-
1993
- def substitution(blockArray, sBox)
1994
- # replace every byte of the input with the byte at that position in the S-box
1995
- 0.upto(3) { |i|
1996
- 0.upto(@blockWords-1) { |j|
1997
- blockArray[i][j] = sBox[blockArray[i][j]]
1998
- }
1999
- }
2000
- return(blockArray)
2001
- end
2002
-
2003
-
2004
- def mix_columns(blockArray)
2005
- mixed = [[], [], [], []]
2006
- 0.upto(@blockWords-1) { |j|
2007
- 0.upto(3) { |i|
2008
- mixed[i][j] = mul(2,blockArray[i][j]) ^
2009
- mul(3,blockArray[(i + 1) % 4][j]) ^
2010
- blockArray[(i + 2) % 4][j] ^
2011
- blockArray[(i + 3) % 4][j]
2012
- }
2013
- }
2014
- return(mixed)
2015
- end
2016
-
2017
-
2018
- def inverse_mix_columns(blockArray)
2019
- unmixed = [[], [], [], []]
2020
- 0.upto(@blockWords-1) { |j|
2021
- 0.upto(3) { |i|
2022
- unmixed[i][j] = mul(0xe, blockArray[i][j]) ^
2023
- mul(0xb, blockArray[(i + 1) % 4][j]) ^
2024
- mul(0xd, blockArray[(i + 2) % 4][j]) ^
2025
- mul(0x9, blockArray[(i + 3) % 4][j])
2026
- }
2027
- }
2028
- return(unmixed)
2029
- end
2030
-
2031
-
2032
- def generate_key_schedule(k, keyBits, blockBits)
2033
- tk = k[0..3][0..@keyWords-1] # using slice to get a copy instead of a reference
2034
- keySched = []
2035
- (@rounds + 1).times { keySched << [[], [], [], []] }
2036
- t = 0
2037
- j = 0
2038
- while ((j < @keyWords) && (t < (@rounds+1)*@blockWords))
2039
- 0.upto(3) { |i|
2040
- keySched[t / @blockWords][i][t % @blockWords] = tk[i][j]
2041
- }
2042
- j += 1
2043
- t += 1
2044
- end
2045
- # while not enough round key material collected, calculate new values
2046
- rconIndex = 0
2047
- while (t < (@rounds+1)*@blockWords)
2048
- 0.upto(3) { |i|
2049
- tk[i][0] ^= S[tk[(i + 1) % 4][@keyWords - 1]]
2050
- }
2051
- tk[0][0] ^= Rcon[rconIndex]
2052
- rconIndex = rconIndex.next
2053
- if (@keyWords != 8)
2054
- 1.upto(@keyWords - 1) { |j|
2055
- 0.upto(3) { |i|
2056
- tk[i][j] ^= tk[i][j-1];
2057
- }
2058
- }
2059
- else
2060
- 1.upto(@keyWords/2 - 1) { |j|
2061
- 0.upto(3) { |i|
2062
- tk[i][j] ^= tk[i][j-1]
2063
- }
2064
- }
2065
- 0.upto(3) { |i|
2066
- tk[i][@keyWords/2] ^= S[tk[i][@keyWords/2 - 1]]
2067
- }
2068
- (@keyWords/2 + 1).upto(@keyWords - 1) { |j|
2069
- 0.upto(3) { |i|
2070
- tk[i][j] ^= tk[i][j-1]
2071
- }
2072
- }
2073
- end
2074
- j = 0
2075
- while ((j < @keyWords) && (t < (@rounds+1) * @blockWords))
2076
- 0.upto(3) { |i|
2077
- keySched[t / @blockWords][i][t % @blockWords] = tk[i][j]
2078
- }
2079
- j += 1
2080
- t += 1
2081
- end
2082
- end
2083
- return(keySched)
2084
- end
2085
-
2086
-
2087
- def encrypt_byte_array(blockArray)
2088
- blockArray = add_round_key(blockArray, @roundKeys[0])
2089
- 1.upto(@rounds - 1) { |round|
2090
- blockArray = substitution(blockArray, S)
2091
- blockArray = shift_rows(blockArray, 0)
2092
- blockArray = mix_columns(blockArray)
2093
- blockArray = add_round_key(blockArray, @roundKeys[round])
2094
- }
2095
- # special round without mix_columns
2096
- blockArray = substitution(blockArray,S)
2097
- blockArray = shift_rows(blockArray,0)
2098
- blockArray = add_round_key(blockArray, @roundKeys[@rounds])
2099
- return(blockArray)
2100
- end
2101
-
2102
-
2103
- def encrypt_block(block)
2104
- raise "block must be #{@blockSize} bytes long" if (block.length() != @blockSize)
2105
- blockArray = [[], [], [], []]
2106
- 0.upto(@blockSize - 1) { |pos|
2107
- blockArray[pos % 4][pos / 4] = block[pos]
2108
- }
2109
- encryptedBlock = encrypt_byte_array(blockArray)
2110
- encrypted = ""
2111
- 0.upto(@blockSize - 1) { |pos|
2112
- encrypted << encryptedBlock[pos % 4][pos / 4]
2113
- }
2114
- return(encrypted)
2115
- end
2116
-
2117
-
2118
- def decrypt_byte_array(blockArray)
2119
- # first special round without inverse_mix_columns
2120
- # add_round_key is an involution - applying it a second time returns the original result
2121
- blockArray = add_round_key(blockArray, @roundKeys[@rounds])
2122
- blockArray = substitution(blockArray,Si) # using inverse S-box
2123
- blockArray = shift_rows(blockArray,1)
2124
- (@rounds-1).downto(1) { |round|
2125
- blockArray = add_round_key(blockArray, @roundKeys[round])
2126
- blockArray = inverse_mix_columns(blockArray)
2127
- blockArray = substitution(blockArray, Si)
2128
- blockArray = shift_rows(blockArray, 1)
2129
- }
2130
- blockArray = add_round_key(blockArray, @roundKeys[0])
2131
- return(blockArray)
2132
- end
2133
-
2134
-
2135
- def decrypt_block(block)
2136
- raise "block must be #{@blockSize} bytes long" if (block.length() != @blockSize)
2137
- blockArray = [[], [], [], []]
2138
- 0.upto(@blockSize - 1) { |pos|
2139
- blockArray[pos % 4][pos / 4] = block[pos]
2140
- }
2141
- decryptedBlock = decrypt_byte_array(blockArray)
2142
- decrypted = ""
2143
- 0.upto(@blockSize - 1) { |pos|
2144
- decrypted << decryptedBlock[pos % 4][pos / 4]
2145
- }
2146
- return(decrypted)
2147
- end
2148
-
2149
-
2150
- end
2151
- end #--}}}
2152
-
2153
- # stringxor.rb Richard Kernahan <kernighan_rich@rubyforge.org>
2154
- module Crypt #--{{{
2155
- module StringXor
2156
-
2157
-
2158
- def ^(aString)
2159
- a = self.unpack('C'*(self.length))
2160
- b = aString.unpack('C'*(aString.length))
2161
- if (b.length < a.length)
2162
- (a.length - b.length).times { b << 0 }
2163
- end
2164
- xor = ""
2165
- 0.upto(a.length-1) { |pos|
2166
- x = a[pos] ^ b[pos]
2167
- xor << x.chr()
2168
- }
2169
- return(xor)
2170
- end
2171
-
2172
-
2173
- end
2174
- end
2175
-
2176
- class String
2177
- include Crypt::StringXor
2178
- end #--}}}
2179
- #--}}}
2180
- }
2181
-
2182
- __END__
2183
- class RaptchaController < ApplicationController
2184
- def index # the image responder
2185
- Raptcha.render self, params
2186
- end
2187
-
2188
- def form # sample on how to use
2189
- render :inline => <<-html
2190
- <html>
2191
- <body>
2192
- <hr>
2193
- <em>valid</em>:#{ Raptcha.valid? params }
2194
- <hr>
2195
- <form method=post>
2196
- #{ Raptcha.input }
2197
- <hr>
2198
- <input type=submit name=submit value=submit />
2199
- <hr>
2200
- <a href="#{ request.request_uri }">new</a>
2201
- </form>
2202
- </body>
2203
- </html>
2204
- html
2205
- end
2206
-
2207
- def inline # does not work in older internet exploders
2208
- render :inline => <<-html
2209
- <html>
2210
- <body>
2211
- <hr>
2212
- <em>valid</em>:#{ Raptcha.valid? params }
2213
- <hr>
2214
- <form method=post>
2215
- #{ Raptcha.input :inline => true }
2216
- <hr>
2217
- <input type=submit name=submit value=submit />
2218
- <hr>
2219
- <a href="#{ request.request_uri }">new</a>
2220
- </form>
2221
- </body>
2222
- </html>
2223
- html
2224
- end
2225
- end