XTEA

From Second Life Wiki
Revision as of 01:08, 7 December 2007 by Strife Onizuka (talk | contribs) (New page: Another XTEA implementation for LSL. Not sure if i have used the correct endian. <lsl>//===================================================// // XTEA Library ...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Another XTEA implementation for LSL. Not sure if i have used the correct endian.

<lsl>//===================================================// // XTEA Library // // "Dec 7 2007", "03:00:09" // // Copyright (C) 2004-2007, Strife Onizuka (cc-by) // // http://creativecommons.org/licenses/by/3.0/ // //===================================================//

//===================================================// // Combined Library // // "Dec 7 2007", "03:00:09" // // Copyright (C) 2004-2007, Strife Onizuka (cc-by) // // http://creativecommons.org/licenses/by/3.0/ // //===================================================// //{

//Functions marked "Mono Safe" are safe for use in LSLEditor & Mono //Functions marked "LSO Safe" are safe for use in LSO //Functions marked "Double Safe" are safe for use in VM's that support doubles (Mono, LSLEditor). //Mono is the future VM for LSL, LSO is the current VM of LSL. //To achieve safety, the functions require more bytecode and sacrifice a bit of performance.

string TrimRight(string src, string chrs)//Mono Safe, LSO Safe {

   integer i = llStringLength(src);
   integer j = i;
   do ; while(~llSubStringIndex(chrs, llGetSubString(src, i = (~-(j = i)), i)) && j);
   return llDeleteSubString(src, j, 0xFFFF);

}

//} Combined Library

integer ReadBase64Integer(string data, integer index) {

   integer S = (index % 3) << 1;
   index = llBase64ToInteger(llGetSubString((data = llGetSubString(data, index = ((index << 4) / 3), index+6)) + "AAAAAA", 0, 5)) << S;
   if(S)
       return index | (llBase64ToInteger(llGetSubString("A" + (llDeleteSubString(data, 0, 1)) + "AAAAA", 0, 5)) >> (6 - S));
   return index;

}

string WriteBase64IntegerPair(string data, integer index, integer low, integer high) {

   integer S = ((index % 3) << 1);
   return  llDeleteSubString(
               llInsertString(
                   data,
                   index = ((index << 4) / 3),
                   llInsertString(
                       llInsertString(
                           llIntegerToBase64(
                               (llBase64ToInteger(llGetSubString((data = llGetSubString(data, index, index + 12)) + "AAAAAA", 0, 5)) & (0xFC000000 << (6 - S))) | 
                               ((low >> S) & ~(0xFC000000 << (6 - S)))
                           ),
                           3,
                           llIntegerToBase64(
                               ((high >> (S + 14)) & ~(-1 << (18 - S))) | 
                               (low << (18 - S))
                           )
                       ),
                       7,
                       llIntegerToBase64(
                           (llBase64ToInteger(llGetSubString((llDeleteSubString(data, 0, 6)) + "AAAAAA", 0, 5)) & ~(-1 << (10 - S))) | 
                           (high << (10 - S))
                       )
                   )
               ),
               index + 12,
               index + 35
           );

}

integer delta = 0x9E3779B9;

string Base64_XTEA_Encipher(integer num_rounds, string v, list k) {

   integer len = llStringLength(v = TrimRight(v,"A="));
   integer i = 0;
   for(len = (3 * (len + 4)) >> 4; i < len; i += 2)
   {
       integer sum = 0;
       integer v0  = ReadBase64Integer(v, i);
       integer v1  = ReadBase64Integer(v, (-~(i)));
       integer j = (-~(num_rounds));
       while((j = ~-j)){
           v0 += (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(k, sum & 3));
           sum += delta;
           v1 += (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(k, (sum >> 11) & 3));
       }
       v = WriteBase64IntegerPair(v, i, v0, v1);
   }
   return TrimRight(v,"A");

}

string Base64_XTEA_Decipher(integer num_rounds, string v, list k) {

   integer len = llStringLength(v = TrimRight(v,"A="));
   integer i = 0;
   for(len = (3 * (len + 4)) >> 4; i < len; i += 2)
   {
       integer sum = delta * num_rounds;
       integer v0  = ReadBase64Integer(v, i);
       integer v1  = ReadBase64Integer(v, (-~(i)));
       integer j = (-~(num_rounds));
       while((j = ~-j)){
           v1 -= (((v0 << 4) ^ ((v0 >> 5) & 0x07FFFFFF)) + v0) ^ (sum + llList2Integer(k, (sum >> 11) & 3));
           sum -= delta;
           v0 -= (((v1 << 4) ^ ((v1 >> 5) & 0x07FFFFFF)) + v1) ^ (sum + llList2Integer(k, sum & 3));
       }
       v = WriteBase64IntegerPair(v, i, v0, v1);
   }
   return TrimRight(v,"A");

}

list mk; integer rounds = 128;

default {

   state_entry()
   {
       key owner = llGetOwner();
       llListen(0, "", owner, "");
       llListen(1, "", owner, "");
       llListen(2, "", owner, "");
       llListen(3, "", owner, "");
   }
   listen(integer a, string b, key c, string d)
   {
       if(a == 1)
       {
           mk = [];
           list e = llCSV2List(d);
           for(a = 0; a < 3; ++a)
               mk += (integer)llList2String(e,a);
           llOwnerSay(llList2CSV(mk));
       }
       else if(a == 2)
       {
           rounds = (integer)d;
       }
       else if(a == 3)
       {
           b = TrimRight(llStringToBase64(d), "=");
           mk = [ReadBase64Integer(b, 0), ReadBase64Integer(b, 1), ReadBase64Integer(b, 2), ReadBase64Integer(b, 3)];
           llOwnerSay(llList2CSV(mk));
       }
       else
       {


           llOwnerSay(b = d = llStringToBase64(d));
           llOwnerSay(d = Base64_XTEA_Encipher(rounds, b, mk));
           llOwnerSay(llList2CSV([d = Base64_XTEA_Decipher(rounds, d, mk), llBase64ToString(d)]));
           llOwnerSay(llList2CSV([b,llBase64ToString(b)]));
       }
   }

}</lsl>