crypt 2.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 52adac97c724e6cda38884007042b2eda55fc299
4
- data.tar.gz: a017aaec965e38ea808116495ddc84ed94048f94
3
+ metadata.gz: c26c671cabb4969a940b582444ad370d623e18b2
4
+ data.tar.gz: db5d9d98b3519d5b7ae97098db35946ef612f192
5
5
  SHA512:
6
- metadata.gz: 97bb5b0bed207146235d0285d78c6435cee219544eee140c8c9aa86b7d70b7437ad657d930f44a3cdaa3face1ef937f62ff16e58e6dd58daa3b84a088714050b
7
- data.tar.gz: 51fec804a2c85eba54a33c81ee4b980636cb9a8e6015c033260acc26812eac511d99f569f13f7802b776038e0bb760cf71ad3f4d8d73ecd1b14e49a9960e79ce
6
+ metadata.gz: 042e0eaa49184aff6932e6697ec475dec5592d1a55c9c34444e4ebabbc5bcbdacb0ad6b07cb2cad4b2e16490a0ede0955b143c815e4e43b81d78e6d93ddae609
7
+ data.tar.gz: 9250d375de4633729a07357d5489497cd92d0f72994882f3833e01ab2aff8dd0e64942a6a918fae9b180cbfca753348e9484529c8092dcc63564276c84f95f09
@@ -1,5 +1,61 @@
1
- # blowfish-tables.rb Richard Kernahan <kernighan_rich@rubyforge.org>
2
-
1
+ #The Crypt library is a pure-ruby implementation of a number of popular encryption algorithms.
2
+ #Block cyphers currently available include Blowfish, GOST, IDEA, and Rijndael (AES).
3
+ #Cypher Block Chaining (CBC) has been implemented.
4
+ #
5
+ #Crypt is written entirely in ruby so deployment is simple - no platform concerns,
6
+ #no library dependencies, nothing to compile.
7
+ #
8
+ #Performance is what you would expect from a pure-ruby implementation: it is adequate for shorter messages
9
+ #but I wouldn't try to encrypt my whole disk with it. If performance is critical then you might want to try
10
+ #ezcrypto's (http://ezcrypto.rubyforge.org) interface to OpenSSL.
11
+ #
12
+ #v.2.2.0 released 23 Sep 2015 fixes a defect in IDEA and replaces tests with specs.
13
+ #
14
+ # require 'crypt/blowfish'
15
+ # blowfish = Crypt::Blowfish.new("A key up to 56 bytes long")
16
+ # plainBlock = "ABCD1234"
17
+ # encryptedBlock = blowfish.encrypt_block(plainBlock)
18
+ # decryptedBlock = blowfish.decrypt_block(encryptedBlock)
19
+ # string = "This is a string which is not a multiple of 8 characters long"
20
+ # encryptedString = bf.encrypt_string(string)
21
+ # decryptedString = bf.decrypt_string(encryptedString)
22
+ # bf.encrypt_file('plain.txt', 'crypt.txt')
23
+ # bf.decrypt_file('crypt.txt', 'decrypt.txt')
24
+ #
25
+ # require 'crypt/gost'
26
+ # # a key shorter than 32 bytes will be padded out with zeroes
27
+ # gost = Crypt::Gost.new("This is a contrived 32 byte key!")
28
+ # plainBlock = "ABCD1234"
29
+ # encryptedBlock = gost.encrypt_block(plainBlock)
30
+ # decryptedBlock = gost.decrypt_block(encryptedBlock)
31
+ #
32
+ # require 'crypt/idea'
33
+ # idea = Crypt::IDEA.new("A key up to 56 bytes long")
34
+ # plainBlock = "ABCD1234"
35
+ # encryptedBlock = idea.encrypt_block(plainBlock)
36
+ # decryptedBlock = idea.decrypt_block(encryptedBlock)
37
+ #
38
+ # require 'crypt/rijndael'
39
+ # rijndael = Crypt::Rijndael.new("A key 16, 24, or 32 bytes length")
40
+ # plainBlock = "ABCDEFGH12345678"
41
+ # encryptedBlock = rijndael.encrypt_block(plainBlock)
42
+ # decryptedBlock = rijndael.decrypt_block(encryptedBlock)
43
+ #
44
+ #Cipher-block chaining (CBC) is supported for each algorithm:
45
+ #
46
+ # blowfish = Crypt::Blowfish.new("A sample key better than this one")
47
+ # blowfish.encrypt_file('plain.txt', 'crypt.txt')
48
+ # blowfish.decrypt_file('crypt.txt', 'plain.txt')
49
+ #
50
+ #You can also read from a plain text stream,
51
+ #encrypt and write to an encrypted output stream, or treat a string as a stream:
52
+ #
53
+ # f = File.new('plain.txt', 'r')
54
+ # g = TCPSocket.new('encrypted.example.com', 2222)
55
+ # blowfish.encrypt_stream(f, g)
56
+ #
57
+ # plainText = "This is plain text."
58
+ # encrypted = blowfish.encrypt_string(plainText)
3
59
  module Crypt
4
60
  module BlowfishTables
5
61
 
@@ -187,4 +243,4 @@ module BlowfishTables
187
243
 
188
244
 
189
245
  end
190
- end
246
+ end
@@ -1,9 +1,8 @@
1
- # blowfish.rb Richard Kernahan <kernighan_rich@rubyforge.org>
1
+ module Crypt
2
+ # blowfish.rb Richard Kernahan
2
3
  #
3
4
  # Blowfish algorithm by Bruce Schneider
4
5
  # Ported by Richard Kernahan from the reference C code
5
-
6
- module Crypt
7
6
  class Blowfish
8
7
 
9
8
  require 'crypt/cbc'
@@ -1,6 +1,6 @@
1
- # cbc.rb Richard Kernahan <kernighan_rich@rubyforge.org>
2
-
3
1
  module Crypt
2
+
3
+ # cbc.rb Richard Kernahan
4
4
  module CBC
5
5
 
6
6
  require 'stringio'
@@ -1,9 +1,8 @@
1
+ module Crypt
1
2
  # gost.rb
2
- # Adapted by Richard Kernahan <kernighan_rich@rubyforge.org>
3
+ # Adapted by Richard Kernahan
3
4
  # from C++ code written by Wei Dai
4
5
  # of the Crypto++ project http://www.eskimo.com/~weidai/cryptlib.html
5
-
6
- module Crypt
7
6
  class Gost
8
7
 
9
8
  require 'crypt/cbc'
@@ -137,4 +136,4 @@ class Gost
137
136
 
138
137
 
139
138
  end
140
- end
139
+ end
@@ -1,10 +1,9 @@
1
- # idea.rb Richard Kernahan <kernighan_rich@rubyforge.org>
1
+ module Crypt
2
+ # idea.rb Richard Kernahan
2
3
 
