
/*
@@@BUILDINFO@@@ TEA.jsx 1.0.1.0   4/16/07
*/
//acrobatconnect = {};
acrobatconnect.tea = {};


 
 /* ---------------------------------------------------------------------------------------- */
 /* CONVERSION FUNCTION
 ------------------- */
 acrobatconnect.tea.DecToHex = function (x) {
 	var s = '', x_ = !isNaN(Number(x)) ? Number(x) : 0;
 	while( Boolean( x_ ) ) { s = '0123456789ABCDEF'.charAt( x_ & 0xf ) + s; x_ >>>= 4; }
 	while ( s.length & 0x7 ) { s = '0' + s; } 
 	return ( s );
 }
 
  
 
 /* --------------------------------------------s-------------------------------------------- */
 /* RUNDOWN ON THE TINY ENCRYPTION ALGORITHM
 ------------------- */
 /* Tiny Encryption Algorithm (TEA) 
 
 	- http://vader.brad.ac.uk/tea/tea.shtml
 
 	The Tiny Encryption Algorithm (TEA) by David Wheeler and Roger Needham 
 		of the Cambridge Computer Laboratory.
 
 	Placed in the Public Domain by David Wheeler and Roger Needham.
 
 
 	TEA is a Feistel cipher with XOR and AND addition as the non-linear mixing functions. 
 
 	TEA takes 64 bits of data in v[0] and v[1], ( 2 x 4 bytes -> 8 ascii chars )
 		and 128 bits of key in k[0] - k[3]. ( 4 x 4 bytes -> 16 bytes )
 
 	The result is returned in w[0] and w[1]. ( 2 x 4 bytes -> 8 ascii chars )
 
 	Returning the result separately makes implementation of cipher modes
 		other than Electronic Code Book a little bit easier.
 
 	TEA can be operated in any of the modes of DES.
 
 	n is the number of iterations. 32 is ample, 16 is sufficient,
 		as few as eight should be OK for most applications,
 		especially ones where the data age quickly (real-time video, for example).
 
 	The algorithm achieves good dispersion after six iterations.
 	The iteration count can be made variable if required.
 
 	delta is chosen to be the Golden ratio ((5/4)1/2 - 1/2 ~ 0.618034) multiplied by 2^32
 
 	Which way round you call the functions is arbitrary:
 
 	DK(EK(P)) = EK(DK(P)) where EK and DK are encryption and decryption under key K respectively
 
 
 	This implementation follows the new variant developed in response 
 		to limitations pointed out by David Wagner 1997
 
 */
 
 
  acrobatconnect.tea.Encipher = function (p1, p2, k)
 {
 	var temp = new Array();
 	temp[0] = 1; // an error flag
 	temp[1] = new Number(p1);
 	temp[2] = new Number(p2);
 
 	var sum = 0;
 	var delta = 0x9E3779B9;
 	var n = 32;
 
 	while ( n-- > 0 )
 	{
 		temp[1] = temp[1] + ( ( temp[2] << 4 ^ temp[2] >> 5 ) + temp[2] ^ sum + k[ ( sum & 3 ) ] );		
 		sum = sum + delta;
 		temp[2] = temp[2] + ( ( temp[1] << 4 ^ temp[1] >> 5 ) + temp[1] ^ sum + k[ ( sum >> 11 & 3 ) ] );
 	}
 
 	// for the error flag maybe check for negative numbers
 
 	return( temp );
 
 }
 
 
 acrobatconnect.tea.Decipher =  function (p1, p2, k)
 {
 	var temp = new Array();
 	temp[0] = 1; // an error flag
 	temp[1] = new Number(p1);	
 	temp[2] = new Number(p2);
 
 	// sum = delta << 5, in general sum = delta * n
 
 	var sum   = 0xC6EF3720;
 	var delta = 0x9E3779B9;
 	var n     = 32;
 
 	while ( n-- > 0 )
 	{
 		temp[2] = temp[2] - ( ( temp[1] << 4 ^ temp[1] >> 5 ) + temp[1] ^ sum + k[ ( sum >> 11 & 3 )] );		
 		sum = sum - delta;
 		temp[1] = temp[1] - ( ( temp[2] << 4 ^ temp[2] >> 5 ) + temp[2] ^ sum + k[ ( sum & 3 ) ] );		
 
 	}
 
 	// for the error flag maybe check for negative numbers
 
 	return( temp );
 
 }

  acrobatconnect.tea.BuildKey = function (str)
 {
 		var k = new Array();
		if(str.length < 4)
			str += "!@%&";
 		k[0] = new Number(str.charCodeAt( str.length - 1) );
 		k[1] = new Number(str.charCodeAt(str.length - 2) );
 		k[2] = new Number(str.charCodeAt(str.length - 3) );
 		k[3] = new Number(str.charCodeAt(str.length - 4) );
		return k;
  }
 
 
 /* ---------------------------------------------------------------------------------------- */
 /* WORKHORSE FUNCTION #1
 ------------------- */
 
