Permalink
Browse files

Update for documentation.

dup incoming strings to str_to_longs so they aren't ruined with padding
add a couple class methods for en/decrypting
  • Loading branch information...
1 parent b7cfcab commit 4658c2f22bdd9a1e7478fa0931455a7e87296571 @sprsquish committed Jun 5, 2009
Showing with 65 additions and 32 deletions.
  1. +24 −11 lib/crypt_tea/xxtea.rb
  2. +41 −21 test/test_xxtea.rb
View
@@ -1,6 +1,5 @@
module Crypt
class XXTEA
- VERSION = '1.2.0'
DELTA = 0x9E3779B9
def initialize(new_key)
@@ -18,49 +17,58 @@ def initialize(new_key)
end
end
- def self.str_to_longs(s, include_count = false)
+ def self.str_to_longs(s, include_count = false) # :nodoc:
+ s = s.dup
length = s.length
((4 - s.length % 4) & 3).times { s << "\0" } # Pad to a multiple of 4
unpacked = s.unpack('V*').collect { |n| int32 n }
unpacked << length if include_count
unpacked
end
- def str_to_longs(s, include_count = false)
+ def str_to_longs(s, include_count = false) # :nodoc:
self.class.str_to_longs s, include_count
end
##
# convert array of longs back to string
- def self.longs_to_str(l, count_included = false)
+ def self.longs_to_str(l, count_included = false) # :nodoc:
s = l.pack('V*')
s = s[0...(l[-1])] if count_included
s
end
- def longs_to_str(l, count_included = false)
+ def longs_to_str(l, count_included = false) # :nodoc:
self.class.longs_to_str l, count_included
end
- def self.int32(n)
+ def self.int32(n) # :nodoc:
n -= 4_294_967_296 while (n >= 2_147_483_648)
n += 4_294_967_296 while (n <= -2_147_483_648)
n.to_i
end
- def int32(n)
+ def int32(n) # :nodoc:
self.class.int32 n
end
- def mx(z, y, sum, p, e)
+ def mx(z, y, sum, p, e) # :nodoc:
int32(
((z >> 5 & 0x07FFFFFF) ^ (y << 2)) +
((y >> 3 & 0x1FFFFFFF) ^ (z << 4))
) ^ int32((sum ^ y) + (@key[(p & 3) ^ e] ^ z))
end
+ ##
+ # Encrypt the +plaintext+ using the +key+
+ def self.encrypt(key, plaintext)
+ self.new(key).encrypt(plaintext)
+ end
+
+ ##
+ # Encrypt the +plaintext+
def encrypt(plaintext)
return '' if plaintext.length == 0
@@ -93,9 +101,14 @@ def encrypt(plaintext)
longs_to_str(v).unpack('a*').pack('m').delete("\n") # base64 encode it without newlines
end
- #
- # decrypt: Use Corrected Block TEA to decrypt ciphertext using password
- #
+ ##
+ # Decrypt the +ciphertext+ using the +key+
+ def self.decrypt(key, ciphertext)
+ self.new(key).decrypt(ciphertext)
+ end
+
+ ##
+ # Decrypt the +ciphertext+
def decrypt(ciphertext)
return '' if ciphertext.length == 0
View
@@ -1,42 +1,62 @@
-$:.unshift File.dirname(__FILE__) + '/../lib'
+require 'rubygems'
+require 'minitest/spec'
+require File.join(File.dirname(__FILE__), *%w[.. lib crypt_tea])
-require 'test/unit'
-require 'crypt_tea'
+MiniTest::Unit.autorun
-class XXTEATest < Test::Unit::TestCase
- def setup
- @key = Crypt::XXTEA.new 'abigfattestkey'
+describe Crypt::XXTEA do
+ before do
+ @key_text = 'abigfattestkey'
+ @key = Crypt::XXTEA.new @key_text
@plaintext = "Oh say can you see, by the dawn's early light"
@cyphertext = "V32cYZc5yLXepm9lxzr4kgGM/eSVurwV0yQWi4uFs0uB2UBlJ19ZRKKMkbMr7DLGc3n1XQ=="
end
- def test_str_to_long
- assert_equal [1953719668, 6778473, 7], Crypt::XXTEA.str_to_longs('testing', true)
+ it 'converts strings to longs' do
+ Crypt::XXTEA.str_to_longs('testing', true).must_equal [1953719668, 6778473, 7]
end
- def test_longs_to_str
- assert_equal 'testing', Crypt::XXTEA.longs_to_str([1953719668, 6778473, 7], true)
+ it 'converts longs to strings' do
+ Crypt::XXTEA.longs_to_str([1953719668, 6778473, 7], true).must_equal 'testing'
end
- def test_key_length
- assert_raise(RuntimeError) { Crypt::XXTEA.new '12345678901234567' }
- assert_raise(RuntimeError) { Crypt::XXTEA.new '' }
+ it 'raises an error when the key is too long' do
+ proc { Crypt::XXTEA.new '12345678901234567' }.must_raise RuntimeError
end
- def test_encrypt
- assert_equal @cyphertext, @key.encrypt(@plaintext)
+ it 'raises an error when the key is blank' do
+ proc { Crypt::XXTEA.new '' }.must_raise RuntimeError
end
- def test_decrypt
- assert_equal @plaintext, @key.decrypt(@cyphertext)
+ it 'works properly with small keys' do
+ key = Crypt::XXTEA.new '123'
+ cyphertext = key.encrypt(@plaintext)
+ key.decrypt(cyphertext).must_equal @plaintext
end
- def test_tiny_plaintext
- assert_equal '1', @key.decrypt(@key.encrypt('1'))
+ it 'properly encrypts when instantiated' do
+ @key.encrypt(@plaintext).must_equal @cyphertext
end
- def test_huge_plaintext
+ it 'properly decrypts when instantiated' do
+ @key.decrypt(@cyphertext).must_equal @plaintext
+ end
+
+ it 'properly en/decrypts tiny text' do
+ txt = '1'
+ @key.decrypt(@key.encrypt(txt)).must_equal txt
+ end
+
+ it 'properly en/decrypts huge text' do
str = '1234567890' * 1_000
- assert_equal str, @key.decrypt(@key.encrypt(str))
+ @key.decrypt(@key.encrypt(str)).must_equal str
+ end
+
+ it 'properly encrypts with a class method' do
+ Crypt::XXTEA.encrypt(@key_text, @plaintext).must_equal @cyphertext
+ end
+
+ it 'properly decrypts with a class method' do
+ Crypt::XXTEA.decrypt(@key_text, @cyphertext).must_equal @plaintext
end
end

0 comments on commit 4658c2f

Please sign in to comment.