Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Looking for 'real' encryption? Start here.

Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
03-15-2007 19:35
From: Strife Onizuka
I haven't tested either optimization.
"If it's not tested, it doesn't work." :o

Your version of Morse's gets stuck and stack/heaps with certain input, and your version of mine has trailing garbage.

Anyway, here's another shot at it. It is the fastest so far, seems to work with UTF-8 input, and doesn't add trailing spaces. It only encodes 60 bits per 64-bit block, but you might be able to use that as a cheap way to see if the decryption input is valid.

CODE
//************************************************//
//* Masa's XTEA encryption/decryption v2 *//
//************************************************//
// NOTE: This version only encodes 60 bits per 64-bit block!
// This code is public domain.
// masa was here 20070315
// so was strife 20070315

//************************************************//
//* XTEA IMPLEMENTATION *//
//************************************************//

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

// Convert 16-byte (128 bit) string to a list of 4 integers.
list xtea_key_from_string( string str ) {
return [
llBase64ToInteger(llStringToBase64(llGetSubString(str, 0, 3))),
llBase64ToInteger(llStringToBase64(llGetSubString(str, 4, 7))),
llBase64ToInteger(llStringToBase64(llGetSubString(str, 8, 11))),
llBase64ToInteger(llStringToBase64(llGetSubString(str, 12, 15)))
];
}

// 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));
v1 += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^
(sum + llList2Integer(xtea_key, ((sum += XTEA_DELTA)>>11) & 3));
} while( num_rounds = ~-num_rounds );

return llIntegerToBase64(v0) + llIntegerToBase64(v1);
}

// 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));
v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^
(sum + llList2Integer(xtea_key, (sum -= XTEA_DELTA) & 3));
} while ( num_rounds = ~-num_rounds );

return llDeleteSubString(llIntegerToBase64(v0), 5, -1) +
llDeleteSubString(llIntegerToBase64(v1), 5, -1);
}

// 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 += 7)),
llBase64ToInteger(llGetSubString(str, ++i, i += 7))
);
} 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 + "====" );
}

//************************************************//
//* TESTS *//
//************************************************//

integer test_assertions = 0;
integer test_failures = 0;

test_assert( integer condition, string description ) {
++test_assertions;
if ( !condition ) {
++test_failures;
llOwnerSay( "ASSERTION FAILED: " + description );
}
}

test_assert_equal( string v1, string v2, string desc ) {
test_assert( v1 == v2, desc + "\nACTUAL=" + v1 + "\nEXPECTED=" + v2 );
}

test_xtea_encipher() {

xtea_num_rounds = 6;
xtea_key = [0x74736574, 0x2c676e69, 0x74736574, 0x2e676e69];
test_assert_equal(
xtea_encipher(0x62626161, 0x64646363),
llIntegerToBase64(0x5117f04b) + llIntegerToBase64(0xb9f38d3c),
"xtea_encipher(rounds=6, string=\"aabbccdd\"," +
"key=\"testing,testing.\") vs std"
);

xtea_num_rounds = 16;
xtea_key = [0x24234021, 0x2a265e25, 0x2b5f2928, 0x5d5b7d7b];
test_assert_equal(
xtea_encipher(0x74536554, 0x23476e49),
llIntegerToBase64(0xe9306ed2) + llIntegerToBase64(0x8f983d5a),
"xtea_encipher(rounds=16, string=\"TeStInG#\"," +
"key=\"!@#$%^&*()_+{}[]\") vs std"
);

xtea_num_rounds = 32;
xtea_key = [0x20202020, 0x20202020, 0x20202020, 0x20202020];
test_assert_equal(
xtea_encipher(0x20202020, 0x20202020),
llIntegerToBase64(0xb63a89e3) + llIntegerToBase64(0x8631c79c),
"xtea_encipher(rounds=32, string=\" \"," +
"key=\" \") vs std"
);
}

test_timed_encrypt(integer num_rounds, string str, string k) {
string encrypted;
string decrypted;
integer len = llStringLength(str);
string info = "rounds=" + (string)num_rounds + ", len=" + (string)len;

xtea_num_rounds = num_rounds;
xtea_key = xtea_key_from_string(k);
llResetTime();

encrypted = xtea_encrypt_string(str);
llOwnerSay( "enc(" + info + "): " + (string)llGetTime() );

llResetTime();
decrypted = xtea_decrypt_string(encrypted);
llOwnerSay( "dec(" + info + "): " + (string)llGetTime() );

test_assert(
str == decrypted,
"test_timed_encrypt(" + (string)num_rounds + "," +
"\"" + str + "\", \"" + k + "\") -- \"" + decrypted + "\""
);
}

test_xtea_encrypt_string() {
test_timed_encrypt(64, llUnescapeURL("%E4%BD%95"), "unicode test");
test_timed_encrypt(64, llUnescapeURL("%E6%94%BF%E5%92%8C%E5%B0%8F%E5%B3%B6"),
"unicode test 2" );

test_timed_encrypt(64, "hello", "test");
test_timed_encrypt(64, "small test", "small key");
test_timed_encrypt(64, ",xaYGp:?iThL *+\"I8!6qGA0eSXCUG1fXxNl'\"T0_" +
"Un.P:u/= N{2{!L -]'mg-89p.on9zjfEJ<lZW;gJ;d" +
"3:u CFK+|qMqmhaI0", "here is a key");
test_timed_encrypt(32, "hello", "test");
test_timed_encrypt(32, "small test", "small key");
test_timed_encrypt(32, ",xaYGp:?iThL *+\"I8!6qGA0eSXCUG1fXxNl'\"T0_" +
"Un.P:u/= N{2{!L -]'mg-89p.on9zjfEJ<lZW;gJ;d" +
"3:u CFK+|qMqmhaI0", "here is a key");
test_timed_encrypt( 6, "hello", "test");
test_timed_encrypt( 6, "small test", "small key");
test_timed_encrypt( 6, ",xaYGp:?iThL *+\"I8!6qGA0eSXCUG1fXxNl'\"T0_" +
"Un.P:u/= N{2{!L -]'mg-89p.on9zjfEJ<lZW;gJ;d" +
"3:u CFK+|qMqmhaI0", "here is a key");
}

