crypt-tea 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,11 @@
1
+ === 1.1.0 / 2009-04-06
2
+
3
+ * BUGFIX
4
+
5
+ * ensure extra characters on the end of decrypted strings are removed
6
+ * Thanks to James Zhang for reporting this
7
+
8
+
1
9
  === 1.0.0 / 2008-04-02
2
10
 
3
11
  * 1 major enhancement
@@ -1,8 +1,23 @@
1
1
  module Crypt
2
2
  class XXTEA
3
- VERSION = '1.0.0'
3
+ VERSION = '1.1.0'
4
4
  DELTA = 0x9E3779B9
5
5
 
6
+ def initialize(new_key)
7
+ @key = str_to_longs(new_key)
8
+
9
+ if @key.length > 4
10
+ raise 'Key is too long (no more than 16 chars)'
11
+
12
+ elsif @key.length == 0
13
+ raise 'Key cannot be empty'
14
+
15
+ elsif @key.length < 4
16
+ @key.length.upto(4) { |i| @key[i] = 0 }
17
+
18
+ end
19
+ end
20
+
6
21
  def self.str_to_longs(s, include_count = false)
7
22
  length = s.length
8
23
  ((4 - s.length % 4) & 3).times { s << "\0" } # Pad to a multiple of 4
@@ -11,76 +26,70 @@ module Crypt
11
26
  unpacked
12
27
  end
13
28
 
14
- def self.longs_to_str(l, unpad = false) # convert array of longs back to string
29
+ def str_to_longs(s, include_count = false)
30
+ self.class.str_to_longs s, include_count
31
+ end
32
+
33
+
34
+ ##
35
+ # convert array of longs back to string
36
+ def self.longs_to_str(l, count_included = false)
15
37
  s = l.pack('V*')
16
- s = s.gsub(/[\000-\037]/,'') if unpad
38
+ s = s[0...(l[-1])] if count_included
17
39
  s
18
40
  end
19
41
 
42
+ def longs_to_str(l, count_included = false)
43
+ self.class.longs_to_str l, count_included
44
+ end
45
+
20
46
 
21
47
  def self.int32(n)
22
- n -= 4294967296 while (n >= 2147483648)
23
- n += 4294967296 while (n <= -2147483649)
48
+ n -= 4_294_967_296 while (n >= 2_147_483_648)
49
+ n += 4_294_967_296 while (n <= -2_147_483_648)
24
50
  n.to_i
25
51
  end
26
52
 
53
+ def int32(n)
54
+ self.class.int32 n
55
+ end
27
56
 
28
- def initialize(new_key)
29
- @key = self.class.str_to_longs(new_key, false)
30
-
31
- if @key.length > 4
32
- raise 'Key is too long (no more than 16 chars)'
33
-
34
- elsif @key.length == 0
35
- raise 'Key cannot be empty'
36
-
37
- elsif @key.length < 4
38
- @key.length.upto(4) { |i| @key[i] = 0 }
39
-
40
- end
57
+ def mx(z, y, sum, p, e)
58
+ int32(
59
+ ((z >> 5 & 0x07FFFFFF) ^ (y << 2)) +
60
+ ((y >> 3 & 0x1FFFFFFF) ^ (z << 4))
61
+ ) ^ int32((sum ^ y) + (@key[(p & 3) ^ e] ^ z))
41
62
  end
42
63
 
43
64
  def encrypt(plaintext)
44
65
  return '' if plaintext.length == 0
45
66
 
46
- v = self.class.str_to_longs(plaintext, true)
67
+ v = str_to_longs(plaintext, true)
47
68
  v[1] = 0 if v.length == 1
48
69
 
49
70
  n = v.length - 1
50
71
 
51
72
  z = v[n]
52
73
  y = v[0]
53
- q = (6 + 52/ (n + 1)).floor
74
+ q = (6 + 52 / (n + 1)).floor
54
75
  sum = 0
55
76
  p = 0
56
77
 
57
78
  while(0 <= (q -= 1)) do
58
- sum = self.class.int32(sum + DELTA)
79
+ sum = int32(sum + DELTA)
59
80
  e = sum >> 2 & 3
60
81
 
61
- (0...n).each do |p|
82
+ n.times do |p|
62
83
  y = v[p + 1];
63
- mx =
64
- self.class.int32(
65
- ((z >> 5 & 0x07FFFFFF) ^ y << 2) +
66
- ((y >> 3 & 0x1FFFFFFF) ^ z << 4)
67
- ) ^ self.class.int32((sum ^ y) + (@key[p & 3 ^ e] ^ z))
68
-
69
- z = v[p] = self.class.int32(v[p] + mx)
84
+ z = v[p] = int32(v[p] + mx(z, y, sum, p, e))
70
85
  end
71
86
 
72
87
  p += 1
73
88
  y = v[0];
74
- mx =
75
- self.class.int32(
76
- ((z >> 5 & 0x07FFFFFF) ^ y << 2) +
77
- ((y >> 3 & 0x1FFFFFFF) ^ z << 4)
78
- ) ^ self.class.int32((sum ^ y) + (@key[p & 3 ^ e] ^ z))
79
-
80
- z = v[p] = self.class.int32(v[p] + mx)
89
+ z = v[p] = int32(v[p] + mx(z, y, sum, p, e))
81
90
  end
82
91
 
83
- self.class.longs_to_str(v).unpack('a*').pack('m').delete("\n") # base64 encode it without newlines
92
+ longs_to_str(v).unpack('a*').pack('m').delete("\n") # base64 encode it without newlines
84
93
  end
85
94
 
86
95
  #