3
4
  # IDEA (International Data Encryption Algorithm) by
4
- # Xuejia Lai and James Massey (1992). Refer to license info at end.
5
- # Ported by Richard Kernahan 2005
5
+ # Xuejia Lai and James Massey (1992). Ported by Richard Kernahan 2005
6
6
 
7
- module Crypt
8
7
  class IDEA
9
8
 
10
9
  require 'crypt/cbc'
@@ -12,24 +11,23 @@ class IDEA
12
11
 
13
12
  require 'digest/md5'
14
13
 
15
- ULONG = 0x100000000
16
14
  USHORT = 0x10000
17
15
 
18
16
  ENCRYPT = 0
19
17
  DECRYPT = 1
20
-
18
+
19
+ attr_accessor(:subkeys)
21
20
 
22
21
  def block_size
23
22
  return(8)
24
23
  end
25
24
 
26
-
27
25
  def initialize(key128, mode)
28
26
  # IDEA is subject to attack unless the key is sufficiently random, so we
29
27
  # take an MD5 digest of a variable-length passphrase to ensure a solid key
30
28
  if (key128.class == String)
31
- digest = Digest::MD5.new().digest(key128)
32
- key128 = digest.unpack('n'*8)
29
+ digest = Digest::MD5.new().digest(key128.b).b()
30
+ key128 = digest.unpack('n8')
33
31
  end
34
32
  raise "Key must be 128 bits (8 words)" unless (key128.class == Array) && (key128.length == 8)
35
33
  raise "Mode must be IDEA::ENCRYPT or IDEA::DECRYPT" unless ((mode == ENCRYPT) | (mode == DECRYPT))
@@ -39,21 +37,19 @@ class IDEA
39
37
  @subkeys = generate_decryption_subkeys(key128)
40
38
  end
41
39
  end
42
-
43
-
40
+
44
41
  def mul(a, b)
45
42
  modulus = 0x10001
46
43
  return((1 - b) % USHORT) if (a == 0)
47
44
  return((1 - a) % USHORT) if (b == 0)
48
- return((a * b) % modulus)
45
+ return((a * b) % modulus % USHORT) # fixed with % USHORT
49
46
  end
50
47
 
51
-
52
48
  def mulInv(x)
53
49
  modulus = 0x10001
54
- x = x.to_i % USHORT
50
+ x = x.to_i % 0x10000
55
51
  return(x) if (x <= 1)
56
- t1 = USHORT / x
52
+ t1 = modulus / x
57
53
  y = modulus % x
58
54
  if (y == 1)
59
55
  inv = (1 - t1) & 0xFFFF
@@ -73,7 +69,6 @@ class IDEA
73
69
  return(inv)
74
70
  end
75
71
 
76
-
77
72
  def generate_encryption_subkeys(key)
78
73
  encrypt_keys = []
79
74
  encrypt_keys[0..7] = key.dup
@@ -85,7 +80,6 @@ class IDEA
85
80
  return(encrypt_keys)
86
81
  end
87
82
 
88
-
89
83
  def generate_decryption_subkeys(key)
90
84
  encrypt_keys = generate_encryption_subkeys(key)
91
85
  decrypt_keys = []
@@ -97,7 +91,7 @@ class IDEA
97
91
  decrypt_keys[i+4] = encrypt_keys.shift % USHORT
98
92
  decrypt_keys[i+5] = encrypt_keys.shift % USHORT
99
93
  decrypt_keys[i] = mulInv(encrypt_keys.shift)
100
- if (i ==0)
94
+ if (i == 0)
101
95
  decrypt_keys[1] = (-encrypt_keys.shift) % USHORT
102
96
  decrypt_keys[2] = (-encrypt_keys.shift) % USHORT
103
97
  else
@@ -109,7 +103,6 @@ class IDEA
109
103
  return(decrypt_keys)
110
104
  end
111
105
 
112
-
113
106
  def crypt_pair(l, r)
114
107
  word = [l, r].pack('NN').unpack('nnnn')
115
108
  k = @subkeys[0..51]
@@ -145,7 +138,6 @@ class IDEA
145
138
  return(encrypted)
146
139
  end
147
140
 
148
-
149
141
  def decrypt_block(block)
150
142
  xl, xr = block.unpack('NN')
151
143
  xl, xr = crypt_pair(xl, xr)
@@ -153,40 +145,6 @@ class IDEA
153
145
  return(decrypted)
154
146
  end
155
147
 
156
-
157
148
  end
158
149
  end
159
150
 
160
- # LICENSE INFORMATION
161
- #
162
- # This software product contains the IDEA algorithm as described and claimed in
163
- # US patent 5,214,703, EPO patent 0482154 (covering Austria, France, Germany,
164
- # Italy, the Netherlands, Spain, Sweden, Switzerland, and the UK), and Japanese
165
- # patent application 508119/1991, "Device for the conversion of a digital block
166
- # and use of same" (hereinafter referred to as "the algorithm"). Any use of
167
- # the algorithm for commercial purposes is thus subject to a license from Ascom
168
- # Systec Ltd. of CH-5506 Maegenwil (Switzerland), being the patentee and sole
169
- # owner of all rights, including the trademark IDEA.
170
- #
171
- # Commercial purposes shall mean any revenue generating purpose including but
172
- # not limited to:
173
- #
174
- # i) Using the algorithm for company internal purposes (subject to a site
175
- # license).
176
- #
177
- # ii) Incorporating the algorithm into any software and distributing such
178
- # software and/or providing services relating thereto to others (subject to
179
- # a product license).
180
- #
181
- # iii) Using a product containing the algorithm not covered by an IDEA license
182
- # (subject to an end user license).
183
- #
184
- # All such end user license agreements are available exclusively from Ascom
185
- # Systec Ltd and may be requested via the WWW at http://www.ascom.ch/systec or
186
- # by email to idea@ascom.ch.
187
- #
188
- # Use other than for commercial purposes is strictly limited to non-revenue
189
- # generating data transfer between private individuals. The use by government
190
- # agencies, non-profit organizations, etc is considered as use for commercial
191
- # purposes but may be subject to special conditions. Any misuse will be
192
- # prosecuted.
@@ -1,9 +1,9 @@
1
- # crypt/rattle.rb Richard Kernahan <kernighan_rich@rubyforge.org>
1
+ module Crypt
2
+ # crypt/noise.rb Richard Kernahan
2
3
 
3
4
  # add_noise - take a message and intersperse noise to make a new noisy message of given byte-length
4
5
  # remove_noise - take a noisy message and extract the message
5
6
 
6
- module Crypt
7
7
  module Noise
8
8
 
9
9
  def add_noise(newLength)
