Difference between revisions of "XTEA Strong Encryption Implementation"

From Second Life Wiki
Jump to navigation Jump to search
m (language tags to <source>)
 
(13 intermediate revisions by 6 users not shown)
Line 8: Line 8:
*{{User|Strife Onizuka}} (blindwandererATgmail.com)
*{{User|Strife Onizuka}} (blindwandererATgmail.com)
*[http://dedricmauriac.wordpress.com/ Dedric Mauriac], Contributor (dedric.mauriacATgmail.com)
*[http://dedricmauriac.wordpress.com/ Dedric Mauriac], Contributor (dedric.mauriacATgmail.com)
*{{User|JB_Kraft}} (php 5 class)


= License =
= License =
This work is licensed under a [http://creativecommons.org/licenses/by/3.0/ Creative Commons Attribution-Share Alike 3.0 Unported License]
This work is licensed under a [http://creativecommons.org/licenses/by/3.0/ Creative Commons Attribution 3.0 Unported License]


You are free:
You are free:
Line 50: Line 51:
If you plan to place this code into the same script as that needing encryption facilities, you need only call the following functions:
If you plan to place this code into the same script as that needing encryption facilities, you need only call the following functions:


<lsl>
<source lang="lsl2">
string Encrypt(string clearText)
string Encrypt(string clearText)
string Decrypt(string cypherText)
string Decrypt(string cypherText)
</lsl>
</source>


Simple as that.
Simple as that.
Line 62: Line 63:


==Changes==
==Changes==
===Version 1.1===
*Changed to treat [[Right Shift]] as if integers were unsigned


===Version 1.0a - Alpha===
===Version 1.0a - Alpha===
Line 80: Line 84:


= Code =
= Code =
== Documentation Comments ==
 
These comments must appear within the script. The script must be modifiable (open-source) even when sold with your product. You may wish to have your encryption script separated from the actual business logic of your objects to protect your IP.
 
<lsl>
 
 
== Original ==
<source lang="lsl2">
//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)
//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)
//Version 1.0
//Version 1.0
Line 184: Line 192:
//deadbolt on the front door or walking in through the back door that you  
//deadbolt on the front door or walking in through the back door that you  
//left open.
//left open.
</lsl>


== Cipher ==
//******************USER-CONFIGURABLE GLOBALS BEGIN HERE*******************
The XTEA cipher is at the heart of this script. It encrypts/decrypts a block of 64 bits at a time (the equivalent of two 32-bit integers or eight bytes).
 
//ENCRYPTION KEYS KEY[1-4]
//These together make up the 128-bit XTEA encryption key.  See the above
//documentation for details. Whatever you do, don't leave them as the default.
integer KEY1 = 11111111;
integer KEY2 = 22222222;
integer KEY3 = 33333333;
integer KEY4 = 44444444;


=== Encryption ===
//DEBUG_FLAG
This is the implementation of XTEA proper.  It takes a block of clear-text consisting of two dwords contained in LSL integers and a 128-bit key contained in an LSL list of 4 integers.  The function then returns the cyphertext in an LSL list of two integers.
//If set to 1, will cause debug text to be printed containing some
<lsl>
//intermediate cleartext/cyphertext and the resultant cyphertext/cleartext.   
list TEAEncrypt(integer dword1, integer dword2,list cypherkey){
//Do not leave this enabled in production environments!!!!
   
integer DEBUG_FLAG = 0;
            list cryptlist = [];
 
//COMM_CHANNEL
            //Set n to the number of cycles given in the CYCLES global variable
//Specifies which channel should be used for debug and test harness communication.
            integer n = CYCLES;
integer COMM_CHANNEL = 0;
 
            integer sum = 0;
//CYCLES
//Specifies the number of rounds to be usedSee the above documentation for
            //Operate for the specified number of cycles.
//details.
            while (n-- > 0){
integer CYCLES = 6;
                dword1 = dword1 + ( ( dword2 << 4 ^ dword2 >> 5 ) + dword2 ^ sum + llList2Integer(cypherkey, (sum & 3) ) );
 
                sum += delta;
//******************USER-CONFIGURABLE GLOBALS END HERE*********************
                dword2 = dword2 + ( ( dword1 << 4 ^ dword1 >> 5 ) + dword1 ^ sum + llList2Integer(cypherkey, (sum >> 11 & 3) ) );
            }
            cryptlist = [dword1,dword2];
            return cryptlist;
}
</lsl>
=== Decryption ===
This is the implementation of XTEA proper.  It takes a block of cypher-text consisting of two dwords contained in LSL integers and a 128-bit key contained in an LSL list of 4 integersThe function then returns the clear-text in an LSL list of two integers.
<lsl>
list TEADecrypt(integer dword1, integer dword2,list cypherkey)
{
            list cryptlist = [];
            //Set n to the number of cycles given in the CYCLES global variable
            integer n = CYCLES;
            integer sum = delta * CYCLES;
            //Operate for the specified number of cycles.       
            while (n-- > 0){
                dword2 = dword2 - ( ( dword1 << 4 ^ dword1 >> 5 ) + dword1 ^ sum + llList2Integer(cypherkey, (sum >> 11 & 3) ) );
                sum -= delta;
                dword1 = dword1 - ( ( dword2 << 4 ^ dword2 >> 5 ) + dword2 ^ sum + llList2Integer(cypherkey, (sum & 3) ) );       
            }
            cryptlist = [dword1,dword2];
            return cryptlist;
}
</lsl>


== Original ==
//Other Globals
<lsl>
list cypherkey = [];
integer delta = 0x9E3779B9;
//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)
 
//Version 1.0
 
//Copyright (C) 2007 by Morse Dillon (morseATmorsedillon.com)
 
//
//Function: ord
//This program is free software; you can redistribute it and/or
//Returns the index of an ASCII character
//modify it under the terms of the GNU General Public License
integer ord(string chr)
//as published by the Free Software Foundation; either version 2
{
//of the License, or (at your option) any later version.
    string ASCII = "            \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
//
    if(llStringLength(chr) != 1) return -1;
//This program is distributed in the hope that it will be useful,
    if(chr == " ") return 32;
//but WITHOUT ANY WARRANTY; without even the implied warranty of
    return llSubStringIndex(ASCII, chr);
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
}
//GNU General Public License for more details.
 
//
 
//You should have received a copy of the GNU General Public License
 
//along with this program; if not, write to the Free Software
//Function: chr
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
//Returns the ASCII character correspondent to index i
//02110-1301, USA.
string chr(integer i)
//========================================================================
{
//
    string ASCII = "            \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
//Included at the end of this source listing is a small bit of example
    i %= 127;
//code that shows the usage.  If you wish to include this implementation
    return llGetSubString(ASCII, i, i);
//in your own work, just replace the example code with your own. Also,
}
//please do not reuse or redistribute this work without including the
 
//above text attributing this code to its author Morse Dillon, the above
 
//GPL statement, and this documentation.
                   
//
//Function:  DWord2Hex
//This is an implentation of the XTEA (eXtended Tiny Encryption Algorithm)  
//Converts a dword containted in a LSL integer to hexadecimal format.       
//block cypher.  (X)TEA is a very good choice of cipher when security
string DWord2Hex(integer m){
//is important but computational power is limited. Although I did a
   
//lot of work on this implementation, enormous amounts of credit must
    string result;
//be given to the creators of the algorithm and those who came before
    integer i = 0;
//me to implement it in other languages and computing environments.
    integer index = 0;
//
   
//***If you do decide to use this code in a project, I'd appreciate
    //Define character string [0-F] for use in building the hex.
//hearing about it.  You can reach me by e-mail at: 
    string characters = "0123456789ABCDEF"; 
//morseATmorsedillon.com
   
//
    //Step through 8 times, for a total of 32 bits, 8 nibbles, and 8 hexadecimal digits.
//
    for (i = 0; i < 8; i++){
//ABOUT TEA AND XTEA
        //Get a nibble by right-shifting and masking off 4 bits.
//------------------
        index = (m >> (i * 4)) & 0xF;
//TEA was originally designed by David Wheeler and Roger Needham
        //Grab character from the characters string at index position and add it to the result string.
//of the Cambridge Computer Laboratory.  The algorithm itself is not
        result = llInsertString(result, 0, llGetSubString(characters,index,index));
//subject to any patents.  While the original TEA was found to have
    }
//some minor weaknesses, XTEA (implemented herein) addresses these. 
   
//
    return result;
//TEA and its derivatives consist of 64-bit block Feistel network
}
//with a 128-bit key.  This implementation uses six cycles, or rounds,
 
//which is less than one would like but still provides a reasonable
 
//level of security (16 is sufficient while 8 is enough for most
 
//applications).  Six is said to achieve theoretically good dispersion,
//Function:  Hex2DWword
//but should more security be desired the number of cycles can easily be
//Converts a string containing a hexadecimal number to a dword contained in a LSL integer.
//modified by changing the CYCLES global variable.  Due to the low
integer Hex2DWord(string m){
//execution speed of LSL scripts, it's suggested to make this as low as
    integer result = 0;
//your comfort level allows.  Encryption time scales linearly with the
    integer i = 0;
//number of cycles.
    string digit;
//
    integer value;
//For more information about XTEA, see the following:
    integer index;
//
   
//Original Paper by Walker and Needham
    string characters = "0123456789ABCDEF";
//http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html
   
//
    for (i = 0; i < 8; i++){
//Wikipedia on TEA
       
//http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
        index = 8 - (i + 1);
//
        digit = llGetSubString(m,index,index);
//
       
//ABOUT THIS IMPLEMENTATION
        value = llSubStringIndex(characters, digit);
//-------------------------
                       
//This is a barebones implementation, and is meant to be included in
        result = result | value << (i * 4);
//the body of the script needing encryption facilities or wrapped
       
//in a link message handler.  If the latter approach is desired, care
    }
//should be taken to only send link messages to the prim containing
   
//this implementation.  If ALL_PRIMS is used as the destination,
    return result;
//one could link a link message listener to the object and intercept
}
//cleartext communications. 
 
//
 
//If you plan to place this code into the same script as that needing
 
//encryption facilities, you need only call the following functions:
//Function: Encrypt
//
//Takes cleartext string, pads and bitpacks it, then encrypts it using TEAEncrypt().
//string Encrypt(string cleartext)
string Encrypt(string cleartext){
//string Decrypt(string cyphertext)
       
//
        //Initialize variables.
//Simple as that.
        integer dword1 = 0;
//
        integer dword2 = 0;
//This implementation does not provide any secure key exchange, so in
        integer cyphertext_numeric;
//terms of key generation and exchange you're on your own.
        list cypherblock;
//
        string cyphertext = "";
//The 128-bit key is contained in four LSL integers: KEY1, KEY2, KEY3,
 
//and KEY4. These are global variables at the beginning of the source
        //Pad cleartext string to the nearest multiple of 8.
//and can be set using a method that works for you.
        while(llStringLength(cleartext) & 0x7) {
//
            cleartext += " ";
//
        }
//**************IF YOU READ ONE THING IN HERE, READ THIS*******************
       
//It is VERY important to remember that there is no such thing as
        //Define more variables pertaining to while loop.
//'cookbook cryptography'! Simply using this cypher does not guarantee
        integer stringlength = llStringLength(cleartext);
//security. Security is an end-to-end concern and responsibility lies
        integer i=0;
//with you to thoroughly examine your project from all possible angles
        integer character;
//if valuable data is at risk. If you doubt this, ask any thief how they'd
       
//rather break into your house - futzing about with picking a high-security
        //Step through cleartext string, encrypting it in 64-bit (8 character) blocks.
//deadbolt on the front door or walking in through the back door that you
        while (i < stringlength){
//left open.
           
 
            //Pack dword1 with 4 bytes. Do so by bit-shifting in each character.
//******************USER-CONFIGURABLE GLOBALS BEGIN HERE*******************
            //4th byte winds up in the most-significant position.
 
            dword1 =  ord(llGetSubString(cleartext,i,i));
//ENCRYPTION KEYS KEY[1-4]
            i++;
//These together make up the 128-bit XTEA encryption key.  See the above
            dword1 = dword1 | (ord(llGetSubString(cleartext,i,i)) << 8);
//documentation for details.  Whatever you do, don't leave them as the default.
            i++;
integer KEY1 = 11111111;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) << 16);
integer KEY2 = 22222222;
            i++;
integer KEY3 = 33333333;
            dword1 = dword1 | (ord(llGetSubString(cleartext,i,i)) << 24);
integer KEY4 = 44444444;
            i++;
           
            //Do it again, this time for dword2                           
            dword2 =  ord(llGetSubString(cleartext,i,i));
            i++;
            dword2 = dword2 | ord(llGetSubString(cleartext,i,i)) << 8;
            i++;
            dword2 = dword2 | ord(llGetSubString(cleartext,i,i)) << 16;
            i++;
            dword2 = dword2 | ord(llGetSubString(cleartext,i,i)) << 24;
            i++;
 
            //Call TEAencrypt() with dword1, dword2, and the cypher key and store result in cypherblock.
            cypherblock = TEAEncrypt(dword1,dword2,cypherkey);
            //Convert dword values from cypherblock to hex and append to cyphertext.
            cyphertext = cyphertext + DWord2Hex(llList2Integer(cypherblock,0)) + DWord2Hex(llList2Integer(cypherblock,1));
                   
            //Reset variables for the next round, just to be safe.
            dword1 = 0;
            dword2 = 0;
            cypherblock = [];
           
            if(DEBUG_FLAG){
                llOwnerSay("Pre-Crypt DWords: " + (string)dword1 + "," + (string)dword2);
                llOwnerSay("Post-Crypt DWords: " + (string)llList2Integer(cypherblock,1) + "," + (string)llList2Integer(cypherblock,2));   
                llOwnerSay("Post-Crypt Hex: " + DWord2Hex(llList2Integer(cypherblock,1)) + "," + DWord2Hex(llList2Integer(cypherblock,2)));
            }
           
        } 
       
        return cyphertext;      


//DEBUG_FLAG
//If set to 1, will cause debug text to be printed containing some
//intermediate cleartext/cyphertext and the resultant cyphertext/cleartext. 
//Do not leave this enabled in production environments!!!!
integer DEBUG_FLAG = 0;


//COMM_CHANNEL
//Specifies which channel should be used for debug and test harness communication.
integer COMM_CHANNEL = 0;


//CYCLES
//Function: Decrypt
//Specifies the number of rounds to be used. See the above documentation for
//Takes cyphertext, decrypts it with TEADecrypt(), and unpacks it into a string.
//details.
string Decrypt(string cyphertext){
integer CYCLES = 6;
       
 
        //Initialize variables.
//******************USER-CONFIGURABLE GLOBALS END HERE*********************
        string hexvalue1 = "";
 
        string hexvalue2 = "";
//Other Globals
        integer dword1 = 0;
list cypherkey = [];
        integer dword2 = 0;
integer delta = 0x9E3779B9;
        list clearblock = []; //res
 
        string cleartext = "";
 
        integer i;
 
       
//Function: ord
       
//Returns the index of an ASCII character
        //Step through cyphertext string, descrypting it block by block.
integer ord(string chr)
        while (i < llStringLength(cyphertext)){
{
           
    string ASCII = "            \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
            //Pull first 32 bits worth of hexadecimal into hexvalue1
    if(llStringLength(chr) != 1) return -1;
            hexvalue1 += llGetSubString(cyphertext,i,i + 7);
    if(chr == " ") return 32;
            i = i + 8;
    return llSubStringIndex(ASCII, chr);
           
}
            //Pull second 32 bits worth of hexadecimal into hexvalue2
            hexvalue2 += llGetSubString(cyphertext,i,i + 7);
            i = i + 8;


            //Convert hexvalues to dwords contained in LSL integers.
            dword1 = Hex2DWord(hexvalue1);
            dword2 = Hex2DWord(hexvalue2);
   
            //Call TEADecrypt() with dword1, dword2, and the cypher key and store result in clearblock list.
            clearblock = TEADecrypt(dword1, dword2, cypherkey);
           
            //Append first 4 characters of ASCII to cleartext string.
            //This is done by pulling the decrypted dwords from the clearblock list and looking up their ASCII values.
            cleartext += chr( llList2Integer(clearblock,0) & 0x000000FF);
            cleartext += chr( (llList2Integer(clearblock,0) & 0x0000FF00)  >> 8);
            cleartext += chr( (llList2Integer(clearblock,0) & 0x00FF0000)  >> 16);
            cleartext += chr( (llList2Integer(clearblock,0) & 0xFF000000)  >> 24);


            //Append second 4 characters of ASCII to cleartext string.
            cleartext += chr( llList2Integer(clearblock,1) & 0x000000FF);
            cleartext += chr( (llList2Integer(clearblock,1) & 0x0000FF00)  >> 8);
            cleartext += chr( (llList2Integer(clearblock,1) & 0x00FF0000)  >> 16);
            cleartext += chr( (llList2Integer(clearblock,1) & 0xFF000000)  >> 24);
            //Reset variables for the next two blocks of decrypt.           
            hexvalue1 = "";
            hexvalue2 = "";
            dword1 = 0;
            dword2 = 0;
            clearblock = [];
           
            if(DEBUG_FLAG){
                llOwnerSay("Pre-Decrypt Hex: " + hexvalue1 + "," + hexvalue2);
                llOwnerSay("Pre-Decrypt DWords: " + (string)dword1 + "," + (string)dword2);
                llOwnerSay("Post-Decrypt DWords: " + (string)llList2Integer(clearblock,1) + "," + (string)llList2Integer(clearblock,2));
            }
           
        }
               
        return cleartext;       
}


//Function: chr
//Returns the ASCII character correspondent to index i
string chr(integer i)
{
    string ASCII = "            \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
    i %= 127;
    return llGetSubString(ASCII, i, i);
}
 
                   
//Function:  DWord2Hex
//Converts a dword containted in a LSL integer to hexadecimal format.       
string DWord2Hex(integer m){
   
    string result;
    integer i = 0;
    integer index = 0;
   
    //Define character string [0-F] for use in building the hex.
    string characters = "0123456789ABCDEF"; 
   
    //Step through 8 times, for a total of 32 bits, 8 nibbles, and 8 hexadecimal digits.
    for (i = 0; i < 8; i++){
        //Get a nibble by right-shifting and masking off 4 bits.
        index  = (m >> (i * 4)) & 0xF;
        //Grab character from the characters string at index position and add it to the result string.
        result = llInsertString(result, 0, llGetSubString(characters,index,index));
    }
   
    return result;
}
//Function:  Hex2DWword
//Converts a string containing a hexadecimal number to a dword contained in a LSL integer.
integer Hex2DWord(string m){
    integer result = 0;
    integer i = 0;
    string digit;
    integer value;
    integer index;
   
    string characters = "0123456789ABCDEF";
   
    for (i = 0; i < 8; i++){
       
        index = 8 - (i + 1);
        digit = llGetSubString(m,index,index);
       
        value = llSubStringIndex(characters, digit);
                       
        result = result | value << (i * 4);
       
    }
   
    return result;
}




//Function: TEAEncrypt
//This is the implementation of XTEA proper.  It takes a block of cleartext
//consisting of two dwords contained in LSL integers and a 128-bit key
//contained in an LSL list of 4 integers.  The function then returns
//the cyphertext in an LSL list of two integers.
list TEAEncrypt(integer dword1, integer dword2,list cypherkey){
   
            list cryptlist = [];
           
            //Set n to the number of cycles given in the CYCLES global variable
            integer n = CYCLES;
                       
            integer sum = 0;
           
            //Operate for the specified number of cycles.
            while (n-- > 0){
                dword1 = dword1 + ( ( dword2 << 4 ^ ((dword2 >> 5) & 0x07FFFFFF) ) + dword2 ^ sum + llList2Integer(cypherkey, (sum & 3) ) );
                sum += delta;
                dword2 = dword2 + ( ( dword1 << 4 ^ ((dword1 >> 5) & 0x07FFFFFF) ) + dword1 ^ sum + llList2Integer(cypherkey, ((sum >> 11) & 3) ) );
            }
           
            cryptlist = [dword1,dword2];
            return cryptlist;
}


//Function: Encrypt
 
//Takes cleartext string, pads and bitpacks it, then encrypts it using TEAEncrypt().
 
string Encrypt(string cleartext){
//Function: TEADecrypt
       
//This is the implementation of XTEA proper. It takes a block of cyphertext
        //Initialize variables.
//consisting of two dwords contained in LSL integers and a 128-bit key
        integer dword1 = 0;
//contained in an LSL list of 4 integers. The function then returns
        integer dword2 = 0;
//the cleartext in an LSL list of two integers.
        integer cyphertext_numeric;
list TEADecrypt(integer dword1, integer dword2,list cypherkey){
        list cypherblock;
   
        string cyphertext = "";
             list cryptlist = [];
 
        //Pad cleartext string to the nearest multiple of 8.
        while(llStringLength(cleartext) & 0x7) {
             cleartext += " ";
        }
       
        //Define more variables pertaining to while loop.
        integer stringlength = llStringLength(cleartext);  
        integer i=0;
        integer character;
       
        //Step through cleartext string, encrypting it in 64-bit (8 character) blocks.
        while (i < stringlength){
              
              
             //Pack dword1 with 4 bytes.  Do so by bit-shifting in each character.
             //Set n to the number of cycles given in the CYCLES global variable
             //4th byte winds up in the most-significant position.
            integer n = CYCLES;
             dword1 =  ord(llGetSubString(cleartext,i,i));
                       
            i++;
            integer sum = delta * CYCLES;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) << 8);
 
            i++;
             //Operate for the specified number of cycles.      
            dword1 = dword1 | (ord(llGetSubString(cleartext,i,i)) << 16);
             while (n-- > 0){
            i++;
                dword2 = dword2 - ( ( dword1 << 4 ^ ((dword1 >> 5) & 0x07FFFFFF) ) + dword1 ^ sum + llList2Integer(cypherkey, ((sum >> 11) & 3) ) );
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) << 24);
                sum -= delta;
             i++;
                dword1 = dword1 - ( ( dword2 << 4 ^ ((dword2 >> 5) & 0x07FFFFFF) ) + dword2 ^ sum + llList2Integer(cypherkey, (sum & 3) ) );      
             }
              
              
             //Do it again, this time for dword2                           
             cryptlist = [dword1,dword2];
            dword2 = ord(llGetSubString(cleartext,i,i));
             return cryptlist;
            i++;
}
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) << 8;
</source>
            i++;
             dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) << 16;
            i++;
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) << 24;
            i++;


            //Call TEAencrypt() with dword1, dword2, and the cypher key and store result in cypherblock.