//************************************************//
//* TEST DRIVER *//
//************************************************//

default {
state_entry() {
test_xtea_encipher();
test_xtea_encrypt_string();
llOwnerSay( "assertions: " + (string)test_assertions + " / " +
"failures: " + (string)test_failures );
llListen(0, "", llGetOwner(), "" );
}

listen(integer channel, string name, key id, string msg) {
test_timed_encrypt( 64, msg, id );
test_timed_encrypt( 32, msg, id );
test_timed_encrypt( 6, msg, id );
}
}


And timings, again run in parallel and resorted. Only tested on the private island this time, don't expect to see these numbers in normal conditions.
CODE
[19:00]  You: small test
[19:00] XTEA.masa2: enc(rounds=64, len=10): 0.444602
[19:00] XTEA.masa2: dec(rounds=64, len=10): 0.466780
[19:00] XTEA.masa2: enc(rounds=32, len=10): 0.222161
[19:00] XTEA.masa2: dec(rounds=32, len=10): 0.267226
[19:00] XTEA.masa2: enc(rounds= 6, len=10): 0.066804
[19:00] XTEA.masa2: dec(rounds= 6, len=10): 0.110981
[19:00] XTEA.masa1: enc(rounds=64, len=10): 0.511228
[19:00] XTEA.masa1: dec(rounds=64, len=10): 0.511611
[19:00] XTEA.masa1: enc(rounds=32, len=10): 0.288884
[19:00] XTEA.masa1: dec(rounds=32, len=10): 0.311588
[19:00] XTEA.masa1: enc(rounds= 6, len=10): 0.133655
[19:00] XTEA.masa1: dec(rounds= 6, len=10): 0.133261
[19:00] XTEA.morse: enc(rounds=64, len=10): 0.689131
[19:00] XTEA.morse: dec(rounds=64, len=10): 0.689452
[19:00] XTEA.morse: enc(rounds=32, len=10): 0.466987
[19:00] XTEA.morse: dec(rounds=32, len=10): 0.489095
[19:00] XTEA.morse: enc(rounds= 6, len=10): 0.311203
[19:00] XTEA.morse: dec(rounds= 6, len=10): 0.311452

[19:01] You: big test big test big test big test big test big test big test big test big test big test big test b
[19:01] XTEA.masa2: enc(rounds=64, len=100): 3.046450
[19:01] XTEA.masa2: dec(rounds=64, len=100): 3.157468
[19:01] XTEA.masa2: enc(rounds=32, len=100): 1.623607
[19:01] XTEA.masa2: dec(rounds=32, len=100): 1.756583
[19:01] XTEA.masa2: enc(rounds= 6, len=100): 0.488945
[19:01] XTEA.masa2: dec(rounds= 6, len=100): 0.645068
[19:01] XTEA.masa1: enc(rounds=64, len=100): 3.156902
[19:01] XTEA.masa1: dec(rounds=64, len=100): 3.068869
[19:01] XTEA.masa1: enc(rounds=32, len=100): 1.734075
[19:01] XTEA.masa1: dec(rounds=32, len=100): 1.667667
[19:01] XTEA.masa1: enc(rounds= 6, len=100): 0.600377
[19:01] XTEA.masa1: dec(rounds= 6, len=100): 0.533817
[19:01] XTEA.morse: enc(rounds=64, len=100): 4.624939
[19:01] XTEA.morse: dec(rounds=64, len=100): 4.558482
[19:01] XTEA.morse: enc(rounds=32, len=100): 3.268742
[19:01] XTEA.morse: dec(rounds=32, len=100): 3.313709
[19:01] XTEA.morse: enc(rounds= 6, len=100): 2.156943
[19:01] XTEA.morse: dec(rounds= 6, len=100): 2.089912

[19:01] You: huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test huge test hug
[19:02] XTEA.masa2: enc(rounds=64, len=1023): 33.399811
[19:03] XTEA.masa2: dec(rounds=64, len=1023): 34.066189
[19:03] XTEA.masa2: enc(rounds=32, len=1023): 18.345398
[19:03] XTEA.masa2: dec(rounds=32, len=1023): 21.657858
[19:03] XTEA.masa2: enc(rounds= 6, len=1023): 8.294439
[19:04] XTEA.masa2: dec(rounds= 6, len=1023): 9.450169
[19:02] XTEA.masa1: Script run-time error
[19:02] XTEA.masa1: Stack-Heap Collision
[19:02] XTEA.morse: enc(rounds=64, len=1023): 56.124554
[19:03] XTEA.morse: dec(rounds=64, len=1023): 51.389164
[19:04] XTEA.morse: enc(rounds=32, len=1023): 42.933647
[19:05] XTEA.morse: dec(rounds=32, len=1023): 40.250027
[19:05] XTEA.morse: enc(rounds= 6, len=1023): 32.390087
[19:06] XTEA.morse: dec(rounds= 6, len=1023): 27.021774


Also I thought I'd point out that you don't have to use XTEA for encrypting every message. You can use it to decode a "one-time pad", and work your way through that using llXorBase64Strings(). Then you can have another script decoding a new pad before you're finished with the current one.
Strife Onizuka
Moonchild
Join date: 3 Mar 2004
Posts: 5,887
03-15-2007 21:59
From: Masakazu Kojima
"If it's not tested, it doesn't work." :o

Your version of Morse's gets stuck and stack/heaps with certain input, and your version of mine has trailing garbage.