@@ -1,6 +1,5 @@
1
- # rijndael-tables.rb Richard Kernahan <kernighan_rich@rubyforge.org>
2
-
3
1
  module Crypt
2
+ # rijndael-tables.rb
4
3
  module RijndaelTables
5
4
 
6
5
  LogTable = [
@@ -114,4 +113,4 @@ Shifts = [
114
113
  ]
115
114
 
116
115
  end
117
- end
116
+ end
@@ -1,4 +1,5 @@
1
- # rijndael.rb Richard Kernahan <kernighan_rich@rubyforge.org>
1
+ require 'crypt/cbc'
2
+ # rijndael.rb Richard Kernahan
2
3
 
3
4
  # Adapted from the reference C implementation:
4
5
  # rijndael-alg-ref.c v2.2 March 2002
@@ -6,16 +7,14 @@
6
7
  # authors: Paulo Barreto and Vincent Rijmen
7
8
  # This code is placed in the public domain.
8
9
 
10
+ require 'crypt/rijndael-tables'
11
+
9
12
  module Crypt
10
13
  class Rijndael
11
14
 
12
- require 'crypt/cbc'
13
15
  include Crypt::CBC
14
-
15
- require 'crypt/rijndael-tables'
16
16
  include Crypt::RijndaelTables
17
17
 
18
-
19
18
  def initialize(userKey, keyBits = 256, blockBits = 128)
20
19
  case keyBits
21
20
  when 128
@@ -0,0 +1,17 @@
1
+ class String
2
+
3
+ def ^(aString)
4
+ a = self.b.unpack('C'*(self.length))
5
+ b = aString.b.unpack('C'*(aString.length))
6
+ if (b.length < a.length)
7
+ (a.length - b.length).times { b << 0 }
8
+ end
9
+ xor = "".b()
10
+ 0.upto(a.length-1) { |pos|
11
+ x = a[pos] ^ b[pos]
12
+ xor << x.chr()
13
+ }
14
+ return(xor)
15
+ end
16
+
17
+ end
@@ -0,0 +1,80 @@
1
+ require 'crypt/blowfish'
2
+ require 'fileutils'
3
+
4
+ describe "Crypt::Blowfish" do
5
+
6
+ it "has a blocksize of 8" do
7
+ bf = Crypt::Blowfish.new("Who is John Galt?") # Schneier's test key
8
+ expect(bf.block_size).to eql(8)
9
+ end
10
+
11
+ it "requires a key of 1-56 bytes" do
12
+ expect {
13
+ b0 = Crypt::Blowfish.new("")
14
+ }.to raise_error(RuntimeError)
15
+ expect {
16
+ b1 = Crypt::Blowfish.new("1")
17
+ }.not_to raise_error()
18
+ expect {
19
+ b56 = Crypt::Blowfish.new("1"*56)
20
+ }.not_to raise_error()
21
+ expect {
22
+ b57 = Crypt::Blowfish.new("1"*57)
23
+ }.to raise_error(RuntimeError)
24
+ end
25
+
26
+ it "encrypts and decrypts 4-byte pairs" do
27
+ bf = Crypt::Blowfish.new("Who is John Galt?")
28
+ orig_l, orig_r = [0xfedcba98, 0x76543210]
29
+ l, r = bf.encrypt_pair(orig_l, orig_r)
30
+ expect(l).to eql(0xcc91732b)
31
+ expect(r).to eql(0x8022f684)
32
+ l, r = bf.decrypt_pair(l, r)
33
+ expect(l).to eql(orig_l)
34
+ expect(r).to eql(orig_r)
35
+ end
36
+
37
+ it "encrypts and decrypts 8-byte blocks" do
38
+ bf = Crypt::Blowfish.new("Who is John Galt?")
39
+ block = "8 byte\u00cd" # unicode string of 8 bytes
40
+ encryptedBlock = bf.encrypt_block(block)
41
+ expect(encryptedBlock).to eql("\xC4G\xD3\xFD7\xF4\x1E\xD0".b())
42
+ decryptedBlock = bf.decrypt_block(encryptedBlock)
43
+ expect(decryptedBlock).to eql(block)
44
+ end
45
+
46
+ it "encrypts and decrypts strings" do
47
+ length = 30 + rand(26)
48
+ userkey = ""
49
+ length.times { userkey << rand(256).chr }
50
+ bf = Crypt::Blowfish.new(userkey)
51
+ string = "This is a string which is not a multiple of 8 characters long"
52
+ encryptedString = bf.encrypt_string(string)
53
+ decryptedString = bf.decrypt_string(encryptedString)
54
+ expect(decryptedString).to eql(string)
55
+ secondstring = "This is another string to check repetitive use."
56
+ encryptedString = bf.encrypt_string(secondstring)
57
+ decryptedString = bf.decrypt_string(encryptedString)
58
+ expect(decryptedString).to eql(secondstring)
59
+ end
60
+
61
+ it "encrypts and decrypts a file" do
62
+ plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
63
+ plainFile = File.new('plain.txt', 'wb+')
64
+ plainFile.puts(plainText)
65
+ plainFile.close()
66
+ bf = Crypt::Blowfish.new("Who is John Galt?")
67
+ bf.encrypt_file('plain.txt', 'crypt.txt')
68
+ bf.decrypt_file('crypt.txt', 'decrypt.txt')
69
+ decryptFile = File.new('decrypt.txt', 'rb')
70
+ decryptText = decryptFile.readlines().join('').chomp()
71
+ decryptFile.close()
72
+ expect(decryptText).to eql(plainText)
73
+ FileUtils.rm('plain.txt')
74
+ FileUtils.rm('crypt.txt')
75
+ FileUtils.rm('decrypt.txt')
76
+ end
77
+
78
+ end
79
+
80
+
@@ -0,0 +1,48 @@
1
+ require 'crypt/gost'
2
+ require 'fileutils'
3
+
4
+ describe "Crypt::Gost" do
5
+
6
+ it "has a blocksize of 8" do
7
+ gost = Crypt::Gost.new("Whatever happened to Yuri Gagarin?")
8
+ expect(gost.block_size).to eql(8)
9
+ end
10
+
11
+ it "encrypts and decrypts 8-byte blocks" do
12
+ gost = Crypt::Gost.new("Whatever happened to Yuri?")
13
+ block = "norandom"
14
+ encryptedBlock = gost.encrypt_block(block)
15
+ expect(encryptedBlock).to eql(".Vy\xFF\x05\e3`".b())
16
+ decryptedBlock = gost.decrypt_block(encryptedBlock)
17
+ expect(decryptedBlock).to eql(block)
18
+ end
19
+
20
+ it "encrypts and decrypts strings" do
21
+ length = 25 + rand(12)
22
+ userkey = ""
23
+ length.times { userkey << rand(256).chr }
24
+ gost = Crypt::Gost.new(userkey)
25
+ string = "This is a string which is not a multiple of 8 characters long"
26
+ encryptedString = gost.encrypt_string(string)
27
+ decryptedString = gost.decrypt_string(encryptedString)
28
+ expect(decryptedString).to eql(string)
29
+ end
30
+
31
+ it "encrypts and decrypts a file" do
32
+ plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
33
+ plainFile = File.new('plain.txt', 'wb+')
34
+ plainFile.puts(plainText)
35
+ plainFile.close()
36
+ gost = Crypt::Gost.new("Whatever happened to Yuri?")
37
+ gost.encrypt_file('plain.txt', 'crypt.txt')
38
+ gost.decrypt_file('crypt.txt', 'decrypt.txt')
39
+ decryptFile = File.new('decrypt.txt', 'rb')
40
+ decryptText = decryptFile.readlines().join('').chomp()
41
+ decryptFile.close()
42
+ expect(decryptText).to eql(plainText)
43
+ FileUtils.rm('plain.txt')
44
+ FileUtils.rm('crypt.txt')
45
+ FileUtils.rm('decrypt.txt')
46
+ end
47
+
48
+ end
@@ -0,0 +1,156 @@
1
+ require 'crypt/idea'
2
+ require 'fileutils'
3
+
4
+ describe "Crypt::IDEA" do
5
+
6
+ it "encrypts and decrypts 4-byte pairs" do
7
+ enc = Crypt::IDEA.new("Nothing can stop an idea whose time has come", Crypt::IDEA::ENCRYPT)
8
+ dec = Crypt::IDEA.new("Nothing can stop an idea whose time has come", Crypt::IDEA::DECRYPT)
9
+ origL = 0x385a41f2
10
+ origR = 0xe03e5930
11
+ cl, cr = enc.crypt_pair(origL, origR)
12
+ dl, dr = dec.crypt_pair(cl, cr)
13
+ expect(dl).to eql(origL)
14
+ expect(dr).to eql(origR)
15
+ end
16
+
17
+ it "encrypts and decrypts 8-byte blocks" do
18
+ enc = Crypt::IDEA.new("Nothing can stop an idea whose time has come", Crypt::IDEA::ENCRYPT)
19
+ dec = Crypt::IDEA.new("Nothing can stop an idea whose time has come", Crypt::IDEA::DECRYPT)
20
+ block = "norandom"
21
+ encryptedBlock = enc.encrypt_block(block)
22
+ expect(encryptedBlock).to eql("\xC2lzEU\x81\e_".b())
23
+ decryptedBlock = dec.decrypt_block(encryptedBlock)
24
+ expect(decryptedBlock).to eql(block)
25
+ end
26
+
27
+ it "encrypts and decrypts strings" do
28
+ enc = Crypt::IDEA.new("Nothing can stop an idea whose time has come", Crypt::IDEA::ENCRYPT)
29
+ dec = Crypt::IDEA.new("Nothing can stop an idea whose time has come", Crypt::IDEA::DECRYPT)
30
+ string = "This is a string which is not a multiple of 8 characters long"
31
+ encryptedString = enc.encrypt_string(string)
32
+ decryptedString = dec.decrypt_string(encryptedString)
33
+ expect(decryptedString).to eql(string)
34
+ end
35
+
36
+ it "encrypts and decrypts a file" do
37
+ plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
38
+ plainFile = File.new('plain.txt', 'wb+')
39
+ plainFile.puts(plainText)
40
+ plainFile.close()
41
+ enc = Crypt::IDEA.new("Nothing can stop an idea whose time has come", Crypt::IDEA::ENCRYPT)
42
+ dec = Crypt::IDEA.new("Nothing can stop an idea whose time has come", Crypt::IDEA::DECRYPT)
43
+ enc.encrypt_file('plain.txt', 'crypt.txt')
44
+ dec.decrypt_file('crypt.txt', 'decrypt.txt')
45
+ decryptFile = File.new('decrypt.txt', 'rb')
46
+ decryptText = decryptFile.readlines().join('').chomp()
47
+ decryptFile.close()
48
+ expect(decryptText).to eql(plainText)
49
+ FileUtils.rm('plain.txt')
50
+ FileUtils.rm('crypt.txt')
51
+ FileUtils.rm('decrypt.txt')
52
+ end
53
+
54
+ def h(s)
55
+ [s].pack("H*")
56
+ end
57
+
58
+ def n8(s)
59
+ h(s).unpack("n8")
60
+ end
61
+
62
+ def conform(key, plain, cipher)
63
+ enc = Crypt::IDEA.new("", Crypt::IDEA::ENCRYPT)
64
+ enc.subkeys = enc.generate_encryption_subkeys(key)
65
+ dec = Crypt::IDEA.new("", Crypt::IDEA::ENCRYPT)
66
+ dec.subkeys = dec.generate_decryption_subkeys(key)
67
+ encryptedBlock = enc.encrypt_block(plain)
68
+ expect(encryptedBlock).to eql(cipher.b())
69
+ decryptedBlock = dec.decrypt_block(encryptedBlock)
70
+ expect(decryptedBlock).to eql(plain)
71
+ end
72
+
73
+ def conform_dec(key, cipher, plain)
74
+ dec = Crypt::IDEA.new("", Crypt::IDEA::ENCRYPT)
75
+ dec.subkeys = dec.generate_decryption_subkeys(key)
76
+ decryptedBlock = dec.decrypt_block(cipher)
77
+ expect(decryptedBlock).to eql(plain)
78
+ end
79
+
80
+ it "conforms to enceryption test vectors" do
81
+ conform([0x8000,0,0,0,0,0,0,0], h("0000000000000000"), h("B1F5F7F87901370F"))
82
+ conform([0x4000,0,0,0,0,0,0,0], h("0000000000000000"), h("B3927DFFB6358626"))
83
+ conform([0x2000,0,0,0,0,0,0,0], h("0000000000000000"), h("E987E0029FB99785"))
84
+ conform([0x1000,0,0,0,0,0,0,0], h("0000000000000000"), h("754A03CE08DB7DAA"))
85
+ conform([0x0800,0,0,0,0,0,0,0], h("0000000000000000"), h("F015F9FB0CFC7E1C"))
86
+ conform([0x0400,0,0,0,0,0,0,0], h("0000000000000000"), h("69C9FE6007B8FCDF"))
87
+ conform([0x0200,0,0,0,0,0,0,0], h("0000000000000000"), h("8DA7BC0E63B40DD0"))
88
+ conform([0x0100,0,0,0,0,0,0,0], h("0000000000000000"), h("2C49BF7DE28C666B"))
89
+ conform([ 0x80,0,0,0,0,0,0,0], h("0000000000000000"), h("9A4717E8F935712B"))
90
+ conform([0,0x8000,0,0,0,0,0,0], h("0000000000000000"), h("95A96731978C1B9A"))
91
+ conform([0,0,0x8000,0,0,0,0,0], h("0000000000000000"), h("398BD9A59E9F5DDB"))
92
+ conform([0,0,0,0x8000,0,0,0,0], h("0000000000000000"), h("AC1D8708AF0A37EE"))
93
+ conform([0,0,0,0,0x8000,0,0,0], h("0000000000000000"), h("FAE3FA7B8DB08800"))
94
+ conform([0,0,0,0,0,0x8000,0,0], h("0000000000000000"), h("B5803F82C0633F01"))
95
+ conform([0,0,0,0,0, 0x10,0,0], h("0000000000000000"), h("9E25090B7D4EF24E"))
96
+ conform([0,0,0,0,0, 0x8,0,0], h("0000000000000000"), h("EF62C1109F374AA8"))
97
+ conform([0,0,0,0,0, 0x2,0,0], h("0000000000000000"), h("5F0CCFE5EB0F19A8"))
98
+ conform([0xffff,0xffff,0xffff,0xffff,0xffff,0x1,0x000f,0xffff], h("0000000000000000"), h("2E4329C12455430B"))
99
+ # had problems with bits 95 to 108 inclusive, fixed by final % USHORT on mul()
100
+ conform([0,0,0,0,0, 0x1,0,0], h("0000000000000000"), h("FCC40014010D617C"))
101
+ conform([0,0,0,0,0,0,0x8000,0], h("0000000000000000"), h("705D780834A498DA"))
102
+ conform([0,0,0,0,0,0,0x4000,0], h("0000000000000000"), h("9BCA7BF025B38A68"))
103
+ conform([0,0,0,0,0,0,0x2000,0], h("0000000000000000"), h("5CF67D0181CB01C1"))
104
+ conform([0,0,0,0,0,0,0x1000,0], h("0000000000000000"), h("ECDE3D81820381C1"))
105
+ conform([0,0,0,0,0,0, 0x80,0], h("0000000000000000"), h("C781050DC4110220"))
106
+ conform([0,0,0,0,0,0, 0x40,0], h("0000000000000000"), h("6DFD0287EC4C0110"))
107
+ conform([0,0,0,0,0,0, 0x20,0], h("0000000000000000"), h("3B8A017EFB61800E"))
108
+ conform([0,0,0,0,0,0, 0x10,0], h("0000000000000000"), h("A08F7F81FF627FC0"))
109
+ conform([0,0,0,0,0,0, 0x8,0], h("0000000000000000"), h("00503FC1AFB93FE0"))
110
+ conform([0,0,0,0,0,0, 0x1,0], h("0000000000000000"), h("46D371477F33B152"))
111
+ conform([0,0,0,0,0,0,0,0x8000], h("0000000000000000"), h("BE67AC7DA294CA7C"))
112
+ conform([0,0,0,0,0,0,0,0], h("8000000000000000"), h("8001000180008000"))
113
+ conform([0,0,0,0,0,0,0,0], h("0080000000000000"), h("9181E3014C80C980"))
114
+ conform([0,0,0,0,0,0,0,0], h("0000800000000000"), h("0001800180008000"))
115
+ conform([0,0,0,0,0,0,0,0], h("0000000200000000"), h("FF49003BFF26FFAA"))
116
+ conform([0,0,0,0,0,0,0,0], h("0000000004000000"), h("100100014C00E000"))
117
+ conform([0,0,0,0,0,0,0,0], h("0000000000040000"), h("01110001FE4C00E0"))
118
+ conform([0,0,0,0,0,0,0,0], h("0000000000001000"), h("8001C001E0009000"))
119
+ conform([0,0,0,0,0,0,0,0], h("0000000000000100"), h("C8012C018E009900"))
120
+ conform([0,0,0,0,0,0,0,0], h("0000000000000040"), h("32010B012380E640"))
121
+ conform([0x0101,0x0101,0x0101,0x0101,0x0101,0x0101,0x0101,0x0101], h("0101010101010101"), h("E3F8AFF7A3795615"))
122
+ conform([0x7777,0x7777,0x7777,0x7777,0x7777,0x7777,0x7777,0x7777], h("7777777777777777"), h("D2E486D93304B9B6"))
123
+ conform([0xF7F7,0xF7F7,0xF7F7,0xF7F7,0xF7F7,0xF7F7,0xF7F7,0xF7F7], h("F7F7F7F7F7F7F7F7"), h("8E13C368F53E55AF"))
124
+ conform([1,0x203,0x405,0x607,0x809,0xa0b,0xc0d,0xe0f], h("0011223344556677"), h("F526AB9A62C0D258"))
125
+ end
126
+
127
+ it "conforms to decryption test vectors" do
128
+ conform_dec(n8("80000000000000000000000000000000"), h("0000000000000000"), h("78071EE87F0130E8"))
129
+ conform_dec(n8("00008000000000000000000000000000"), h("0000000000000000"), h("14D47C44835EEB99"))
130
+ conform_dec(n8("00000000800000000000000000000000"), h("0000000000000000"), h("CEA444C8CE44C2C2"))
131
+ conform_dec(n8("00000000000000000080000000000000"), h("0000000000000000"), h("6A9EF2F77DE21D8E"))
132
+ conform_dec(n8("00000000000000000000000800000000"), h("0000000000000000"), h("E698BE39AEA13C79"))
133
+ conform_dec(n8("00000000000000000000000000400000"), h("0000000000000000"), h("0579E00B945ED0B2"))
134
+ conform_dec(n8("00000000000000000000000000080000"), h("0000000000000000"), h("F0903DB58BEFF8CF"))
135
+ conform_dec(n8("00000000000000000000000000000040"), h("0000000000000000"), h("F75986F389F08110"))
136
+ conform_dec(n8("00000000000000000000000000000000"), h("8000000000000000"), h("8001000180008000"))
137
+ conform_dec(n8("00000000000000000000000000000000"), h("0002000000000000"), h("FE47FF8D0132FF26"))
138
+ conform_dec(n8("00000000000000000000000000000000"), h("0000000000200000"), h("08810001F2600700"))
139
+ conform_dec(n8("00000000000000000000000000000000"), h("0000000000000400"), h("2001B00138006400"))
140
+ conform_dec(n8("11111111111111111111111111111111"), h("1111111111111111"), h("3A1D3B4DB127C8B7"))
141
+ conform_dec(n8("52525252525252525252525252525252"), h("5252525252525252"), h("B255918917D30DB6"))
142
+ conform_dec(n8("66666666666666666666666666666666"), h("6666666666666666"), h("C9248B00868D8651"))
143
+ conform_dec(n8("ABABABABABABABABABABABABABABABAB"), h("ABABABABABABABAB"), h("5A4C4870F25A207F"))
144
+ conform_dec(n8("000102030405060708090A0B0C0D0E0F"), h("0011223344556677"), h("DB2D4A92AA68273F"))
145
+ conform_dec(n8("2BD6459F82C5B300952C49104881FF48"), h("EA024714AD5C4D84"), h("F129A6601EF62A47"))
146
+ end
147
+
148
+ it "calculates multiplicative inverses" do
149
+ idea = Crypt::IDEA.new("", Crypt::IDEA::ENCRYPT)
150
+ expect(idea.mulInv(0)).to eql(0)
151
+ (1..0xffff).each { |i|
152
+ expect(i * idea.mulInv(i) % 0x10001).to eql(1)
153
+ }
154
+ end
155
+
156
+ end
@@ -0,0 +1,58 @@
1
+ require 'crypt/rijndael'
2
+ require 'fileutils'
3
+
4
+ describe "Crypt::Rijndael" do
5
+
6
+ it "has a blocksize of 128, 192, or 256 bits" do
7
+ expect {
8
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 64)
9
+ }.to raise_error(RuntimeError)
10
+ expect {
11
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 64)
12
+ }.to raise_error(RuntimeError)
13
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 256)
14
+ expect(rijndael.block_size).to eql(32)
15
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 256, 128)
16
+ expect(rijndael.block_size).to eql(16)
17
+ end
18
+
19
+ it "encrypts and decrypts 8-byte blocks" do
20
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 128)
21
+ block = "This block \u00cd 16" # unicode string of 16 bytes
22
+ encryptedBlock = rijndael.encrypt_block(block)
23
+ expect(encryptedBlock).to eql("\x8E\x88\x03\xB8> PnwR)\x93\x1A\xC9:\xC4".b())
24
+ decryptedBlock = rijndael.decrypt_block(encryptedBlock)
25
+ expect(decryptedBlock).to eql(block)
26
+ # attempt to encrypt with wrong block size
27
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 256)
28
+ expect {
29
+ encryptedBlock = rijndael.encrypt_block(block)
30
+ }.to raise_error(RuntimeError)
31
+ end
32
+
33
+ it "encrypts and decrypts strings" do
34
+ rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?")
35
+ string = "This is a string which is not a multiple of 8 characters long"
36
+ encryptedString = rijndael.encrypt_string(string)
37
+ decryptedString = rijndael.decrypt_string(encryptedString)
38
+ expect(decryptedString).to eql(string)
39
+ end
40
+
41
+ it "encrypts and decrypts a file" do
42
+ plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
43
+ plainFile = File.new('plain.txt', 'wb+')
44
+ plainFile.puts(plainText)
45
+ plainFile.close()
46
+ rijndael = Crypt::Rijndael.new("Whatever happened to Yuri?")
47
+ rijndael.encrypt_file('plain.txt', 'crypt.txt')
48
+ rijndael.decrypt_file('crypt.txt', 'decrypt.txt')
49
+ decryptFile = File.new('decrypt.txt', 'rb')
50
+ decryptText = decryptFile.readlines().join('').chomp()
51
+ decryptFile.close()
52
+ expect(decryptText).to eql(plainText)
53
+ FileUtils.rm('plain.txt')
54
+ FileUtils.rm('crypt.txt')
55
+ FileUtils.rm('decrypt.txt')
56
+ end
57
+
58
+ end
metadata CHANGED
@@ -1,60 +1,58 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crypt
3
3
  version: !ruby/object:Gem::Version