== Usage Example ==
            cypherblock = TEAEncrypt(dword1,dword2,cypherkey);
Listens on COMM_CHANNEL for a message and encrypts it, then turns around and decrypts the resultant cypher-text. Object than says the encrypted and decrypted messages to the owner.
<source lang="lsl2">
            //Convert dword values from cypherblock to hex and append to cyphertext.
default
            cyphertext = cyphertext + DWord2Hex(llList2Integer(cypherblock,0)) + DWord2Hex(llList2Integer(cypherblock,1));
{
                   
    state_entry()
            //Reset variables for the next round, just to be safe.
    {
            dword1 = 0;
        llListen(COMM_CHANNEL, "", NULL_KEY, "");
            dword2 = 0;
        cypherkey = [KEY1,KEY2,KEY3,KEY4];
            cypherblock = [];
    }
           
 
            if(DEBUG_FLAG){
    listen(integer channel, string name, key id, string message)
                llOwnerSay("Pre-Crypt DWords: " + (string)dword1 + "," + (string)dword2);
    {
                llOwnerSay("Post-Crypt DWords: " + (string)llList2Integer(cypherblock,1) + "," + (string)llList2Integer(cypherblock,2));  
         string temp_cyphertext = Encrypt(message);
                llOwnerSay("Post-Crypt Hex: " + DWord2Hex(llList2Integer(cypherblock,1)) + "," + DWord2Hex(llList2Integer(cypherblock,2)));
            }
           
        
          
          
         return cyphertext;      
         string temp_cleartext = Decrypt(temp_cyphertext);
}
       
 
        llOwnerSay("\nOriginal Cleartext: " + message + "\nCyphertext: " + temp_cyphertext + "\nDecrypted Cleartext: " + temp_cleartext);
    }
}
</source>


== Optimized ==
This version is untested but if it works should run faster (and be able to handle larger strings).


//Function: Decrypt
<source lang="lsl2">
//Takes cyphertext, decrypts it with TEADecrypt(), and unpacks it into a string.
// Include the documentation comments from above (separated here only for easier management)
string Decrypt(string cyphertext){
 
       
//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)
        //Initialize variables.
//Version 1.0a Alpha
        string hexvalue1 = "";
//Copyright (C) 2007 by Strife Onizuka (blindwandererATgmail.com)
        string hexvalue2 = "";
//
        integer dword1 = 0;
//Version 1.0
        integer dword2 = 0;
//Copyright (C) 2007 by Morse Dillon (morseATmorsedillon.com)
        list clearblock = []; //res
//
        string cleartext = "";
//This program is free software; you can redistribute it and/or
        integer i;
//modify it under the terms of the GNU General Public License
       
//as published by the Free Software Foundation; either version 2
       
//of the License, or (at your option) any later version.
        //Step through cyphertext string, descrypting it block by block.
//
        while (i < llStringLength(cyphertext)){
//This program is distributed in the hope that it will be useful,
           
//but WITHOUT ANY WARRANTY; without even the implied warranty of
            //Pull first 32 bits worth of hexadecimal into hexvalue1
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
            hexvalue1 += llGetSubString(cyphertext,i,i + 7);
//GNU General Public License for more details.
            i = i + 8;
//
           
//You should have received a copy of the GNU General Public License
            //Pull second 32 bits worth of hexadecimal into hexvalue2
//along with this program; if not, write to the Free Software
            hexvalue2 += llGetSubString(cyphertext,i,i + 7);
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
            i = i + 8;
//02110-1301, USA.
 
//========================================================================
            //Convert hexvalues to dwords contained in LSL integers.
//
            dword1 = Hex2DWord(hexvalue1);
//Included at the end of this source listing is a small bit of example
            dword2 = Hex2DWord(hexvalue2);
//code that shows the usage.  If you wish to include this implementation
   
//in your own work, just replace the example code with your own.  Also,  
            //Call TEADecrypt() with dword1, dword2, and the cypher key and store result in clearblock list.
//please do not reuse or redistribute this work without including the
            clearblock = TEADecrypt(dword1, dword2, cypherkey);
//above text attributing this code to its author Morse Dillon, the above
           
//GPL statement, and this documentation.
            //Append first 4 characters of ASCII to cleartext string.
//
            //This is done by pulling the decrypted dwords from the clearblock list and looking up their ASCII values.
//This is an implentation of the XTEA (eXtended Tiny Encryption Algorithm)  
            cleartext += chr( llList2Integer(clearblock,0) & 0x000000FF);
//block cypher.  (X)TEA is a very good choice of cipher when security
            cleartext += chr( (llList2Integer(clearblock,0) & 0x0000FF00) >> 8);
//is important but computational power is limited.  Although I did a
            cleartext += chr( (llList2Integer(clearblock,0) & 0x00FF0000)  >> 16);
//lot of work on this implementation, enormous amounts of credit must
            cleartext += chr( (llList2Integer(clearblock,0) & 0xFF000000>> 24);
//be given to the creators of the algorithm and those who came before
 
//me to implement it in other languages and computing environments.
            //Append second 4 characters of ASCII to cleartext string.
//
            cleartext += chr( llList2Integer(clearblock,1) & 0x000000FF);
//***If you do decide to use this code in a project, I'd appreciate
            cleartext += chr( (llList2Integer(clearblock,1) & 0x0000FF00)  >> 8);
//hearing about it.  You can reach me by e-mail at: 
            cleartext += chr( (llList2Integer(clearblock,1) & 0x00FF0000>> 16);
//morseATmorsedillon.com
            cleartext += chr( (llList2Integer(clearblock,1) & 0xFF000000)  >> 24);
//
 
//
            //Reset variables for the next two blocks of decrypt.          
//ABOUT TEA AND XTEA
            hexvalue1 = "";
//------------------
            hexvalue2 = "";
//TEA was originally designed by David Wheeler and Roger Needham
            dword1 = 0;
//of the Cambridge Computer Laboratory. The algorithm itself is not
            dword2 = 0;
//subject to any patents. While the original TEA was found to have
            clearblock = [];
//some minor weaknesses, XTEA (implemented herein) addresses these.  
           
//
            if(DEBUG_FLAG){
//TEA and its derivatives consist of 64-bit block Feistel network
                llOwnerSay("Pre-Decrypt Hex: " + hexvalue1 + "," + hexvalue2);
//with a 128-bit key. This implementation uses six cycles, or rounds,
                llOwnerSay("Pre-Decrypt DWords: " + (string)dword1 + "," + (string)dword2);
//which is less than one would like but still provides a reasonable
                llOwnerSay("Post-Decrypt DWords: " + (string)llList2Integer(clearblock,1) + "," + (string)llList2Integer(clearblock,2));
//level of security (16 is sufficient while 8 is enough for most
            }
//applications). Six is said to achieve theoretically good dispersion,  
           
//but should more security be desired the number of cycles can easily be
        }
//modified by changing the CYCLES global variable. Due to the low
               
//execution speed of LSL scripts, it's suggested to make this as low as
        return cleartext;       
//your comfort level allows.  Encryption time scales linearly with the
}
//number of cycles.
 
//
 
//For more information about XTEA, see the following:
 
//
//Function: TEADecrypt
//Original Paper by Walker and Needham
//This is the implementation of XTEA proper.  It takes a block of cleartext
//http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html
//consisting of two dwords contained in LSL integers and a 128-bit key
//
//contained in an LSL list of 4 integersThe function then returns
//Wikipedia on TEA
//the cyphertext in an LSL list of two integers.
//http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
list TEAEncrypt(integer dword1, integer dword2,list cypherkey){
//
   
//
            list cryptlist = [];
//ABOUT THIS IMPLEMENTATION
           
//-------------------------
            //Set n to the number of cycles given in the CYCLES global variable
//This is a barebones implementation, and is meant to be included in
            integer n = CYCLES;
//the body of the script needing encryption facilities or wrapped
                       
//in a link message handlerIf the latter approach is desired, care
            integer sum = 0;
//should be taken to only send link messages to the prim containing
           
//this implementation. If ALL_PRIMS is used as the destination,
            //Operate for the specified number of cycles.
//one could link a link message listener to the object and intercept
            while (n-- > 0){
//cleartext communications. 
                dword1 = dword1 + ( ( dword2 << 4 ^ dword2 >> 5 ) + dword2 ^ sum + llList2Integer(cypherkey, (sum & 3) ) );
//
                sum += delta;
//If you plan to place this code into the same script as that needing
                dword2 = dword2 + ( ( dword1 << 4 ^ dword1 >> 5 ) + dword1 ^ sum + llList2Integer(cypherkey, (sum >> 11 & 3) ) );
//encryption facilities, you need only call the following functions:
            }
//
           
//string Encrypt(string cleartext)
            cryptlist = [dword1,dword2];
//string Decrypt(string cyphertext)
 
//
            return cryptlist;
//Simple as that.
}
//
 
//This implementation does not provide any secure key exchange, so in
 
//terms of key generation and exchange you're on your own.
 
//
//Function: TEADecrypt
//The 128-bit key is contained in four LSL integers: KEY1, KEY2, KEY3,
//This is the implementation of XTEA proper. It takes a block of cyphertext
//and KEY4.  These are global variables at the beginning of the source
//consisting of two dwords contained in LSL integers and a 128-bit key  
//and can be set using a method that works for you.
//contained in an LSL list of 4 integers. The function then returns
//
//the cleartext in an LSL list of two integers.
//
list TEADecrypt(integer dword1, integer dword2,list cypherkey){
//CHANGES
   
//-------
            list cryptlist = [];
//
           
//1.0a - Alpha
            //Set n to the number of cycles given in the CYCLES global variable
//*General optimization to run faster and use less bytecode.
            integer n = CYCLES;
//*Encrypt: Pad works differently, no longer extra characters appended to the output.
                       
//*TEAEncrypt: Changed the return type
            integer sum = delta * CYCLES;
//*ord: Added null support.
 
//
            //Operate for the specified number of cycles.       
//1.0
            while (n-- > 0){
//*Initial Release
                dword2 = dword2 - ( ( dword1 << 4 ^ dword1 >> 5 ) + dword1 ^ sum + llList2Integer(cypherkey, (sum >> 11 & 3) ) );
//
                sum -= delta;
//
                dword1 = dword1 - ( ( dword2 << 4 ^ dword2 >> 5 ) + dword2 ^ sum + llList2Integer(cypherkey, (sum & 3) ) );       
//FUTURE CHANGES
            }
//--------------
           
//
            cryptlist = [dword1,dword2];
//It would be nice if it supported UTF-8; but adding that would be alot
            return cryptlist;
//of work. The main issue is the decoding, the bytes would have to be
}
//reassembled into characters. It would be time consuming. Another possibility
</lsl>
//would be to implement XTEA to output to BASE64 instead of hex strings (also
//time consuming to implement).
//
//
//**************IF YOU READ ONE THING IN HERE, READ THIS*******************
//It is VERY important to remember that there is no such thing as
//'cookbook cryptography'!  Simply using this cypher does not guarantee
//security.  Security is an end-to-end concern and responsibility lies
//with you to thoroughly examine your project from all possible angles
//if valuable data is at risk.  If you doubt this, ask any thief how they'd
//rather break into your house - futzing about with picking a high-security
//deadbolt on the front door or walking in through the back door that you
//left open.


== Usage Example ==
//******************USER-CONFIGURABLE GLOBALS BEGIN HERE*******************
Listens on COMM_CHANNEL for a message and encrypts it, then turns around and decrypts the resultant cypher-text. Object than says the encrypted and decrypted messages to the owner.
<lsl>
default
{
    state_entry()
    {
        llListen(COMM_CHANNEL, "", NULL_KEY, "");
        cypherkey = [KEY1,KEY2,KEY3,KEY4];
    }


    listen(integer channel, string name, key id, string message)
//ENCRYPTION KEYS KEY[1-4]
    {
//These together make up the 128-bit XTEA encryption key.  See the above
        string temp_cyphertext = Encrypt(message);
//documentation for details.  Whatever you do, don't leave them as the default.
       
//Don't be stupid and make it obvious like your av's key.
        string temp_cleartext = Decrypt(temp_cyphertext);
integer KEY1 = 11111111;
       
integer KEY2 = 22222222;
        llOwnerSay("\nOriginal Cleartext: " + message + "\nCyphertext: " + temp_cyphertext + "\nDecrypted Cleartext: " + temp_cleartext);
integer KEY3 = 33333333;
    }
integer KEY4 = 44444444;
}
</lsl>


== Optimized ==
//COMM_CHANNEL
This version is untested but if it works should run faster (and be able to handle larger strings).
//Specifies which channel should be used for debug and test harness communication.
integer COMM_CHANNEL = 0;


<lsl>
//CYCLES
// Include the documentation comments from above (separated here only for easier management)
//Specifies the number of rounds to be used.  See the above documentation for
//details.
integer CYCLES = 6;


//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)
//******************USER-CONFIGURABLE GLOBALS END HERE*********************
//Version 1.0a Alpha
 
//Copyright (C) 2007 by Strife Onizuka (blindwandererATgmail.com)
//Other Globals
//
list cypherkey = [];
//Version 1.0
integer delta = 0x9E3779B9;
//Copyright (C) 2007 by Morse Dillon (morseATmorsedillon.com)
 
//
string ASCII = "            \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
//This program is free software; you can redistribute it and/or
string characters = "0123456789ABCDEF";
//modify it under the terms of the GNU General Public License
 
//as published by the Free Software Foundation; either version 2
//Function: ord
//of the License, or (at your option) any later version.
//Returns the index of an ASCII character
//
integer ord(string chr)
//This program is distributed in the hope that it will be useful,
{
//but WITHOUT ANY WARRANTY; without even the implied warranty of
    if(chr)
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    {
//GNU General Public License for more details.
        if(llStringLength(chr) > 1) return -1;
//
        if(chr == " ") return 32;
//You should have received a copy of the GNU General Public License
        return llSubStringIndex(ASCII, chr);
//along with this program; if not, write to the Free Software
    }
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    return 0;
//02110-1301, USA.
}
//========================================================================
 
//
//Function: chr
//Included at the end of this source listing is a small bit of example
//Returns the ASCII character correspondent to index i
//code that shows the usage.  If you wish to include this implementation
string chr(integer i)
//in your own work, just replace the example code with your own. Also,
{
//please do not reuse or redistribute this work without including the
    if(i)
//above text attributing this code to its author Morse Dillon, the above
        return llGetSubString(ASCII, i %= 127, i);
//GPL statement, and this documentation.
    return "";
//
}
//This is an implentation of the XTEA (eXtended Tiny Encryption Algorithm)  
 
//block cypher.  (X)TEA is a very good choice of cipher when security
//Function:  DWord2Hex
//is important but computational power is limited.  Although I did a
//Converts a dword contained in a LSL integer to hexadecimal format.      
//lot of work on this implementation, enormous amounts of credit must
string DWord2Hex(integer m)
//be given to the creators of the algorithm and those who came before
{
//me to implement it in other languages and computing environments.
    string result;
//
    integer i = 0;
//***If you do decide to use this code in a project, I'd appreciate
 
//hearing about it. You can reach me by e-mail at: 
    //Define character string [0-F] for use in building the hex.
//morseATmorsedillon.com
    //Step through 8 times, for a total of 32 bits, 8 nibbles, and 8 hexadecimal digits.
//
    do{
//
        integer index = (m >> i) & 0xF;
//ABOUT TEA AND XTEA
        result = llGetSubString(characters, index, index) + result;
//------------------
    }while((i += 4) < 32);
//TEA was originally designed by David Wheeler and Roger Needham
    return result;
//of the Cambridge Computer Laboratory. The algorithm itself is not
}
//subject to any patents.  While the original TEA was found to have
 
//some minor weaknesses, XTEA (implemented herein) addresses these.
//Function: Encrypt
//
//Takes cleartext string, pads and bitpacks it, then encrypts it using TEAEncrypt().
//TEA and its derivatives consist of 64-bit block Feistel network
string Encrypt(string cleartext)
//with a 128-bit key. This implementation uses six cycles, or rounds,
{
//which is less than one would like but still provides a reasonable
    string cyphertext = "";
//level of security (16 is sufficient while 8 is enough for most
    integer i = llStringLength(cleartext);
//applications).  Six is said to achieve theoretically good dispersion,  
    if((i += (0x7 & -i)))//Pad cleartext string to the nearest multiple of 8.
//but should more security be desired the number of cycles can easily be
    {
//modified by changing the CYCLES global variable.  Due to the low
        //Step through cleartext string backwords, encrypting it in 64-bit (8 character) blocks.
//execution speed of LSL scripts, it's suggested to make this as low as
        do{
//your comfort level allows.  Encryption time scales linearly with the
            //i=~-i is the same as --i, just a bit faster and lighter on bytecode; requires one less stack manipulation.
//number of cycles.
            //Pack dword1 with 4 bytes.  Do so by bit-shifting in each character.
//
            //4th byte winds up in the most-significant position.
//For more information about XTEA, see the following:
            integer dword2 =    (    ord(llGetSubString(cleartext,i=~-i,i))      )    |
//
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 8 )    |
//Original Paper by Walker and Needham
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 16)   |
//http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 24)    ;
//
 
//Wikipedia on TEA
            //Do it again, this time for dword1                           
//http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
            integer dword1 =    (    ord(llGetSubString(cleartext,i=~-i,i))      )    |
//
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 8 )    |
//
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 16)    |
//ABOUT THIS IMPLEMENTATION
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 24)    ;
//-------------------------
 
//This is a barebones implementation, and is meant to be included in
            //Call TEAencrypt() with dword1, dword2, and the cypher key and store result in cypherblock.
//the body of the script needing encryption facilities or wrapped
 
//in a link message handler. If the latter approach is desired, care
            //Convert dword values from cypherblock to hex and append to cyphertext.
//should be taken to only send link messages to the prim containing
            cyphertext = TEAEncrypt(dword1,dword2,cypherkey) + cyphertext;
//this implementation.  If ALL_PRIMS is used as the destination,
        }while(i);
//one could link a link message listener to the object and intercept
    }
//cleartext communications.  
    return cyphertext;
//
}  
//If you plan to place this code into the same script as that needing
 
//encryption facilities, you need only call the following functions:
 
