crypt 1.1.3 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -36,7 +36,7 @@ module CBC
36
36
  cryptStream.write(encrypted)
37
37
  chain = encrypted
38
38
  end
39
-
39
+
40
40
  # write the final block
41
41
  # At most block_size()-1 bytes can be part of the message.
42
42
  # That means the final byte can be used to store the number of meaningful
@@ -44,13 +44,13 @@ module CBC
44
44
  block = '' if block.nil?
45
45
  buffer = block.split('')
46
46
  remainingMessageBytes = buffer.length
47
+ # we use 7-bit characters to avoid possible strange behavior on the Mac
47
48
  remainingMessageBytes.upto(block_size()-2) { buffer << rand(128).chr }
48
49
  buffer << remainingMessageBytes.chr
49
50
  block = buffer.join('')
50
51
  block = block ^ chain
51
52
  encrypted = encrypt_block(block)
52
53
  cryptStream.write(encrypted)
53
- chain = encrypted
54
54
  end
55
55
 
56
56
 
@@ -77,7 +77,7 @@ module CBC
77
77
  aFile = File.new(filename, mode)
78
78
  rescue
79
79
  puts "Sorry. There was a problem opening the file <#{filename}>."
80
- aFile.close unless aFile.closed?
80
+ aFile.close() unless aFile.nil?
81
81
  raise
82
82
  end
83
83
  return(aFile)
@@ -85,8 +85,8 @@ module CBC
85
85
 
86
86
 
87
87
  def encrypt_file(plainFilename, cryptFilename)
88
- plainFile = carefully_open_file(plainFilename, 'br')
89
- cryptFile = carefully_open_file(cryptFilename, 'bw+')
88
+ plainFile = carefully_open_file(plainFilename, 'rb')
89
+ cryptFile = carefully_open_file(cryptFilename, 'wb+')
90
90
  encrypt_stream(plainFile, cryptFile)
91
91
  plainFile.close unless plainFile.closed?
92
92
  cryptFile.close unless cryptFile.closed?
@@ -94,8 +94,8 @@ module CBC
94
94
 
95
95
 
96
96
  def decrypt_file(cryptFilename, plainFilename)
97
- cryptFile = carefully_open_file(cryptFilename, 'br')
98
- plainFile = carefully_open_file(plainFilename, 'bw+')
97
+ cryptFile = carefully_open_file(cryptFilename, 'rb')
98
+ plainFile = carefully_open_file(plainFilename, 'wb+')
99
99
  decrypt_stream(cryptFile, plainFile)
100
100
  cryptFile.close unless cryptFile.closed?
101
101
  plainFile.close unless plainFile.closed?
@@ -53,7 +53,7 @@ class IDEA
53
53
  modulus = 0x10001
54
54
  x = x.to_i % USHORT
55
55
  return(x) if (x <= 1)
56
- t1 = 0x10000 / x
56
+ t1 = USHORT / x
57
57
  y = modulus % x
58
58
  if (y == 1)
59
59
  inv = (1 - t1) & 0xFFFF
@@ -76,7 +76,7 @@ class IDEA
76
76
 
77
77
  def generate_encryption_subkeys(key)
78
78
  encrypt_keys = []