Anyway, here's another shot at it. It is the fastest so far, seems to work with UTF-8 input, and doesn't add trailing spaces. It only encodes 60 bits per 64-bit block, but you might be able to use that as a cheap way to see if the decryption input is valid.


Yeah the version i posted had a bad remove at the end; i knew about the problem and was too tired to fix it. Was working on making it smarter but it that had a rounding problem caused by it getting converted to a float. I don't really have time to make things work ~_~. I've had to cut down on time at the computer because of my hands giving me problems.

---

You *must* pad your llBase64ToInteger string to six characters. Been a while since I checked this but if you don't you get tail end corruption. llBase64ToInteger reads 6 characters worth of data regardless of it being available (it overruns the null). So whatever is past the null gets worked into the result as well. *wonders if a bug report was ever sent*

CODE

list xtea_key_from_string( string str ) {
str = llStringToBase64(str);
return [
llBase64ToInteger( llGetSubString(str, 0, 3) +"AA"),
llBase64ToInteger( llGetSubString(str, 4, 7) +"AA"),
llBase64ToInteger( llGetSubString(str, 8, 11) +"AA"),
llBase64ToInteger( llGetSubString(str, 12, 15) +"AA")
];
}
_____________________
Truth is a river that is always splitting up into arms that reunite. Islanded between the arms, the inhabitants argue for a lifetime as to which is the main river.
- Cyril Connolly

Without the political will to find common ground, the continual friction of tactic and counter tactic, only creates suspicion and hatred and vengeance, and perpetuates the cycle of violence.
- James Nachtwey
Keknehv Psaltery
Hacker
Join date: 11 Apr 2005
Posts: 1,185
03-16-2007 00:47
As for the security of TEA,

From http://www.kremlinencrypt.com/algorithms.htm
From: someone

Tiny Encryption Algorithm (TEA)

TEA is a cryptographic algorithm designed to minimize memory footprint, and maximize speed. However, the cryptographers from Counterpane Systems have discovered three related-key attacks on TEA, the best of which requires only 2^23 chosen plaintexts and one related key query. The problems arise from the overly simple key schedule. Each TEA key can be found to have three other equivalent keys, as described in a paper by David Wagner, John Kelsey, and Bruce Schneier. This precludes the possibility of using TEA as a hash function. Roger Needham and David Wheeler have proposed extensions to TEA that counter the above attacks.


From http://en.wikipedia.org/wiki/Chosen_plaintext
From: someone

Chosen-plaintext attack

A chosen-plaintext attack (CPA) is an attack model for cryptanalysis which presumes that the attacker has the capability to choose arbitrary plaintexts to be encrypted and obtain the corresponding ciphertexts. The goal of the attack is to gain some further information which reduces the security of the encryption scheme. In the worst case, a chosen-plaintext attack could reveal the scheme's secret key.

This appears, at first glance, to be an unrealistic model; it would certainly be unlikely that an attacker could persuade a human cryptographer to encrypt large amounts of plaintexts of the attacker's choosing. Modern cryptography, on the other hand, is implemented in software or hardware and is used for a diverse range of applications; for many cases, a chosen-plaintext attack is often very feasible. Chosen-plaintext attacks become extremely important in the context of public key cryptography, where the encryption key is public and attackers can encrypt any plaintext they choose.


Thus, TEA is fine, so long as you prevent a chosen-plaintext attack.

Also, encrypting 2^23 chosen plaintexts in LSL would take an exceedingly long time.


At least, that's how it appears to me-- I'm a bit behind on my cryptography.
Masakazu Kojima
ケロ
Join date: 23 Apr 2004
Posts: 232
03-16-2007 05:44
From: Strife Onizuka
You *must* pad your llBase64ToInteger string to six characters. Been a while since I checked this but if you don't you get tail end corruption. llBase64ToInteger reads 6 characters worth of data regardless of it being available (it overruns the null). So whatever is past the null gets worked into the result as well.
Base64 encodes 3 bytes in 4 characters, so decoding 4 characters gets you 3 bytes and the null. llBase64ToInteger( "dGVz" ) is 0x74657300. Though that is still wrong in this case and that function should be:
CODE
list xtea_key_from_string( string str ) {
return [
llBase64ToInteger(llStringToBase64(llGetSubString(str, 0, 3))),
llBase64ToInteger(llStringToBase64(llGetSubString(str, 4, 7))),
llBase64ToInteger(llStringToBase64(llGetSubString(str, 8, 11))),
llBase64ToInteger(llStringToBase64(llGetSubString(str, 12, 15)))
];
}
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
04-12-2007 11:43
I am trying to find an accessible - meaning English with decent explanations, or at least some good code - website that presents a PHP implementation of XTEA compatible with any of the LSL implementations here.

Anyone have any good linkies to share?
_____________________
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
04-12-2007 12:00
TEA and XTEA are both reasoanbly simple algorithms and there are numerous web site around with the required information. I admit to knowing zero php but it should be relatively simple to implement (we did an LSL version of TEA a few months back)
Talarus Luan
Ancient Archaean Dragon
Join date: 18 Mar 2006
Posts: 4,831
04-12-2007 12:15
http://en.wikipedia.org/wiki/XTEA

That should get you started. :)
Tobia Forcella
Registered User
Join date: 4 Mar 2007
Posts: 30
04-16-2007 18:29
Hello, i'm trying the PEAR Crypt_Xtea package found here:

http://pear.php.net/package/Crypt_Xtea/

i don't understand how to let it comunicate with the Xtea LSL script;

I LSL we have 4 keys, on php only one:

CODE
<?php
require_once 'Crypt/Xtea.php';

$data = 'abcdefghijklmnopqrstuvwxyz';
$key = '0123456789abcdef';

$crypt = new Crypt_Xtea();
$encrypted = $crypt->encrypt($data, $key);
$decrypted = $crypt->decrypt($encrypted, $key);
?>


and on the README it say: The output of both the encrypt() and decrypt() functions is a binary string.