//
//Function: Decrypt
//string Encrypt(string cleartext)
//Takes cyphertext, decrypts it with TEADecrypt(), and unpacks it into a string.
//string Decrypt(string cyphertext)
string Decrypt(string cyphertext){
//
 
//Simple as that.
    //Initialize variables.
//
    string cleartext = "";
//This implementation does not provide any secure key exchange, so in
    integer i = -llStringLength(cyphertext);
//terms of key generation and exchange you're on your own.
 
//
    //Step through cyphertext string, decrypting it block by block.
//The 128-bit key is contained in four LSL integers:  KEY1, KEY2, KEY3,
    if((i -= (0xF & i)))//Pad cyphertext string to the nearest multiple of 16.
//and KEY4.  These are global variables at the beginning of the source
    {
//and can be set using a method that works for you.
        do
//
        {
//
 
//CHANGES
            //Convert hexvalues to dwords contained in LSL integers.
//-------
            //Call TEADecrypt() with dword1, dword2, and the cypher key and store result in clearblock list.
//
            list clearblock = TEADecrypt((integer)("0x"+llGetSubString(cyphertext,i, ~-(i -= 8))),
//1.0a - Alpha
                                        (integer)("0x"+llGetSubString(cyphertext,i, ~-(i -= 8))), cypherkey);
//*General optimization to run faster and use less bytecode.
 
//*Encrypt: Pad works differently, no longer extra characters appended to the output.
            //Append first 4 characters of ASCII to cleartext string.
//*TEAEncrypt: Changed the return type
            //This is done by pulling the decrypted dwords from the clearblock list and looking up their ASCII values.
//*ord: Added null support.
            integer t = llList2Integer(clearblock,1);
//
            cleartext += chr( (t      ) & 0xFF) +
//1.0
                        chr( (t >> 8 ) & 0xFF) +
//*Initial Release
                        chr( (t >> 16) & 0xFF) +
//
                        chr( (t = llList2Integer(clearblock,0) >> 24) & 0xFF) +
//
                        chr( (t      ) & 0xFF) +
//FUTURE CHANGES
                        chr( (t >> 8 ) & 0xFF) +
//--------------
                        chr( (t >> 16) & 0xFF) +
//
                        chr( (t >> 24) & 0xFF) ;
//It would be nice if it supported UTF-8; but adding that would be alot
        }while(i);
//of work. The main issue is the decoding, the bytes would have to be
    }
//reassembled into characters. It would be time consuming. Another possibility
    return cleartext;       
//would be to implement XTEA to output to BASE64 instead of hex strings (also
}
//time consuming to implement).
 
//
 
//
//Function: TEADecrypt
//**************IF YOU READ ONE THING IN HERE, READ THIS*******************
//This is the implementation of XTEA properIt takes a block of cleartext
//It is VERY important to remember that there is no such thing as
//consisting of two dwords contained in LSL integers and a 128-bit key
//'cookbook cryptography'!  Simply using this cypher does not guarantee
//contained in an LSL list of 4 integers.  The function then returns
//security.  Security is an end-to-end concern and responsibility lies
//the cyphertext in an LSL list of two integers.
//with you to thoroughly examine your project from all possible angles
string TEAEncrypt(integer dword1, integer dword2, list cypherkey_)
//if valuable data is at riskIf you doubt this, ask any thief how they'd
{
//rather break into your house - futzing about with picking a high-security
    if(CYCLES > 0)//$[E20011] /*lslint ignore*/
//deadbolt on the front door or walking in through the back door that you
    {
//left open.
        //Set n to the number of cycles given in the CYCLES global variable
 
        integer n = CYCLES;
//******************USER-CONFIGURABLE GLOBALS BEGIN HERE*******************
        integer sum = 0;
 
        //Operate for the specified number of cycles.
//ENCRYPTION KEYS KEY[1-4]
        do{
//These together make up the 128-bit XTEA encryption key.  See the above
            dword1 = dword1 + ( ( dword2 << 4 ^ dword2 >> 5 ) + dword2 ^ sum + llList2Integer(cypherkey_, (sum & 3) ) );
//documentation for details.  Whatever you do, don't leave them as the default.
            dword2 = dword2 + ( ( dword1 << 4 ^ dword1 >> 5 ) + dword1 ^ sum + llList2Integer(cypherkey_, ((sum += delta) >> 11 & 3) ) );
//Don't be stupid and make it obvious like your av's key.
        }while (n = ~-n);
integer KEY1 = 11111111;
    }
integer KEY2 = 22222222;
    return DWord2Hex(dword1) + DWord2Hex(dword2);
integer KEY3 = 33333333;
}
integer KEY4 = 44444444;


//COMM_CHANNEL
//Specifies which channel should be used for debug and test harness communication.
integer COMM_CHANNEL = 0;


//CYCLES
//Function: TEADecrypt
//Specifies the number of rounds to be usedSee the above documentation for
//This is the implementation of XTEA proper.  It takes a block of cyphertext
//details.
//consisting of two dwords contained in LSL integers and a 128-bit key
integer CYCLES = 6;
//contained in an LSL list of 4 integersThe function then returns
//the cleartext in an LSL list of two integers.
list TEADecrypt(integer dword1, integer dword2,list cypherkey_)
{
    if(CYCLES > 0)//$[E20011] /*lslint ignore*/
    {
        //Set n to the number of cycles given in the CYCLES global variable
        integer n = CYCLES;
        integer sum = delta * CYCLES;
        //Operate for the specified number of cycles.       
        do{
            dword2 = dword2 - ( ( dword1 << 4 ^ dword1 >> 5 ) + dword1 ^ sum + llList2Integer(cypherkey_, (sum >> 11 & 3) ) );
            dword1 = dword1 - ( ( dword2 << 4 ^ dword2 >> 5 ) + dword2 ^ sum + llList2Integer(cypherkey_, ((sum -= delta) & 3) ) );       
        }while (n = ~-n);
    }
    return [dword1,dword2];
}


//******************USER-CONFIGURABLE GLOBALS END HERE*********************


//Other Globals
//XTEA Usage Example
list cypherkey = [];
//Listens on COMM_CHANNEL for a message and encrypts it, then turns around and decrypts the resultant cyphertext.
integer delta = 0x9E3779B9;
//Object than says the encrypted and decrypted messages to the owner.
 
default
string ASCII = "            \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
string characters = "0123456789ABCDEF";
 
//Function: ord
//Returns the index of an ASCII character
integer ord(string chr)
{
{
     if(chr)
     state_entry()
    {
        llListen(COMM_CHANNEL, "", NULL_KEY, "");
        cypherkey = [KEY1,KEY2,KEY3,KEY4];
    }
 
    listen(integer channel, string name, key id, string message)
     {
     {
         if(llStringLength(chr) > 1) return -1;
         string temp_cyphertext = Encrypt(message);
         if(chr == " ") return 32;
 
         return llSubStringIndex(ASCII, chr);
         string temp_cleartext = Decrypt(temp_cyphertext);
 
         llOwnerSay("\nOriginal Cleartext: " + message + "\nCyphertext: " + temp_cyphertext + "\nDecrypted Cleartext: " + temp_cleartext);
     }
     }
    return 0;
}
}
</source>


//Function: chr
== XTEA LSL <-> PHP ==
//Returns the ASCII character correspondent to index i
This is an XTEA implementation that has both LSL and PHP scripts to allow strong encryption not only inside LSL but also between LSL and a PHP serverscript.
string chr(integer i)
 
{
For those who want to see this in action with your Web server try these. Be sure that if you  edit these that Rounds and Key Phrase are the same in both LSL and PHP versions.
    if(i)
        return llGetSubString(ASCII, i %= 127, i);
    return "";
}


//Function:  DWord2Hex
LSL - PLACE IN PRIM -- Edit to change URL and tosend text.
//Converts a dword contained in a LSL integer to hexadecimal format.      
string DWord2Hex(integer m)
{
    string result;
    integer i = 0;


    //Define character string [0-F] for use in building the hex.
<source lang="lsl2">
    //Step through 8 times, for a total of 32 bits, 8 nibbles, and 8 hexadecimal digits.
    do{
        integer index = (m >> i) & 0xF;
        result = llGetSubString(characters, index, index) + result;
    }while((i += 4) < 32);
    return result;
}


//Function: Encrypt
//************************************************//
//Takes cleartext string, pads and bitpacks it, then encrypts it using TEAEncrypt().
//* Masa's XTEA encryption/decryption v3        *//
string Encrypt(string cleartext)
//* Modified by SleightOf Hand for Stability and *//
{
//* intercommunication with PHP version          *//
    string cyphertext = "";
//************************************************//
    integer i = llStringLength(cleartext);
// NOTE: This version only encodes 60 bits per 64-bit block!
    if((i += (0x7 & -i)))//Pad cleartext string to the nearest multiple of 8.
// This code is public domain.  
    {
// Sleight was here 20070522
        //Step through cleartext string backwords, encrypting it in 64-bit (8 character) blocks.
// masa was here 20070315
        do{
// so was strife 20070315
            //i=~-i is the same as --i, just a bit faster and lighter on bytecode; requires one less stack manipulation.
// so was adz 20070812
            //Pack dword1 with 4 bytes.  Do so by bit-shifting in each character.
//
            //4th byte winds up in the most-significant position.
// This was Modified by SleightOf Hand to allow
            integer dword2 =    (    ord(llGetSubString(cleartext,i=~-i,i))      )    |
// Strong encryption between LSL and PHP.  
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 8 )    |
//************************************************//
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 16)    |
//* XTEA IMPLEMENTATION                          *//
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 24)    ;
//************************************************//


            //Do it again, this time for dword1                           
integer XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
            integer dword1 =    (   ord(llGetSubString(cleartext,i=~-i,i))      )   |
integer xtea_num_rounds = 6;
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 8 )    |
list   xtea_key        = [0, 0, 0, 0];  
                                (   ord(llGetSubString(cleartext,i=~-i,i)) << 16)    |
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 24)    ;


            //Call TEAencrypt() with dword1, dword2, and the cypher key and store result in cypherblock.


            //Convert dword values from cypherblock to hex and append to cyphertext.
// Converts any string to a 32 char MD5 string and then to a list of
            cyphertext = TEAEncrypt(dword1,dword2,cypherkey) + cyphertext;
// 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific
        }while(i);
// 128 bit key is generated for any string passed.
    }
list xtea_key_from_string( string str )
    return cyphertext;
{
}
    str = llMD5String(str,0); // Use Nonce = 0
    return [    hexdec(llGetSubString( str, 0, 7)),
                hexdec(llGetSubString( str,  8,  15)),
                hexdec(llGetSubString(  str,  16,  23)),
                hexdec(llGetSubString(  str,  24,  31))];  
}  


// Encipher two integers and return the result as a 12-byte string
// containing two base64-encoded integers.
string xtea_encipher( integer v0, integer v1 )
{
    integer num_rounds = xtea_num_rounds;
    integer sum = 0;
    do {
        // LSL does not have unsigned integers, so when shifting right we
        // have to mask out sign-extension bits.
        v0  += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
        sum +=  XTEA_DELTA;
        v1  += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3));


//Function: Decrypt
    } while( --num_rounds );
//Takes cyphertext, decrypts it with TEADecrypt(), and unpacks it into a string.
    //return only first 6 chars to remove "=="'s and compact encrypted text.
string Decrypt(string cyphertext){
    return llGetSubString(llIntegerToBase64(v0),0,5) +
          llGetSubString(llIntegerToBase64(v1),0,5);
}


    //Initialize variables.
// Decipher two base64-encoded integers and return the FIRST 30 BITS of
     string cleartext = "";
// each as one 10-byte base64-encoded string.  
     integer i = -llStringLength(cyphertext);
string xtea_decipher( integer v0, integer v1 )
{
     integer num_rounds = xtea_num_rounds;  
     integer sum = XTEA_DELTA*xtea_num_rounds;
    do {
        // LSL does not have unsigned integers, so when shifting right we
        // have to mask out sign-extension bits.
        v1  -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3));
        sum -= XTEA_DELTA;
        v0  -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum  & 3));
    } while ( --num_rounds );  


     //Step through cyphertext string, decrypting it block by block.
     return llGetSubString(llIntegerToBase64(v0), 0, 4) +
    if((i -= (0xF & i)))//Pad cyphertext string to the nearest multiple of 16.
          llGetSubString(llIntegerToBase64(v1), 0, 4);
    {
}
        do
        {


            //Convert hexvalues to dwords contained in LSL integers.
// Encrypt a full string using XTEA.  
            //Call TEADecrypt() with dword1, dword2, and the cypher key and store result in clearblock list.
string xtea_encrypt_string( string str )
            list clearblock = TEADecrypt((integer)("0x"+llGetSubString(cyphertext,i, ~-(i -= 8))),
{
                                        (integer)("0x"+llGetSubString(cyphertext,i, ~-(i -= 8))), cypherkey);
    // encode string
 
    str = llStringToBase64(str);
            //Append first 4 characters of ASCII to cleartext string.
    // remove trailing =s so we can do our own 0 padding
            //This is done by pulling the decrypted dwords from the clearblock list and looking up their ASCII values.
    integer i = llSubStringIndex( str, "=" );
            integer t = llList2Integer(clearblock,1);
    if ( i != -1 )  
            cleartext += chr( (t      ) & 0xFF) +
        str = llDeleteSubString( str, i, -1 );  
                        chr( (t >> 8 ) & 0xFF) +
 
                        chr( (t >> 16) & 0xFF) +
    // we don't want to process padding, so get length before adding it
                        chr( (t = llList2Integer(clearblock,0) >> 24) & 0xFF) +
    integer len = llStringLength(str);  
                        chr( (t      ) & 0xFF) +
                        chr( (t >> 8 ) & 0xFF) +
                        chr( (t >> 16) & 0xFF) +
                        chr( (t >> 24) & 0xFF) ;
        }while(i);
    }
    return cleartext;       
}


    // zero pad
    str += "AAAAAAAAAA=";


//Function: TEADecrypt
    string result;
//This is the implementation of XTEA proper.  It takes a block of cleartext
     i = 0;  
//consisting of two dwords contained in LSL integers and a 128-bit key
//contained in an LSL list of 4 integers.  The function then returns
//the cyphertext in an LSL list of two integers.
string TEAEncrypt(integer dword1, integer dword2, list cypherkey_)
{
     if(CYCLES > 0)//$[E20011] /*lslint ignore*/
    {
        //Set n to the number of cycles given in the CYCLES global variable
        integer n = CYCLES;
        integer sum = 0;
        //Operate for the specified number of cycles.
        do{
            dword1 = dword1 + ( ( dword2 << 4 ^ dword2 >> 5 ) + dword2 ^ sum + llList2Integer(cypherkey_, (sum & 3) ) );
            dword2 = dword2 + ( ( dword1 << 4 ^ dword1 >> 5 ) + dword1 ^ sum + llList2Integer(cypherkey_, ((sum += delta) >> 11 & 3) ) );
        }while (n = ~-n);
    }
    return DWord2Hex(dword1) + DWord2Hex(dword2);
}


    do {
        // encipher 30 (5*6) bits at a time.
        result += xtea_encipher(
            llBase64ToInteger(llGetSubString(str,  i, i += 4) + "A="),
            llBase64ToInteger(llGetSubString(str, ++i, i += 4) + "A=")
        );
    } while ( ++i < len );


//Function: TEADecrypt
     return result;  
//This is the implementation of XTEA proper.  It takes a block of cyphertext
}  
//consisting of two dwords contained in LSL integers and a 128-bit key
//contained in an LSL list of 4 integers.  The function then returns
//the cleartext in an LSL list of two integers.
list TEADecrypt(integer dword1, integer dword2,list cypherkey_)
{
    if(CYCLES > 0)//$[E20011] /*lslint ignore*/
    {
        //Set n to the number of cycles given in the CYCLES global variable
        integer n = CYCLES;
        integer sum = delta * CYCLES;
        //Operate for the specified number of cycles.       
        do{
            dword2 = dword2 - ( ( dword1 << 4 ^ dword1 >> 5 ) + dword1 ^ sum + llList2Integer(cypherkey_, (sum >> 11 & 3) ) );
            dword1 = dword1 - ( ( dword2 << 4 ^ dword2 >> 5 ) + dword2 ^ sum + llList2Integer(cypherkey_, ((sum -= delta) & 3) ) );       
        }while (n = ~-n);
    }
     return [dword1,dword2];
}
 


//XTEA Usage Example
// Decrypt a full string using XTEA  
//Listens on COMM_CHANNEL for a message and encrypts it, then turns around and decrypts the resultant cyphertext.
string xtea_decrypt_string( string str ) {  
//Object than says the encrypted and decrypted messages to the owner.
     integer len = llStringLength(str);
default
    integer i;
{
    string result;
     state_entry()
     do {  
     {
         result += xtea_decipher(  
         llListen(COMM_CHANNEL, "", NULL_KEY, "");
            llBase64ToInteger(llGetSubString(str,   i, i += 5) + "=="),  
         cypherkey = [KEY1,KEY2,KEY3,KEY4];
            llBase64ToInteger(llGetSubString(str, ++i, i += 5) + "==")  
     }
         );  
     } while ( ++i < len );


     listen(integer channel, string name, key id, string message)
     // Replace multiple trailing zeroes with a single one
     {
    i = llStringLength(result) - 1;
        string temp_cyphertext = Encrypt(message);
    while ( llGetSubString(result, --i, i+1) == "AA" )
        result = llDeleteSubString(result, i+1, i+1);
     return llBase64ToString( result + "====" );  
}


        string temp_cleartext = Decrypt(temp_cyphertext);
key requestid; // just to check if we're getting the result we've asked for; all scripts in the same object get the same replies
string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +


        llOwnerSay("\nOriginal Cleartext: " + message + "\nCyphertext: " + temp_cyphertext + "\nDecrypted Cleartext: " + temp_cleartext);
                          "abcdefghijklmnopqrstuvwxyz" +  
    }
}
</lsl>


== XTEA LSL <-> PHP ==
                          "0123456789+/";
This is an XTEA implementation that has both LSL and PHP scripts to allow strong encryption not only inside LSL but also between LSL and a PHP serverscript.
string url = "http://<enter your URL here>/test-script.php";


For those who want to see this in action with your Web server try these. Be sure that if you  edit these that Rounds and Key Phrase are the same in both LSL and PHP versions.


LSL - PLACE IN PRIM -- Edit to change URL and tosend text.


<lsl>
default
 
{
//************************************************//
    touch_start(integer number)
//* Masa's XTEA encryption/decryption v3         *//
    {
//* Modified by SleightOf Hand for Stability and *//
         string tosend = "this is a message to send";
//* intercommunication with PHP version          *//
        llWhisper(0, "Message to Send = " + tosend);
//************************************************//
        xtea_key = xtea_key_from_string("this is a test key");
// NOTE: This version only encodes 60 bits per 64-bit block!
        string message = xtea_encrypt_string(tosend);
// This code is public domain.
        llWhisper(0, "Message to Server = " + message);
// Sleight was here 20070522
        requestid = llHTTPRequest(url,
// masa was here 20070315
            [HTTP_METHOD, "POST",
// so was strife 20070315
            HTTP_MIMETYPE, "application/x-www-form-urlencoded"],
// so was adz 20070812
            "parameter1=" + llEscapeURL(message));
//
    }
// This was Modified by SleightOf Hand to allow
// Strong encryption between LSL and PHP.
//************************************************//
//* XTEA IMPLEMENTATION                          *//
//************************************************//


integer XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
    http_response(key request_id, integer status, list metadata, string body)
integer xtea_num_rounds = 6;
    {
list   xtea_key        = [0, 0, 0, 0];
        if (request_id == requestid) {  
 
            llWhisper(0, "Web server sent: " + body);
integer hex2int(string hex) {
            integer clean = 0;
    if(llGetSubString(hex,0,1) == "0x")
            string cleanbody = "";
        return (integer)hex;
            while(~llSubStringIndex(base64,llGetSubString(body,clean,clean))){
    if(llGetSubString(hex,0,0) == "x")
                cleanbody += llGetSubString(body,clean,clean++);
        return (integer)("0"+hex);
            }
    return(integer)("0x"+hex);
            llWhisper(0, "Cleaned : " + cleanbody);
            llWhisper(0, "Web server said: " + xtea_decrypt_string( cleanbody ));
        }
    }
}
}


</source>


// Convers any string to a 32 char MD5 string and then to a list of
PHP Code - Place on web server at location that LSL URL will be looking for.
// 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific
// 128 bit key is generated for any string passed.
list xtea_key_from_string( string str )
{
    str = llMD5String(str,0); // Use Nonce = 0
    return [    hex2int(llGetSubString(  str,  0,  7)),
                hex2int(llGetSubString(  str,  8,  15)),
                hex2int(llGetSubString(  str,  16,  23)),
                hex2int(llGetSubString(  str,  24,  31))];
}


// Encipher two integers and return the result as a 12-byte string
<source lang="php">
// containing two base64-encoded integers.  
//************************************************//
string xtea_encipher( integer v0, integer v1 )
//* Sleight's PHP XTEA encryption/decryption v3  *//
{
//* Modified by SleightOf Hand for Stability and *//
    integer num_rounds = xtea_num_rounds;
//* intercommunication between PHP & LSL        *//
    integer sum = 0;
//************************************************//
    do {
// NOTE: This version only encodes 60 bits per 64-bit block!
        // LSL does not have unsigned integers, so when shifting right we
// This code is public domain.
        // have to mask out sign-extension bits.  
// Sleight was here 20070522
        v0  += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
// masa was here 20070315
        sum +=  XTEA_DELTA;
// so was strife 20070315
        v1  += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3));
