/** * com.sekati.crypt.TEA * @version 1.0.1 * @author jason m horwitz | sekati.com * Copyright (C) 2007 jason m horwitz, Sekat LLC. All Rights Reserved. * Released under the MIT License: http://www.opensource.org/licenses/mit-license.php * * Sourced from ascrypt for dependencies only - version 2.0, author Mika Pamu * Original Javascript implementation: * Chris Veness, Movable Type Ltd: www.movable-type.co.uk * Algorithm: David Wheeler & Roger Needham, Cambridge University Computer Lab * @see http://www.movable-type.co.uk/scripts/TEAblock.html */ import com.sekati.crypt.ICipher; /** * Encrypts and decrypts text with the TEA (Block) algorithm. */ class com.sekati.crypt.TEA implements ICipher { /** * Encrypts a string with the specified key. * @param src (String) string to encrypt * @param key (String) encryption key * @return String */ public static function encrypt(src:String, key:String):String { var v:Array = charsToLongs( strToChars( src ) ); var k:Array = charsToLongs( strToChars( key ) ); var n:Number = v.length; if (n == 0) return ""; if (n == 1) v[n++] = 0; var z:Number = v[n - 1], y:Number = v[0], delta:Number = 0x9E3779B9; var mx:Number, e:Number, q:Number = Math.floor( 6 + 52 / n ), sum:Number = 0; while (q-- > 0) { sum += delta; e = sum >>> 2 & 3; for (var p:Number = 0; p < n - 1 ; p++) { y = v[p + 1]; mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z); z = v[p] += mx; } y = v[0]; mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z); z = v[n - 1] += mx; } return charsToHex( longsToChars( v ) ); } /** * Decrypts a string with the specified key. * @param src (String) string to decrypt * @param key (String) decryption key * @return String */ public static function decrypt(src:String, key:String):String { var v:Array = charsToLongs( hexToChars( src ) ); var k:Array = charsToLongs( strToChars( key ) ); var n:Number = v.length; if (n == 0) return ""; var z:Number = v[n - 1], y:Number = v[0], delta:Number = 0x9E3779B9; var mx:Number, e:Number, q:Number = Math.floor( 6 + 52 / n ), sum:Number = q * delta; while (sum != 0) { e = sum >>> 2 & 3; for(var p:Number = n - 1; p > 0 ; p--) { z = v[p - 1]; mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z); y = v[p] -= mx; } z = v[n - 1]; mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z); y = v[0] -= mx; sum -= delta; } return charsToStr( longsToChars( v ) ); } private static function charsToLongs(chars:Array):Array { var temp:Array = new Array( Math.ceil( chars.length / 4 ) ); for (var i:Number = 0; i < temp.length ; i++) { temp[i] = chars[i * 4] + (chars[i * 4 + 1] << 8) + (chars[i * 4 + 2] << 16) + (chars[i * 4 + 3] << 24); } return temp; } private static function longsToChars(longs:Array):Array { var codes:Array = new Array( ); for (var i:Number = 0; i < longs.length ; i++) { codes.push( longs[i] & 0xFF, longs[i] >>> 8 & 0xFF, longs[i] >>> 16 & 0xFF, longs[i] >>> 24 & 0xFF ); } return codes; } private static function charsToHex(chars:Array):String { var result:String = new String( "" ); var hexes:Array = new Array( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" ); for (var i:Number = 0; i < chars.length ; i++) { result += hexes[chars[i] >> 4] + hexes[chars[i] & 0xf]; } return result; } private static function hexToChars(hex:String):Array { var codes:Array = new Array( ); for (var i:Number = (hex.substr( 0, 2 ) == "0x") ? 2 : 0; i < hex.length ; i += 2) { codes.push( parseInt( hex.substr( i, 2 ), 16 ) ); } return codes; } private static function charsToStr(chars:Array):String { var result:String = new String( "" ); for (var i:Number = 0; i < chars.length ; i++) { result += String.fromCharCode( chars[i] ); } return result; } private static function strToChars(str:String):Array { var codes:Array = new Array( ); for (var i:Number = 0; i < str.length ; i++) { codes.push( str.charCodeAt( i ) ); } return codes; } private function TEA() { } }