@@ -89,40 +98,28 @@ module Crypt
89
98
  def decrypt(ciphertext)
90
99
  return '' if ciphertext.length == 0
91
100
 
92
- v = self.class.str_to_longs(ciphertext.unpack('m').pack("a*")) # base64 decode and convert to array of 'longs'
101
+ v = str_to_longs(ciphertext.unpack('m').pack("a*")) # base64 decode and convert to array of 'longs'
93
102
  n = v.length - 1
94
103
  z = v[n]
95
104
  y = v[0]
96
105
  q = (6 + 52 / (n + 1)).floor
97
- sum = self.class.int32(q * DELTA)
106
+ sum = int32(q * DELTA)
98
107
  p = 0
99
108
 
100
109
  while (sum != 0) do
101
110
  e = sum >> 2 & 3
102
111
  n.downto(1) do |p|
103
112
  z = v[p - 1]
104
- mx =
105
- self.class.int32(
106
- ((z >> 5 & 0x07FFFFFF) ^ y << 2) +
107
- ((y >> 3 & 0x1FFFFFFF) ^ z << 4)
108
- ) ^ self.class.int32((sum ^ y) + (@key[p & 3 ^ e] ^ z))
109
-
110
- y = v[p] = self.class.int32(v[p] - mx)
113
+ y = v[p] = int32(v[p] - mx(z, y, sum, p, e))
111
114
  end
112
115
 
113
116
  p -= 1
114
117
  z = v[n]
115
- mx =
116
- self.class.int32(
117
- ((z >> 5 & 0x07FFFFFF) ^ y << 2) +
118
- ((y >> 3 & 0x1FFFFFFF) ^ z << 4)
119
- ) ^ self.class.int32((sum ^ y) + (@key[p & 3 ^ e] ^ z))
120
-
121
- y = v[0] = self.class.int32(v[0] - mx)
122
- sum = self.class.int32(sum - DELTA)
118
+ y = v[0] = int32(v[0] - mx(z, y, sum, p, e))
119
+ sum = int32(sum - DELTA)
123
120
  end
124
121
 
125
- self.class.longs_to_str(v, true)
122
+ longs_to_str(v, true)
126
123
  end
127
124
 
128
125
  end
@@ -5,15 +5,17 @@ require 'crypt_tea'
5
5
 
6
6
  class XXTEATest < Test::Unit::TestCase
7
7
  def setup
8
- @key = Crypt::XXTEA.new 'testkey'
8
+ @key = Crypt::XXTEA.new 'abigfattestkey'
9
+ @plaintext = "Oh say can you see, by the dawn's early light"
10
+ @cyphertext = "V32cYZc5yLXepm9lxzr4kgGM/eSVurwV0yQWi4uFs0uB2UBlJ19ZRKKMkbMr7DLGc3n1XQ=="
9
11
  end
10
12
 
11
13
  def test_str_to_long
12
- assert_equal [1953719668, 6778473], Crypt::XXTEA.str_to_longs('testing')
14
+ assert_equal [1953719668, 6778473, 7], Crypt::XXTEA.str_to_longs('testing', true)
13
15
  end
14
16
 
15
17
  def test_longs_to_str
16
- assert_equal 'testing', Crypt::XXTEA.longs_to_str([1953719668, 6778473], true)
18
+ assert_equal 'testing', Crypt::XXTEA.longs_to_str([1953719668, 6778473, 7], true)
17
19
  end
18
20
 
19
21
  def test_key_length
@@ -22,10 +24,19 @@ class XXTEATest < Test::Unit::TestCase
22
24
  end
23
25
 
24
26
  def test_encrypt
25
- assert_equal 'qYkeGc3ignEvPGM7RS06iQ==', @key.encrypt('plaintext')
27
+ assert_equal @cyphertext, @key.encrypt(@plaintext)
26
28
  end
27
29
 
28
30
  def test_decrypt
29
- assert_equal 'plaintext', @key.decrypt('qYkeGc3ignEvPGM7RS06iQ==')
31
+ assert_equal @plaintext, @key.decrypt(@cyphertext)
32
+ end
33
+
34
+ def test_tiny_plaintext
35
+ assert_equal '1', @key.decrypt(@key.encrypt('1'))
36
+ end
37
+
38
+ def test_huge_plaintext
39
+ str = '1234567890' * 1_000
40
+ assert_equal str, @key.decrypt(@key.encrypt(str))
30
41
  end
31
42
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crypt-tea
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeff Smick
@@ -30,17 +30,18 @@ cert_chain:
30
30
  M6zkPH2hkWs=
31
31
  -----END CERTIFICATE-----
32
32
 
33
- date: 2008-04-14 00:00:00 -07:00
33
+ date: 2009-04-06 00:00:00 -07:00
34
34
  default_executable:
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: hoe
38
+ type: :development
38
39
  version_requirement:
39
40
  version_requirements: !ruby/object:Gem::Requirement
40
41
  requirements:
41
42
  - - ">="
42
43
  - !ruby/object:Gem::Version
43
- version: 1.5.1
44
+ version: 1.11.0
44
45
  version:
45
46
  description: An implementation of the Tiny Encryption Algorithm that's compatible with PHP's xxTEA
46
47
  email:
@@ -85,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
86
  requirements: []
86
87
 
87
88
  rubyforge_project: crypt-tea
88
- rubygems_version: 1.1.1
89
+ rubygems_version: 1.3.1
89
90
  signing_key:
90
91
  specification_version: 2
91
92
  summary: An implementation of the Tiny Encryption Algorithm that's compatible with PHP's xxTEA
metadata.gz.sig CHANGED
Binary file