// so was adz 20080812
//
// This was converted from the LSL version by
// SleightOf Hand to allow Strong encryption
// between LSL and PHP. If you find this useful
// any donations appreciated.
//************************************************//
//* XTEA IMPLEMENTATION                          *//
//************************************************//


    } while( num_rounds = ~-num_rounds );  
$_XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
    //return only first 6 chars to remove "=="'s and compact encrypted text.
$_xtea_num_rounds = 6;
    return llGetSubString(llIntegerToBase64(v0),0,5) +
$_xtea_key        = array(0, 0, 0, 0);
          llGetSubString(llIntegerToBase64(v1),0,5);  
$_base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
}
          "abcdefghijklmnopqrstuvwxyz".
          "0123456789+/";


// Decipher two base64-encoded integers and return the FIRST 30 BITS of
// Returns Integer based on 8 byte Base64 Code XXXXXX== (llBase64ToInteger)
// each as one 10-byte base64-encoded string.
function base64_integer($str){
string xtea_decipher( integer v0, integer v1 )
global $_base64;
{  
if(strlen($str) != 8) return 0;
    integer num_rounds = xtea_num_rounds;  
  return ((strpos($_base64,$str{0}) << 26)|
    integer sum = XTEA_DELTA*xtea_num_rounds;  
(strpos($_base64,$str{1}) << 20)|
    do {
(strpos($_base64,$str{2}) << 14)|
        // LSL does not have unsigned integers, so when shifting right we
(strpos($_base64,$str{3}) << 8) |
        // have to mask out sign-extension bits.
  (strpos($_base64,$str{4}) << 2) |
        v1 -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3));
(strpos($_base64,$str{5}) >> 4));
        sum -= XTEA_DELTA;
}
        v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum  & 3));  
    } while ( num_rounds = ~-num_rounds );


    return llGetSubString(llIntegerToBase64(v0), 0, 4) +
// Returns 8 Byte Base64 code based on 32 bit integer ((llIntegerToBase64)
          llGetSubString(llIntegerToBase64(v1), 0, 4);  
function integer_base64($int){
}  
global $_base64;
if($int != (integer) $int) return 0;
return  $_base64{($int >> 26 & 0x3F)} .
$_base64{($int >> 20 & 0x3F)} .
$_base64{($int >> 14 & 0x3F)} .
$_base64{($int >> 8 & 0x3F)}  .
$_base64{($int >> 2 & 0x3F)}  .
$_base64{($int << 4 & 0x3F)} . "==";
}


// Encrypt a full string using XTEA.
//strict 32 bit addition using logic
string xtea_encrypt_string( string str )
function binadd($val1 , $val2){
{  
$tc = $val1 & $val2;
    // encode string
$ta = $val1 ^ $val2;
    str = llStringToBase64(str);  
do{
    // remove trailing =s so we can do our own 0 padding
  $tac = ($tc << 1) & 0x0FFFFFFFF;
    integer i = llSubStringIndex( str, "=" );  
  $tc = $ta & $tac;
    if ( i != -1 )
  $ta = $ta ^ $tac;
        str = llDeleteSubString( str, i, -1 );  
}while($tc);
return $ta; // $ta will now be the result so return it
}


    // we don't want to process padding, so get length before adding it
// Converts any string to a 32 char MD5 string and then to a list of
    integer len = llStringLength(str);  
// 4 * 32 bit integers = 128 bit Key.
function xtea_key_from_string( $str ) {
global $_xtea_key;
$str = md5($str . ":0"); // Use nonce = 0 in LSL for same output
$_xtea_key[0] = hexdec(substr($str,0,8));
$_xtea_key[1] = hexdec(substr($str,8,8));
$_xtea_key[2] = hexdec(substr($str,16,8));
$_xtea_key[3] = hexdec(substr($str,24,8));
}


    // zero pad
// Encipher two integers and return the result as a 12-byte string
    str += "AAAAAAAAAA=";  
// containing two base64-encoded integers.
 
function xtea_encipher( $v0 , $v1 ) {
    string result;  
global  $_xtea_num_rounds , $_xtea_key , $_XTEA_DELTA;
    i = 0;  
$num_rounds = $_xtea_num_rounds;
$sum = 0;
do {
  // LSL only has 32 bit integers. However PHP automatically changes
  // 32 bit integers to 64 bit floats as necessary. This causes
  // incompatibilities between the LSL Encryption and the PHP
  // counterpart. I got round this by changing all addition to
  // binary addition using logical & and ^ and loops to handle bit
  // carries. This forces the 32 bit integer to remain 32 bits as
  // I mask out any carry over 32 bits. this bring the output of the
  // encrypt routine to conform with the output of its LSL counterpart.


    do {
  // LSL does not have unsigned integers, so when shifting right we
        // encipher 30 (5*6) bits at a time.  
  // have to mask out sign-extension bits.
        result += xtea_encipher(
            llBase64ToInteger(llGetSubString(str,  i, i += 4) + "A="),
            llBase64ToInteger(llGetSubString(str, ++i, i += 4) + "A=")
        );
    } while ( ++i < len );


    return result;
  // calculate ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
}
  $v0a = binadd((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) , $v1);
 
  // calculate ($sum + $_xtea_key[$sum & 3])
// Decrypt a full string using XTEA
  $v0b = binadd($sum , $_xtea_key[$sum & 3]);
string xtea_decrypt_string( string str ) {
  // Calculate ($v0 + ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
    integer len = llStringLength(str);  
  //            ^ ($sum + $_xtea_key[$sum & 3]))
    integer i;
  $v0 = binadd($v0 , ($v0a  ^ $v0b));
    string result;  
    do {
        result += xtea_decipher(  
            llBase64ToInteger(llGetSubString(str,  i, i += 5) + "=="),
            llBase64ToInteger(llGetSubString(str, ++i, i += 5) + "==")  
        );
    } while ( ++i < len );  


    // Replace multiple trailing zeroes with a single one
  //Calculate ($sum + $_XTEA_DELTA)
    i = llStringLength(result) - 1;
  $sum = binadd($sum , $_XTEA_DELTA);
    while ( llGetSubString(result, --i, i+1) == "AA" )  
        result = llDeleteSubString(result, i+1, i+1);
    return llBase64ToString( result + "====" );  
}


key requestid; // just to check if we're getting the result we've asked for; all scripts in the same object get the same replies
  //Calculate ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
  $v1a = binadd((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF))  , $v0);
  // Calculate ($sum + $_xtea_key[($sum >>11) & 3])
  $v1b = binadd($sum , $_xtea_key[($sum >>11) & 3]);
  //Calculate ($v1 + ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0
  //          ^ ($sum & $_xtea_key[($sum >>11) & 3]))
  $v1 = binadd($v1 , ($v1a  ^ $v1b));
} while( $num_rounds = ~-$num_rounds );
//return only first 6 chars to remove "=="'s and compact encrypted text.
return substr(integer_base64($v0),0,6) . substr(integer_base64($v1),0,6);
}


                          "abcdefghijklmnopqrstuvwxyz" +
// Decipher two base64-encoded integers and return the FIRST 30 BITS of
// each as one 10-byte base64-encoded string.
function xtea_decipher( $v0, $v1 ) {
global  $_xtea_num_rounds , $_xtea_key , $_XTEA_DELTA;
$num_rounds = $_xtea_num_rounds;
$sum = 0; // $_XTEA_DELTA * $_xtea_num_rounds;
$tda = $_XTEA_DELTA;
do{ // Binary multiplication using binary manipulation
  if($num_rounds & 1){
  $sum = binadd($sum , $tda);
  }
  $num_rounds = $num_rounds >> 1;
  $tda = ($tda << 1) & 0x0FFFFFFFF;
}while($num_rounds);
$num_rounds = $_xtea_num_rounds; // reset $num_rounds back to its proper setting;


                          "0123456789+/";
do {
string url = "http://<enter your URL here>/test-script.php";
  // LSL only has 32 bit integers. However PHP automatically changes
  // 32 bit integers to 64 bit floats as necessary. This causes
  // incompatibilities between the LSL Encryption and the PHP
  // counterpart. I got round this by changing all addition to
  // binary addition using logical & and ^ and loops to handle bit
  // carries. This forces the 32 bit integer to remain 32 bits as
  // I mask out any carry over 32 bits. this bring the output of the
  // decrypt routine to conform with the output of its LSL counterpart.
  // Subtractions are handled by using 2's compliment


  // LSL does not have unsigned integers, so when shifting right we
  // have to mask out sign-extension bits.


  // calculate ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
  $v1a = binadd((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) , $v0);
  // calculate ($sum + $_xtea_key[($sum>>11) & 3])
  $v1b = binadd($sum , $_xtea_key[($sum>>11) & 3]);
  //Calculate 2's compliment of ($v1a ^ $v1b) for subtraction
  $v1c = binadd((~($v1a ^ $v1b)) , 1);
  //Calculate ($v1 - ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
  //            ^ ($sum + $_xtea_key[($sum>>11) & 3]))
  $v1 = binadd($v1 , $v1c);


default
  // Calculate new $sum based on $num_rounds - 1
{
  $tnr = $num_rounds - 1; // Temp $num_rounds
    touch_start(integer number)
  $sum = 0; // $_XTEA_DELTA * ($num_rounds - 1);
    {
  $tda = $_XTEA_DELTA;
        string tosend = "this is a message to send";
  do{ // Binary multiplication using binary manipulation
        llWhisper(0, "Message to Send = " + tosend);
  if($tnr & 1){
        xtea_key = xtea_key_from_string("this is a test key");
    $sum = binadd($sum , $tda);
        string message = xtea_encrypt_string(tosend);
  }
        llWhisper(0, "Message to Server = " + message);
  $tnr = $tnr >> 1;
        requestid = llHTTPRequest(url,  
  $tda = ($tda << 1) & 0x0FFFFFFFF;
            [HTTP_METHOD, "POST",
  }while($tnr);
            HTTP_MIMETYPE, "application/x-www-form-urlencoded"],
            "parameter1=" + llEscapeURL(message));
    }


    http_response(key request_id, integer status, list metadata, string body)
  //Calculate ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
    {
  $v0a = binadd((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) , $v1);
        if (request_id == requestid) {
  //Calculate ($sum + $_xtea_key[$sum & 3])
            llWhisper(0, "Web server sent: " + body);
  $v0b = binadd($sum , $_xtea_key[$sum & 3]);
            integer clean = 0;
  //Calculate 2's compliment of ($v0a ^ $v0b) for subtraction
            string cleanbody = "";
  $v0c = binadd((~($v0a ^ $v0b)) , 1);
            while(~llSubStringIndex(base64,llGetSubString(body,clean,clean))){
  //Calculate ($v0 - ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1
                cleanbody += llGetSubString(body,clean,clean++);
  //          ^ ($sum + $_xtea_key[$sum & 3]))
            }
  $v0 = binadd($v0 , $v0c);
            llWhisper(0, "Cleaned : " + cleanbody);
} while ( $num_rounds = ~-$num_rounds );
            llWhisper(0, "Web server said: " + xtea_decrypt_string( cleanbody ));
 
        }
return substr(integer_base64($v0), 0, 5) . substr(integer_base64($v1), 0, 5);
    }
}
}


</lsl>
// Encrypt a full string using XTEA.
function xtea_encrypt_string( $str ) {
// encode Binany string to Base64
$str = base64_encode($str);


PHP Code - Place on web server at location that LSL URL will be looking for.
// remove trailing =s so we can do our own 0 padding
 
$i = strpos($str, '=', 0);
<pre>
  if ( $i !== FALSE  ){
//************************************************//
  $str = substr( $str, 0, $i);
//* Sleight's PHP XTEA encryption/decryption v3 *//
}
//* Modified by SleightOf Hand for Stability and *//
// we don't want to process padding, so get length before adding it
//* intercommunication between PHP & LSL        *//
$len = strlen($str);
//************************************************//
// zero pad
// NOTE: This version only encodes 60 bits per 64-bit block!
$str .= "AAAAAAAAAA=";
// This code is public domain.
$result = "";
// Sleight was here 20070522
$i = 0;
// masa was here 20070315
// so was strife 20070315
// so was adz 20080812
//
// This was converted from the LSL version by
// SleightOf Hand to allow Strong encryption
// between LSL and PHP. If you find this usefull
// any donations apreciated.
//************************************************//
//* XTEA IMPLEMENTATION                          *//
//************************************************//


$_XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
do {
$_xtea_num_rounds = 6;
  // encipher 30 (5*6) bits at a time.
$_xtea_key        = array(0, 0, 0, 0);
  $enc1 = base64_integer(substr($str , $i , 5) . "A==");
$_base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
  $i += 5;
          "abcdefghijklmnopqrstuvwxyz".
  $enc2 = base64_integer(substr($str , $i , 5) . "A==");
          "0123456789+/";
  $i += 5;
 
  $result .= xtea_encipher($enc1, $enc2);
// Returns Integer based on 8 byte Base64 Code XXXXXX== (llBase64ToInteger)
  } while ( $i < $len );
function base64_integer($str){
  return $result; //Return Encrypted string
global $_base64;
if(strlen($str) != 8) return 0;
return ((strpos($_base64,$str{0}) << 26)|
(strpos($_base64,$str{1}) << 20)|
  (strpos($_base64,$str{2}) << 14)|
(strpos($_base64,$str{3}) << 8) |
(strpos($_base64,$str{4}) << 2) |
  (strpos($_base64,$str{5}) >> 4));
}
}


// Returns 8 Byte Base64 code based on 32 bit integer ((llIntegerToBase64)
// Decrypt a full string using XTEA
function integer_base64($int){
function xtea_decrypt_string( $str ) {
  global $_base64;
  global $_base64 ;
if($int != (integer) $int) return 0;
return  $_base64{($int >> 26 & 0x3F)} .
$_base64{($int >> 20 & 0x3F)} .
$_base64{($int >> 14 & 0x3F)} .
$_base64{($int >> 8 & 0x3F)}  .
$_base64{($int >> 2 & 0x3F)}  .
$_base64{($int << 4 & 0x3F)} . "==";
}


//strict 32 bit addition using logic
$len = strlen($str);
function binadd($val1 , $val2){
  $i;
  $tc = $val1 & $val2;
  $result;
  $ta = $val1 ^ $val2;
  do {
  do{
   $dec1 = base64_integer(substr($str , $i , 6)."==");
   $tac = ($tc << 1) & 0x0FFFFFFFF;
   $i += 6;
   $tc = $ta & $tac;
  $dec2 = base64_integer(substr($str , $i , 6)."==");
   $ta = $ta ^ $tac;
   $i += 6;
  }while($tc);
  $result .= xtea_decipher( $dec1, $dec2);
  return $ta; // $ta will now be the result so return it
  } while ( $i < $len );
 
// Replace multiple trailing zeroes with a single one
$result = rtrim($result, "A");
$i = strlen($result);
  $mod = $i%4; //Depending on encoded length different appends are needed
if($mod == 1) $result .= "A==";
else if($mod == 2 ) $result .= "==";
else if($mod == 3) $result .= "=";
 
return base64_decode( $result );
}
}


// Convers any string to a 32 char MD5 string and then to a list of
// Only works with PHP compiled as an Apache module
// 4 * 32 bit integers = 128 bit Key.
$headers = apache_request_headers();
function xtea_key_from_string( $str ) {
global $_xtea_key;
$str = md5($str . ":0"); // Use nonce = 0 in LSL for same output
eval("\$_xtea_key[0] = 0x" . substr($str,0,8) . ";");
eval("\$_xtea_key[1] = 0x" . substr($str,8,8) . ";");
eval("\$_xtea_key[2] = 0x" . substr($str,16,8) . ";");
eval("\$_xtea_key[3] = 0x" . substr($str,24,8) . ";");
}


// Encipher two integers and return the result as a 12-byte string
$objectName = $headers["X-SecondLife-Object-Name"];
// containing two base64-encoded integers.
$objectKey    = $headers["X-SecondLife-Object-Key"];
function xtea_encipher( $v0 , $v1 ) {
$ownerKey    = $headers["X-SecondLife-Owner-Key"];
global  $_xtea_num_rounds , $_xtea_key , $_XTEA_DELTA;
$ownerName = $headers["X-SecondLife-Owner-Name"];
$num_rounds = $_xtea_num_rounds;
$region        = $headers["X-SecondLife-Region"];
$sum = 0;
// and so on for getting all the other variables ...
do {
  // LSL only has 32 bit integers. However PHP automaticly changes
  // 32 bit integers to 64 bit floats as nessesary. This causes
  // incompatibilities between the LSL Encryption and the PHP
  // counterpart. I got round this by changing all addition to
  // binary addition using logical & and ^ and loops to handle bit
  // carries. This forces the 32 bit integer to remain 32 bits as
  // I mask out any carry over 32 bits. this bring the output of the
  // encrypt routine to conform with the output of its LSL counterpart.


  // LSL does not have unsigned integers, so when shifting right we
//to pull out this headers in other kinds of installations, use this (Adz)
  // have to mask out sign-extension bits.
/*
$objectName    = $_SERVER['HTTP_X_SECONDLIFE_OBJECT_NAME'];
$objectKey    = $_SERVER['HTTP_X_SECONDLIFE_OBJECT_KEY'];
$region        = $_SERVER['HTTP_X_SECONDLIFE_REGION'];
$ownerName    = $_SERVER['HTTP_X_SECONDLIFE_OWNER_NAME'];
$ownerKey      = $_SERVER['HTTP_X_SECONDLIFE_OWNER_KEY'];
*/


  // calculate ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
xtea_key_from_string("this is a test key");
  $v0a = binadd((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) , $v1);
// get things from $_POST[]
  // calculate ($sum + $_xtea_key[$sum & 3])
// Naturally enough, if this is empty, you won't get anything
  $v0b = binadd($sum , $_xtea_key[$sum & 3]);
$parameter1 = xtea_decrypt_string($_POST["parameter1"]);
  // Calculate ($v0 + ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
  //            ^ ($sum + $_xtea_key[$sum & 3]))
  $v0 = binadd($v0 , ($v0a  ^ $v0b));


  //Calculate ($sum + $_XTEA_DELTA)
echo xtea_encrypt_string($ownerName . " just said " . $parameter1) . "\n";
  $sum = binadd($sum , $_XTEA_DELTA);
</source>


  //Calculate ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
This should result in the following output.
  $v1a = binadd((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF))  , $v0);
  // Calculate ($sum + $_xtea_key[($sum >>11) & 3])
  $v1b = binadd($sum , $_xtea_key[($sum >>11) & 3]);
  //Calculate ($v1 + ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0
  //          ^ ($sum & $_xtea_key[($sum >>11) & 3]))
  $v1 = binadd($v1 , ($v1a  ^ $v1b));
} while( $num_rounds = ~-$num_rounds );
//return only first 6 chars to remove "=="'s and compact encrypted text.
return substr(integer_base64($v0),0,6) . substr(integer_base64($v1),0,6);
}