4
- version: '2.0'
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Kernahan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-11 00:00:00.000000000 Z
11
+ date: 2015-09-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: The Crypt library is a pure-ruby implementation of a number of popular
14
14
  encryption algorithms. Block cyphers currently include Blowfish, GOST, IDEA, and
15
15
  Rijndael (AES). Cypher Block Chaining (CBC) has been implemented, and unicode is
16
16
  supported.
17
- email: kernighan_rich@rubyforge.org
17
+ email: recdev@finalstep.com.au
18
18
  executables: []
19
19
  extensions: []
20
20
  extra_rdoc_files: []
21
21
  files:
22
- - crypt/blowfish-tables.rb
23
- - crypt/blowfish.rb
24
- - crypt/cbc.rb
25
- - crypt/gost.rb
26
- - crypt/idea.rb
27
- - crypt/noise.rb
28
- - crypt/rijndael-tables.rb
29
- - crypt/rijndael.rb
30
- - crypt/stringxor.rb
31
- - test/break-idea.rb
32
- - test/devServer.rb
33
- - test/test-blowfish.rb
34
- - test/test-gost.rb
35
- - test/test-idea.rb
36
- - test/test-rijndael.rb
37
- homepage: http://crypt.rubyforge.org/
22
+ - lib/crypt/blowfish-tables.rb
23
+ - lib/crypt/blowfish.rb
24
+ - lib/crypt/cbc.rb
25
+ - lib/crypt/gost.rb
26
+ - lib/crypt/idea.rb
27
+ - lib/crypt/noise.rb
28
+ - lib/crypt/rijndael-tables.rb
29
+ - lib/crypt/rijndael.rb
30
+ - lib/crypt/stringxor.rb
31
+ - specs/blowfish.rb
32
+ - specs/gost.rb
33
+ - specs/idea.rb
34
+ - specs/rijndael.rb
35
+ homepage: http://crypt.finalstep.com.au/
38
36
  licenses:
39
37
  - MIT
40
38
  metadata: {}
41
39
  post_install_message:
42
40
  rdoc_options: []
43
41
  require_paths:
44
- - .
42
+ - "."
45
43
  required_ruby_version: !ruby/object:Gem::Requirement
46
44
  requirements:
47
- - - '>='
45
+ - - ">="
48
46
  - !ruby/object:Gem::Version
49
47
  version: '0'
50
48
  required_rubygems_version: !ruby/object:Gem::Requirement
51
49
  requirements:
52
- - - '>='
50
+ - - ">="
53
51
  - !ruby/object:Gem::Version
54
52
  version: '0'
55
53
  requirements: []
56
54
  rubyforge_project: crypt
57
- rubygems_version: 2.1.10
55
+ rubygems_version: 2.4.5.1
58
56
  signing_key:
59
57
  specification_version: 4
60
58
  summary: Pure-ruby cryptographic library including Blowfish, GOST, IDEA, and Rijndael
@@ -1,27 +0,0 @@
1
- # stringxor.rb Richard Kernahan <kernighan_rich@rubyforge.org>
2
-
3
- module Crypt
4
- module StringXor
5
-
6
-
7
- def ^(aString)
8
- a = self.unpack('C'*(self.length))
9
- b = aString.unpack('C'*(aString.length))
10
- if (b.length < a.length)
11
- (a.length - b.length).times { b << 0 }
12
- end
13
- xor = "".force_encoding("ASCII-8BIT") # stop ruby 2 using Unicode
14
- 0.upto(a.length-1) { |pos|
15
- x = a[pos] ^ b[pos]
16
- xor << x.chr()
17
- }
18
- return(xor)
19
- end
20
-
21
-
22
- end
23
- end
24
-
25
- class String
26
- include Crypt::StringXor
27
- end
@@ -1,61 +0,0 @@
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
-
@@ -1,16 +0,0 @@
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
-
@@ -1,90 +0,0 @@
1
- # test-blowfish.rb
2
- # updated 11-Feb-2014 for ruby 2.0
3
-
4
- require 'test/unit'
5
- require 'crypt/blowfish'
6
- require 'crypt/cbc'
7
- require 'fileutils'
8
-
9
- class TestBlowfish < Test::Unit::TestCase
10
-
11
- def setup
12
- @bf = Crypt::Blowfish.new("Who is John Galt?") # Schneier's test key
13
- end
14
-
15
- def teardown
16
- end
17
-
18
- def test_block_size
19
- assert_equal(8, @bf.block_size(), "Wrong block size")
20
- end
21
-
22
- def test_initialize
23
- assert_raise(RuntimeError) {
24
- b0 = Crypt::Blowfish.new("")
25
- }
26
- assert_nothing_raised() {
27
- b1 = Crypt::Blowfish.new("1")
28
- }
29
- assert_nothing_raised() {
30
- b56 = Crypt::Blowfish.new("1"*56)
31
- }
32
- assert_raise(RuntimeError) {
33
- b57 = Crypt::Blowfish.new("1"*57)
34
- }
35
- end
36
-
37
- def test_pair
38
- bf = Crypt::Blowfish.new("Who is John Galt?")
39
- orig_l, orig_r = [0xfedcba98, 0x76543210]
40
- l, r = bf.encrypt_pair(orig_l, orig_r)
41
- assert_equal(0xcc91732b, l)
42
- assert_equal(0x8022f684, r)
43
- l, r = bf.decrypt_pair(l, r)
44
- assert_equal(orig_l, l)
45
- assert_equal(orig_r, r)
46
- end
47
-
48
- def test_block
49
- bf = Crypt::Blowfish.new("Who is John Galt?")
50
- block = "8 byte\u00cd" # unicode string of 8 bytes
51
- encryptedBlock = bf.encrypt_block(block)
52
- assert_equal("\xC4G\xD3\xFD7\xF4\x1E\xD0".force_encoding('ASCII-8BIT'), encryptedBlock)
53
- decryptedBlock = bf.decrypt_block(encryptedBlock)
54
- assert_equal(block, decryptedBlock)
55
- end
56
-
57
- def test_string
58
- length = 30 + rand(26)
59
- userkey = ""
60
- length.times { userkey << rand(256).chr }
61
- bf = Crypt::Blowfish.new(userkey)
62
- string = "This is a string which is not a multiple of 8 characters long"
63
- encryptedString = bf.encrypt_string(string)
64
- decryptedString = bf.decrypt_string(encryptedString)
65
- assert_equal(string, decryptedString)
66
- secondstring = "This is another string to check repetitive use."
67
- encryptedString = bf.encrypt_string(secondstring)
68
- decryptedString = bf.decrypt_string(encryptedString)
69
- assert_equal(secondstring, decryptedString)
70
-
71
- end
72
-
73
- def test_file
74
- plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
75
- plainFile = File.new('plain.txt', 'wb+')
76
- plainFile.puts(plainText)
77
- plainFile.close()
78
- bf = Crypt::Blowfish.new("Who is John Galt?")
79
- bf.encrypt_file('plain.txt', 'crypt.txt')
80
- bf.decrypt_file('crypt.txt', 'decrypt.txt')
81
- decryptFile = File.new('decrypt.txt', 'rb')
82
- decryptText = decryptFile.readlines().join('').chomp()
83
- decryptFile.close()
84
- assert_equal(plainText, decryptText)
85
- FileUtils.rm('plain.txt')
86
- FileUtils.rm('crypt.txt')
87
- FileUtils.rm('decrypt.txt')
88
- end
89
-
90
- end
@@ -1,77 +0,0 @@
1
- # updated 11-Feb-2014 for ruby 2.0
2
-
3
- require 'test/unit'
4
- require 'crypt/gost'
5
- require 'fileutils'
6
-
7
- class TestGost < Test::Unit::TestCase
8
-
9
- def setup
10
- end
11
-
12
- def teardown
13
- end
14
-
15
- def test_init
16
- assert_nothing_raised(RuntimeError) {
17
- gost = Crypt::Gost.new("Whatever happened to Yuri Gagarin?")
18
- }
19
- assert_nothing_raised(RuntimeError) {
20
- gost = Crypt::Gost.new("Whatever happened to Yuri?")
21
- }
22
- end
23
-
24
- def test_block_size
25
- gost = Crypt::Gost.new("Whatever happened to Yuri?")
26
- assert_equal(8, gost.block_size(), "Wrong block size")
27
- end
28
-
29
- def test_pair
30
- gost = Crypt::Gost.new("Whatever happened to Yuri?")
31
- orig_l, orig_r = [0xfedcba98, 0x76543210]
32
- l, r = gost.encrypt_pair(orig_l, orig_r)
33
- assert_equal(0xaefaf8f4, l)
34
- assert_equal(0xe24891b0, r)
35
- l, r = gost.decrypt_pair(l, r)
36
- assert_equal(orig_l, l)
37
- assert_equal(orig_r, r)
38
- end
39
-
40
- def test_block
41
- gost = Crypt::Gost.new("Whatever happened to Yuri?")
42
- block = "norandom"
43
- encryptedBlock = gost.encrypt_block(block)
44
- assert_equal(".Vy\xFF\x05\e3`".force_encoding('ASCII-8BIT'), encryptedBlock)
45
- decryptedBlock = gost.decrypt_block(encryptedBlock)
46
- assert_equal(block, decryptedBlock)
47
- end
48
-
49
- def test_string
50
- length = 25 + rand(12)
51
- userkey = ""
52
- length.times { userkey << rand(256).chr }
53
- gost = Crypt::Gost.new(userkey)
54
- string = "This is a string which is not a multiple of 8 characters long"
55
- encryptedString = gost.encrypt_string(string)
56
- decryptedString = gost.decrypt_string(encryptedString)
57
- assert_equal(string, decryptedString)
58
- end
59
-
60
- def test_file
61
- plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
62
- plainFile = File.new('plain.txt', 'wb+')
63
- plainFile.puts(plainText)
64
- plainFile.close()
65
- gost = Crypt::Gost.new("Whatever happened to Yuri?")
66
- gost.encrypt_file('plain.txt', 'crypt.txt')
67
- gost.decrypt_file('crypt.txt', 'decrypt.txt')
68
- decryptFile = File.new('decrypt.txt', 'rb')
69
- decryptText = decryptFile.readlines().join('').chomp()
70
- decryptFile.close()
71
- assert_equal(plainText, decryptText)
72
- FileUtils.rm('plain.txt')
73
- FileUtils.rm('crypt.txt')
74
- FileUtils.rm('decrypt.txt')
75
- end
76
-
77
- end
@@ -1,79 +0,0 @@
1
- # updated 11-Feb-2014 for ruby 2.0 - changed expected values representation
2
-
3
- require 'test/unit'
4
- require 'crypt/idea'
5
- require 'fileutils'
6
-
7
- class TestIdea < Test::Unit::TestCase
8
-
9
- def setup
10
- end
11
-
12
- def teardown
13
- end
14
-
15
- def test_init
16
- assert_nothing_raised(RuntimeError) {
17
- idea_en = Crypt::IDEA.new("Who was John Galt and where's my breakfast?", Crypt::IDEA::ENCRYPT)
18
- }
19
- end
20
-
21
- def test_block_size
22
- idea_en = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::ENCRYPT)
23
- assert_equal(8, idea_en.block_size(), "Wrong block size")
24
- end
25
-
26
- def test_pair
27
- idea_en = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::ENCRYPT)
28
- orig_l, orig_r = [0xfedcba98, 0x76543210]
29
- l, r = idea_en.crypt_pair(orig_l, orig_r)
30
- assert_equal(0x05627e79, l)
31
- assert_equal(0x69476521, r)
32
- idea_de = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::DECRYPT)
33
- l, r = idea_de.crypt_pair(l, r)
34
- assert_equal(orig_l, l)
35
- assert_equal(orig_r, r)
36
- end
37
-
38
- def test_block
39
- idea_en = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::ENCRYPT)
40
- block = "8 byte\u00cd" # unicode string of 8 bytes
41
- encryptedBlock = idea_en.encrypt_block(block)
42
- expected = "\xFA\xB1P\tk\xB0\x1C\xE1".force_encoding("ASCII-8BIT")
43
- assert_equal(expected, encryptedBlock)
44
- idea_de = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::DECRYPT)
45
- decryptedBlock = idea_de.decrypt_block(encryptedBlock)
46
- assert_equal(block, decryptedBlock.force_encoding("UTF-8"))
47
- end
48
-
49
- def test_string
50
- length = 25 + rand(12)
51
- userkey = ""
52
- length.times { userkey << rand(256).chr }
53
- idea_en = Crypt::IDEA.new(userkey, Crypt::IDEA::ENCRYPT)
54
- string = "This is a string which is not a multiple of 8 characters long"
55
- encryptedString = idea_en.encrypt_string(string)
56
- idea_de = Crypt::IDEA.new(userkey, Crypt::IDEA::DECRYPT)
57
- decryptedString = idea_de.decrypt_string(encryptedString)
58
- assert_equal(string, decryptedString)
59
- end
60
-
61
- def test_file
62
- plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
63
- plainFile = File.new('plain.txt', 'wb+')
64
- plainFile.puts(plainText)
65
- plainFile.close()
66
- idea_en = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::ENCRYPT)
67
- idea_en.encrypt_file('plain.txt', 'crypt.txt')
68
- idea_de = Crypt::IDEA.new("Who is John Galt", Crypt::IDEA::DECRYPT)
69
- idea_de.decrypt_file('crypt.txt', 'decrypt.txt')
70
- decryptFile = File.new('decrypt.txt', 'rb')
71
- decryptText = decryptFile.readlines().join('').chomp()
72
- decryptFile.close()
73
- assert_equal(plainText, decryptText)
74
- FileUtils.rm('plain.txt')
75
- FileUtils.rm('crypt.txt')
76
- FileUtils.rm('decrypt.txt')
77
- end
78
-
79
- end
@@ -1,69 +0,0 @@
1
- # updated 11-Feb-2014 for ruby 2.0 - convert test strings into byte arrays, expected value representation
2
-
3
- require 'test/unit'
4
- require 'crypt/rijndael'
5
- require 'fileutils'
6
-
7
- class TestRijndael < Test::Unit::TestCase
8
-
9
- def setup
10
- end
11
-
12
- def teardown
13
- end
14
-
15
- def test_init
16
- assert_raise(RuntimeError) {
17
- rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 64)
18
- }
19
- assert_raise(RuntimeError) {
20
- rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 64)
21
- }
22
- end
23
-
24
- def test_block_size
25
- rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 256)
26
- assert_equal(32, rijndael.block_size)
27
- rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 256, 128)
28
- assert_equal(16, rijndael.block_size)
29
- end
30
-
31
- def test_block
32
- rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 128)
33
- block = "This block \u00cd 16" # unicode string of 16 bytes
34
- encryptedBlock = rijndael.encrypt_block(block)
35
- assert_equal("\x8E\x88\x03\xB8> PnwR)\x93\x1A\xC9:\xC4".force_encoding("ASCII-8BIT"), encryptedBlock)
36
- decryptedBlock = rijndael.decrypt_block(encryptedBlock)
37
- assert_equal(block.force_encoding("ASCII-8BIT"), decryptedBlock)
38
- rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?", 128, 256)
39
- assert_raise(RuntimeError) {
40
- encryptedBlock = rijndael.encrypt_block(block)
41
- }
42
- end
43
-
44
- def test_string
45
- rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?")
46
- string = "This is a string which is not a multiple of 8 characters long"
47
- encryptedString = rijndael.encrypt_string(string)
48
- decryptedString = rijndael.decrypt_string(encryptedString)
49
- assert_equal(string, decryptedString)
50
- end
51
-
52
- def test_file
53
- plainText = "This is a multi-line string\nwhich is not a multiple of 8 \ncharacters long."
54
- plainFile = File.new('plain.txt', 'wb+')
55
- plainFile.puts(plainText)
56
- plainFile.close()
57
- rijndael = Crypt::Rijndael.new("Who is this John Galt guy, anyway?")
58
- rijndael.encrypt_file('plain.txt', 'crypt.txt')
59
- rijndael.decrypt_file('crypt.txt', 'decrypt.txt')
60
- decryptFile = File.new('decrypt.txt', 'rb')
61
- decryptText = decryptFile.readlines().join('').chomp()
62
- decryptFile.close()
63
- assert_equal(plainText, decryptText)
64
- FileUtils.rm('plain.txt')
65
- FileUtils.rm('crypt.txt')
66
- FileUtils.rm('decrypt.txt')
67
- end
68
-
69
- end