1  /**
     2   * com.sekati.crypt.TEA
     3   * @version 1.0.1
     4   * @author jason m horwitz | sekati.com
     5   * Copyright (C) 2007  jason m horwitz, Sekat LLC. All Rights Reserved.
     6   * Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
     7   * 
     8   * Sourced from ascrypt for dependencies only - version 2.0, author Mika Pamu
     9   * Original Javascript implementation:
    10   * Chris Veness, Movable Type Ltd: www.movable-type.co.uk
    11   * Algorithm: David Wheeler & Roger Needham, Cambridge University Computer Lab
    12   * @see http://www.movable-type.co.uk/scripts/TEAblock.html
    13   */
    14  
    15  import com.sekati.crypt.ICipher;
    16  
    17  /**
    18   * Encrypts and decrypts text with the TEA (Block) algorithm.
    19   */
    20  class com.sekati.crypt.TEA implements ICipher {
    21  
    22  	/**
    23  	 * Encrypts a string with the specified key.
    24  	 * @param src (String) string to encrypt
    25  	 * @param key (String) encryption key
    26  	 * @return String 
    27  	 */
    28  	public static function encrypt(src:String, key:String):String {
    29  		var v:Array = charsToLongs( strToChars( src ) );
    30  		var k:Array = charsToLongs( strToChars( key ) );
    31  		var n:Number = v.length;
    32  		if (n == 0) return "";
    33  		if (n == 1) v[n++] = 0;
    34  		var z:Number = v[n - 1], y:Number = v[0], delta:Number = 0x9E3779B9;
    35  		var mx:Number, e:Number, q:Number = Math.floor( 6 + 52 / n ), sum:Number = 0;
    36  		while (q-- > 0) {
    37  			sum += delta;
    38  			e = sum >>> 2 & 3;
    39  			for (var p:Number = 0; p < n - 1 ; p++) {
    40  				y = v[p + 1];
    41  				mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
    42  				z = v[p] += mx;
    43  			}
    44  			y = v[0];
    45  			mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
    46  			z = v[n - 1] += mx;
    47  		}
    48  		return charsToHex( longsToChars( v ) );
    49  	}
    50  
    51  	/**
    52  	 * Decrypts a string with the specified key.
    53  	 * @param src (String) string to decrypt
    54  	 * @param key (String) decryption key
    55  	 * @return String 
    56  	 */
    57  	public static function decrypt(src:String, key:String):String {
    58  		var v:Array = charsToLongs( hexToChars( src ) );
    59  		var k:Array = charsToLongs( strToChars( key ) );
    60  		var n:Number = v.length;
    61  		if (n == 0) return "";
    62  		var z:Number = v[n - 1], y:Number = v[0], delta:Number = 0x9E3779B9;
    63  		var mx:Number, e:Number, q:Number = Math.floor( 6 + 52 / n ), sum:Number = q * delta;
    64  		while (sum != 0) {
    65  			e = sum >>> 2 & 3;
    66  			for(var p:Number = n - 1; p > 0 ; p--) {
    67  				z = v[p - 1];
    68  				mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
    69  				y = v[p] -= mx;
    70  			}
    71  			z = v[n - 1];
    72  			mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
    73  			y = v[0] -= mx;
    74  			sum -= delta;
    75  		}
    76  		return charsToStr( longsToChars( v ) );
    77  	}
    78  
    79  	private static function charsToLongs(chars:Array):Array {
    80  		var temp:Array = new Array( Math.ceil( chars.length / 4 ) );
    81  		for (var i:Number = 0; i < temp.length ; i++) {
    82  			temp[i] = chars[i * 4] + (chars[i * 4 + 1] << 8) + (chars[i * 4 + 2] << 16) + (chars[i * 4 + 3] << 24);
    83  		}
    84  		return temp;
    85  	}
    86  
    87  	private static function longsToChars(longs:Array):Array {
    88  		var codes:Array = new Array( );
    89  		for (var i:Number = 0; i < longs.length ; i++) {
    90  			codes.push( longs[i] & 0xFF, longs[i] >>> 8 & 0xFF, longs[i] >>> 16 & 0xFF, longs[i] >>> 24 & 0xFF );
    91  		}
    92  		return codes;
    93  	}
    94  
    95  	private static function charsToHex(chars:Array):String {
    96  		var result:String = new String( "" );
    97  		var hexes:Array = new Array( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" );
    98  		for (var i:Number = 0; i < chars.length ; i++) {
    99  			result += hexes[chars[i] >> 4] + hexes[chars[i] & 0xf];
   100  		}
   101  		return result;
   102  	}
   103  
   104  	private static function hexToChars(hex:String):Array {
   105  		var codes:Array = new Array( );
   106  		for (var i:Number = (hex.substr( 0, 2 ) == "0x") ? 2 : 0; i < hex.length ; i += 2) {
   107  			codes.push( parseInt( hex.substr( i, 2 ), 16 ) );
   108  		}
   109  		return codes;
   110  	}
   111  
   112  	private static function charsToStr(chars:Array):String {
   113  		var result:String = new String( "" );
   114  		for (var i:Number = 0; i < chars.length ; i++) {
   115  			result += String.fromCharCode( chars[i] );
   116  		}
   117  		return result;
   118  	}
   119  
   120  	private static function strToChars(str:String):Array {
   121  		var codes:Array = new Array( );
   122  		for (var i:Number = 0; i < str.length ; i++) {
   123  			codes.push( str.charCodeAt( i ) );
   124  		}
   125  		return codes;
   126  	}
   127  
   128  	private function TEA() {
   129  	}
   130  }