// Decipher two base64-encoded integers and return the FIRST 30 BITS of
Object whispers: Message to Send = this is a message to send<br/>
// each as one 10-byte base64-encoded string.
Object whispers: Message to Server = JSdgCA0FDyhgLlUnSgqMQWkAxz1AzA1vr9zwSEDnCgwJ6GNQ<br />
function xtea_decipher( $v0, $v1 ) {
Object whispers: Web server sent: SVbqNQ5XdkngeUI3bgP+s6eAT6GM4AWnYCYApcfxagrPbxmwiY7WXA4J+gEQ1AYhRQNvcnEwfZSo/AuKVtIw<br />
global  $_xtea_num_rounds , $_xtea_key , $_XTEA_DELTA;
Object whispers: Cleaned : SVbqNQ5XdkngeUI3bgP+s6eAT6GM4AWnYCYApcfxagrPbxmwiY7WXA4J+gEQ1AYhRQNvcnEwfZSo/AuKVtIw<br />
$num_rounds = $_xtea_num_rounds;
Object whispers: Web server said: SleightOf Hand just said this is a message to send
$sum = 0; // $_XTEA_DELTA * $_xtea_num_rounds;
$tda = $_XTEA_DELTA;
do{ // Binary multiplication using binary manipulation
  if($num_rounds & 1){
  $sum = binadd($sum , $tda);
  }
  $num_rounds = $num_rounds >> 1;
  $tda = ($tda << 1) & 0x0FFFFFFFF;
}while($num_rounds);
$num_rounds = $_xtea_num_rounds; // reset $num_rounds back to its propper setting;


do {
PHP 5 class of XTEA
  // LSL only has 32 bit integers. However PHP automaticly changes
  // 32 bit integers to 64 bit floats as nessesary. This causes
  // incompatibilities between the LSL Encryption and the PHP
  // counterpart. I got round this by changing all addition to
  // binary addition using logical & and ^ and loops to handle bit
  // carries. This forces the 32 bit integer to remain 32 bits as
  // I mask out any carry over 32 bits. this bring the output of the
  // decrypt routine to conform with the output of its LSL counterpart.
  // Subtrations are handled by using 2's compliment


  // LSL does not have unsigned integers, so when shifting right we
<source lang="php">
  // have to mask out sign-extension bits.
<?php
// http://wiki.secondlife.com/wiki/XTEA_Strong_Encryption_Implementation
//************************************************//
//* Sleight's PHP XTEA encryption/decryption v3  *//
//* Modified by SleightOf Hand for Stability and *//
//* intercommunication between PHP & LSL         *//
//************************************************//
// NOTE: This version only encodes 60 bits per 64-bit block!
// This code is public domain.
// Sleight was here 20070522
// masa was here 20070315
// so was strife 20070315
// so was adz 20080812
// gave this some class 20080201 JB Kraft
//
// This was converted from the LSL version by
// SleightOf Hand to allow Strong encryption
// between LSL and PHP. If you find this usefull
// any donations apreciated.
//************************************************//
//* XTEA IMPLEMENTATION                          *//
//************************************************//


  // calculate ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
/**
  $v1a = binadd((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) , $v0);
* PHP 5 class to do XTEA crypting
   // calculate ($sum + $_xtea_key[($sum>>11) & 3])
*
   $v1b = binadd($sum , $_xtea_key[($sum>>11) & 3]);
* $xtea = new XTEA( "mypassword" );
   //Calculate 2's compliment of ($v1a ^ $v1b) for subtraction
* $crypted = $xtea->encrypt( "Some bogus string" );
   $v1c = binadd((~($v1a ^ $v1b)) , 1);
* echo "Encrypted: " . bin2hex($crypted);
   //Calculate ($v1 - ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
* echo "Decrypted: " . $xtea->decrypt( $crypted );
   //           ^ ($sum + $_xtea_key[($sum>>11) & 3]))
*
   $v1 = binadd($v1 , $v1c);
* @package whatevah
* @author JB Kraft
**/
class XTEA
{
 
   private $_XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
   private $_xtea_num_rounds = 6;
  private $_xtea_key       = array(0, 0, 0, 0);
   private $_base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 
  /**
  * CTOR
  *
  * @param  $passwd the password to use for crypting
  * @author JB Kraft
  **/
   public function __construct( $passwd )
   {
    $this->xtea_key_from_string( $passwd );   
  }
 
   /**
  * Encrypt a full string using XTEA.
  *
  * @param $str the string to encrypt
  * @return the encrypted string
  * @author JB Kraft
  **/
  public function encrypt( $str )  
   {
  // encode Binany string to Base64
  $str = base64_encode($str);


  // Calculate new $sum based on $num_rounds - 1
  // remove trailing =s so we can do our own 0 padding
  $tnr = $num_rounds - 1;  // Temp $num_rounds
  $i = strpos($str, '=', 0);
  $sum = 0; // $_XTEA_DELTA * ($num_rounds - 1);
   if ( $i !== FALSE  ){
  $tda = $_XTEA_DELTA;
     $str = substr( $str, 0, $i);
  do{ // Binary multiplication using binary manipulation
   if($tnr & 1){
     $sum = binadd($sum , $tda);
   }
   }
   $tnr = $tnr >> 1;
  // we don't want to process padding, so get length before adding it
  $tda = ($tda << 1) & 0x0FFFFFFFF;
   $len = strlen($str);
   }while($tnr);
  // zero pad
  $str .= "AAAAAAAAAA=";
  $result = "";
  $i = 0;
 
  do {
    // encipher 30 (5*6) bits at a time.
    $enc1 = $this->base64_integer(substr($str , $i , 5) . "A==");
    $i += 5;
    $enc2 = $this->base64_integer(substr($str , $i , 5) . "A==");
    $i += 5;
    $result .= $this->xtea_encipher($enc1, $enc2);
  } while ( $i < $len );
  return $result; //Return Encrypted string
   }
 
  /**
  * Decrypt a full string using XTEA
  *
  * @param $str the string to decrypt
  * @return the decrypted string
  * @author JB Kraft
  **/
  public function decrypt( $str )
  {
  $len = strlen($str);
  $i = 0;
  $result = '';
  do {
    $dec1 = $this->base64_integer(substr($str , $i , 6)."==");
    $i += 6;
    $dec2 = $this->base64_integer(substr($str , $i , 6)."==");
    $i += 6;
    $result .= $this->xtea_decipher( $dec1, $dec2);
  } while ( $i < $len );
 
  // Replace multiple trailing zeroes with a single one
  $i = strlen($result);
  while ( substr($result, --$i, 1) == "A" );
  $result = substr($result, 0, $i+1);
  $i = strlen($result);
  $mod = $i%4; //Depending on encoded length diffrent appends are needed
  if($mod == 1) $result .= "A==";
  else if($mod == 2 ) $result .= "==";
  else if($mod == 3) $result .= "=";


   //Calculate ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
  return base64_decode( $result );
  $v0a = binadd((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) , $v1);
  }
  //Calculate ($sum + $_xtea_key[$sum & 3])
 
  $v0b = binadd($sum , $_xtea_key[$sum & 3]);
  // -----------------------------
  //Calculate 2's compliment of ($v0a ^ $v0b) for subtraction
  // stuff below here is protected
  $v0c = binadd((~($v0a ^ $v0b)) , 1);
  // -----------------------------
  //Calculate ($v0 - ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1
 
  //          ^ ($sum + $_xtea_key[$sum & 3]))
  // Returns Integer based on 8 byte Base64 Code XXXXXX== (llBase64ToInteger)
   $v0 = binadd($v0 , $v0c);
  protected function base64_integer($str)
} while ( $num_rounds = ~-$num_rounds );
  {
  if(strlen($str) != 8) return 0;
  return ((strpos($this->_base64,$str{0}) << 26)|
  (strpos($this->_base64,$str{1}) << 20)|
  (strpos($this->_base64,$str{2}) << 14)|
  (strpos($this->_base64,$str{3}) << 8) |
  (strpos($this->_base64,$str{4}) << 2) |
  (strpos($this->_base64,$str{5}) >> 4));
  }
 
  // Returns 8 Byte Base64 code based on 32 bit integer ((llIntegerToBase64)
  protected function integer_base64($int)
  {
  if($int != (integer) $int) return 0;
  return  $this->_base64{($int >> 26 & 0x3F)} .
  $this->_base64{($int >> 20 & 0x3F)} .
  $this->_base64{($int >> 14 & 0x3F)} .
  $this->_base64{($int >> 8 & 0x3F)}  .
  $this->_base64{($int >> 2 & 0x3F)}  .
  $this->_base64{($int << 4 & 0x3F)} . "==";
  }
 
   //strict 32 bit addition using logic
  protected function binadd($val1 , $val2)
  {
  $tc = $val1 & $val2;
  $ta = $val1 ^ $val2;
  do{
    $tac = ($tc << 1) & 0x0FFFFFFFF;
    $tc = $ta & $tac;
    $ta = $ta ^ $tac;
  }while($tc);
  return $ta; // $ta will now be the result so return it
  }
 
  // Convers any string to a 32 char MD5 string and then to a list of
  // 4 * 32 bit integers = 128 bit Key.
  protected function xtea_key_from_string( $str )
  {
  $str = md5($str . ":0"); // Use nonce = 0 in LSL for same output
  $this->_xtea_key[0] = hexdec(substr($str,0,8));
  $this->_xtea_key[1] = hexdec(substr($str,8,8));
  $this->_xtea_key[2] = hexdec(substr($str,16,8));
  $this->_xtea_key[3] = hexdec(substr($str,24,8));
  }
 
  // Encipher two integers and return the result as a 12-byte string
  // containing two base64-encoded integers.
  protected function xtea_encipher( $v0 , $v1 )
  {
  $num_rounds = $this->_xtea_num_rounds;
  $sum = 0;
  do {
    // LSL only has 32 bit integers. However PHP automatically changes
    // 32 bit integers to 64 bit floats as necessary. This causes
    // incompatibilities between the LSL Encryption and the PHP
    // counterpart. I got round this by changing all addition to
    // binary addition using logical & and ^ and loops to handle bit
    // carries. This forces the 32 bit integer to remain 32 bits as
    // I mask out any carry over 32 bits. this bring the output of the
    // encrypt routine to conform with the output of its LSL counterpart.
 
    // LSL does not have unsigned integers, so when shifting right we
    // have to mask out sign-extension bits.
 
    // calculate ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
    $v0a = $this->binadd((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) , $v1);
    // calculate ($sum + $this->_xtea_key[$sum & 3])
    $v0b = $this->binadd($sum , $this->_xtea_key[$sum & 3]);
    // Calculate ($v0 + ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
    //            ^ ($sum + $this->_xtea_key[$sum & 3]))
    $v0 = $this->binadd($v0 , ($v0a ^ $v0b));
 
    //Calculate ($sum + $this->_XTEA_DELTA)
    $sum = $this->binadd($sum , $this->_XTEA_DELTA);
 
    //Calculate ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
    $v1a = $this->binadd((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) , $v0);
    // Calculate ($sum + $this->_xtea_key[($sum >>11) & 3])
    $v1b = $this->binadd($sum , $this->_xtea_key[($sum >>11) & 3]);
    //Calculate ($v1 + ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0
    //          ^ ($sum & $this->_xtea_key[($sum >>11) & 3]))
    $v1 = $this->binadd($v1 , ($v1a  ^ $v1b));
  } while( $num_rounds = ~-$num_rounds );
  //return only first 6 chars to remove "=="'s and compact encrypted text.
  return substr($this->integer_base64($v0),0,6) . substr($this->integer_base64($v1),0,6);
  }
 
  // Decipher two base64-encoded integers and return the FIRST 30 BITS of
   // each as one 10-byte base64-encoded string.
  protected function xtea_decipher( $v0, $v1 )
  {
  $num_rounds = $this->_xtea_num_rounds;
  $sum = 0; // $this->_XTEA_DELTA * $this->_xtea_num_rounds;
  $tda = $this->_XTEA_DELTA;
  do{ // Binary multiplication using binary manipulation
    if($num_rounds & 1){
    $sum = $this->binadd($sum , $tda);
    }
    $num_rounds = $num_rounds >> 1;
    $tda = ($tda << 1) & 0x0FFFFFFFF;
  }while($num_rounds);
  $num_rounds = $this->_xtea_num_rounds; // reset $num_rounds back to its propper setting;
 
  do {
    // LSL only has 32 bit integers. However PHP automatically changes
    // 32 bit integers to 64 bit floats as necessary. This causes
    // incompatibilities between the LSL Encryption and the PHP
    // counterpart. I got round this by changing all addition to
    // binary addition using logical & and ^ and loops to handle bit
    // carries. This forces the 32 bit integer to remain 32 bits as
    // I mask out any carry over 32 bits. this bring the output of the
    // decrypt routine to conform with the output of its LSL counterpart.
    // Subtractions are handled by using 2's compliment
 
    // LSL does not have unsigned integers, so when shifting right we
    // have to mask out sign-extension bits.


return substr(integer_base64($v0), 0, 5) . substr(integer_base64($v1), 0, 5);
    // calculate ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
}
    $v1a = $this->binadd((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) , $v0);
    // calculate ($sum + $this->_xtea_key[($sum>>11) & 3])
    $v1b = $this->binadd($sum , $this->_xtea_key[($sum>>11) & 3]);
    //Calculate 2's compliment of ($v1a ^ $v1b) for subtraction
    $v1c = $this->binadd((~($v1a ^ $v1b)) , 1);
    //Calculate ($v1 - ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
    //            ^ ($sum + $this->_xtea_key[($sum>>11) & 3]))
    $v1 = $this->binadd($v1 , $v1c);


// Encrypt a full string using XTEA.
    // Calculate new $sum based on $num_rounds - 1
function xtea_encrypt_string( $str ) {
    $tnr = $num_rounds - 1;  // Temp $num_rounds
// encode Binany string to Base64
    $sum = 0; // $this->_XTEA_DELTA * ($num_rounds - 1);
$str = base64_encode($str);
    $tda = $this->_XTEA_DELTA;
    do{ // Binary multiplication using binary manipulation
    if($tnr & 1){
      $sum = $this->binadd($sum , $tda);
    }
    $tnr = $tnr >> 1;
    $tda = ($tda << 1) & 0x0FFFFFFFF;
    }while($tnr);


// remove trailing =s so we can do our own 0 padding
    //Calculate ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
$i = strpos($str, '=', 0);
    $v0a = $this->binadd((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) , $v1);
if ( $i !== FALSE  ){
    //Calculate ($sum + $this->_xtea_key[$sum & 3])
  $str = substr( $str, 0, $i);
    $v0b = $this->binadd($sum , $this->_xtea_key[$sum & 3]);
}
    //Calculate 2's compliment of ($v0a ^ $v0b) for subtraction
// we don't want to process padding, so get length before adding it
    $v0c = $this->binadd((~($v0a ^ $v0b)) , 1);
$len = strlen($str);
    //Calculate ($v0 - ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1
// zero pad
    //          ^ ($sum + $this->_xtea_key[$sum & 3]))
$str .= "AAAAAAAAAA=";
    $v0 = $this->binadd($v0 , $v0c);
$result = "";
  } while ( $num_rounds = ~-$num_rounds );
$i = 0;


do {
  return substr($this->integer_base64($v0), 0, 5) . substr($this->integer_base64($v1), 0, 5);
  // encipher 30 (5*6) bits at a time.
   }
  $enc1 = base64_integer(substr($str , $i , 5) . "A==");
  $i += 5;
  $enc2 = base64_integer(substr($str , $i , 5) . "A==");
  $i += 5;
  $result .= xtea_encipher($enc1, $enc2);
} while ( $i < $len );
return $result; //Return Encrypted string
}
 
// Decrypt a full string using XTEA
function xtea_decrypt_string( $str ) {
global $_base64 ;
 
$len = strlen($str);
$i;
$result;
do {
  $dec1 = base64_integer(substr($str , $i , 6)."==");
   $i += 6;
  $dec2 = base64_integer(substr($str , $i , 6)."==");
  $i += 6;
  $result .= xtea_decipher( $dec1, $dec2);
} while ( $i < $len );


// Replace multiple trailing zeroes with a single one
$i = strlen($result);
while ( substr($result, --$i, 1) == "A" );
$result = substr($result, 0, $i+1);
$i = strlen($result);
$mod = $i%4; //Depending on encoded length diffrent appends are needed
if($mod == 1) $result .= "A==";
else if($mod == 2 ) $result .= "==";
else if($mod == 3) $result .= "=";
return base64_decode( $result );
}
}


// Only works with PHP compiled as an Apache module
?>
$headers = apache_request_headers();
</source>
 
$objectName = $headers["X-SecondLife-Object-Name"];
$objectKey    = $headers["X-SecondLife-Object-Key"];
$ownerKey    = $headers["X-SecondLife-Owner-Key"];
$ownerName = $headers["X-SecondLife-Owner-Name"];
$region        = $headers["X-SecondLife-Region"];
// and so on for getting all the other variables ...
 
//to pull out this headers in other kinds of installations, use this (Adz)
/*
$objectName    = $_SERVER['HTTP_X_SECONDLIFE_OBJECT_NAME'];
$objectKey    = $_SERVER['HTTP_X_SECONDLIFE_OBJECT_KEY'];
$region        = $_SERVER['HTTP_X_SECONDLIFE_REGION'];
$ownerName    = $_SERVER['HTTP_X_SECONDLIFE_OWNER_NAME'];
$ownerKey      = $_SERVER['HTTP_X_SECONDLIFE_OWNER_KEY'];
*/
 
xtea_key_from_string("this is a test key");
// get things from $_POST[]
// Naturally enough, if this is empty, you won't get anything
$parameter1 = xtea_decrypt_string($_POST["parameter1"]);
 
echo xtea_encrypt_string($ownerName . " just said " . $parameter1) . "\n";
</pre>
 
This should result in the following output.
 
Object whispers: Message to Send = this is a message to send
Object whispers: Message to Server = JSdgCA0FDyhgLlUnSgqMQWkAxz1AzA1vr9zwSEDnCgwJ6GNQ
Object whispers: Web server sent: SVbqNQ5XdkngeUI3bgP+s6eAT6GM4AWnYCYApcfxagrPbxmwiY7WXA4J+gEQ1AYhRQNvcnEwfZSo/AuKVtIw
Object whispers: Cleaned : SVbqNQ5XdkngeUI3bgP+s6eAT6GM4AWnYCYApcfxagrPbxmwiY7WXA4J+gEQ1AYhRQNvcnEwfZSo/AuKVtIw
Object whispers: Web server said: SleightOf Hand just said this is a message to send


= Test Vectors =
= Test Vectors =
Line 1,525: Line 1,652:
The following code has been imported to LSL to test the vectors with an XTEA implementation. It also makes use of a modified version of the [[Hex]] method on this wiki to display the data. Right Shift of signed integers is handed by techniques introduced in the [[Right_Shift]] method on this wiki.
The following code has been imported to LSL to test the vectors with an XTEA implementation. It also makes use of a modified version of the [[Hex]] method on this wiki to display the data. Right Shift of signed integers is handed by techniques introduced in the [[Right_Shift]] method on this wiki.


<lsl>
<source lang="lsl2">
// XTEA is a version of slightly improved TEA
// XTEA is a version of slightly improved TEA
// The plain or cypher text is in v[0], v[1]
// The plain or cypher text is in v[0], v[1]
Line 1,615: Line 1,742:
     }
     }
}
}
</lsl>
</source>