acrobatconnect.tea.TEAencrypt = function (inString, key)
 {
	key = acrobatconnect.tea.BuildKey(key);	

	// init local variables
 	var p1D = 0; var p2D = 0;	
 	var res = null; var outString = '';
 	
 	// predetermine inverse string length
 	var invlen = 100/inString.length;
 
 	// initialize an error flag of 64 bits
 	// include the newlines so it's even easier to spot
 	// alternatively issue a report to the status field
 	var errormark = "!!!!!!!\x0d\x0d!!!!!!!";

 	// pad the input so that it's a multiple of 8
 	while ( inString.length & 0x7 ) { inString += '\t'; }
 
 	var i = 0;
 	while ( i < inString.length ) {
 
 		// slam 4 bytes into a dword 
 		p1D  = inString.charCodeAt(i++); 		
 		p1D |= inString.charCodeAt(i++) << 16; 		
 
 		// mask off 32 bits to be safe
 		// javascript numbers are 64 bit IEEE double doubles
 		p1D &= 0xFFFFFFFF;
 
 		// slam 4 bytes into a dword
 		p2D  = inString.charCodeAt(i++); 		
 		p2D |= inString.charCodeAt(i++) << 16; 		
 
 		// mask off 32 bits to be safe
 		// javascript numbers are 64 bit IEEE double doubles
 		p2D &= 0xFFFFFFFF;
 
 		// send dwords to be enciphered
 		res =  acrobatconnect.tea.Encipher(p1D, p2D, key);
 
 		// check the validity flag
 		// convert the results to hex to facilitate deciphering - 16 chars generated per turn
 		// append the hex values to the output buffer 
 		// do not include any new lines - the form is set to wrap
 
 		// the validity flag defaults to true because I'm not certain what to check for ;-)
 
 		outString += ( res[0] ? '' + acrobatconnect.tea.DecToHex(res[1]) +  acrobatconnect.tea.DecToHex(res[2]) :   errormark );
		if( !res[0]  )
			throw new Error("error in DecToHex");
 		// later perhaps the outString should be chunked up
 		// along the lines of B64 email attachments
 		// although 0-9 and A-F are 6 and 7 bit values respectively
 		// it's really a question of post limitations on the http server
 
 		// clear the temporary variables
 		p1D = 0; p2D = 0; res = null;
  		
 	}
  
 	return  outString;
 
 }
 
 /* ---------------------------------------------------------------------------------------- */
 /* WORKHORSE FUNCTION #2
 ------------------- */
 
acrobatconnect.tea.TEAdecrypt = function (inString, key)
 {
 
	key = acrobatconnect.tea.BuildKey(key);
	
 	if ( inString.length < 1 ) {  		
 		return '';
 	}
   
 	// predetermine inverse string length
 	var invlen = 100/inString.length;
 
 	// init local variables
 	var p3H = ''; var p4H = '';
 	var p3D = 0;  var p4D = 0;
 	var res = null; var outString = '';
 
 	// loop through input string
 	var i = 0; 
 	while ( i < inString.length ) {
 
 		// should check for our errormarker too!
 
 		// 8 hex chars make a dword 
 		// - unloop de loop - it's faster
 		p3H += inString.charAt(i++); // 1
 		p3H += inString.charAt(i++); // 2
 		p3H += inString.charAt(i++); // 3
 		p3H += inString.charAt(i++); // 4
 		p3H += inString.charAt(i++); // 5
 		p3H += inString.charAt(i++); // 6
 		p3H += inString.charAt(i++); // 7
 		p3H += inString.charAt(i++); // 8
 
 		// 8 hex chars make a dword 
 		// - unloop de loop - it's faster
 		p4H += inString.charAt(i++); // 1
 		p4H += inString.charAt(i++); // 2
 		p4H += inString.charAt(i++); // 3
 		p4H += inString.charAt(i++); // 4
 		p4H += inString.charAt(i++); // 5
 		p4H += inString.charAt(i++); // 6
 		p4H += inString.charAt(i++); // 7
 		p4H += inString.charAt(i++); // 8
 
 		// convert hex strings to dwords
 		p3D = parseInt(p3H,16);
 		p4D = parseInt(p4H,16);
 
 		// pass dwords to decipher routine
 		res =  acrobatconnect.tea.Decipher(p3D, p4D, key);
 
 		// transform results back into alphanumic characters
 		// check validity flag - always defaults true ...
 		if ( res[0] ) {
 
 			// unpack first dword
 			outString += String.fromCharCode( ( res[1] & 0x0000FFFF ) ); 			
 			outString += String.fromCharCode( ( res[1] & 0xFFFF0000 ) >> 16 ); 			
 
 			// unpack second dword
 			outString += String.fromCharCode( ( res[2] & 0x0000FFFF ) ); 			
 			outString += String.fromCharCode( ( res[2] & 0xFFFF0000 ) >> 16 ); 			
 
 		}
 		
 		// reset temporary variables
 		p3H = ''; p4H = '';
 		p3D = 0;  p4D = 0;
 		res = null;
 
 	}
	//Remove trailing tabs
	outString = outString.replace(/(\u0009*$)/g, '' );		

 	return outString;
 
 }
 //acrobatconnect.tea.TEAdecrypt( app.preferences.acrobatconnect_password, app.preferences.acrobatconnect_meetingURL );