How to set keys that give the same result? What i'm missing?

Thank you very much and sorry for my english :)
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
04-16-2007 20:08
I haven't yet gotten to the part that needs encryption in my current project, but if someone can answer this question it will be of absolutely tremendous value.

I can use php_mcrypt or the Pear module, either one.
_____________________
Tobia Forcella
Registered User
Join date: 4 Mar 2007
Posts: 30
04-16-2007 20:25
Yes!!

But don't know if mcrypt can be used with LSL, the only encryption i've found is this XTEA; can anyone help?
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
04-16-2007 20:58
From: Tobia Forcella
Yes!!

But don't know if mcrypt can be used with LSL, the only encryption i've found is this XTEA; can anyone help?


mcrypt also has XTEA cipher capability, at least according to the PHP.NET man page on mcrypt. Presumably both the Pear module and the mcrypt module are output-level compatible, so if we can figure out how to set the LSL scripts that were given above to decrypt their output we should be able to use PHP to encrypt and send data to in-world objects, which would be tremendously useful on my current project.

I will offer a code bounty of $5,000L for someone that can provide a PHP script that uses either method to encrypt data using XTEA that is then successfully decrypted in SL using the scripts given above, with instructions on how to set up the keys in the LSL script.

Failing that, when I get more time I will try to do it myself and post my results here. That may be weeks, though, since I am currently quite busy :)
_____________________
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
04-16-2007 23:34
XTEA is a 128 bit encryption system i.e. 16 8 bit characters.
The LSL implementation uses 4 32 bit integers.
Given your encryption key is

$key = '0123456789abcdef';

The LSL XTEA will be using the numeric equivelent of that string:-

key1 = 0x30313233; // 0123
key2 = 0x34353637; // 4567
key3 = 0x38396162; // 89ab
key4 = 0x63646566; // cdef


or to put it in terms of the code previously given

list xtea_key = [ 0x30313233, 0x34353637, 0x38396162, 0x63646566 ];
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
04-16-2007 23:43
From: Newgate Ludd
XTEA is a 128 bit encryption system i.e. 16 8 bit characters.
The LSL implementation uses 4 32 bit integers.
Given your encryption key is

$key = '0123456789abcdef';

The LSL XTEA will be using the numeric equivelent of that string:-

key1 = 0x30313233; // 0123
key2 = 0x34353637; // 4567
key3 = 0x38396162; // 89ab
key4 = 0x63646566; // cdef


or to put it in terms of the code previously given

list xtea_key = [ 0x30313233, 0x34353637, 0x38396162, 0x63646566 ];


Paid you some money in-world for providing part of the answer I was looking for :)

Feel like taking on an example of PHP->LSL next?

My use case as I envision it now (not to that point yet) is that an XTEA encrypted email will be sent from a PHP script to an in-world object that will use the LSL implementations above to decrypt the data.

If it's easier for someone to whip up an example using llHttpRequest() to get the encrypted data and then decrypt that, that will be good too.


.
_____________________
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
04-17-2007 00:03
From: RobbyRacoon Olmstead
Paid you some money in-world for providing part of the answer I was looking for :)

Feel like taking on an example of PHP->LSL next?

My use case as I envision it now (not to that point yet) is that an XTEA encrypted email will be sent from a PHP script to an in-world object that will use the LSL implementations above to decrypt the data.

If it's easier for someone to whip up an example using llHttpRequest() to get the encrypted data and then decrypt that, that will be good too.


.

LOL, thanks Robby wasnt required but always appreciated.
I'll pass on doing anything with PHP as I've never played with it.

The existing PHP system you have should be directly appliciable i.e. You PHP script need only encrytpt the text and then email SL as normal. Your receiver can be the standard LSL email handler but then passing the data off to the XTEA decryption process.
Examples of both have been posted.

The real problem will be ensuring that both ends are using not only the same encryption key but also the same number of 'rounds' / cycles of the encryption process. The XTEA standard is 64 rounds which may be prohibitively large in LSL.
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
04-17-2007 00:20
From: Newgate Ludd
LOL, thanks Robby wasnt required but always appreciated.
I'll pass on doing anything with PHP as I've never played with it.

The existing PHP system you have should be directly appliciable i.e. You PHP script need only encrytpt the text and then email SL as normal. Your receiver can be the standard LSL email handler but then passing the data off to the XTEA decryption process.
Examples of both have been posted.

The real problem will be ensuring that both ends are using not only the same encryption key but also the same number of 'rounds' / cycles of the encryption process. The XTEA standard is 64 rounds which may be prohibitively large in LSL.


yeah, I haven't even played with it enough to know if I can reduce the number of rounds, but I am comforted by two big facts for my use case:
  1. I am not processing money or anything as remotely sensitive or critical as that. I just want to provide an obstacle to people trying to cheat the system, and can be satisfied if the obstacle is enough to delay them until the data is no longer useful.
  2. Decryption is faster than encryption, and I'm glad that the LSL side is doing the decryption rather than the other way around.
And as for paying you, well, it was worth it to me. I hope that it demonstrates also that I really *will* pay someone to put together a working end-to-end example, and that I'm not just talking out my butt :)


.
_____________________
Tobia Forcella
Registered User
Join date: 4 Mar 2007
Posts: 30
04-17-2007 05:46
Thank you to all:

i'm trying it:

on LSL:

CODE
integer KEY1 = 0x30313233;
integer KEY2 = 0x34353637;
integer KEY3 = 0x38396162;
integer KEY4 = 0x63646566;


with the output:

Original Cleartext: test
Cyphertext: 90DFC14A3D1DA76C
Decrypted Cleartext: test

on php:

CODE
<?php
require_once 'xtea/Xtea.php';

$data = 'test';
$key = '0123456789abcdef';