{{#vardefine:sort|XTEA Strong Encryption Implementation}}{{LSLC|Library}}{{LSLC|Examples}}
{{#vardefine:sort|XTEA Strong Encryption Implementation}}{{LSLC|Library}}{{LSLC|Examples}}
  [[Category:LSL Encryption]]
  [[Category:LSL Encryption]]

Latest revision as of 17:20, 24 January 2015

XTEA Strong Encryption Implementation - Linden Scripting Language (LSL) Version 1.0

Contributors

License

This work is licensed under a Creative Commons Attribution 3.0 Unported License

You are free:

  • to Share — to copy, distribute and transmit the work
  • to Remix — to adapt the work

Under the following conditions

  • Attribution. You must attribute the work in the manner specified by the author or licensor (but not in any way that suggests that they endorse you or your use of the work).
  1. For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to this web page.
  2. Any of the above conditions can be waived if you get permission from the copyright holder.
  3. Nothing in this license impairs or restricts the author's moral rights.

Disclaimer

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

IF YOU READ ONE THING IN HERE, READ THIS

It is VERY important to remember that there is no such thing as cookbook cryptography! Simply using this cypher does not guarantee security. Security is an end-to-end concern and responsibility lies with you to thoroughly examine your project from all possible angles if valuable data is at risk. If you doubt this, ask any thief how they'd rather break into your house - futzing about with picking a high-security deadbolt on the front door or walking in through the back door that you left open.

Documentation

Included at the end of this source listing is a small bit of example code that shows the usage. If you wish to include this implementation in your own work, just replace the example code with your own. Also, please do not reuse or redistribute this work without including the above text attributing this code to its author Morse Dillon, the above GPL statement, and this documentation.

This is an implementation of the XTEA (eXtended Tiny Encryption Algorithm) block cypher. (X)TEA is a very good choice of cipher when security is important but computational power is limited. Although I did a lot of work on this implementation, enormous amounts of credit must be given to the creators of the algorithm and those who came before me to implement it in other languages and computing environments.

If you do decide to use this code in a project, I'd appreciate hearing about it. You can reach me by e-mail at: morseATmorsedillon.com

About TEA

The Tiny Encryption Algorithm (TEA), was originally designed by David Wheeler and Roger Needham of the Cambridge Computer Laboratory. The algorithm itself is not subject to any patents. While the original TEA was found to have some minor weaknesses, the eXtended Tiny Encryption Algorithm (XTEA) implemented herein addresses these.

NOTE: XTEA has been superseded by Corrected Block TEA (XXTEA)

TEA and its derivatives consist of 64-bit block Feistel network with a 128-bit key. This implementation uses six cycles, or rounds, which is less than one would like but still provides a reasonable level of security (16 is sufficient while 8 is enough for most applications). Six is said to achieve theoretically good dispersion, but should more security be desired the number of cycles can easily be modified by changing the CYCLES global variable. Due to the low execution speed of LSL scripts, it's suggested to make this as low as your comfort level allows. Encryption time scales linearly with the number of cycles.

About this implementation

This is a bare bones implementation, and is meant to be included in the body of the script needing encryption facilities or wrapped in a link message handler. If the latter approach is desired, care should be taken to only send link messages to the prim containing this implementation. If ALL_PRIMS is used as the destination, one could link a link message listener to the object and intercept clear-text communications.

If you plan to place this code into the same script as that needing encryption facilities, you need only call the following functions:

string Encrypt(string clearText)
string Decrypt(string cypherText)

Simple as that.

This implementation does not provide any secure key exchange, so in terms of key generation and exchange you're on your own.

The 128-bit key is contained in four LSL integers: KEY1, KEY2, KEY3, and KEY4. These are global variables at the beginning of the source and can be set using a method that works for you.

Changes

Version 1.1

  • Changed to treat Right Shift as if integers were unsigned

Version 1.0a - Alpha

  • General optimization to run faster and use less bytecode.
  • Encrypt: Pad works differently, no longer extra characters appended to the output.
  • TEAEncrypt: Changed the return type
  • ord: Added null support.

Version 1.0

  • Initial Release

Future Recommendations

  • Support UTF-8
  • Output to Base64 instead of Hex strings
  • Append hash to the message to verify integrity of data
  • Hash clear-text passwords into 128 bit keys
  • Upgrade to XXTEA

Code

Original

 
//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)
//Version 1.0
//Copyright (C) 2007 by Morse Dillon (morseATmorsedillon.com)
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
//02110-1301, USA.
//========================================================================
//
//Included at the end of this source listing is a small bit of example 
//code that shows the usage.  If you wish to include this implementation 
//in your own work, just replace the example code with your own.  Also, 
//please do not reuse or redistribute this work without including the 
//above text attributing this code to its author Morse Dillon, the above
//GPL statement, and this documentation.
//
//This is an implentation of the XTEA (eXtended Tiny Encryption Algorithm) 
//block cypher.  (X)TEA is a very good choice of cipher when security
//is important but computational power is limited.  Although I did a
//lot of work on this implementation, enormous amounts of credit must
//be given to the creators of the algorithm and those who came before
//me to implement it in other languages and computing environments.
//
//***If you do decide to use this code in a project, I'd appreciate 
//hearing about it.  You can reach me by e-mail at:  
//morseATmorsedillon.com
//
//
//ABOUT TEA AND XTEA
//------------------
//TEA was originally designed by David Wheeler and Roger Needham 
//of the Cambridge Computer Laboratory.  The algorithm itself is not
//subject to any patents.  While the original TEA was found to have
//some minor weaknesses, XTEA (implemented herein) addresses these.  
//
//TEA and its derivatives consist of 64-bit block Feistel network 
//with a 128-bit key.  This implementation uses six cycles, or rounds,
//which is less than one would like but still provides a reasonable
//level of security (16 is sufficient while 8 is enough for most 
//applications).  Six is said to achieve theoretically good dispersion, 
//but should more security be desired the number of cycles can easily be 
//modified by changing the CYCLES global variable.  Due to the low 
//execution speed of LSL scripts, it's suggested to make this as low as 
//your comfort level allows.  Encryption time scales linearly with the 
//number of cycles.
//
//For more information about XTEA, see the following:
//
//Original Paper by Walker and Needham
//http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html
//
//Wikipedia on TEA
//http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
//
//
//ABOUT THIS IMPLEMENTATION
//-------------------------
//This is a barebones implementation, and is meant to be included in
//the body of the script needing encryption facilities or wrapped
//in a link message handler.  If the latter approach is desired, care
//should be taken to only send link messages to the prim containing
//this implementation.  If ALL_PRIMS is used as the destination,
//one could link a link message listener to the object and intercept
//cleartext communications.  
//
//If you plan to place this code into the same script as that needing
//encryption facilities, you need only call the following functions:
//
//string Encrypt(string cleartext)
//string Decrypt(string cyphertext)
//
//Simple as that.
//
//This implementation does not provide any secure key exchange, so in
//terms of key generation and exchange you're on your own.
//
//The 128-bit key is contained in four LSL integers:  KEY1, KEY2, KEY3,
//and KEY4.  These are global variables at the beginning of the source
//and can be set using a method that works for you.
//
//
//**************IF YOU READ ONE THING IN HERE, READ THIS*******************
//It is VERY important to remember that there is no such thing as
//'cookbook cryptography'!  Simply using this cypher does not guarantee
//security.  Security is an end-to-end concern and responsibility lies
//with you to thoroughly examine your project from all possible angles
//if valuable data is at risk.  If you doubt this, ask any thief how they'd
//rather break into your house - futzing about with picking a high-security
//deadbolt on the front door or walking in through the back door that you 
//left open.

//******************USER-CONFIGURABLE GLOBALS BEGIN HERE*******************

//ENCRYPTION KEYS KEY[1-4]
//These together make up the 128-bit XTEA encryption key.  See the above 
//documentation for details.  Whatever you do, don't leave them as the default.
integer KEY1 = 11111111;
integer KEY2 = 22222222;
integer KEY3 = 33333333;
integer KEY4 = 44444444;

//DEBUG_FLAG
//If set to 1, will cause debug text to be printed containing some 
//intermediate cleartext/cyphertext and the resultant cyphertext/cleartext.  
//Do not leave this enabled in production environments!!!!
integer DEBUG_FLAG = 0;

//COMM_CHANNEL
//Specifies which channel should be used for debug and test harness communication.
integer COMM_CHANNEL = 0;

//CYCLES
//Specifies the number of rounds to be used.  See the above documentation for
//details.
integer CYCLES = 6;

//******************USER-CONFIGURABLE GLOBALS END HERE*********************

//Other Globals
list cypherkey = [];
integer delta = 0x9E3779B9;



//Function: ord
//Returns the index of an ASCII character
integer ord(string chr)
{
    string ASCII = "             \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
    if(llStringLength(chr) != 1) return -1;
    if(chr == " ") return 32;
    return llSubStringIndex(ASCII, chr);
}



//Function: chr
//Returns the ASCII character correspondent to index i
string chr(integer i)
{
    string ASCII = "             \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
    i %= 127;
    return llGetSubString(ASCII, i, i);
}

   
                     
//Function:  DWord2Hex
//Converts a dword containted in a LSL integer to hexadecimal format.        
string DWord2Hex(integer m){
    
    string result;
    integer i = 0;
    integer index = 0;
    
    //Define character string [0-F] for use in building the hex.
    string characters = "0123456789ABCDEF";   
    
    //Step through 8 times, for a total of 32 bits, 8 nibbles, and 8 hexadecimal digits.
    for (i = 0; i < 8; i++){
        //Get a nibble by right-shifting and masking off 4 bits.
        index  = (m >> (i * 4)) & 0xF;
        //Grab character from the characters string at index position and add it to the result string.
        result = llInsertString(result, 0, llGetSubString(characters,index,index));
    }
    
    return result;
}



//Function:  Hex2DWword
//Converts a string containing a hexadecimal number to a dword contained in a LSL integer.
integer Hex2DWord(string m){
    integer result = 0;
    integer i = 0;
    string digit;
    integer value;
    integer index;
    
    string characters = "0123456789ABCDEF";
    
    for (i = 0; i < 8; i++){
        
        index = 8 - (i + 1);
        digit = llGetSubString(m,index,index);
        
        value = llSubStringIndex(characters, digit);
                        
        result = result | value << (i * 4);
        
    }
    
    return result;
}



//Function: Encrypt
//Takes cleartext string, pads and bitpacks it, then encrypts it using TEAEncrypt().
string Encrypt(string cleartext){
        
        //Initialize variables.
        integer dword1 = 0;
        integer dword2 = 0;
        integer cyphertext_numeric;
        list cypherblock;
        string cyphertext = "";

        //Pad cleartext string to the nearest multiple of 8.
        while(llStringLength(cleartext) & 0x7) {
            cleartext += " ";
        }
        
        //Define more variables pertaining to while loop.
        integer stringlength = llStringLength(cleartext); 
        integer i=0;
        integer character;
        
        //Step through cleartext string, encrypting it in 64-bit (8 character) blocks.
        while (i < stringlength){
            
            //Pack dword1 with 4 bytes.  Do so by bit-shifting in each character.
            //4th byte winds up in the most-significant position.
            dword1 =  ord(llGetSubString(cleartext,i,i));
            i++;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) << 8);
            i++;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) << 16);
            i++;
            dword1 =  dword1 | (ord(llGetSubString(cleartext,i,i)) << 24);
            i++;
            
            //Do it again, this time for dword2                            
            dword2 =  ord(llGetSubString(cleartext,i,i));
            i++;
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) << 8;
            i++;
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) << 16;
            i++;
            dword2 =  dword2 | ord(llGetSubString(cleartext,i,i)) << 24;
            i++;

            //Call TEAencrypt() with dword1, dword2, and the cypher key and store result in cypherblock.
            cypherblock = TEAEncrypt(dword1,dword2,cypherkey);
 
            //Convert dword values from cypherblock to hex and append to cyphertext.
            cyphertext = cyphertext + DWord2Hex(llList2Integer(cypherblock,0)) + DWord2Hex(llList2Integer(cypherblock,1));
                    
            //Reset variables for the next round, just to be safe.
            dword1 = 0;
            dword2 = 0;
            cypherblock = [];
            
            if(DEBUG_FLAG){
                llOwnerSay("Pre-Crypt DWords: " + (string)dword1 + "," + (string)dword2);
                llOwnerSay("Post-Crypt DWords: " + (string)llList2Integer(cypherblock,1) + "," + (string)llList2Integer(cypherblock,2));    
                llOwnerSay("Post-Crypt Hex: " + DWord2Hex(llList2Integer(cypherblock,1)) + "," + DWord2Hex(llList2Integer(cypherblock,2)));
            }
            
        }  
        
        return cyphertext;        
}  



//Function: Decrypt
//Takes cyphertext, decrypts it with TEADecrypt(), and unpacks it into a string.
string Decrypt(string cyphertext){
        
        //Initialize variables.
        string hexvalue1 = "";
        string hexvalue2 = "";
        integer dword1 = 0;
        integer dword2 = 0;
        list clearblock = []; //res
        string cleartext = "";
        integer i;
        
        
        //Step through cyphertext string, descrypting it block by block.
        while (i < llStringLength(cyphertext)){
            
            //Pull first 32 bits worth of hexadecimal into hexvalue1
            hexvalue1 += llGetSubString(cyphertext,i,i + 7);
            i = i + 8;
            
            //Pull second 32 bits worth of hexadecimal into hexvalue2
            hexvalue2 += llGetSubString(cyphertext,i,i + 7);
            i = i + 8;

            //Convert hexvalues to dwords contained in LSL integers.
            dword1 = Hex2DWord(hexvalue1);
            dword2 = Hex2DWord(hexvalue2); 
    
            //Call TEADecrypt() with dword1, dword2, and the cypher key and store result in clearblock list.
            clearblock = TEADecrypt(dword1, dword2, cypherkey);
            
            //Append first 4 characters of ASCII to cleartext string.
            //This is done by pulling the decrypted dwords from the clearblock list and looking up their ASCII values.
            cleartext += chr( llList2Integer(clearblock,0) & 0x000000FF);
            cleartext += chr( (llList2Integer(clearblock,0) & 0x0000FF00)  >> 8);
            cleartext += chr( (llList2Integer(clearblock,0) & 0x00FF0000)  >> 16);
            cleartext += chr( (llList2Integer(clearblock,0) & 0xFF000000)  >> 24);

            //Append second 4 characters of ASCII to cleartext string.
            cleartext += chr( llList2Integer(clearblock,1) & 0x000000FF);
            cleartext += chr( (llList2Integer(clearblock,1) & 0x0000FF00)  >> 8);
            cleartext += chr( (llList2Integer(clearblock,1) & 0x00FF0000)  >> 16);
            cleartext += chr( (llList2Integer(clearblock,1) & 0xFF000000)  >> 24);

            //Reset variables for the next two blocks of decrypt.            
            hexvalue1 = "";
            hexvalue2 = "";
            dword1 = 0;
            dword2 = 0;
            clearblock = [];
            
            if(DEBUG_FLAG){
                llOwnerSay("Pre-Decrypt Hex: " + hexvalue1 + "," + hexvalue2);
                llOwnerSay("Pre-Decrypt DWords: " + (string)dword1 + "," + (string)dword2);
                llOwnerSay("Post-Decrypt DWords: " + (string)llList2Integer(clearblock,1) + "," + (string)llList2Integer(clearblock,2));
            }
             
        }
                
        return cleartext;        
}



//Function: TEAEncrypt
//This is the implementation of XTEA proper.  It takes a block of cleartext
//consisting of two dwords contained in LSL integers and a 128-bit key 
//contained in an LSL list of 4 integers.  The function then returns 
//the cyphertext in an LSL list of two integers.
list TEAEncrypt(integer dword1, integer dword2,list cypherkey){
    
            list cryptlist = [];
            
            //Set n to the number of cycles given in the CYCLES global variable
            integer n = CYCLES;
                        
            integer sum = 0;
            
            //Operate for the specified number of cycles.
            while (n-- > 0){
                dword1 = dword1 + ( ( dword2 << 4 ^ ((dword2 >> 5) & 0x07FFFFFF) ) + dword2 ^ sum + llList2Integer(cypherkey, (sum & 3) ) );
                sum += delta;
                dword2 = dword2 + ( ( dword1 << 4 ^ ((dword1 >> 5) & 0x07FFFFFF) ) + dword1 ^ sum + llList2Integer(cypherkey, ((sum >> 11) & 3) ) );
            }
            
            cryptlist = [dword1,dword2];

            return cryptlist;
}



//Function: TEADecrypt
//This is the implementation of XTEA proper.  It takes a block of cyphertext
//consisting of two dwords contained in LSL integers and a 128-bit key 
//contained in an LSL list of 4 integers.  The function then returns 
//the cleartext in an LSL list of two integers.
list TEADecrypt(integer dword1, integer dword2,list cypherkey){
    
            list cryptlist = [];
            
            //Set n to the number of cycles given in the CYCLES global variable
            integer n = CYCLES;
                        
            integer sum = delta * CYCLES;

            //Operate for the specified number of cycles.        
            while (n-- > 0){
                dword2 = dword2 - ( ( dword1 << 4 ^ ((dword1 >> 5) & 0x07FFFFFF) ) + dword1 ^ sum + llList2Integer(cypherkey, ((sum >> 11) & 3) ) );
                sum -= delta;
                dword1 = dword1 - ( ( dword2 << 4 ^ ((dword2 >> 5) & 0x07FFFFFF) ) + dword2 ^ sum + llList2Integer(cypherkey, (sum & 3) ) );        
            }
            
            cryptlist = [dword1,dword2];
            return cryptlist;
}

Usage Example

Listens on COMM_CHANNEL for a message and encrypts it, then turns around and decrypts the resultant cypher-text. Object than says the encrypted and decrypted messages to the owner.

default
{
    state_entry()
    {
        llListen(COMM_CHANNEL, "", NULL_KEY, "");
        cypherkey = [KEY1,KEY2,KEY3,KEY4];
    }

    listen(integer channel, string name, key id, string message)
    {
        string temp_cyphertext = Encrypt(message);
        
        string temp_cleartext = Decrypt(temp_cyphertext);
        
        llOwnerSay("\nOriginal Cleartext: " + message + "\nCyphertext: " + temp_cyphertext + "\nDecrypted Cleartext: " + temp_cleartext);
    }
}

Optimized

This version is untested but if it works should run faster (and be able to handle larger strings).

// Include the documentation comments from above (separated here only for easier management)

//XTEA Strong Encryption Implementation - Linden Scripting Language (LSL)
//Version 1.0a Alpha
//Copyright (C) 2007 by Strife Onizuka (blindwandererATgmail.com)
//
//Version 1.0
//Copyright (C) 2007 by Morse Dillon (morseATmorsedillon.com)
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
//02110-1301, USA.
//========================================================================
//
//Included at the end of this source listing is a small bit of example 
//code that shows the usage.  If you wish to include this implementation 
//in your own work, just replace the example code with your own.  Also, 
//please do not reuse or redistribute this work without including the 
//above text attributing this code to its author Morse Dillon, the above
//GPL statement, and this documentation.
//
//This is an implentation of the XTEA (eXtended Tiny Encryption Algorithm) 
//block cypher.  (X)TEA is a very good choice of cipher when security
//is important but computational power is limited.  Although I did a
//lot of work on this implementation, enormous amounts of credit must
//be given to the creators of the algorithm and those who came before
//me to implement it in other languages and computing environments.
//
//***If you do decide to use this code in a project, I'd appreciate 
//hearing about it.  You can reach me by e-mail at:  
//morseATmorsedillon.com
//
//
//ABOUT TEA AND XTEA
//------------------
//TEA was originally designed by David Wheeler and Roger Needham 
//of the Cambridge Computer Laboratory.  The algorithm itself is not
//subject to any patents.  While the original TEA was found to have
//some minor weaknesses, XTEA (implemented herein) addresses these.  
//
//TEA and its derivatives consist of 64-bit block Feistel network 
//with a 128-bit key.  This implementation uses six cycles, or rounds,
//which is less than one would like but still provides a reasonable
//level of security (16 is sufficient while 8 is enough for most 
//applications).  Six is said to achieve theoretically good dispersion, 
//but should more security be desired the number of cycles can easily be 
//modified by changing the CYCLES global variable.  Due to the low 
//execution speed of LSL scripts, it's suggested to make this as low as 
//your comfort level allows.  Encryption time scales linearly with the 
//number of cycles.
//
//For more information about XTEA, see the following:
//
//Original Paper by Walker and Needham
//http://www.ftp.cl.cam.ac.uk/ftp/papers/djw-rmn/djw-rmn-tea.html
//
//Wikipedia on TEA
//http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
//
//
//ABOUT THIS IMPLEMENTATION
//-------------------------
//This is a barebones implementation, and is meant to be included in
//the body of the script needing encryption facilities or wrapped
//in a link message handler.  If the latter approach is desired, care
//should be taken to only send link messages to the prim containing
//this implementation.  If ALL_PRIMS is used as the destination,
//one could link a link message listener to the object and intercept
//cleartext communications.  
//
//If you plan to place this code into the same script as that needing
//encryption facilities, you need only call the following functions:
//
//string Encrypt(string cleartext)
//string Decrypt(string cyphertext)
//
//Simple as that.
//
//This implementation does not provide any secure key exchange, so in
//terms of key generation and exchange you're on your own.
//
//The 128-bit key is contained in four LSL integers:  KEY1, KEY2, KEY3,
//and KEY4.  These are global variables at the beginning of the source
//and can be set using a method that works for you.
//
//
//CHANGES
//-------
//
//1.0a - Alpha
//*General optimization to run faster and use less bytecode.
//*Encrypt: Pad works differently, no longer extra characters appended to the output.
//*TEAEncrypt: Changed the return type
//*ord: Added null support.
//
//1.0
//*Initial Release
//
//
//FUTURE CHANGES
//--------------
//
//It would be nice if it supported UTF-8; but adding that would be alot
//of work. The main issue is the decoding, the bytes would have to be
//reassembled into characters. It would be time consuming. Another possibility
//would be to implement XTEA to output to BASE64 instead of hex strings (also
//time consuming to implement).
//
//
//**************IF YOU READ ONE THING IN HERE, READ THIS*******************
//It is VERY important to remember that there is no such thing as
//'cookbook cryptography'!  Simply using this cypher does not guarantee
//security.  Security is an end-to-end concern and responsibility lies
//with you to thoroughly examine your project from all possible angles
//if valuable data is at risk.  If you doubt this, ask any thief how they'd
//rather break into your house - futzing about with picking a high-security
//deadbolt on the front door or walking in through the back door that you 
//left open.

//******************USER-CONFIGURABLE GLOBALS BEGIN HERE*******************

//ENCRYPTION KEYS KEY[1-4]
//These together make up the 128-bit XTEA encryption key.  See the above 
//documentation for details.  Whatever you do, don't leave them as the default.
//Don't be stupid and make it obvious like your av's key.
integer KEY1 = 11111111;
integer KEY2 = 22222222;
integer KEY3 = 33333333;
integer KEY4 = 44444444;

//COMM_CHANNEL
//Specifies which channel should be used for debug and test harness communication.
integer COMM_CHANNEL = 0;

//CYCLES
//Specifies the number of rounds to be used.  See the above documentation for
//details.
integer CYCLES = 6;

//******************USER-CONFIGURABLE GLOBALS END HERE*********************

//Other Globals
list cypherkey = [];
integer delta = 0x9E3779B9;

string ASCII = "             \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
string characters = "0123456789ABCDEF";