79
- encrypt_keys[0..7] = key
79
+ encrypt_keys[0..7] = key.dup
80
80
  8.upto(51) { |i|
81
81
  a = ((i + 1) % 8 > 0) ? (i-7) : (i-15)
82
82
  b = ((i + 2) % 8 < 2) ? (i-14) : (i-6)
@@ -0,0 +1,378 @@
1
+ # Thanks to Binky DaClown who wrote this pure-ruby implementation
2
+ # http://rubyforge.org/projects/prstringio/
3
+ # Apparently CBC does not work well with the C-based stringio
4
+
5
+ module Crypt
6
+ class PureRubyStringIO
7
+
8
+ include Enumerable
9
+
10
+ SEEK_CUR = IO::SEEK_CUR
11
+ SEEK_END = IO::SEEK_END
12
+ SEEK_SET = IO::SEEK_SET
13
+
14
+ @@relayMethods = [:<<, :all?, :any?, :binmode, :close, :close_read, :close_write, :closed?, :closed_read?,
15
+ :closed_write?, :collect, :detect, :each, :each_byte, :each_line, :each_with_index,
16
+ :entries, :eof, :eof?, :fcntl, :fileno, :find, :find_all, :flush, :fsync, :getc, :gets,
17
+ :grep, :include?, :inject, :isatty, :length, :lineno, :lineno=, :map, :max, :member?,
18
+ :min, :partition, :path, :pid, :pos, :pos=, :print, :printf, :putc, :puts, :read,
19
+ :readchar, :readline, :readlines, :reject, :rewind, :seek, :select, :size, :sort,
20
+ :sort_by, :string, :string=, :sync, :sync=, :sysread, :syswrite, :tell, :truncate, :tty?,
21
+ :ungetc, :write, :zip]
22
+
23
+ def self.open(string="", mode="r+")
24
+ if block_given? then
25
+ sio = new(string, mode)
26
+ rc = yield(sio)
27
+ sio.close
28
+ rc
29
+ else
30
+ new(string, mode)
31
+ end
32
+ end
33
+
34
+ def <<(obj)
35
+ requireWritable
36
+ write obj
37
+ self
38
+ end
39
+
40
+ def binmode
41
+ self
42
+ end
43
+
44
+ def close
45
+ requireOpen
46
+ @sio_closed_read = true
47
+ @sio_closed_write = true
48
+ self
49
+ end
50
+
51
+ def close_read
52
+ raise IOError, "closing non-duplex IO for reading", caller if closed_read?
53
+ @sio_closed_read = true
54
+ self
55
+ end
56
+
57
+ def close_write
58
+ raise IOError, "closing non-duplex IO for writing", caller if closed_write?
59
+ @sio_closed_read = true
60
+ self
61
+ end
62
+
63
+ def closed?
64
+ closed_read? && closed_write?
65
+ end
66
+
67
+ def closed_read?
68
+ @sio_closed_read
69
+ end
70
+
71
+ def closed_write?
72
+ @sio_closed_write
73
+ end
74
+
75
+ def each(sep_string=$/, &block)
76
+ requireReadable
77
+ @sio_string.each(sep_string, &block)
78
+ @sio_pos = @sio_string.length
79
+ end
80
+
81
+ def each_byte(&block)
82
+ requireReadable
83
+ @sio_string.each_byte(&block)
84
+ @sio_pos = @sio_string.length
85
+ end
86
+
87
+ def eof
88
+ requireReadable { @sio_pos >= @sio_string.length }
89
+ end
90
+
91
+ def fcntl(integer_cmd, arg)
92
+ raise NotImplementedError, "The fcntl() function is unimplemented on this machine", caller
93
+ end
94
+
95
+ def fileno
96
+ nil
97
+ end
98
+
99
+ def flush
100
+ self
101
+ end
102
+
103
+ def fsync
104
+ 0
105
+ end
106
+
107
+ def getc
108
+ requireReadable
109
+ char = @sio_string[@sio_pos]
110
+ @sio_pos += 1 unless char.nil?
111
+ char
112
+ end
113
+
114
+ def gets(sep_string=$/)
115
+ requireReadable
116
+ @sio_lineno += 1
117
+ pstart = @sio_pos
118
+ @sio_pos = @sio_string.index(sep_string, @sio_pos) || [@sio_string.length, @sio_pos].max
119
+ @sio_string[pstart..@sio_pos]
120
+ end
121
+
122
+ def initialize(string="", mode="r+")
123
+ @sio_string = string.to_s
124
+ @sio_lineno = 0
125
+ @mode = mode
126
+ @relay = nil
127
+ case mode.delete("b")
128
+ when "r"
129
+ @sio_closed_read = false
130
+ @sio_closed_write = true
131
+ @sio_pos = 0
132
+ when "r+"
133
+ @sio_closed_read = false
134
+ @sio_closed_write = false
135
+ @sio_pos = 0
136
+ when "w"
137
+ @sio_closed_read = true
138
+ @sio_closed_write = false
139
+ @sio_pos = 0
140
+ @sio_string.replace("")
141
+ when "w+"
142
+ @sio_closed_read = false
143
+ @sio_closed_write = false
144
+ @sio_pos = 0
145
+ @sio_string.replace("")
146
+ when "a"
147
+ @sio_closed_read = true
148
+ @sio_closed_write = false
149
+ @sio_pos = @sio_string.length
150
+ when "a+"
151
+ @sio_closed_read = false
152
+ @sio_closed_write = false
153
+ @sio_pos = @sio_string.length
154
+ else
155
+ raise ArgumentError, "illegal access mode #{mode}", caller
156
+ end
157
+ end
158
+
159
+ def isatty
160
+ flase
161
+ end
162
+
163
+ def length
164
+ @sio_string.length
165
+ end
166
+
167
+ def lineno
168
+ @sio_lineno
169
+ end
170
+
171
+ def lineno=(integer)
172
+ @sio_lineno = integer
173
+ end
174
+
175
+ def path
176
+ nil
177
+ end
178
+
179
+ def pid
180
+ nil
181
+ end
182
+
183
+ def pos
184
+ @sio_pos
185
+ end
186
+
187
+ def pos=(integer)
188
+ raise Errno::EINVAL, "Invalid argument", caller if integer < 0
189
+ @sio_pos = integer
190
+ end
191
+
192
+ def print(*args)
193
+ requireWritable
194
+ args.unshift($_) if args.empty
195
+ args.each { |obj| write(obj) }
196
+ write($\) unless $\.nil?
197
+ nil
198
+ end
199
+
200
+ def printf(format_string, *args)
201
+ requireWritable
202
+ write format(format_string, *args)
203
+ nil
204
+ end
205
+
206
+ def putc(obj)
207
+ requireWritable
208
+ write(obj.is_a?(Numeric) ? sprintf("%c", obj) : obj.to_s[0..0])
209
+ obj
210
+ end
211
+
212
+ def puts(*args)
213
+ requireWritable
214
+ args.unshift("") if args.empty?
215
+ args.each { |obj|
216
+ write obj
217
+ write $/
218
+ }
219
+ nil
220
+ end
221
+
222
+ def read(length=nil, buffer=nil)
223
+ requireReadable
224
+ len = length || [@sio_string.length - @sio_pos, 0].max
225
+ raise ArgumentError, "negative length #{len} given", caller if len < 0
226
+ buffer ||= ""
227
+ pstart = @sio_pos
228
+ @sio_pos += len
229
+ buffer.replace(@sio_string[pstart..@sio_pos])
230
+ buffer.empty? && !length.nil? ? nil : buffer
231
+ end
232
+
233
+ def readchar
234
+ requireReadable
235
+ raise EOFError, "End of file reached", caller if eof?
236
+ getc
237
+ end
238
+
239
+ def readline
240
+ requireReadable
241
+ raise EOFError, "End of file reached", caller if eof?
242
+ gets
243
+ end
244
+
245
+ def readlines(sep_string=$/)
246
+ requireReadable
247
+ raise EOFError, "End of file reached", caller if eof?
248
+ rc = []
249
+ until eof
250
+ rc << gets(sep_string)
251
+ end
252
+ rc
253
+ end
254
+
255
+ def reopen(string, mode=nil)
256
+ if string.is_a?(self.class) then
257
+ raise ArgumentError, "wrong number of arguments (2 for 1)", caller if !mode.nil?
258
+ @relay = string
259
+ instance_eval(%Q{
260
+ class << self
261
+ @@relayMethods.each { |name|
262
+ define_method(name, ObjectSpace._id2ref(#{@relay.object_id}).method(("original_" + name.to_s).to_sym).to_proc)
263
+ }
264
+ end
265
+ })
266
+ else
267
+ raise ArgumentError, "wrong number of arguments (1 for 2)", caller if mode.nil?
268
+ class << self
269
+ @@relayMethods.each { |name|
270
+ alias_method(name, "original_#{name}".to_sym)
271
+ public name
272
+ }
273
+ @relay = nil
274
+ end unless @relay.nil?
275
+ @sio_string = string.to_s
276
+ @mode = mode
277
+ end
278
+ end
279
+
280
+ def rewind
281
+ @sio_pos = 0
282
+ @sio_lineno = 0
283
+ end
284
+
285
+ def seek(amount, whence=SEEK_SET)
286
+ if whence == SEEK_CUR then
287
+ offset += @sio_pos
288
+ elsif whence == SEEK_END then
289
+ offset += size
290
+ end
291
+ @sio_pos = offset
292
+ end
293
+
294
+ def string
295
+ @sio_string
296
+ end
297
+
298
+ def string=(newstring)
299
+ @sio_string = newstring
300
+ end
301
+
302
+ def sync
303
+ true
304
+ end
305
+
306
+ def sync=(boolean)
307
+ boolean
308
+ end
309
+
310
+ def sysread(length=nil, buffer=nil)
311
+ requireReadable
312
+ raise EOFError, "End of file reached", caller if eof?
313
+ read(length, buffer)
314
+ end
315
+
316
+ def syswrite(string)
317
+ requireWritable
318
+ addition = "\000" * (@sio_string.length - @sio_pos) + string.to_s
319
+ @sio_string[@sio_pos..(addition.length - 1)] = addition
320
+ @sio_pos += addition.size
321
+ addition.size
322
+ end
323
+
324
+ #In ruby 1.8.4 truncate differs from the docs in two ways.
325
+ #First, if an integer greater that the length is given then the string is expanded to the new integer
326
+ #length. As this expansion seems to contain junk characters instead of nulls I suspect this may be a
327
+ #flaw in the C code which could cause a core dump if abused/used.
328
+ #Second, the documentation states that truncate returns 0. It returns the integer instead.
329
+ #This implementation follows the documentation in the first instance as I suspect this will be fixed
330
+ #in the C code. In the second instance, it follows the actions of the C code instead of the docs.
331
+ #This was decided as it causes no immedeate harm and this ruby implentation is to be as compatable
332
+ #as possible with the C version. Should the C version change to match the docs the ruby version
333
+ #will be simple to update as well.
334
+ def truncate(integer)
335
+ requireWritable
336
+ raise Errno::EINVAL, "Invalid argument - negative length", caller if integer < 0
337
+ @sio_string[[integer, @sio_string.length].max..-1] = ""
338
+ integer
339
+ end
340
+
341
+ def ungetc(integer)
342
+ requireWritable
343
+ if @sio_pos > 0 then
344
+ @sio_pos -= 1
345
+ putc(integer)
346
+ @sio_pos -= 1
347
+ end
348
+ end
349
+
350
+ alias :each_line :each
351
+ alias :eof? :eof
352
+ alias :size :length
353
+ alias :tty? :isatty
354
+ alias :tell :pos
355
+ alias :write :syswrite
356
+
357
+ protected
358
+ @@relayMethods.each { |name|
359
+ alias_method("original_#{name}".to_sym, name)
360
+ protected "original_#{name}".to_sym
361
+ }
362
+
363
+ private
364
+
365
+ def requireReadable
366
+ raise IOError, "not opened for reading", caller[1..-1] if @sio_closed_read
367
+ end
368
+
369
+ def requireWritable
370
+ raise IOError, "not opened for writing", caller[1..-1] if @sio_closed_write
371
+ end
372
+
373
+ def requireOpen
374
+ raise IOError, "closed stream", caller[1..-1] if @sio_closed_read && @sio_closed_write
375
+ end
376
+
377
+ end
378
+ end
@@ -0,0 +1,61 @@
1
+ # break-idea.rb Richard Kernahan <kernighan_rich@rubyforge.org>
2
+ # prove that IDEA is broken and try to find out why
3
+
4
+ require 'crypt/idea'
5
+ require 'crypt/blowfish'
6
+
7
+ # generate evidence for defect in IDEA implementation
8
+ # idea_en = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::ENCRYPT)
9
+ # idea_de = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::DECRYPT)
10
+ # srand()
11
+ # puts "Finding pairs that fail to encrypt:"
12
+ # while(true)
13
+ # origL = rand(Crypt::IDEA::ULONG)
14
+ # origR = rand(Crypt::IDEA::ULONG)
15
+ # cl, cr = idea_en.crypt_pair(origL, origR)
16
+ # dl, dr = idea_de.crypt_pair(cl, cr)
17
+ # if ((origL != dl) | (origR != dr))
18
+ # cl, cr = idea_en.crypt_pair(origL, origR)
19
+ # dl, dr = idea_de.crypt_pair(cl, cr)
20
+ # if ((origL != dl) | (origR != dr))
21
+ # printf("[0x%-9x , 0x%-9x]\n", origL, origR)
22
+ # $stdout.flush()
23
+ # end
24
+ # end
25
+ # end
26
+ # fatalPairs = [
27
+ # [0x5bb809a4, 0x804d4aba ],
28
+ # [0xead99b1 , 0xf64a62dd ],
29
+ # [0x50d72345, 0x4f6036d9 ],
30
+ # [0x32d41b94, 0x796a2eb5 ],
31
+ # [0x5d8a606e, 0x33befad ],
32
+ # [0x87b9dd21, 0xf5d9e7ce ],
33
+ # [0xd96be22c, 0x68fe08c9 ],
34
+ # [0x452131e8, 0xe687bd5 ],
35
+ # [0x827d9308, 0x512ace3d ],
36
+ # [0x5f0931d1, 0xb3b5c5c1 ],
37
+ # [0xd6dc1475, 0xf8964e8b ],
38
+ # [0xb7d7bba6, 0x8b8652e9 ],
39
+ # [0x2f42b24b, 0x6a889e95 ],
40
+ # [0x4e6eaebb, 0x99816f1 ]
41
+ # ]
42
+ # fatalPairs.each { |pair|
43
+ # origL, origR = pair
44
+ # cl, cr = idea_en.crypt_pair(origL, origR)
45
+ # dl, dr = idea_de.crypt_pair(cl, cr)
46
+ # if ((origL != dl) | (origR != dr))
47
+ # puts "still broken"
48
+ # end
49
+ # }
50
+ #idea = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::ENCRYPT)
51
+ #(-3..0x10003).each { |a|
52
+ # inv = idea.mulInv(a)
53
+ # product = idea.mul(a, inv)
54
+ # if product != 1
55
+ # puts "a=#{a} inv=#{inv} mul(a,inv)=#{product}"
56
+ # $stdout.flush()
57
+ # end
58
+ #}
59
+
60
+
61
+
@@ -0,0 +1,16 @@
1
+ # run the crypt website
2
+
3
+ require 'webrick'
4
+ include WEBrick
5
+
6
+ serverConfig = {
7
+ :Port => 80,
8
+ :Logger => WEBrick::Log.new($stderr, WEBrick::Log::ERROR),
9
+ :AccessLog => [[$stderr, WEBrick::AccessLog::COMBINED_LOG_FORMAT]]
10
+ }
11
+ server = WEBrick::HTTPServer.new(serverConfig)
12
+ server.mount("/", HTTPServlet::FileHandler, "C:/workspace/Crypt/site/", {:FancyIndexing => true})
13
+ server.mount("/crypt", HTTPServlet::FileHandler, "C:/workspace/Crypt/crypt/", {:FancyIndexing => true})
14
+
15
+ server.start
16
+
@@ -0,0 +1,89 @@
1
+ # testblowfish.rb bryllig
2
+
3
+ require 'test/unit'
4
+ require 'crypt/blowfish'
5
+ require 'crypt/cbc'
6
+ require 'fileutils'
7
+
8
+ class TestBlowfish < Test::Unit::TestCase
9
+
10
+ def setup
11
+ @bf = Crypt::Blowfish.new("Who is John Galt?") # Schneier's test key
12
+ end
13
+
14
+ def teardown
15
+ end
16
+
17
+ def test_block_size
18
+ assert_equal(8, @bf.block_size(), "Wrong block size")
19
+ end
20
+
21
+ def test_initialize
22
+ assert_raise(RuntimeError) {
23
+ b0 = Crypt::Blowfish.new("")
24
+ }
25
+ assert_nothing_raised() {
26
+ b1 = Crypt::Blowfish.new("1")
27
+ }
28
+ assert_nothing_raised() {
29
+ b56 = Crypt::Blowfish.new("1"*56)
30
+ }
31
+ assert_raise(RuntimeError) {
32
+ b57 = Crypt::Blowfish.new("1"*57)
33
+ }
34
+ end
35
+
36
+ def test_pair
37
+ bf = Crypt::Blowfish.new("Who is John Galt?")
38
+ orig_l, orig_r = [0xfedcba98, 0x76543210]
39
+ l, r = bf.encrypt_pair(orig_l, orig_r)
40
+ assert_equal(0xcc91732b, l)
41
+ assert_equal(0x8022f684, r)
42
+ l, r = bf.decrypt_pair(l, r)
43
+ assert_equal(orig_l, l)
44
+ assert_equal(orig_r, r)
45
+ end
46
+
47
+ def test_block
48
+ bf = Crypt::Blowfish.new("Who is John Galt?")
49
+ block = "norandom"
50
+ encryptedBlock = bf.encrypt_block(block)
51
+ assert_equal("\236\353k\321&Q\"\220", encryptedBlock)
52
+ decryptedBlock = bf.decrypt_block(encryptedBlock)
53
+ assert_equal(block, decryptedBlock)
54
+ end
55
+
56
+ def test_string
57
+ length = 30 + rand(26)
58
+ userkey = ""
59
+ length.times { userkey << rand(256).chr }
60
+ bf = Crypt::Blowfish.new(userkey)
61
+ string = "This is a string which is not a multiple of 8 characters long"
62
+ encryptedString = bf.encrypt_string(string)
63
+ decryptedString = bf.decrypt_string(encryptedString)
64
+ assert_equal(string, decryptedString)
65
+ secondstring = "This is another string to check repetitive use."
66
+ encryptedString = bf.encrypt_string(secondstring)
67
+ decryptedString = bf.decrypt_string(encryptedString)
68
+ assert_equal(secondstring, decryptedString)
69
+
70
+ end
71
+
72
+ def test_file
73
+ plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
74
+ plainFile = File.new('plain.txt', 'wb+')
75
+ plainFile.puts(plainText)
76
+ plainFile.close()
77
+ bf = Crypt::Blowfish.new("Who is John Galt?")
78
+ bf.encrypt_file('plain.txt', 'crypt.txt')
79
+ bf.decrypt_file('crypt.txt', 'decrypt.txt')
80
+ decryptFile = File.new('decrypt.txt', 'rb')
81
+ decryptText = decryptFile.readlines().join('').chomp()
82
+ decryptFile.close()
83
+ assert_equal(plainText, decryptText)
84
+ FileUtils.rm('plain.txt')
85
+ FileUtils.rm('crypt.txt')
86
+ FileUtils.rm('decrypt.txt')
87
+ end
88
+
89
+ end
@@ -0,0 +1,75 @@
1
+ require 'test/unit'
2
+ require 'crypt/gost'
3
+ require 'fileutils'
4
+
5
+ class TestGost < Test::Unit::TestCase
6
+
7
+ def setup
8
+ end
9
+
10
+ def teardown
11
+ end
12
+
13
+ def test_init
14
+ assert_nothing_raised(RuntimeError) {
15
+ gost = Crypt::Gost.new("Whatever happened to Yuri Gagarin?")
16
+ }
17
+ assert_nothing_raised(RuntimeError) {
18
+ gost = Crypt::Gost.new("Whatever happened to Yuri?")
19
+ }
20
+ end
21
+
22
+ def test_block_size
23
+ gost = Crypt::Gost.new("Whatever happened to Yuri?")
24
+ assert_equal(8, gost.block_size(), "Wrong block size")
25
+ end
26
+
27
+ def test_pair
28
+ gost = Crypt::Gost.new("Whatever happened to Yuri?")
29
+ orig_l, orig_r = [0xfedcba98, 0x76543210]
30
+ l, r = gost.encrypt_pair(orig_l, orig_r)
31
+ assert_equal(0xaefaf8f4, l)
32
+ assert_equal(0xe24891b0, r)
33
+ l, r = gost.decrypt_pair(l, r)
34
+ assert_equal(orig_l, l)
35
+ assert_equal(orig_r, r)
36
+ end
37
+
38
+ def test_block
39
+ gost = Crypt::Gost.new("Whatever happened to Yuri?")
40
+ block = "norandom"
41
+ encryptedBlock = gost.encrypt_block(block)
42
+ assert_equal(".Vy\377\005\e3`", encryptedBlock)
43
+ decryptedBlock = gost.decrypt_block(encryptedBlock)
44
+ assert_equal(block, decryptedBlock)
45
+ end
46
+
47
+ def test_string
48
+ length = 25 + rand(12)
49
+ userkey = ""
50
+ length.times { userkey << rand(256).chr }
51
+ gost = Crypt::Gost.new(userkey)
52
+ string = "This is a string which is not a multiple of 8 characters long"
53
+ encryptedString = gost.encrypt_string(string)
54
+ decryptedString = gost.decrypt_string(encryptedString)
55
+ assert_equal(string, decryptedString)
56
+ end
57
+
58
+ def test_file
59
+ plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
60
+ plainFile = File.new('plain.txt', 'wb+')
61
+ plainFile.puts(plainText)
62
+ plainFile.close()
63
+ gost = Crypt::Gost.new("Whatever happened to Yuri?")
64
+ gost.encrypt_file('plain.txt', 'crypt.txt')
65
+ gost.decrypt_file('crypt.txt', 'decrypt.txt')
66
+ decryptFile = File.new('decrypt.txt', 'rb')
67
+ decryptText = decryptFile.readlines().join('').chomp()
68
+ decryptFile.close()
69
+ assert_equal(plainText, decryptText)
70
+ FileUtils.rm('plain.txt')
71
+ FileUtils.rm('crypt.txt')
72
+ FileUtils.rm('decrypt.txt')
73
+ end
74
+
75
+ end
@@ -0,0 +1,76 @@
1
+ require 'test/unit'
2
+ require 'crypt/idea'
3
+ require 'fileutils'
4
+
5
+ class TestIdea < Test::Unit::TestCase
6
+
7
+ def setup
8
+ end
9
+
10
+ def teardown
11
+ end
12
+
13
+ def test_init
14
+ assert_nothing_raised(RuntimeError) {
15
+ idea_en = Crypt::IDEA.new("Who was John Galt and where's my breakfast?", Crypt::IDEA::ENCRYPT)
16
+ }
17
+ end
18
+
19
+ def test_block_size
20
+ idea_en = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::ENCRYPT)
21
+ assert_equal(8, idea_en.block_size(), "Wrong block size")
22
+ end
23
+
24
+ def test_pair
25
+ idea_en = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::ENCRYPT)
26
+ orig_l, orig_r = [0xfedcba98, 0x76543210]
27
+ l, r = idea_en.crypt_pair(orig_l, orig_r)
28
+ assert_equal(0x05627e79, l)
29
+ assert_equal(0x69476521, r)
30
+ idea_de = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::DECRYPT)
31
+ l, r = idea_de.crypt_pair(l, r)
32
+ assert_equal(orig_l, l)
33
+ assert_equal(orig_r, r)
34
+ end
35
+
36
+ def test_block
37
+ idea_en = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::ENCRYPT)
38
+ block = "norandom"
39
+ encryptedBlock = idea_en.encrypt_block(block)
40
+ assert_equal("\235\003\326u\001\330\361\t", encryptedBlock)
41
+ idea_de = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::DECRYPT)
42
+ decryptedBlock = idea_de.decrypt_block(encryptedBlock)
43
+ assert_equal(block, decryptedBlock)
44
+ end
45
+
46
+ def test_string
47
+ length = 25 + rand(12)
48
+ userkey = ""
49
+ length.times { userkey << rand(256).chr }
50
+ idea_en = Crypt::IDEA.new(userkey, Crypt::IDEA::ENCRYPT)
51
+ string = "This is a string which is not a multiple of 8 characters long"
52
+ encryptedString = idea_en.encrypt_string(string)
53
+ idea_de = Crypt::IDEA.new(userkey, Crypt::IDEA::DECRYPT)
54
+ decryptedString = idea_de.decrypt_string(encryptedString)
55
+ assert_equal(string, decryptedString)
56
+ end
57
+
58
+ def test_file
59
+ plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
60
+ plainFile = File.new('plain.txt', 'wb+')
61
+ plainFile.puts(plainText)
62
+ plainFile.close()
63
+ idea_en = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::ENCRYPT)
64
+ idea_en.encrypt_file('plain.txt', 'crypt.txt')
65
+ idea_de = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::DECRYPT)
66
+ idea_de.decrypt_file('crypt.txt', 'decrypt.txt')
67
+ decryptFile = File.new('decrypt.txt', 'rb')
68
+ decryptText = decryptFile.readlines().join('').chomp()
69
+ decryptFile.close()
70
+ assert_equal(plainText, decryptText)
71
+ FileUtils.rm('plain.txt')
72
+ FileUtils.rm('crypt.txt')
73
+ FileUtils.rm('decrypt.txt')
74
+ end
75
+
76
+ end
@@ -0,0 +1,67 @@
1
+ require 'test/unit'
2
+ require 'crypt/rijndael'
3
+ require 'fileutils'
4
+
5
+ class TestRijndael < Test::Unit::TestCase
6
+
7
+ def setup
8
+ end
9
+
10
+ def teardown
11
+ end
12
+
13
+ def test_init
14
+ assert_raise(RuntimeError) {
15
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 64)
16
+ }
17
+ assert_raise(RuntimeError) {
18
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 64)
19
+ }
20
+ end
21
+
22
+ def test_block_size
23
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 256)
24
+ assert_equal(32, rijndael.block_size)
25
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 256, 128)
26
+ assert_equal(16, rijndael.block_size)
27
+ end
28
+
29
+ def test_block
30
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 128)
31
+ block = "\341q\214NIj\023u\343\330s\323\354$g\277"
32
+ encryptedBlock = rijndael.encrypt_block(block)
33
+ assert_equal("\024\246^\332T\323x`\323yB\352\2159\212R", encryptedBlock)
34
+ decryptedBlock = rijndael.decrypt_block(encryptedBlock)
35
+ assert_equal(block, decryptedBlock)
36
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 256)
37
+ assert_raise(RuntimeError) {
38
+ encryptedBlock = rijndael.encrypt_block(block)
39
+ }
40
+ end
41
+
42
+ def test_string
43
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?")
44
+ string = "This is a string which is not a multiple of 8 characters long"
45
+ encryptedString = rijndael.encrypt_string(string)
46
+ decryptedString = rijndael.decrypt_string(encryptedString)
47
+ assert_equal(string, decryptedString)
48
+ end
49
+
50
+ def test_file
51
+ plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
52
+ plainFile = File.new('plain.txt', 'wb+')
53
+ plainFile.puts(plainText)
54
+ plainFile.close()
55
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?")
56
+ rijndael.encrypt_file('plain.txt', 'crypt.txt')
57
+ rijndael.decrypt_file('crypt.txt', 'decrypt.txt')
58
+ decryptFile = File.new('decrypt.txt', 'rb')
59
+ decryptText = decryptFile.readlines().join('').chomp()
60
+ decryptFile.close()
61
+ assert_equal(plainText, decryptText)
62
+ FileUtils.rm('plain.txt')
63
+ FileUtils.rm('crypt.txt')
64
+ FileUtils.rm('decrypt.txt')
65
+ end
66
+
67
+ end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.10
3
3
  specification_version: 1
4
4
  name: crypt
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.1.3
7
- date: 2006-08-05
6
+ version: 1.1.4
7
+ date: 2006-08-06
8
8
  summary: "The Crypt library is a pure-ruby implementation of a number of popular
9
9
  encryption algorithms. Block cyphers currently include Blowfish, GOST, IDEA, and
10
10
  Rijndael (AES). Cypher Block Chaining (CBC) has been implemented. Twofish,
@@ -36,9 +36,16 @@ files:
36
36
  - crypt/gost.rb
37
37
  - crypt/idea.rb
38
38
  - crypt/noise.rb
39
+ - crypt/purerubystringio.rb
39
40
  - crypt/rijndael-tables.rb
40
41
  - crypt/rijndael.rb
41
42
  - crypt/stringxor.rb
43
+ - test/break-idea.rb
44
+ - test/devServer.rb
45
+ - test/test-blowfish.rb
46
+ - test/test-gost.rb
47
+ - test/test-idea.rb
48
+ - test/test-rijndael.rb
42
49
  test_files: []
43
50
  rdoc_options: []
44
51
  extra_rdoc_files: []