$crypt = new Crypt_Xtea();
$encrypted = $crypt->encrypt($data, $key);
$decrypted = $crypt->decrypt($encrypted, $key);
echo "<br />$data<br />$encrypted<br />$decrypted";


with output:

test
ãü`5?Ý
test

what is wrong? can some one please post a working example on how to have the same encrypted text? I can pay for it! :)

Thanky you very much!
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
04-17-2007 06:04
From: Tobia Forcella
Thank you to all:

i'm trying it:

on LSL:

CODE
integer KEY1 = 0x30313233;
integer KEY2 = 0x34353637;
integer KEY3 = 0x38396162;
integer KEY4 = 0x63646566;


with the output:

Original Cleartext: test
Cyphertext: 90DFC14A3D1DA76C
Decrypted Cleartext: test

on php:

CODE
<?php
require_once 'xtea/Xtea.php';

$data = 'test';
$key = '0123456789abcdef';

$crypt = new Crypt_Xtea();
$encrypted = $crypt->encrypt($data, $key);
$decrypted = $crypt->decrypt($encrypted, $key);
echo "<br />$data<br />$encrypted<br />$decrypted";


with output:

test
ãü`5?Ý
test

what is wrong? can some one please post a working example on how to have the same encrypted text? I can pay for it! :)

Thanky you very much!


The original comment about 'binary strings' plus the text make it look to me like its outputing it as 8 bit integer values rather than as an ASCII string.

 = ??