//Function: ord
//Returns the index of an ASCII character
integer ord(string chr)
{
    if(chr)
    {
        if(llStringLength(chr) > 1) return -1;
        if(chr == " ") return 32;
        return llSubStringIndex(ASCII, chr);
    }
    return 0;
}

//Function: chr
//Returns the ASCII character correspondent to index i
string chr(integer i)
{
    if(i)
        return llGetSubString(ASCII, i %= 127, i);
    return "";
}

//Function:  DWord2Hex
//Converts a dword contained in a LSL integer to hexadecimal format.        
string DWord2Hex(integer m)
{
    string result;
    integer i = 0;

    //Define character string [0-F] for use in building the hex.
    //Step through 8 times, for a total of 32 bits, 8 nibbles, and 8 hexadecimal digits.
    do{
        integer index = (m >> i) & 0xF;
        result = llGetSubString(characters, index, index) + result;
    }while((i += 4) < 32);
    return result;
}

//Function: Encrypt
//Takes cleartext string, pads and bitpacks it, then encrypts it using TEAEncrypt().
string Encrypt(string cleartext)
{
    string cyphertext = "";
    integer i = llStringLength(cleartext);
    if((i += (0x7 & -i)))//Pad cleartext string to the nearest multiple of 8.
    {
        //Step through cleartext string backwords, encrypting it in 64-bit (8 character) blocks.
        do{
            //i=~-i is the same as --i, just a bit faster and lighter on bytecode; requires one less stack manipulation.
            //Pack dword1 with 4 bytes.  Do so by bit-shifting in each character.
            //4th byte winds up in the most-significant position.
            integer dword2 =    (    ord(llGetSubString(cleartext,i=~-i,i))      )    |
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 8 )    |
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 16)    |
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 24)    ;

            //Do it again, this time for dword1                            
            integer dword1 =    (    ord(llGetSubString(cleartext,i=~-i,i))      )    |
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 8 )    |
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 16)    |
                                (    ord(llGetSubString(cleartext,i=~-i,i)) << 24)    ;

            //Call TEAencrypt() with dword1, dword2, and the cypher key and store result in cypherblock.

            //Convert dword values from cypherblock to hex and append to cyphertext.
            cyphertext = TEAEncrypt(dword1,dword2,cypherkey) + cyphertext;
        }while(i);
    }
    return cyphertext;
}  


//Function: Decrypt
//Takes cyphertext, decrypts it with TEADecrypt(), and unpacks it into a string.
string Decrypt(string cyphertext){

    //Initialize variables.
    string cleartext = "";
    integer i = -llStringLength(cyphertext);

    //Step through cyphertext string, decrypting it block by block.
    if((i -= (0xF & i)))//Pad cyphertext string to the nearest multiple of 16.
    {
        do
        {

            //Convert hexvalues to dwords contained in LSL integers.
            //Call TEADecrypt() with dword1, dword2, and the cypher key and store result in clearblock list.
            list clearblock = TEADecrypt((integer)("0x"+llGetSubString(cyphertext,i, ~-(i -= 8))), 
                                         (integer)("0x"+llGetSubString(cyphertext,i, ~-(i -= 8))), cypherkey);

            //Append first 4 characters of ASCII to cleartext string.
            //This is done by pulling the decrypted dwords from the clearblock list and looking up their ASCII values.
            integer t = llList2Integer(clearblock,1);
            cleartext += chr( (t      ) & 0xFF) +
                         chr( (t >> 8 ) & 0xFF) +
                         chr( (t >> 16) & 0xFF) +
                         chr( (t = llList2Integer(clearblock,0) >> 24) & 0xFF) +
                         chr( (t      ) & 0xFF) +
                         chr( (t >> 8 ) & 0xFF) +
                         chr( (t >> 16) & 0xFF) +
                         chr( (t >> 24) & 0xFF) ;
        }while(i);
    }
    return cleartext;        
}


//Function: TEADecrypt
//This is the implementation of XTEA proper.  It takes a block of cleartext
//consisting of two dwords contained in LSL integers and a 128-bit key 
//contained in an LSL list of 4 integers.  The function then returns 
//the cyphertext in an LSL list of two integers.
string TEAEncrypt(integer dword1, integer dword2, list cypherkey_)
{
    if(CYCLES > 0)//$[E20011] /*lslint ignore*/
    {
        //Set n to the number of cycles given in the CYCLES global variable
        integer n = CYCLES;
        integer sum = 0;
        //Operate for the specified number of cycles.
        do{
            dword1 = dword1 + ( ( dword2 << 4 ^ dword2 >> 5 ) + dword2 ^ sum + llList2Integer(cypherkey_, (sum & 3) ) );
            dword2 = dword2 + ( ( dword1 << 4 ^ dword1 >> 5 ) + dword1 ^ sum + llList2Integer(cypherkey_, ((sum += delta) >> 11 & 3) ) );
        }while (n = ~-n);
    }
    return DWord2Hex(dword1) + DWord2Hex(dword2);
}


//Function: TEADecrypt
//This is the implementation of XTEA proper.  It takes a block of cyphertext
//consisting of two dwords contained in LSL integers and a 128-bit key 
//contained in an LSL list of 4 integers.  The function then returns 
//the cleartext in an LSL list of two integers.
list TEADecrypt(integer dword1, integer dword2,list cypherkey_)
{
    if(CYCLES > 0)//$[E20011] /*lslint ignore*/
    {
        //Set n to the number of cycles given in the CYCLES global variable
        integer n = CYCLES;
        integer sum = delta * CYCLES;
        //Operate for the specified number of cycles.        
        do{
            dword2 = dword2 - ( ( dword1 << 4 ^ dword1 >> 5 ) + dword1 ^ sum + llList2Integer(cypherkey_, (sum >> 11 & 3) ) );
            dword1 = dword1 - ( ( dword2 << 4 ^ dword2 >> 5 ) + dword2 ^ sum + llList2Integer(cypherkey_, ((sum -= delta) & 3) ) );        
        }while (n = ~-n);
    }
    return [dword1,dword2];
}


//XTEA Usage Example
//Listens on COMM_CHANNEL for a message and encrypts it, then turns around and decrypts the resultant cyphertext.
//Object than says the encrypted and decrypted messages to the owner.
default
{
    state_entry()
    {
        llListen(COMM_CHANNEL, "", NULL_KEY, "");
        cypherkey = [KEY1,KEY2,KEY3,KEY4];
    }

    listen(integer channel, string name, key id, string message)
    {
        string temp_cyphertext = Encrypt(message);

        string temp_cleartext = Decrypt(temp_cyphertext);

        llOwnerSay("\nOriginal Cleartext: " + message + "\nCyphertext: " + temp_cyphertext + "\nDecrypted Cleartext: " + temp_cleartext);
    }
}

XTEA LSL <-> PHP

This is an XTEA implementation that has both LSL and PHP scripts to allow strong encryption not only inside LSL but also between LSL and a PHP serverscript.

For those who want to see this in action with your Web server try these. Be sure that if you edit these that Rounds and Key Phrase are the same in both LSL and PHP versions.

LSL - PLACE IN PRIM -- Edit to change URL and tosend text.

//************************************************// 
//* Masa's XTEA encryption/decryption v3         *// 
//* Modified by SleightOf Hand for Stability and *// 
//* intercommunication with PHP version          *// 
//************************************************// 
// NOTE: This version only encodes 60 bits per 64-bit block! 
// This code is public domain. 
// Sleight was here 20070522 
// masa was here 20070315 
// so was strife 20070315 
// so was adz 20070812
//
// This was Modified by SleightOf Hand to allow
// Strong encryption between LSL and PHP. 
//************************************************// 
//* XTEA IMPLEMENTATION                          *// 
//************************************************// 

integer XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31 
integer xtea_num_rounds = 6; 
list    xtea_key        = [0, 0, 0, 0]; 


// Converts any string to a 32 char MD5 string and then to a list of
// 4 * 32 bit integers = 128 bit Key. MD5 ensures always a specific
// 128 bit key is generated for any string passed.
list xtea_key_from_string( string str )
{ 
    str = llMD5String(str,0); // Use Nonce = 0
    return [    hexdec(llGetSubString(  str,  0,  7)), 
                hexdec(llGetSubString(  str,  8,  15)), 
                hexdec(llGetSubString(  str,  16,  23)), 
                hexdec(llGetSubString(  str,  24,  31))]; 
} 

// Encipher two integers and return the result as a 12-byte string 
// containing two base64-encoded integers. 
string xtea_encipher( integer v0, integer v1 )
{ 
    integer num_rounds = xtea_num_rounds; 
    integer sum = 0; 
    do { 
        // LSL does not have unsigned integers, so when shifting right we 
        // have to mask out sign-extension bits. 
        v0  += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum & 3));
        sum +=  XTEA_DELTA;
        v1  += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum >> 11) & 3)); 

    } while( --num_rounds ); 
    //return only first 6 chars to remove "=="'s and compact encrypted text.
    return llGetSubString(llIntegerToBase64(v0),0,5) +
           llGetSubString(llIntegerToBase64(v1),0,5); 
} 

// Decipher two base64-encoded integers and return the FIRST 30 BITS of 
// each as one 10-byte base64-encoded string. 
string xtea_decipher( integer v0, integer v1 )
{ 
    integer num_rounds = xtea_num_rounds; 
    integer sum = XTEA_DELTA*xtea_num_rounds; 
    do { 
        // LSL does not have unsigned integers, so when shifting right we 
        // have to mask out sign-extension bits. 
        v1  -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(xtea_key, (sum>>11) & 3)); 
        sum -= XTEA_DELTA;
        v0  -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(xtea_key, sum  & 3)); 
    } while ( --num_rounds ); 

    return llGetSubString(llIntegerToBase64(v0), 0, 4) + 
           llGetSubString(llIntegerToBase64(v1), 0, 4); 
} 

// Encrypt a full string using XTEA. 
string xtea_encrypt_string( string str )
{ 
    // encode string 
    str = llStringToBase64(str); 
    // remove trailing =s so we can do our own 0 padding 
    integer i = llSubStringIndex( str, "=" ); 
    if ( i != -1 ) 
        str = llDeleteSubString( str, i, -1 ); 

    // we don't want to process padding, so get length before adding it 
    integer len = llStringLength(str); 

    // zero pad 
    str += "AAAAAAAAAA="; 

    string result; 
    i = 0; 

    do { 
        // encipher 30 (5*6) bits at a time. 
        result += xtea_encipher( 
            llBase64ToInteger(llGetSubString(str,   i, i += 4) + "A="), 
            llBase64ToInteger(llGetSubString(str, ++i, i += 4) + "A=") 
        ); 
    } while ( ++i < len ); 

    return result; 
} 

// Decrypt a full string using XTEA 
string xtea_decrypt_string( string str ) { 
    integer len = llStringLength(str); 
    integer i; 
    string result; 
    do { 
        result += xtea_decipher( 
            llBase64ToInteger(llGetSubString(str,   i, i += 5) + "=="), 
            llBase64ToInteger(llGetSubString(str, ++i, i += 5) + "==") 
        ); 
    } while ( ++i < len ); 

    // Replace multiple trailing zeroes with a single one 
    i = llStringLength(result) - 1; 
    while ( llGetSubString(result, --i, i+1) == "AA" ) 
        result = llDeleteSubString(result, i+1, i+1); 
    return llBase64ToString( result + "====" ); 
} 

key requestid; // just to check if we're getting the result we've asked for; all scripts in the same object get the same replies
string base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + 

                          "abcdefghijklmnopqrstuvwxyz" + 

                          "0123456789+/";
string url = "http://<enter your URL here>/test-script.php";



default
{
    touch_start(integer number)
    {
        string tosend = "this is a message to send";
        llWhisper(0, "Message to Send = " + tosend);
        xtea_key = xtea_key_from_string("this is a test key");
        string message = xtea_encrypt_string(tosend);
        llWhisper(0, "Message to Server = " + message);
        requestid = llHTTPRequest(url, 
            [HTTP_METHOD, "POST",
             HTTP_MIMETYPE, "application/x-www-form-urlencoded"],
            "parameter1=" + llEscapeURL(message));
    }

    http_response(key request_id, integer status, list metadata, string body)
    {
        if (request_id == requestid) { 
            llWhisper(0, "Web server sent: " + body);
            integer clean = 0;
            string cleanbody = "";
            while(~llSubStringIndex(base64,llGetSubString(body,clean,clean))){
                cleanbody += llGetSubString(body,clean,clean++);
            }
            llWhisper(0, "Cleaned : " + cleanbody);
            llWhisper(0, "Web server said: " + xtea_decrypt_string( cleanbody ));
        }
    }
}

PHP Code - Place on web server at location that LSL URL will be looking for.

//************************************************//
//* Sleight's PHP XTEA encryption/decryption v3  *//
//* Modified by SleightOf Hand for Stability and *//
//* intercommunication between PHP & LSL         *//
//************************************************//
// NOTE: This version only encodes 60 bits per 64-bit block!
// This code is public domain.
// Sleight was here 20070522
// masa was here 20070315
// so was strife 20070315
// so was adz 20080812
//
// This was converted from the LSL version by
// SleightOf Hand to allow Strong encryption
// between LSL and PHP. If you find this useful
// any donations appreciated.
//************************************************//
//* XTEA IMPLEMENTATION                          *//
//************************************************//

$_XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
$_xtea_num_rounds = 6;
$_xtea_key        = array(0, 0, 0, 0);
$_base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
           "abcdefghijklmnopqrstuvwxyz".
           "0123456789+/";

// Returns Integer based on 8 byte Base64 Code XXXXXX== (llBase64ToInteger)
function base64_integer($str){
 global $_base64;
 if(strlen($str) != 8) return 0;
 return ((strpos($_base64,$str{0}) << 26)|
 (strpos($_base64,$str{1}) << 20)|
 (strpos($_base64,$str{2}) << 14)|
 (strpos($_base64,$str{3}) << 8) |
 (strpos($_base64,$str{4}) << 2) |
 (strpos($_base64,$str{5}) >> 4));
}

// Returns 8 Byte Base64 code based on 32 bit integer ((llIntegerToBase64)
function integer_base64($int){
 global $_base64;
 if($int != (integer) $int) return 0;
 return  $_base64{($int >> 26 & 0x3F)} .
 $_base64{($int >> 20 & 0x3F)} .
 $_base64{($int >> 14 & 0x3F)} .
 $_base64{($int >> 8 & 0x3F)}  .
 $_base64{($int >> 2 & 0x3F)}  .
 $_base64{($int << 4 & 0x3F)} . "==";
}

//strict 32 bit addition using logic
function binadd($val1 , $val2){
 $tc = $val1 & $val2;
 $ta = $val1 ^ $val2;
 do{
  $tac = ($tc << 1) & 0x0FFFFFFFF;
  $tc = $ta & $tac;
  $ta = $ta ^ $tac;
 }while($tc);
 return $ta; // $ta will now be the result so return it
}

// Converts any string to a 32 char MD5 string and then to a list of
// 4 * 32 bit integers = 128 bit Key.
function xtea_key_from_string( $str ) {
 global $_xtea_key;
 $str = md5($str . ":0"); // Use nonce = 0 in LSL for same output
 $_xtea_key[0] = hexdec(substr($str,0,8));
 $_xtea_key[1] = hexdec(substr($str,8,8));
 $_xtea_key[2] = hexdec(substr($str,16,8));
 $_xtea_key[3] = hexdec(substr($str,24,8));
}

// Encipher two integers and return the result as a 12-byte string
// containing two base64-encoded integers.
function xtea_encipher( $v0 , $v1 ) {
 global  $_xtea_num_rounds , $_xtea_key , $_XTEA_DELTA;
 $num_rounds = $_xtea_num_rounds;
 $sum = 0;
 do {
  // LSL only has 32 bit integers. However PHP automatically changes
  // 32 bit integers to 64 bit floats as necessary. This causes
  // incompatibilities between the LSL Encryption and the PHP
  // counterpart. I got round this by changing all addition to
  // binary addition using logical & and ^ and loops to handle bit
  // carries. This forces the 32 bit integer to remain 32 bits as
  // I mask out any carry over 32 bits. this bring the output of the
  // encrypt routine to conform with the output of its LSL counterpart.

  // LSL does not have unsigned integers, so when shifting right we
  // have to mask out sign-extension bits.

  // calculate ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
  $v0a = binadd((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) , $v1);
  // calculate ($sum + $_xtea_key[$sum & 3])
  $v0b = binadd($sum , $_xtea_key[$sum & 3]);
  // Calculate ($v0 + ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
  //            ^ ($sum + $_xtea_key[$sum & 3]))
  $v0 = binadd($v0 , ($v0a  ^ $v0b));

  //Calculate ($sum + $_XTEA_DELTA)
  $sum = binadd($sum , $_XTEA_DELTA);

  //Calculate ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
  $v1a = binadd((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF))  , $v0);
  // Calculate ($sum + $_xtea_key[($sum >>11) & 3])
  $v1b = binadd($sum , $_xtea_key[($sum >>11) & 3]);
  //Calculate ($v1 + ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0
  //           ^ ($sum & $_xtea_key[($sum >>11) & 3]))
  $v1 = binadd($v1 , ($v1a  ^ $v1b));
 } while( $num_rounds = ~-$num_rounds );
 //return only first 6 chars to remove "=="'s and compact encrypted text.
 return substr(integer_base64($v0),0,6) . substr(integer_base64($v1),0,6);
}

// Decipher two base64-encoded integers and return the FIRST 30 BITS of
// each as one 10-byte base64-encoded string.
function xtea_decipher( $v0, $v1 ) {
 global  $_xtea_num_rounds , $_xtea_key , $_XTEA_DELTA;
 $num_rounds = $_xtea_num_rounds;
 $sum = 0; // $_XTEA_DELTA * $_xtea_num_rounds;
 $tda = $_XTEA_DELTA;
 do{ // Binary multiplication using binary manipulation
  if($num_rounds & 1){
   $sum = binadd($sum , $tda);
  }
  $num_rounds = $num_rounds >> 1;
  $tda = ($tda << 1) & 0x0FFFFFFFF;
 }while($num_rounds);
 $num_rounds = $_xtea_num_rounds; // reset $num_rounds back to its proper setting;

 do {
  // LSL only has 32 bit integers. However PHP automatically changes
  // 32 bit integers to 64 bit floats as necessary. This causes
  // incompatibilities between the LSL Encryption and the PHP
  // counterpart. I got round this by changing all addition to
  // binary addition using logical & and ^ and loops to handle bit
  // carries. This forces the 32 bit integer to remain 32 bits as
  // I mask out any carry over 32 bits. this bring the output of the
  // decrypt routine to conform with the output of its LSL counterpart.
  // Subtractions are handled by using 2's compliment

  // LSL does not have unsigned integers, so when shifting right we
  // have to mask out sign-extension bits.

  // calculate ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
  $v1a = binadd((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) , $v0);
  // calculate ($sum + $_xtea_key[($sum>>11) & 3])
  $v1b = binadd($sum , $_xtea_key[($sum>>11) & 3]);
  //Calculate 2's compliment of ($v1a ^ $v1b) for subtraction
  $v1c = binadd((~($v1a ^ $v1b)) , 1);
  //Calculate ($v1 - ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
  //            ^ ($sum + $_xtea_key[($sum>>11) & 3]))
  $v1 = binadd($v1 , $v1c);

  // Calculate new $sum based on $num_rounds - 1
  $tnr = $num_rounds - 1;  // Temp $num_rounds
  $sum = 0; // $_XTEA_DELTA * ($num_rounds - 1);
  $tda = $_XTEA_DELTA;
  do{ // Binary multiplication using binary manipulation
   if($tnr & 1){
    $sum = binadd($sum , $tda);
   }
   $tnr = $tnr >> 1;
   $tda = ($tda << 1) & 0x0FFFFFFFF;
  }while($tnr);

  //Calculate ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
  $v0a = binadd((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) , $v1);
  //Calculate ($sum + $_xtea_key[$sum & 3])
  $v0b = binadd($sum , $_xtea_key[$sum & 3]);
  //Calculate 2's compliment of ($v0a ^ $v0b) for subtraction
  $v0c = binadd((~($v0a ^ $v0b)) , 1);
  //Calculate ($v0 - ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1
  //           ^ ($sum + $_xtea_key[$sum & 3]))
  $v0 = binadd($v0 , $v0c);
 } while ( $num_rounds = ~-$num_rounds );

 return substr(integer_base64($v0), 0, 5) . substr(integer_base64($v1), 0, 5);
}

