flatulent 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/README +60 -16
  2. data/flatulent-0.0.2.gem +0 -0
  3. data/lib/flatulent/crypt/blowfish-tables.rb +190 -0
  4. data/lib/flatulent/crypt/blowfish.rb +109 -0
  5. data/lib/flatulent/crypt/cbc.rb +123 -0
  6. data/lib/flatulent/crypt/gost.rb +140 -0
  7. data/lib/flatulent/crypt/idea.rb +193 -0
  8. data/lib/flatulent/crypt/noise.rb +94 -0
  9. data/lib/flatulent/crypt/purerubystringio.rb +378 -0
  10. data/lib/flatulent/crypt/rijndael-tables.rb +117 -0
  11. data/lib/flatulent/crypt/rijndael.rb +269 -0
  12. data/lib/flatulent/crypt/stringxor.rb +27 -0
  13. data/lib/flatulent.rb +332 -121
  14. data/lib/flatulent.rb.bak +337 -0
  15. data/rails/app/controllers/flatulent_controller.rb +61 -6
  16. data/rails/lib/flatulent/attributes.rb +79 -0
  17. data/rails/lib/flatulent/crypt/blowfish-tables.rb +190 -0
  18. data/rails/lib/flatulent/crypt/blowfish.rb +109 -0
  19. data/rails/lib/flatulent/crypt/cbc.rb +123 -0
  20. data/rails/lib/flatulent/crypt/gost.rb +140 -0
  21. data/rails/lib/flatulent/crypt/idea.rb +193 -0
  22. data/rails/lib/flatulent/crypt/noise.rb +94 -0
  23. data/rails/lib/flatulent/crypt/purerubystringio.rb +378 -0
  24. data/rails/lib/flatulent/crypt/rijndael-tables.rb +117 -0
  25. data/rails/lib/flatulent/crypt/rijndael.rb +269 -0
  26. data/rails/lib/flatulent/fontfiles/banner.flf +2494 -0
  27. data/rails/lib/flatulent/fontfiles/big.flf +2204 -0
  28. data/rails/lib/flatulent/fontfiles/block.flf +1691 -0
  29. data/rails/lib/flatulent/fontfiles/bubble.flf +1630 -0
  30. data/rails/lib/flatulent/fontfiles/digital.flf +1286 -0
  31. data/rails/lib/flatulent/fontfiles/ivrit.flf +900 -0
  32. data/rails/lib/flatulent/fontfiles/lean.flf +1691 -0
  33. data/rails/lib/flatulent/fontfiles/mini.flf +899 -0
  34. data/rails/lib/flatulent/fontfiles/mnemonic.flf +3702 -0
  35. data/rails/lib/flatulent/fontfiles/script.flf +1493 -0
  36. data/rails/lib/flatulent/fontfiles/shadow.flf +1097 -0
  37. data/rails/lib/flatulent/fontfiles/slant.flf +1295 -0
  38. data/rails/lib/flatulent/fontfiles/small.flf +1097 -0
  39. data/rails/lib/flatulent/fontfiles/smscript.flf +1097 -0
  40. data/rails/lib/flatulent/fontfiles/smshadow.flf +899 -0
  41. data/rails/lib/flatulent/fontfiles/smslant.flf +1097 -0
  42. data/rails/lib/flatulent/fontfiles/standard.flf +2227 -0
  43. data/rails/lib/flatulent/fontfiles/term.flf +600 -0
  44. data/rails/lib/flatulent/pervasives.rb +32 -0
  45. data/rails/lib/flatulent/stringxor.rb +27 -0
  46. data/rails/lib/flatulent/text/double_metaphone.rb +356 -0
  47. data/rails/lib/flatulent/text/figlet/font.rb +117 -0
  48. data/rails/lib/flatulent/text/figlet/smusher.rb +64 -0
  49. data/rails/lib/flatulent/text/figlet/typesetter.rb +68 -0
  50. data/rails/lib/flatulent/text/figlet.rb +17 -0
  51. data/rails/lib/flatulent/text/levenshtein.rb +65 -0
  52. data/rails/lib/flatulent/text/metaphone.rb +97 -0
  53. data/rails/lib/flatulent/text/porter_stemming.rb +171 -0
  54. data/rails/lib/flatulent/text/soundex.rb +61 -0
  55. data/rails/lib/flatulent/text.rb +6 -0
  56. data/rails/lib/flatulent.rb +450 -0
  57. data/rails/log/development.log +14297 -0
  58. data/rails/log/fastcgi.crash.log +111 -0
  59. data/rails/log/lighttpd.access.log +3993 -0
  60. data/rails/log/lighttpd.error.log +111 -0
  61. data/rails/tmp/cache/javascripts/prototype.js-gzip-3275912-71260-1183440172 +0 -0
  62. data/rails/tmp/sessions/ruby_sess.32d68bc997054475 +0 -0
  63. data/rails/tmp/sessions/ruby_sess.4694a4b9bdf9bcf4 +0 -0
  64. data/rails/tmp/sessions/ruby_sess.99469fde69043a05 +0 -0
  65. data/rails/tmp/sessions/ruby_sess.a588c0a457345912 +0 -0
  66. data/rails/tmp/sessions/ruby_sess.b3344125a84a3efa +0 -0
  67. data/samples.rb +10 -0
  68. metadata +69 -3
  69. data/flatulent-0.0.0.gem +0 -0
