flatulent 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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