// Encrypt a full string using XTEA.
function xtea_encrypt_string( $str ) {
 // encode Binany string to Base64
 $str = base64_encode($str);

 // remove trailing =s so we can do our own 0 padding
 $i = strpos($str, '=', 0);
 if ( $i !== FALSE  ){
  $str = substr( $str, 0, $i);
 }
 // we don't want to process padding, so get length before adding it
 $len = strlen($str);
 // zero pad
 $str .= "AAAAAAAAAA=";
 $result = "";
 $i = 0;

 do {
  // encipher 30 (5*6) bits at a time.
  $enc1 = base64_integer(substr($str , $i , 5) . "A==");
  $i += 5;
  $enc2 = base64_integer(substr($str , $i , 5) . "A==");
  $i += 5;
  $result .= xtea_encipher($enc1, $enc2);
 } while ( $i < $len );
 return $result; //Return Encrypted string
}

// Decrypt a full string using XTEA
function xtea_decrypt_string( $str ) {
 global $_base64 ;

 $len = strlen($str);
 $i;
 $result;
 do {
  $dec1 = base64_integer(substr($str , $i , 6)."==");
  $i += 6;
  $dec2 = base64_integer(substr($str , $i , 6)."==");
  $i += 6;
  $result .= xtea_decipher( $dec1, $dec2);
 } while ( $i < $len );

 // Replace multiple trailing zeroes with a single one
 $result = rtrim($result, "A");
 $i = strlen($result);
 $mod = $i%4; //Depending on encoded length different appends are needed
 if($mod == 1) $result .= "A==";
 else if($mod == 2 ) $result .= "==";
 else if($mod == 3) $result .= "=";

 return base64_decode( $result );
}

// Only works with PHP compiled as an Apache module
$headers = apache_request_headers();

$objectName = $headers["X-SecondLife-Object-Name"];
$objectKey     = $headers["X-SecondLife-Object-Key"];
$ownerKey     = $headers["X-SecondLife-Owner-Key"];
$ownerName = $headers["X-SecondLife-Owner-Name"];
$region        = $headers["X-SecondLife-Region"];
// and so on for getting all the other variables ...

//to pull out this headers in other kinds of installations, use this (Adz)
/*
$objectName    = $_SERVER['HTTP_X_SECONDLIFE_OBJECT_NAME'];
$objectKey     = $_SERVER['HTTP_X_SECONDLIFE_OBJECT_KEY'];
$region        = $_SERVER['HTTP_X_SECONDLIFE_REGION'];
$ownerName     = $_SERVER['HTTP_X_SECONDLIFE_OWNER_NAME'];
$ownerKey      = $_SERVER['HTTP_X_SECONDLIFE_OWNER_KEY'];
*/

xtea_key_from_string("this is a test key");
// get things from $_POST[]
// Naturally enough, if this is empty, you won't get anything
$parameter1 = xtea_decrypt_string($_POST["parameter1"]);

echo xtea_encrypt_string($ownerName . " just said " . $parameter1) . "\n";

This should result in the following output.

Object whispers: Message to Send = this is a message to send
Object whispers: Message to Server = JSdgCA0FDyhgLlUnSgqMQWkAxz1AzA1vr9zwSEDnCgwJ6GNQ
Object whispers: Web server sent: SVbqNQ5XdkngeUI3bgP+s6eAT6GM4AWnYCYApcfxagrPbxmwiY7WXA4J+gEQ1AYhRQNvcnEwfZSo/AuKVtIw
Object whispers: Cleaned : SVbqNQ5XdkngeUI3bgP+s6eAT6GM4AWnYCYApcfxagrPbxmwiY7WXA4J+gEQ1AYhRQNvcnEwfZSo/AuKVtIw
Object whispers: Web server said: SleightOf Hand just said this is a message to send

PHP 5 class of XTEA

<?php
// http://wiki.secondlife.com/wiki/XTEA_Strong_Encryption_Implementation
//************************************************//
//* Sleight's PHP XTEA encryption/decryption v3  *//
//* Modified by SleightOf Hand for Stability and *//
//* intercommunication between PHP & LSL         *//
//************************************************//
// NOTE: This version only encodes 60 bits per 64-bit block!
// This code is public domain.
// Sleight was here 20070522
// masa was here 20070315
// so was strife 20070315
// so was adz 20080812
// gave this some class 20080201 JB Kraft
//
// This was converted from the LSL version by
// SleightOf Hand to allow Strong encryption
// between LSL and PHP. If you find this usefull
// any donations apreciated.
//************************************************//
//* XTEA IMPLEMENTATION                          *//
//************************************************//

/**
 * PHP 5 class to do XTEA crypting
 *
 * $xtea = new XTEA( "mypassword" );
 * $crypted = $xtea->encrypt( "Some bogus string" );
 * echo "Encrypted: " . bin2hex($crypted);
 * echo "Decrypted: " . $xtea->decrypt( $crypted );
 *
 * @package whatevah
 * @author JB Kraft
 **/
class XTEA
{

  private $_XTEA_DELTA      = 0x9E3779B9; // (sqrt(5) - 1) * 2^31
  private $_xtea_num_rounds = 6;
  private $_xtea_key        = array(0, 0, 0, 0);
  private $_base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";


  /**
   * CTOR
   *
   * @param  $passwd the password to use for crypting
   * @author JB Kraft
   **/
  public function __construct( $passwd )
  {
    $this->xtea_key_from_string( $passwd );    
  }

  /**
   * Encrypt a full string using XTEA.
   *
   * @param $str the string to encrypt
   * @return the encrypted string
   * @author JB Kraft
   **/
  public function encrypt( $str ) 
  {
   // encode Binany string to Base64
   $str = base64_encode($str);

   // remove trailing =s so we can do our own 0 padding
   $i = strpos($str, '=', 0);
   if ( $i !== FALSE  ){
    $str = substr( $str, 0, $i);
   }
   // we don't want to process padding, so get length before adding it
   $len = strlen($str);
   // zero pad
   $str .= "AAAAAAAAAA=";
   $result = "";
   $i = 0;

   do {
    // encipher 30 (5*6) bits at a time.
    $enc1 = $this->base64_integer(substr($str , $i , 5) . "A==");
    $i += 5;
    $enc2 = $this->base64_integer(substr($str , $i , 5) . "A==");
    $i += 5;
    $result .= $this->xtea_encipher($enc1, $enc2);
   } while ( $i < $len );
   return $result; //Return Encrypted string
  }

  /**
   * Decrypt a full string using XTEA
   *
   * @param $str the string to decrypt
   * @return the decrypted string
   * @author JB Kraft
   **/
  public function decrypt( $str ) 
  {
   $len = strlen($str);
   $i = 0;
   $result = '';
   do {
    $dec1 = $this->base64_integer(substr($str , $i , 6)."==");
    $i += 6;
    $dec2 = $this->base64_integer(substr($str , $i , 6)."==");
    $i += 6;
    $result .= $this->xtea_decipher( $dec1, $dec2);
   } while ( $i < $len );

   // Replace multiple trailing zeroes with a single one
   $i = strlen($result);
   while ( substr($result, --$i, 1) == "A" );
   $result = substr($result, 0, $i+1);
   $i = strlen($result);
   $mod = $i%4; //Depending on encoded length diffrent appends are needed
   if($mod == 1) $result .= "A==";
   else if($mod == 2 ) $result .= "==";
   else if($mod == 3) $result .= "=";

   return base64_decode( $result );
  }
  
  // -----------------------------
  // stuff below here is protected
  // -----------------------------

  // Returns Integer based on 8 byte Base64 Code XXXXXX== (llBase64ToInteger)
  protected function base64_integer($str)
  {
   if(strlen($str) != 8) return 0;
   return ((strpos($this->_base64,$str{0}) << 26)|
   (strpos($this->_base64,$str{1}) << 20)|
   (strpos($this->_base64,$str{2}) << 14)|
   (strpos($this->_base64,$str{3}) << 8) |
   (strpos($this->_base64,$str{4}) << 2) |
   (strpos($this->_base64,$str{5}) >> 4));
  }

  // Returns 8 Byte Base64 code based on 32 bit integer ((llIntegerToBase64)
  protected function integer_base64($int)
  {
   if($int != (integer) $int) return 0;
   return  $this->_base64{($int >> 26 & 0x3F)} .
   $this->_base64{($int >> 20 & 0x3F)} .
   $this->_base64{($int >> 14 & 0x3F)} .
   $this->_base64{($int >> 8 & 0x3F)}  .
   $this->_base64{($int >> 2 & 0x3F)}  .
   $this->_base64{($int << 4 & 0x3F)} . "==";
  }

  //strict 32 bit addition using logic
  protected function binadd($val1 , $val2)
  {
   $tc = $val1 & $val2;
   $ta = $val1 ^ $val2;
   do{
    $tac = ($tc << 1) & 0x0FFFFFFFF;
    $tc = $ta & $tac;
    $ta = $ta ^ $tac;
   }while($tc);
   return $ta; // $ta will now be the result so return it
  }

  // Convers any string to a 32 char MD5 string and then to a list of
  // 4 * 32 bit integers = 128 bit Key.
  protected function xtea_key_from_string( $str ) 
  {
   $str = md5($str . ":0"); // Use nonce = 0 in LSL for same output
   $this->_xtea_key[0] = hexdec(substr($str,0,8));
   $this->_xtea_key[1] = hexdec(substr($str,8,8));
   $this->_xtea_key[2] = hexdec(substr($str,16,8));
   $this->_xtea_key[3] = hexdec(substr($str,24,8));
  }

  // Encipher two integers and return the result as a 12-byte string
  // containing two base64-encoded integers.
  protected function xtea_encipher( $v0 , $v1 ) 
  {
   $num_rounds = $this->_xtea_num_rounds;
   $sum = 0;
   do {
    // LSL only has 32 bit integers. However PHP automatically changes
    // 32 bit integers to 64 bit floats as necessary. This causes
    // incompatibilities between the LSL Encryption and the PHP
    // counterpart. I got round this by changing all addition to
    // binary addition using logical & and ^ and loops to handle bit
    // carries. This forces the 32 bit integer to remain 32 bits as
    // I mask out any carry over 32 bits. this bring the output of the
    // encrypt routine to conform with the output of its LSL counterpart.

    // LSL does not have unsigned integers, so when shifting right we
    // have to mask out sign-extension bits.

    // calculate ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
    $v0a = $this->binadd((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) , $v1);
    // calculate ($sum + $this->_xtea_key[$sum & 3])
    $v0b = $this->binadd($sum , $this->_xtea_key[$sum & 3]);
    // Calculate ($v0 + ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
    //            ^ ($sum + $this->_xtea_key[$sum & 3]))
    $v0 = $this->binadd($v0 , ($v0a  ^ $v0b));

    //Calculate ($sum + $this->_XTEA_DELTA)
    $sum = $this->binadd($sum , $this->_XTEA_DELTA);

    //Calculate ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
    $v1a = $this->binadd((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF))  , $v0);
    // Calculate ($sum + $this->_xtea_key[($sum >>11) & 3])
    $v1b = $this->binadd($sum , $this->_xtea_key[($sum >>11) & 3]);
    //Calculate ($v1 + ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0
    //           ^ ($sum & $this->_xtea_key[($sum >>11) & 3]))
    $v1 = $this->binadd($v1 , ($v1a  ^ $v1b));
   } while( $num_rounds = ~-$num_rounds );
   //return only first 6 chars to remove "=="'s and compact encrypted text.
   return substr($this->integer_base64($v0),0,6) . substr($this->integer_base64($v1),0,6);
  }

  // Decipher two base64-encoded integers and return the FIRST 30 BITS of
  // each as one 10-byte base64-encoded string.
  protected function xtea_decipher( $v0, $v1 ) 
  {
   $num_rounds = $this->_xtea_num_rounds;
   $sum = 0; // $this->_XTEA_DELTA * $this->_xtea_num_rounds;
   $tda = $this->_XTEA_DELTA;
   do{ // Binary multiplication using binary manipulation
    if($num_rounds & 1){
     $sum = $this->binadd($sum , $tda);
    }
    $num_rounds = $num_rounds >> 1;
    $tda = ($tda << 1) & 0x0FFFFFFFF;
   }while($num_rounds);
   $num_rounds = $this->_xtea_num_rounds; // reset $num_rounds back to its propper setting;

   do {
    // LSL only has 32 bit integers. However PHP automatically changes
    // 32 bit integers to 64 bit floats as necessary. This causes
    // incompatibilities between the LSL Encryption and the PHP
    // counterpart. I got round this by changing all addition to
    // binary addition using logical & and ^ and loops to handle bit
    // carries. This forces the 32 bit integer to remain 32 bits as
    // I mask out any carry over 32 bits. this bring the output of the
    // decrypt routine to conform with the output of its LSL counterpart.
    // Subtractions are handled by using 2's compliment

    // LSL does not have unsigned integers, so when shifting right we
    // have to mask out sign-extension bits.

    // calculate ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
    $v1a = $this->binadd((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) , $v0);
    // calculate ($sum + $this->_xtea_key[($sum>>11) & 3])
    $v1b = $this->binadd($sum , $this->_xtea_key[($sum>>11) & 3]);
    //Calculate 2's compliment of ($v1a ^ $v1b) for subtraction
    $v1c = $this->binadd((~($v1a ^ $v1b)) , 1);
    //Calculate ($v1 - ((($v0 << 4) ^ (($v0 >> 5) & 0x07FFFFFF)) + $v0)
    //            ^ ($sum + $this->_xtea_key[($sum>>11) & 3]))
    $v1 = $this->binadd($v1 , $v1c);

    // Calculate new $sum based on $num_rounds - 1
    $tnr = $num_rounds - 1;  // Temp $num_rounds
    $sum = 0; // $this->_XTEA_DELTA * ($num_rounds - 1);
    $tda = $this->_XTEA_DELTA;
    do{ // Binary multiplication using binary manipulation
     if($tnr & 1){
      $sum = $this->binadd($sum , $tda);
     }
     $tnr = $tnr >> 1;
     $tda = ($tda << 1) & 0x0FFFFFFFF;
    }while($tnr);

    //Calculate ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1)
    $v0a = $this->binadd((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) , $v1);
    //Calculate ($sum + $this->_xtea_key[$sum & 3])
    $v0b = $this->binadd($sum , $this->_xtea_key[$sum & 3]);
    //Calculate 2's compliment of ($v0a ^ $v0b) for subtraction
    $v0c = $this->binadd((~($v0a ^ $v0b)) , 1);
    //Calculate ($v0 - ((($v1 << 4) ^ (($v1 >> 5) & 0x07FFFFFF)) + $v1
    //           ^ ($sum + $this->_xtea_key[$sum & 3]))
    $v0 = $this->binadd($v0 , $v0c);
   } while ( $num_rounds = ~-$num_rounds );

   return substr($this->integer_base64($v0), 0, 5) . substr($this->integer_base64($v1), 0, 5);
  }

}

?>

Test Vectors

These are test vectors to verify that the implementation is working correctly. Although the LSL implementation is for six rounds only, it can easily be changed to verify that the implementation is working as expected. Having a proper implementation allows other systems to communicate using the LSL implementation of XTEA.

Bouncy Castle C# API

These test vectors are taken from The Bouncy Castle C# API.

Rounds Data Key Vector
32 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0xDEE9D4D8 0xF7131ED9
32 0x01020304 0x05060708 0x00000000 0x00000000 0x00000000 0x00000000 0x065C1B89 0x75C6A816
32 0x00000000 0x00000000 0x01234567 0x12345678 0x23456789 0x3456789A 0x1FF9A026 0x1AC64264
32 0x01020304 0x05060708 0x01234567 0x12345678 0x23456789 0x3456789A 0x8C67155B 0x2EF91EAD

Test Vectors for TEA and XTEA

These test vectors used are from Test Vectors for TEA and XTEA. They are made by starting with a vector of 6 zeroes, data followed by key, and coding with one cycle then moving the six cyclically so that n becomes n-1 modulo 6.

Round vector
1 0x00000000 0x9E3779B9 0x00000000 0x00000000 0x00000000 0x00000000
2 0xEC01A1DE 0xAAA0256D 0x00000000 0x00000000 0x00000000 0x00000000
4 0xBC3A7DE2 0x4E238EB9 0x00000000 0x00000000 0xEC01A1DE 0x114F6D74
8 0x31C5FA6C 0x241756D6 0xBC3A7DE2 0x845846CF 0x2794A127 0x6B8EA8B8
16 0x1D8E6992 0x9A478905 0x6A1D78C8 0x08C86D67 0x2A65BFBE 0xB4BD6E46
32 0xD26428AF 0x0A202283 0x27F917B1 0xC1DA8993 0x60E2ACAA 0xA6EB923D
64 0x7A01CBC9 0xB03D6068 0x62EE209F 0x069B7AFC 0x376A8936 0xCDC9E923

LSL Test

The following code has been imported to LSL to test the vectors with an XTEA implementation. It also makes use of a modified version of the Hex method on this wiki to display the data. Right Shift of signed integers is handed by techniques introduced in the Right_Shift method on this wiki.

// XTEA is a version of slightly improved TEA
// The plain or cypher text is in v[0], v[1]
// The key is in k[n], where n = 0 - 3
// The number of coding cycles is given by N and
// the number of decoding cycles is given by -N

list XTEA(list v, list k, integer N) // Replaces TEA's Code and Decode
{
    integer y = llList2Integer(v, 0);
    integer z = llList2Integer(v, 1);
    integer DELTA = 0x9E3779B9;
    integer limit = DELTA * N;
    integer sum = 0;
    
    if(N > 0) // encrypt
    {
        while(sum != limit)
        {
            y   += (z << 4 ^ ((z >> 5) & 0x07FFFFFF)) + z ^ sum + llList2Integer(k, sum & 3);
            sum += DELTA;
            z   += (y << 4 ^ ((y >> 5) & 0x07FFFFFF)) + y ^ sum + llList2Integer(k, (sum >> 11) & 3);
        }
    }
    else // decrypt
    {
         for(sum = -limit; sum; )
         {   z   -= (y << 4 ^ ((y >> 5) & 0x07FFFFFF)) + y ^ sum + llList2Integer(k, (sum >> 11) & 3);
             sum -= DELTA;
             y   -= (z << 4 ^ ((z >> 5) & 0x07FFFFFF)) + z ^ sum + llList2Integer(k, sum & 3);
         }
    }
    
    return [y,z];
}
string hex(integer value)
{
    string h = "";
    while (value)
    {
        string c = llGetSubString("0123456789ABCDEF", value & 0xF, value & 0xF);
        h = c + h;
        value = (value >> 4) & 0x0FFFFFFF;
    }
    return "0x" + llGetSubString("00000000" + h, -8, -1);
}
default
{
    state_entry()
    {

        // Bouncy Castle C# API Test Vectors
        list v;
        v = XTEA([0x00000000, 0x00000000], [0x00000000, 0x00000000, 0x00000000, 0x00000000], 32);
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + "\t" + hex(llList2Integer(v, 1)) + "\texpected\t0xDEE9D4D8\t0xF7131ED9");
        
        v = XTEA([0x01020304, 0x05060708], [0x00000000, 0x00000000, 0x00000000, 0x00000000], 32);
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + "\t" + hex(llList2Integer(v, 1)) + "\texpected\t0x065C1B89\t0x75C6A816");
        
        v = XTEA([0x00000000, 0x00000000], [0x01234567, 0x12345678, 0x23456789, 0x3456789A], 32);
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + "\t" + hex(llList2Integer(v, 1)) + "\texpected\t0x1FF9A026\t0x1AC64264");
        
        v = XTEA([0x01020304, 0x05060708], [0x01234567, 0x12345678, 0x23456789, 0x3456789A], 32);
        llSay(DEBUG_CHANNEL, hex(llList2Integer(v, 0)) + "\t" + hex(llList2Integer(v, 1)) + "\texpected\t0x8C67155B\t0x2EF91EAD");

        // Test Vectors for XTEA

        list pz = [0,0,0,0,0,0,0];
        integer n;
        for (n = 1; n < 65; n++)
        {  
            
            list a = XTEA(llList2List(pz, n, n + 1), llList2List(pz, n + 2, n + 5), n);
            
            pz = llListReplaceList(pz, a, n, n + 1);

            if (n == (n & -n))                         // if n power of 2
                llSay(DEBUG_CHANNEL, 
                    (string)n 
                    + "\t" + hex(llList2Integer(pz, n + 0)) 
                    + "\t" + hex(llList2Integer(pz, n + 1)) 
                    + "\t" + hex(llList2Integer(pz, n + 2))
                    + "\t" + hex(llList2Integer(pz, n + 3)) 
                    + "\t" + hex(llList2Integer(pz, n + 4))
                    + "\t" + hex(llList2Integer(pz, n + 5))
                );
            pz = llListReplaceList(pz, llList2List(pz, n, n + 5), n + 6, n + 11);
        }
    }
}