@@ -0,0 +1,109 @@
1
+ # blowfish.rb Richard Kernahan <kernighan_rich@rubyforge.org>
2
+ #
3
+ # Blowfish algorithm by Bruce Schneider
4
+ # Ported by Richard Kernahan from the reference C code
5
+ module Crypt
6
+ class Blowfish
7
+
8
+ require 'crypt/cbc'
9
+ include Crypt::CBC
10
+
11
+ require 'crypt/blowfish-tables'
12
+ include Crypt::BlowfishTables
13
+
14
+ ULONG = 0x100000000
15
+
16
+ def block_size
17
+ return(8)
18
+ end
19
+
20
+
21
+ def initialize(key)
22
+ @key = key
23
+ raise "Bad key length: the key must be 1-56 bytes." unless (key.length.between?(1,56))
24
+ @pArray = []
25
+ @sBoxes = []
26
+ setup_blowfish()
27
+ end
28
+
29
+
30
+ def f(x)
31
+ a, b, c, d = [x].pack('N').unpack('CCCC')
32
+ y = (@sBoxes[0][a] + @sBoxes[1][b]) % ULONG
33
+ y = (y ^ @sBoxes[2][c]) % ULONG
34
+ y = (y + @sBoxes[3][d]) % ULONG
35
+ return(y)
36
+ end
37
+
38
+
39
+ def setup_blowfish()
40
+ @sBoxes = Array.new(4) { |i| INITIALSBOXES[i].clone }
41
+ @pArray = INITIALPARRAY.clone
42
+ keypos = 0
43
+ 0.upto(17) { |i|
44
+ data = 0
45
+ 4.times {
46
+ data = ((data << 8) | @key[keypos]) % ULONG
47
+ keypos = (keypos.next) % @key.length
48
+ }
49
+ @pArray[i] = (@pArray[i] ^ data) % ULONG
50
+ }
51
+ l = 0
52
+ r = 0
53
+ 0.step(17, 2) { |i|
54
+ l, r = encrypt_pair(l, r)
55
+ @pArray[i] = l
56
+ @pArray[i+1] = r
57
+ }
58
+ 0.upto(3) { |i|
59
+ 0.step(255, 2) { |j|
60
+ l, r = encrypt_pair(l, r)
61
+ @sBoxes[i][j] = l
62
+ @sBoxes[i][j+1] = r
63
+ }
64
+ }
65
+ end
66
+
67
+ def encrypt_pair(xl, xr)
68
+ 0.upto(15) { |i|
69
+ xl = (xl ^ @pArray[i]) % ULONG
70
+ xr = (xr ^ f(xl)) % ULONG
71
+ xl, xr = [xl, xr].reverse
72
+ }
73
+ xl, xr = [xl, xr].reverse
74
+ xr = (xr ^ @pArray[16]) % ULONG
75
+ xl = (xl ^ @pArray[17]) % ULONG
76
+ return([xl, xr])
77
+ end
78
+
79
+
80
+ def decrypt_pair(xl, xr)
81
+ 17.downto(2) { |i|
82
+ xl = (xl ^ @pArray[i]) % ULONG
83
+ xr = (xr ^ f(xl)) % ULONG
84
+ xl, xr = [xl, xr].reverse
85
+ }
86
+ xl, xr = [xl, xr].reverse
87
+ xr = (xr ^ @pArray[1]) % ULONG
88
+ xl = (xl ^ @pArray[0]) % ULONG
89
+ return([xl, xr])
90
+ end
91
+
92
+
93
+ def encrypt_block(block)
94
+ xl, xr = block.unpack('NN')
95
+ xl, xr = encrypt_pair(xl, xr)
96
+ encrypted = [xl, xr].pack('NN')
97
+ return(encrypted)
98
+ end
99
+
100
+
101
+ def decrypt_block(block)
102
+ xl, xr = block.unpack('NN')
103
+ xl, xr = decrypt_pair(xl, xr)
104
+ decrypted = [xl, xr].pack('NN')
105
+ return(decrypted)
106
+ end
107
+
108
+ end
109
+ end
@@ -0,0 +1,123 @@
1
+ # cbc.rb Richard Kernahan <kernighan_rich@rubyforge.org>
2
+
3
+ module Crypt
4
+ module CBC
5
+
6
+ require 'stringio'
7
+ require 'crypt/stringxor'
8
+
9
+ ULONG = 0x100000000
10
+
11
+ # When this module is mixed in with an encryption class, the class
12
+ # must provide three methods: encrypt_block(block) and decrypt_block(block)
13
+ # and block_size()
14
+
15
+
16
+ def generate_initialization_vector(words)
17
+ srand(Time.now.to_i)
18
+ vector = ""
19
+ words.times {
20
+ vector << [rand(ULONG)].pack('N')
21
+ }
22
+ return(vector)
23
+ end
24
+
25
+
26
+ def encrypt_stream(plainStream, cryptStream)
27
+ # Cypher-block-chain mode
28
+
29
+ initVector = generate_initialization_vector(block_size() / 4)
30
+ chain = encrypt_block(initVector)
31
+ cryptStream.write(chain)
32
+
33
+ while ((block = plainStream.read(block_size())) && (block.length == block_size()))
34
+ block = block ^ chain
35
+ encrypted = encrypt_block(block)
36
+ cryptStream.write(encrypted)
37
+ chain = encrypted
38
+ end
39
+
40
+ # write the final block
41
+ # At most block_size()-1 bytes can be part of the message.
42
+ # That means the final byte can be used to store the number of meaningful
43
+ # bytes in the final block
44
+ block = '' if block.nil?
45
+ buffer = block.split('')
46
+ remainingMessageBytes = buffer.length
47
+ # we use 7-bit characters to avoid possible strange behavior on the Mac
48
+ remainingMessageBytes.upto(block_size()-2) { buffer << rand(128).chr }
49
+ buffer << remainingMessageBytes.chr
50
+ block = buffer.join('')
51
+ block = block ^ chain
52
+ encrypted = encrypt_block(block)
53
+ cryptStream.write(encrypted)
54
+ end
55
+
56
+
57
+ def decrypt_stream(cryptStream, plainStream)
58
+ # Cypher-block-chain mode
59
+ chain = cryptStream.read(block_size())
60
+
61
+ while (block = cryptStream.read(block_size()))
62
+ decrypted = decrypt_block(block)
63
+ plainText = decrypted ^ chain
64
+ plainStream.write(plainText) unless cryptStream.eof?
65
+ chain = block
66
+ end
67
+
68
+ # write the final block, omitting the padding
69
+ buffer = plainText.split('')
70
+ remainingMessageBytes = buffer.last.unpack('C').first
71
+ remainingMessageBytes.times { plainStream.write(buffer.shift) }
72
+ end
73
+
74
+
75
+ def carefully_open_file(filename, mode)
76
+ begin
77
+ aFile = File.new(filename, mode)
78
+ rescue
79
+ puts "Sorry. There was a problem opening the file <#{filename}>."
80
+ aFile.close() unless aFile.nil?
81
+ raise
82
+ end
83
+ return(aFile)
84
+ end
85
+
86
+
87
+ def encrypt_file(plainFilename, cryptFilename)
88
+ plainFile = carefully_open_file(plainFilename, 'rb')
89
+ cryptFile = carefully_open_file(cryptFilename, 'wb+')
90
+ encrypt_stream(plainFile, cryptFile)
91
+ plainFile.close unless plainFile.closed?
92
+ cryptFile.close unless cryptFile.closed?
93
+ end
94
+
95
+
96
+ def decrypt_file(cryptFilename, plainFilename)
97
+ cryptFile = carefully_open_file(cryptFilename, 'rb')
98
+ plainFile = carefully_open_file(plainFilename, 'wb+')
99
+ decrypt_stream(cryptFile, plainFile)
100
+ cryptFile.close unless cryptFile.closed?
101
+ plainFile.close unless plainFile.closed?
102
+ end
103
+
104
+
105
+ def encrypt_string(plainText)
106
+ plainStream = StringIO.new(plainText)
107
+ cryptStream = StringIO.new('')
108
+ encrypt_stream(plainStream, cryptStream)
109
+ cryptText = cryptStream.string
110
+ return(cryptText)
111
+ end
112
+
113
+
114
+ def decrypt_string(cryptText)
115
+ cryptStream = StringIO.new(cryptText)
116
+ plainStream = StringIO.new('')
117
+ decrypt_stream(cryptStream, plainStream)
118
+ plainText = plainStream.string
119
+ return(plainText)
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,140 @@
1
+ # gost.rb
2
+ # Adapted by Richard Kernahan <kernighan_rich@rubyforge.org>
3
+ # from C++ code written by Wei Dai
4
+ # of the Crypto++ project http://www.eskimo.com/~weidai/cryptlib.html
5
+
6
+ module Crypt
7
+ class Gost
8
+
9
+ require 'crypt/cbc'
10
+ include CBC
11
+
12
+ ULONG = 0x100000000
13
+
14
+ def block_size
15
+ return(8)
16
+ end
17
+
18
+
19
+ def initialize(userKey)
20
+
21
+ # These are the S-boxes given in Applied Cryptography 2nd Ed., p. 333
22
+ @sBox = [
23
+ [4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3],
24
+ [14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9],
25
+ [5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11],
26
+ [7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3],
27
+ [6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2],
28
+ [4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14],
29
+ [13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12],
30
+ [1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12]
31
+ ]
32
+
33
+ # These are the S-boxes given in the GOST source code listing in Applied
34
+ # Cryptography 2nd Ed., p. 644. They appear to be from the DES S-boxes
35
+ # [13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 ],
36
+ # [ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 ],
37
+ # [12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 ],
38
+ # [ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 ],
39
+ # [ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 ],
40
+ # [10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 ],
41
+ # [15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 ],
42
+ # [14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 ]
43
+
44
+ # precalculate the S table
45
+ @sTable = precalculate_S_table()
46
+
47
+ # derive the 32-byte key from the user-supplied key
48
+ userKeyLength = userKey.length
49
+ @key = userKey[0..31].unpack('C'*32)
50
+ if (userKeyLength < 32)
51
+ userKeyLength.upto(31) { @key << 0 }
52
+ end
53
+ end
54
+
55
+
56
+ def precalculate_S_table()
57
+ sTable = [[], [], [], []]
58
+ 0.upto(3) { |i|
59
+ 0.upto(255) { |j|
60
+ t = @sBox[2*i][j % 16] | (@sBox[2*i+1][j/16] << 4)
61
+ u = (8*i + 11) % 32
62
+ v = (t << u) | (t >> (32-u))
63
+ sTable[i][j] = (v % ULONG)
64
+ }
65
+ }
66
+ return(sTable)
67
+ end
68
+
69
+
70
+ def f(longWord)
71
+ longWord = longWord % ULONG
72
+ a, b, c, d = [longWord].pack('L').unpack('CCCC')
73
+ return(@sTable[3][d] ^ @sTable[2][c] ^ @sTable[1][b] ^ @sTable[0][a])
74
+ end
75
+
76
+
77
+ def encrypt_pair(xl, xr)
78
+ 3.times {
79
+ xr ^= f(xl+@key[0])
80
+ xl ^= f(xr+@key[1])
81
+ xr ^= f(xl+@key[2])
82
+ xl ^= f(xr+@key[3])
83
+ xr ^= f(xl+@key[4])
84
+ xl ^= f(xr+@key[5])
85
+ xr ^= f(xl+@key[6])
86
+ xl ^= f(xr+@key[7])
87
+ }
88
+ xr ^= f(xl+@key[7])
89
+ xl ^= f(xr+@key[6])
90
+ xr ^= f(xl+@key[5])
91
+ xl ^= f(xr+@key[4])
92
+ xr ^= f(xl+@key[3])
93
+ xl ^= f(xr+@key[2])
94
+ xr ^= f(xl+@key[1])
95
+ xl ^= f(xr+@key[0])
96
+ return([xr, xl])
97
+ end
98
+
99
+
100
+ def decrypt_pair(xl, xr)
101
+ xr ^= f(xl+@key[0])
102
+ xl ^= f(xr+@key[1])
103
+ xr ^= f(xl+@key[2])
104
+ xl ^= f(xr+@key[3])
105
+ xr ^= f(xl+@key[4])
106
+ xl ^= f(xr+@key[5])
107
+ xr ^= f(xl+@key[6])
108
+ xl ^= f(xr+@key[7])
109
+ 3.times {
110
+ xr ^= f(xl+@key[7])
111
+ xl ^= f(xr+@key[6])
112
+ xr ^= f(xl+@key[5])
113
+ xl ^= f(xr+@key[4])
114
+ xr ^= f(xl+@key[3])
115
+ xl ^= f(xr+@key[2])
116
+ xr ^= f(xl+@key[1])
117
+ xl ^= f(xr+@key[0])
118
+ }
119
+ return([xr, xl])
120
+ end
121
+
122
+
123
+ def encrypt_block(block)
124
+ xl, xr = block.unpack('NN')
125
+ xl, xr = encrypt_pair(xl, xr)
126
+ encrypted = [xl, xr].pack('NN')
127
+ return(encrypted)
128
+ end
129
+
130
+
131
+ def decrypt_block(block)
132
+ xl, xr = block.unpack('NN')
133
+ xl, xr = decrypt_pair(xl, xr)
134
+ decrypted = [xl, xr].pack('NN')
135
+ return(decrypted)
136
+ end
137
+
138
+
139
+ end
140
+ end
@@ -0,0 +1,193 @@
1
+ # idea.rb Richard Kernahan <kernighan_rich@rubyforge.org>
2
+
3
+ # 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
6
+
7
+ module Crypt
8
+ class IDEA
9
+
10
+ require 'crypt/cbc'
11
+ include Crypt::CBC
12
+
13
+ require 'digest/md5'
14
+
15
+ ULONG = 0x100000000
16
+ USHORT = 0x10000
17
+
18
+ ENCRYPT = 0
19
+ DECRYPT = 1
20
+
21
+
22
+ def block_size
23
+ return(8)
24
+ end
25
+
26
+
27
+ def initialize(key128, mode)
28
+ # IDEA is subject to attack unless the key is sufficiently random, so we
29
+ # take an MD5 digest of a variable-length passphrase to ensure a solid key
30
+ if (key128.class == String)
31
+ digest = Digest::MD5.new(key128).digest
32
+ key128 = digest.unpack('n'*8)
33
+ end
34
+ raise "Key must be 128 bits (8 words)" unless (key128.class == Array) && (key128.length == 8)
35
+ raise "Mode must be IDEA::ENCRYPT or IDEA::DECRYPT" unless ((mode == ENCRYPT) | (mode == DECRYPT))
36
+ if (mode == ENCRYPT)
37
+ @subkeys = generate_encryption_subkeys(key128)
38
+ else (mode == DECRYPT)
39
+ @subkeys = generate_decryption_subkeys(key128)
40
+ end
41
+ end
42
+
43
+
44
+ def mul(a, b)
45
+ modulus = 0x10001
46
+ return((1 - b) % USHORT) if (a == 0)
47
+ return((1 - a) % USHORT) if (b == 0)
48
+ return((a * b) % modulus)
49
+ end
50
+
51
+
52
+ def mulInv(x)
53
+ modulus = 0x10001
54
+ x = x.to_i % USHORT
55
+ return(x) if (x <= 1)
56
+ t1 = USHORT / x
57
+ y = modulus % x
58
+ if (y == 1)
59
+ inv = (1 - t1) & 0xFFFF
60
+ return(inv)
61
+ end
62
+ t0 = 1
63
+ while (y != 1)
64
+ q = x / y
65
+ x = x % y
66
+ t0 = t0 + (q * t1)
67
+ return(t0) if (x == 1)
68
+ q = y / x
69
+ y = y % x
70
+ t1 = t1 + (q * t0)
71
+ end
72
+ inv = (1 - t1) & 0xFFFF
73
+ return(inv)
74
+ end
75
+
76
+
77
+ def generate_encryption_subkeys(key)
78
+ encrypt_keys = []
79
+ encrypt_keys[0..7] = key.dup
80
+ 8.upto(51) { |i|
81
+ a = ((i + 1) % 8 > 0) ? (i-7) : (i-15)
82
+ b = ((i + 2) % 8 < 2) ? (i-14) : (i-6)
83
+ encrypt_keys[i] = ((encrypt_keys[a] << 9) | (encrypt_keys[b] >> 7)) % USHORT
84
+ }
85
+ return(encrypt_keys)
86
+ end
87
+
88
+
89
+ def generate_decryption_subkeys(key)
90
+ encrypt_keys = generate_encryption_subkeys(key)
91
+ decrypt_keys = []
92
+ decrypt_keys[48] = mulInv(encrypt_keys.shift)
93
+ decrypt_keys[49] = (-encrypt_keys.shift) % USHORT
94
+ decrypt_keys[50] = (-encrypt_keys.shift) % USHORT
95
+ decrypt_keys[51] = mulInv(encrypt_keys.shift)
96
+ 42.step(0, -6) { |i|
97
+ decrypt_keys[i+4] = encrypt_keys.shift % USHORT
98
+ decrypt_keys[i+5] = encrypt_keys.shift % USHORT
99
+ decrypt_keys[i] = mulInv(encrypt_keys.shift)
100
+ if (i ==0)
101
+ decrypt_keys[1] = (-encrypt_keys.shift) % USHORT
102
+ decrypt_keys[2] = (-encrypt_keys.shift) % USHORT
103
+ else
104
+ decrypt_keys[i+2] = (-encrypt_keys.shift) % USHORT
105
+ decrypt_keys[i+1] = (-encrypt_keys.shift) % USHORT
106
+ end
107
+ decrypt_keys[i+3] = mulInv(encrypt_keys.shift)
108
+ }
109
+ return(decrypt_keys)
110
+ end
111
+
112
+
113
+ def crypt_pair(l, r)
114
+ word = [l, r].pack('NN').unpack('nnnn')
115
+ k = @subkeys[0..51]
116
+ 8.downto(1) { |i|
117
+ word[0] = mul(word[0], k.shift)
118
+ word[1] = (word[1] + k.shift) % USHORT
119
+ word[2] = (word[2] + k.shift) % USHORT
120
+ word[3] = mul(word[3], k.shift)
121
+ t2 = word[0] ^ word[2]
122
+ t2 = mul(t2, k.shift)
123
+ t1 = (t2 + (word[1] ^ word[3])) % USHORT
124
+ t1 = mul(t1, k.shift)
125
+ t2 = (t1 + t2) % USHORT
126
+ word[0] ^= t1
127
+ word[3] ^= t2
128
+ t2 ^= word[1]
129
+ word[1] = word[2] ^ t1
130
+ word[2] = t2
131
+ }
132
+ result = []
133
+ result << mul(word[0], k.shift)
134
+ result << (word[2] + k.shift) % USHORT
135
+ result << (word[1] + k.shift) % USHORT
136
+ result << mul(word[3], k.shift)
137
+ twoLongs = result.pack('nnnn').unpack('NN')
138
+ return(twoLongs)
139
+ end
140
+
141
+ def encrypt_block(block)
142
+ xl, xr = block.unpack('NN')
143
+ xl, xr = crypt_pair(xl, xr)
144
+ encrypted = [xl, xr].pack('NN')
145
+ return(encrypted)
146
+ end
147
+
148
+
149
+ def decrypt_block(block)
150
+ xl, xr = block.unpack('NN')
151
+ xl, xr = crypt_pair(xl, xr)
152
+ decrypted = [xl, xr].pack('NN')
153
+ return(decrypted)
154
+ end
155
+
156
+
157
+ end
158
+ end
159
+
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.
193
+
@@ -0,0 +1,94 @@
1
+ # crypt/rattle.rb Richard Kernahan <kernighan_rich@rubyforge.org>
2
+
3
+ # add_noise - take a message and intersperse noise to make a new noisy message of given byte-length
4
+ # remove_noise - take a noisy message and extract the message
5
+
6
+ module Crypt
7
+ module Noise
8
+
9
+ def add_noise(newLength)
10
+ message = self
11
+ usableNoisyMessageLength = newLength / 9 * 8
12
+ bitmapSize = newLength / 9
13
+ remainingBytes = newLength - usableNoisyMessageLength - bitmapSize
14
+ if (message.length > usableNoisyMessageLength)
15
+ minimumNewLength = (message.length / 8.0).ceil * 9
16
+ puts "For a clear text of #{message.length} bytes, the minimum obscured length"
17
+ puts "is #{minimumNewLength} bytes which allows for no noise in the message."
18
+ puts "You should choose an obscured length of at least double the clear text"
19
+ puts "length, such as #{message.length / 8 * 32} bytes"
20
+ raise "Insufficient length for noisy message"
21
+ end
22
+ bitmap = []
23
+ usableNoisyMessageLength.times { bitmap << false }
24
+ srand(Time.now.to_i)
25
+ positionsSelected = 0
26
+ while (positionsSelected < message.length)
27
+ positionTaken = rand(usableNoisyMessageLength)
28
+ if bitmap[positionTaken]
29
+ next
30
+ else
31
+ bitmap[positionTaken] = true
32
+ positionsSelected = positionsSelected.next
33
+ end
34
+ end
35
+
36
+ noisyMessage = ""
37
+ 0.upto(bitmapSize-1) { |byte|
38
+ c = 0
39
+ 0.upto(7) { |bit|
40
+ c = c + (1<<bit) if bitmap[byte * 8 + bit]
41
+ }
42
+ noisyMessage << c.chr
43
+ }
44
+ posInMessage = 0
45
+ 0.upto(usableNoisyMessageLength-1) { |pos|
46
+ if bitmap[pos]
47
+ meaningfulByte = message[posInMessage]
48
+ noisyMessage << meaningfulByte
49
+ posInMessage = posInMessage.next
50
+ else
51
+ noiseByte = rand(256).chr
52
+ noisyMessage << noiseByte
53
+ end
54
+ }
55
+ remainingBytes.times {
56
+ noiseByte = rand(256).chr
57
+ noisyMessage << noiseByte
58
+ }
59
+ return(noisyMessage)
60
+ end
61
+
62
+
63
+ def remove_noise
64
+ noisyMessage = self
65
+ bitmapSize = noisyMessage.length / 9
66
+ actualMessageLength = bitmapSize * 8
67
+
68
+ actualMessageStart = bitmapSize
69
+ actualMessageFinish = bitmapSize + actualMessageLength - 1
70
+ actualMessage = noisyMessage[actualMessageStart..actualMessageFinish]
71
+
72
+ bitmap = []
73
+ 0.upto(bitmapSize - 1) { |byte|
74
+ c = noisyMessage[byte]
75
+ 0.upto(7) { |bit|
76
+ bitmap[byte * 8 + bit] = (c[bit] == 1)
77
+ }
78
+ }
79
+ clearMessage = ""
80
+ 0.upto(actualMessageLength) { |pos|
81
+ meaningful = bitmap[pos]
82
+ if meaningful
83
+ clearMessage << actualMessage[pos]
84
+ end
85
+ }
86
+ return(clearMessage)
87
+ end
88
+
89
+ end
90
+ end
91
+
92
+ class String
93
+ include Crypt::Noise
94
+ end