ã = 0xE3
ü = 0xFC
` = 0x60
5 = 0x35
 = ??
? = 0x3F
Ý = 0xDD

or as an ASCII String ??E3FC6035??3FDD

That both systems can encrypt and decrypt their own text would point to any difference between the two as being caused either by an key mismatch or a difference in number of 'rounds'. Or even a slight difference in the implementation of the XTEA algorithms !
Tobia Forcella
Registered User
Join date: 4 Mar 2007
Posts: 30
04-17-2007 06:13
in the read me of XTEA PEAR package we can read:
The output of both the encrypt() and decrypt() functions is a binary string.

So what i can do to convert?
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
I'd switch package!
04-17-2007 06:33
From: Tobia Forcella
in the read me of XTEA PEAR package we can read:
The output of both the encrypt() and decrypt() functions is a binary string.

So what i can do to convert?



On a slightly more serious note I'd look for a hexdump type routine.
hexdump converts a string (or any block of data) into its hex equivelent on a byte by byte basis. I'm afraid I know absolutely zero php so will be of very little help in that area.

The next step would be to confirm that the number of rounds being used is the same.
Do you have access to the PEAR XTEA source code? The suggested default is 64 rounds but I know the LSL script was using less. If you are using the originally posed script it will only be 6.

change the line
CODE
integer CYCLES = 6;
to
CODE
integer CYCLES = 64;
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
04-17-2007 06:53
From: Tobia Forcella
in the read me of XTEA PEAR package we can read:
The output of both the encrypt() and decrypt() functions is a binary string.

So what i can do to convert?


CODE

require_once 'xtea.php';

function str_hex($string){
$hex='';
for ($i=0; $i < strlen($string); $i++){
$hex .= dechex(ord($string[$i]));
}
return $hex;
}


function hex_str($hex){
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2){
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}

$data = 'test';
$key = '0123456789abcdef';

$crypt = new Crypt_Xtea();
$encrypted = $crypt->encrypt($data, $key);
$decrypted = $crypt->decrypt($encrypted, $key);
$encoded = str_hex($encrypted);
echo "<br />$data<br />{$encoded}<br />$decrypted";


The LSL version is outputing a hex-encoded string.

This example I put in above outputs a hex-encoded string also, but it still doesn't match the output you are getting from your LSL example. It might be worth noting that the Crypt_Xtea class uses 32 cycles for the encryption, I can't remember what the LSL example is using by default.

[Edit]: Oh. Newgate kind of answered the same thing when I wasn't looking :) Try 32 cycles instead of 64 with the above code and report on that too, please.

.
_____________________
Pavel Palen
Registered User
Join date: 3 Apr 2007
Posts: 1
04-17-2007 07:27
thank you to all!!

I tryed to put in LSL:

integer CYCLES = 32;

the LSL output is:

509EC619BA00C6EE

IN PHP:

3e3fc60351a3fdd

this is the source code of the php package:

CODE
<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
//
// +----------------------------------------------------------------------+
// | PHP version 4.0 |
// +----------------------------------------------------------------------+
// | Copyright (c) 2002-2004 The PHP Group |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license, |
// | that is bundled with this package in the file LICENSE, and is |
// | available at through the world-wide-web at |
// | http://www.php.net/license/2_02.txt. |
// | If you did not receive a copy of the PHP license and are unable to |
// | obtain it through the world-wide-web, please send a note to |
// | license@php.net so we can mail you a copy immediately. |
// +----------------------------------------------------------------------+
// | Authors: Jeroen Derks <jeroen@derks.it> |
// +----------------------------------------------------------------------+
// | Original code: http://vader.brad.ac.uk/tea/source.shtml#new_ansi |
// | Currently to be found at: |
// | http://www.simonshepherd.supanet.com/source.shtml#new_ansi |
// +----------------------------------------------------------------------+
//
// $Id: Xtea.php,v 1.13 2004/10/04 20:23:22 jeroend Exp $
//

/** PEAR base class */
require_once 'PEAR.php';

/**
* Class that implements the xTEA encryption algorithm.
* Class that implements the xTEA encryption algorithm.<br />
* This enables you to encrypt data without requiring mcrypt.
*
* From the C source:
* -----------------------------------------
* The Tiny Encryption Algorithm (TEA) by
* David Wheeler and Roger Needham of the
* Cambridge Computer Laboratory.
*
* Placed in the Public Domain by
* David Wheeler and Roger Needham.
*
* **** ANSI C VERSION (New Variant) ****
*
* Notes:
*
* TEA is a Feistel cipher with XOR and
* and addition as the non-linear mixing
* functions.
*
* Takes 64 bits of data in v[0] and v[1].
* Returns 64 bits of data in w[0] and w[1].
* Takes 128 bits of key in k[0] - k[3].
*
* TEA can be operated in any of the modes
* of DES. Cipher Block Chaining is, for example,
* simple to implement.
*
* n is the number of iterations. 32 is ample,
* 16 is sufficient, as few as eight may be OK.
* The algorithm achieves good dispersion after
* six iterations. The iteration count can be
* made variable if required.
*
* Note this is optimised for 32-bit CPUs with
* fast shift capabilities. It can very easily
* be ported to assembly language on most CPUs.
*
* delta is chosen to be the real part of (the
* golden ratio Sqrt(5/4) - 1/2 ~ 0.618034
* multiplied by 2^32).
*
* This version has been amended to foil two
* weaknesses identified by David A. Wagner
* (daw@cs.berkeley.edu): 1) effective key
* length of old-variant TEA was 126 not 128
* bits 2) a related key attack was possible
* although impractical.
*
* void encipher(unsigned long *const v,unsigned long *const w,
* const unsigned long *const k)
* {
* register unsigned long y=v[0],z=v[1],sum=0,delta=0x9E3779B9,n=32;
*
* while(n-->0)
* {
* y+= (z<<4 ^ z>>5) + z ^ sum + k[sum&3];
* sum += delta;
* z+= (y<<4 ^ y>>5) + y ^ sum + k[sum>>11 & 3];
* }
*
* w[0]=y; w[1]=z;
* }
*
* void decipher(unsigned long *const v,unsigned long *const w,
* const unsigned long *const k)
* {
* register unsigned long y=v[0],z=v[1],sum=0xC6EF3720,
* delta=0x9E3779B9,n=32;
*
* # sum = delta<<5, in general sum = delta * n
*
* while(n-->0)
* {
* z-= (y<<4 ^ y>>5) + y ^ sum + k[sum>>11 & 3];
* sum -= delta;
* y-= (z<<4 ^ z>>5) + z ^ sum + k[sum&3];
* }
*
* w[0]=y; w[1]=z;
* }
*
* -----------------------------------------
*
* @TODO Add CFB.
*
* @package Crypt_Xtea
* @version $Revision: 1.13 $
* @access public
* @author Jeroen Derks <jeroen@derks.it>
*/

class Crypt_Xtea extends PEAR
{

/**
* Number of iterations.
* @var integer
* @access private
* @see setIter(), getIter()
*/
var $n_iter;


// {{{ Crypt_Xtea()

/**
* Constructor, sets the number of iterations.
*
* @access public
* @author Jeroen Derks <jeroen@derks.it>
* @see setIter()
*/
function Crypt_Xtea()
{
$this->setIter(32);
}

// }}}
// {{{ setIter()

/**
* Set the number of iterations to use.
*
* @param integer $n_iter Number of iterations to use.
*
* @access public
* @author Jeroen Derks <jeroen@derks.it>
* @see $n_iter, getIter()
*/
function setIter($n_iter)
{
$this->n_iter = $n_iter;
}

// }}}
// {{{ getIter()

/**
* Get the number of iterations to use.
*
* @return integer Number of iterations to use.
*
* @access public
* @author Jeroen Derks <jeroen@derks.it>
* @see $n_iter, setIter()
*/
function getIter()
{
return $this->n_iter;
}

// }}}
// {{{ encrypt()

/**
* Encrypt a string using a specific key.
*
* @param string $data Data to encrypt.
* @param string $key Key to encrypt data with (binary string).
*
* @return string Binary encrypted character string.
*
* @access public
* @author Jeroen Derks <jeroen@derks.it>
* @see decrypt(), _encipherLong(), _resize(), _str2long()
*/
function encrypt($data, $key)
{
// resize data to 32 bits (4 bytes)
$n = $this->_resize($data, 4);

// convert data to long
$data_long[0] = $n;
$n_data_long = $this->_str2long(1, $data, $data_long);

// resize data_long to 64 bits (2 longs of 32 bits)
$n = count($data_long);
if (($n & 1) == 1) {
$data_long[$n] = chr(0);
$n_data_long++;
}

// resize key to a multiple of 128 bits (16 bytes)
$this->_resize($key, 16, true);

// convert key to long
$n_key_long = $this->_str2long(0, $key, $key_long);

// encrypt the long data with the key
$enc_data = '';
$w = array(0, 0);
$j = 0;
$k = array(0, 0, 0, 0);
for ($i = 0; $i < $n_data_long; ++$i) {
// get next key part of 128 bits
if ($j + 4 <= $n_key_long) {
$k[0] = $key_long[$j];
$k[1] = $key_long[$j + 1];
$k[2] = $key_long[$j + 2];
$k[3] = $key_long[$j + 3];
} else {
$k[0] = $key_long[$j % $n_key_long];
$k[1] = $key_long[($j + 1) % $n_key_long];
$k[2] = $key_long[($j + 2) % $n_key_long];
$k[3] = $key_long[($j + 3) % $n_key_long];
}
$j = ($j + 4) % $n_key_long;

$this->_encipherLong($data_long[$i], $data_long[++$i], $w, $k);

// append the enciphered longs to the result
$enc_data .= $this->_long2str($w[0]);
$enc_data .= $this->_long2str($w[1]);
}

return $enc_data;
}

// }}}
// {{{ decrypt()

/**
* Decrypt an encrypted string using a specific key.
*
* @param string $data Encrypted data to decrypt.
* @param string $key Key to decrypt encrypted data with (binary string).
*
* @return string Binary decrypted character string.
*
* @access public
* @author Jeroen Derks <jeroen@derks.it>
* @see _encipherLong(), encrypt(), _resize(), _str2long()
*/
function decrypt($enc_data, $key)
{
// convert data to long
$n_enc_data_long = $this->_str2long(0, $enc_data, $enc_data_long);

// resize key to a multiple of 128 bits (16 bytes)
$this->_resize($key, 16, true);

// convert key to long
$n_key_long = $this->_str2long(0, $key, $key_long);

// decrypt the long data with the key
$data = '';
$w = array(0, 0);
$j = 0;
$len = 0;
$k = array(0, 0, 0, 0);
$pos = 0;

for ($i = 0; $i < $n_enc_data_long; $i += 2) {
// get next key part of 128 bits
if ($j + 4 <= $n_key_long) {
$k[0] = $key_long[$j];
$k[1] = $key_long[$j + 1];
$k[2] = $key_long[$j + 2];
$k[3] = $key_long[$j + 3];
} else {
$k[0] = $key_long[$j % $n_key_long];
$k[1] = $key_long[($j + 1) % $n_key_long];
$k[2] = $key_long[($j + 2) % $n_key_long];
$k[3] = $key_long[($j + 3) % $n_key_long];
}
$j = ($j + 4) % $n_key_long;

$this->_decipherLong($enc_data_long[$i], $enc_data_long[$i + 1], $w, $k);

// append the deciphered longs to the result data (remove padding)
if (0 == $i) {
$len = $w[0];
if (4 <= $len) {
$data .= $this->_long2str($w[1]);
} else {
$data .= substr($this->_long2str($w[1]), 0, $len % 4);
}
} else {
$pos = ($i - 1) * 4;
if ($pos + 4 <= $len) {
$data .= $this->_long2str($w[0]);

if ($pos + 8 <= $len) {
$data .= $this->_long2str($w[1]);
} elseif ($pos + 4 < $len) {
$data .= substr($this->_long2str($w[1]), 0, $len % 4);
}
} else {
$data .= substr($this->_long2str($w[0]), 0, $len % 4);
}
}
}
return $data;
}

// }}}
// {{{ _encipherLong()

/**
* Encipher a single long (32-bit) value.
*
* @param integer $y 32 bits of data.
* @param integer $z 32 bits of data.
* @param array &$w Placeholder for enciphered 64 bits (in w[0] and w[1]).
* @param array &$k Key 128 bits (in k[0]-k[3]).
*
* @access private
* @author Jeroen Derks <jeroen@derks.it>
* @see $n_iter, _add(), _rshift(), _decipherLong()
*/
function _encipherLong($y, $z, &$w, &$k)
{
$sum = (integer) 0;
$delta = 0x9E3779B9;
$n = (integer) $this->n_iter;

while ($n-- > 0) {
$y = $this->_add($y,
$this->_add($z << 4 ^ $this->_rshift($z, 5), $z) ^
$this->_add($sum, $k[$sum & 3]));
$sum = $this->_add($sum, $delta);
$z = $this->_add($z,
$this->_add($y << 4 ^ $this->_rshift($y, 5), $y) ^
$this->_add($sum, $k[$this->_rshift($sum, 11) & 3]));
}

$w[0] = $y;
$w[1] = $z;
}

// }}}
// {{{ _decipherLong()

/**
* Decipher a single long (32-bit) value.
*
* @param integer $y 32 bits of enciphered data.
* @param integer $z 32 bits of enciphered data.
* @param array &$w Placeholder for deciphered 64 bits (in w[0] and w[1]).
* @param array &$k Key 128 bits (in k[0]-k[3]).
*
* @access private
* @author Jeroen Derks <jeroen@derks.it>
* @see $n_iter, _add(), _rshift(), _decipherLong()
*/
function _decipherLong($y, $z, &$w, &$k)
{
// sum = delta<<5, in general sum = delta * n
$sum = 0xC6EF3720;
$delta = 0x9E3779B9;
$n = (integer) $this->n_iter;

while ($n-- > 0) {
$z = $this->_add($z,
-($this->_add($y << 4 ^ $this->_rshift($y, 5), $y) ^
$this->_add($sum, $k[$this->_rshift($sum, 11) & 3])));
$sum = $this->_add($sum, -$delta);
$y = $this->_add($y,
-($this->_add($z << 4 ^ $this->_rshift($z, 5), $z) ^
$this->_add($sum, $k[$sum & 3])));
}

$w[0] = $y;
$w[1] = $z;
}

// }}}
// {{{ _resize()

/**
* Resize data string to a multiple of specified size.
*
* @param string $data Data string to resize to specified size.
* @param integer $size Size in bytes to align data to.
* @param boolean $nonull Set to true if padded bytes should not be zero.
*
* @return integer Length of supplied data string.
*
* @access private
* @author Jeroen Derks <jeroen@derks.it>
*/
function _resize(&$data, $size, $nonull = false)
{
$n = strlen($data);
$nmod = $n % $size;

if ($nmod > 0) {
if ($nonull) {
for ($i = $n; $i < $n - $nmod + $size; ++$i) {
$data[$i] = $data[$i % $n];
}
} else {
for ($i = $n; $i < $n - $nmod + $size; ++$i) {
$data[$i] = chr(0);
}
}
}
return $n;
}

// }}}
// {{{ _hex2bin()

/**
* Convert a hexadecimal string to a binary string (e.g. convert "616263" to "abc").
*
* @param string $str Hexadecimal string to convert to binary string.
*
* @return string Binary string.
*
* @access private
* @author Jeroen Derks <jeroen@derks.it>
*/
function _hex2bin($str)
{
$len = strlen($str);
return pack('H' . $len, $str);
}

// }}}
// {{{ _str2long()

/**
* Convert string to array of long.
*
* @param integer $start Index into $data_long for output.
* @param string &$data Input string.
* @param array &$data_long Output array of long.
*
* @return integer Index from which to optionally continue.
*
* @access private
* @author Jeroen Derks <jeroen@derks.it>
*/
function _str2long($start, &$data, &$data_long)
{
$n = strlen($data);

$tmp = unpack('N*', $data);
$j = $start;

foreach ($tmp as $value)
$data_long[$j++] = $value;

return $j;
}

// }}}
// {{{ _long2str()

/**
* Convert long to character string.
*
* @param long $l Long to convert to character string.
*
* @return string Character string.
*
* @access private
* @author Jeroen Derks <jeroen@derks.it>
*/
function _long2str($l)
{
return pack('N', $l);
}

// }}}
// {{{ _rshift()

/**
* Handle proper unsigned right shift, dealing with PHP's signed shift.
*
* @access private
* @since 2004/Sep/06
* @author Jeroen Derks <jeroen@derks.it>
*/
function _rshift($integer, $n)
{
// convert to 32 bits
if (0xffffffff < $integer || -0xffffffff > $integer) {
$integer = fmod($integer, 0xffffffff + 1);
}

// convert to unsigned integer
if (0x7fffffff < $integer) {
$integer -= 0xffffffff + 1.0;
} elseif (-0x80000000 > $integer) {
$integer += 0xffffffff + 1.0;
}

// do right shift
if (0 > $integer) {
$integer &= 0x7fffffff; // remove sign bit before shift
$integer >>= $n; // right shift
$integer |= 1 << (31 - $n); // set shifted sign bit
} else {
$integer >>= $n; // use normal right shift
}

return $integer;
}

// }}}
// {{{ _add()

/**
* Handle proper unsigned add, dealing with PHP's signed add.
*
* @access private
* @since 2004/Sep/06
* @author Jeroen Derks <jeroen@derks.it>
*/
function _add($i1, $i2)
{
$result = 0.0;

foreach (func_get_args() as $value) {
// remove sign if necessary
if (0.0 > $value) {
$value -= 1.0 + 0xffffffff;
}

$result += $value;
}

// convert to 32 bits
if (0xffffffff < $result || -0xffffffff > $result) {
$result = fmod($result, 0xffffffff + 1);
}

// convert to signed integer
if (0x7fffffff < $result) {
$result -= 0xffffffff + 1.0;
} elseif (-0x80000000 > $result) {
$result += 0xffffffff + 1.0;
}

return $result;
}

// }}}
}

?>
Tobia Forcella
Registered User
Join date: 4 Mar 2007
Posts: 30
04-17-2007 07:32
sorry, pavel palen is my friend, i posted from him PC ;)
Tobia Forcella
Registered User
Join date: 4 Mar 2007
Posts: 30
04-17-2007 10:30
I did some other tests, using mcrypt too, but still can't have one valid :(

this is php:

CODE
<?php
$data = 'test';
$key = '0123456789abcdef';
/*

using PEAR xtea

*/
require_once 'xtea/Xtea.php';
$crypt = new Crypt_Xtea();
$encrypted = $crypt->encrypt($data, $key);
$decrypted = $crypt->decrypt($encrypted, $key);

/*

using mcrypt

*/
$td = mcrypt_module_open('xtea', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $key, $iv);
$encrypted_data = mcrypt_generic($td, $data);
$decrypted_data = mdecrypt_generic($td, $encrypted_data);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
echo "Using PEAR Xtea: ", bin2hex($encrypted), " - $decrypted<br />";
echo "Using mcrypt: ", bin2hex($encrypted_data), " - $decrypted_data";
?>


the result is:

Using PEAR Xtea: 03e3fc60351a3fdd - test
Using mcrypt: 6c302719dd265d3f - test����

in LSL i have with the word "test":

6 cicles: 90DFC14A3D1DA76C
8 cicles: 080D978FEB8F47AB
16: FB4CFF68CF2A4630
32: 509EC619BA00C6EE
64: 0872BC1C4A41ED70
128: E9FAFE702703D73F

i'm using the Morse Dillon's version on the wiki...
Newgate Ludd
Out of Chesse Error
Join date: 8 Apr 2005
Posts: 2,103
04-18-2007 00:10
Whats interesting is that the PEAR and MCrypt implementations give different results for resumably the same Key? that would suggest that they are using a different number of cycles or slightly different implementations. I have read that the operator precedence rules of some languages may lead to different results but i dont know PHP so cannot comment.

That the LSL version gives totally different results points to a similar problem, although it doesnt rule out that my decoding of the key insn't totally off. Big endian / little endian ordering (i.e. Byte swapping) may be playing an issue since although a character string should always be in string order the LSL implementation is using 4 byte integers which will (possibly) be byte swapped.

Try the following

integer KEY1 = 0x33323130;
integer KEY2 = 0x37363534;
integer KEY3 = 0x62639138;
integer KEY4 = 0x66656463;
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
04-18-2007 00:33
From: Newgate Ludd
Whats interesting is that the PEAR and MCrypt implementations give different results for resumably the same Key? that would suggest that they are using a different number of cycles or slightly different implementations. I have read that the operator precedence rules of some languages may lead to different results but i dont know PHP so cannot comment.

That the LSL version gives totally different results points to a similar problem, although it doesnt rule out that my decoding of the key insn't totally off. Big endian / little endian ordering (i.e. Byte swapping) may be playing an issue since although a character string should always be in string order the LSL implementation is using 4 byte integers which will (possibly) be byte swapped.

Try the following

integer KEY1 = 0x33323130;
integer KEY2 = 0x37363534;
integer KEY3 = 0x62639138;
integer KEY4 = 0x66656463;


I guess I need to re-read this entire thread now, cause that prompted a memory (I think so, at least) of someone saying something about LSL not having unsigned integers and having to do a workaround. If that is the case, it's probably not worth the effort to pursue in my case, since XTEA is really overkill for what I needed anyways.

Btw: The Pear class uses 32 cycles by default, and doesn't seem to work right with other values.
_____________________
1 2 3 4