Difference between revisions of "User:Kireji Haiku/SIMchat headset"

From Second Life Wiki
Jump to navigation Jump to search
m (saving some script memory, causing less lag and made minor speed-improvements)
Line 27: Line 27:
==Script:==
==Script:==
<lsl>
<lsl>
string ProtocolSignature = "ENC";//your signature
key ownerKey;
float  ProtocolVersion = 0.3; // can range from 0.0 to 255.255
string ownerName;
string  Password = "P@ssw0rd";//your password
 
integer communicationsChannel = 9;//the channel you use for communication
integer KEY1 = 11111111;
string  strHex = "0123456789ABCDEF";//hex-password
integer KEY2 = 22222222;
integer KEY3 = 33333333;
integer KEY4 = 44444444;
 
//##############################################################################
integer COMM_CHANNEL = 9;
//do not change anything below if you are not 100% sure about what you are doing
 
//##############################################################################
integer CYCLES = 6;
 
list cypherkey = [];
string  Header;
integer delta = 0x9E3779B9;
integer Debug = TRUE;
 
integer listener;
integer ord(string chr)
string error(string message)
{
{
     if(Debug) llSay(DEBUG_CHANNEL, message);
    string ASCII = "            \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
     return "";
 
     if(llStringLength(chr) != 1)
        return -1;
 
    if(chr == " ")
        return 32;
 
     return llSubStringIndex(ASCII, chr);
}
}
 
string decrypt(string password, string message)
string chr(integer i)
{
{
    integer signatureLength = llStringLength(ProtocolSignature);
     string ASCII = "             \n                    !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
    integer headerLength = signatureLength + 12;
     i %= 127;
    if(llStringLength(message) < signatureLength + 44)
 
        return error("Too small for secret message.");
     return llGetSubString(ASCII, i, i);
    if(llSubStringIndex(message, ProtocolSignature) != 0)
        return error("Unknown protocol.");
    integer index = signatureLength;
     string major = "0x" + llGetSubString(message, index, ++index);
    string minor = "0x" + llGetSubString(message, ++index, ++index);
    float version = (float)((string)((integer)major) + "." + (string)((integer)minor));
    if(version != ProtocolVersion)
        return error("Unknown version.");
    integer nonce = (integer)("0x" + llGetSubString(message, ++index, index + 7));
    message = llGetSubString(message, headerLength, -1);
    string oneTimePad = llMD5String(password, nonce);
    while(llStringLength(oneTimePad) < (llStringLength(message) / 2 * 3))
        oneTimePad += llMD5String(oneTimePad, nonce);
     oneTimePad = llStringToBase64(oneTimePad);
    message = llXorBase64StringsCorrect(message, oneTimePad);
     message = llBase64ToString(message);
    string digest = llGetSubString(message, 0, 31);
    message = llGetSubString(message, 32, -1);
    if(llMD5String(message, nonce) != digest)
        return error("Message digest was not valid.");
    return message;
}
}
 
string hex(integer value)
string DWord2Hex(integer m)
{
{
     integer digit = value & 0xF;
     string result;
     string text = llGetSubString(strHex, digit, digit);
     integer i = 0;
     value = (value >> 4) & 0xfffFFFF;
     integer index = 0;
     integer odd = TRUE;
 
     while(value)
     string characters = "0123456789ABCDEF";  
 
     for (i = 0; i < 8; i++)
     {
     {
         digit = value & 0xF;
         index  = (m >> (i * 4)) & 0xF;
         text = llGetSubString(strHex, digit, digit) + text;
         result = llInsertString(result, 0, llGetSubString(characters,index,index));
        odd = !odd;
        value = value >> 4;
     }
     }
    if(odd)
 
        text = "0" + text;
     return result;
     return text;
}
}
 
string encrypt(string password, string message)
integer Hex2DWord(string m)
{
{
     integer nonce = (integer)llFrand(0x7FFFFFFF);
     integer result = 0;
    message = llMD5String(message, nonce) + message;
    integer i = 0;
    string oneTimePad = llMD5String(password, nonce);
    string digit;
     integer count = (llStringLength(message) - 1) / 32;
    integer value;
    if(count)
    integer index;
         do
 
             oneTimePad += llMD5String(oneTimePad, nonce);
    string characters = "0123456789ABCDEF";
    while(--count);
 
    return Header + llGetSubString("00000000" + hex(nonce), -8, -1) + llXorBase64StringsCorrect(llStringToBase64(message), llStringToBase64(oneTimePad));
    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;
}
 
string Encrypt(string cleartext)
{
        integer dword1 = 0;
        integer dword2 = 0;
        integer cyphertext_numeric;
        list cypherblock;
        string cyphertext = "";
 
        while(llStringLength(cleartext) & 0x7)
            cleartext += " ";
 
        integer stringlength = llStringLength(cleartext);  
        integer i=0;
        integer character;
 
        while (i < stringlength)
         {
            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++;
 
            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++;
 
            cypherblock = TEAEncrypt(dword1,dword2,cypherkey);
 
            cyphertext = cyphertext + DWord2Hex(llList2Integer(cypherblock,0)) + DWord2Hex(llList2Integer(cypherblock,1));
 
            dword1 = 0;
            dword2 = 0;
            cypherblock = [];
        }
 
        return cyphertext;       
 
string Decrypt(string cyphertext)
{
        string hexvalue1 = "";
        string hexvalue2 = "";
        integer dword1 = 0;
        integer dword2 = 0;
        list clearblock = [];
        string cleartext = "";
        integer i;
 
        while (i < llStringLength(cyphertext))
        {
            hexvalue1 += llGetSubString(cyphertext,i,i + 7);
            i = i + 8;
 
            hexvalue2 += llGetSubString(cyphertext,i,i + 7);
            i = i + 8;
 
            dword1 = Hex2DWord(hexvalue1);
            dword2 = Hex2DWord(hexvalue2);
 
            clearblock = TEADecrypt(dword1, dword2, cypherkey);
 
            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);
 
            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);
 
            hexvalue1 = "";
            hexvalue2 = "";
            dword1 = 0;
            dword2 = 0;
            clearblock = [];
        }
 
        return cleartext;      
}
}
 
init1()
list TEAEncrypt(integer dword1, integer dword2,list cypherkey)
{
{
    list versions = llParseString2List((string)ProtocolVersion, ["."], []);
            list cryptlist = [];
    string minor = llList2String(versions, 1);
 
    integer p = 0;
            integer n = CYCLES;
    while(llGetSubString(minor, --p, p) == "0");
 
    Header = ProtocolSignature + hex(llList2Integer(versions, 0)) + hex((integer)llGetSubString(minor, 0xFF000000, p));
            integer sum = 0;
 
            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;
}
}
 
init2()
list TEADecrypt(integer dword1, integer dword2,list cypherkey)
{
{
    if(listener != 0)
            list cryptlist = [];
    {
 
        llListenRemove(listener);
            integer n = CYCLES;
        listener = 0;
 
    }
            integer sum = delta * CYCLES;
    listener = llListen(communicationsChannel, "", NULL_KEY, "");
 
            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;
}
}
 
default
default
{
{
    state_entry()
    {
        init1();
        init2();
        llOwnerSay("\n \n \n \nInitialisation complete!\nSIMchat online!\nType /" + (string)communicationsChannel + " and then your message to talk to people that have their channel set to the same.");
        llSetLinkPrimitiveParamsFast(LINK_THIS,[
        PRIM_NAME,"SIMchat(" + llKey2Name(llGetOwner()) + ")",
        PRIM_DESC,"Last reset was: " + llGetTimestamp()]);
    }
     on_rez(integer start_param)
     on_rez(integer start_param)
     {
     {
         llResetScript();
         if (llGetOwner() != ownerKey)
        {
            llReleaseControls();
            llResetScript();
        }
     }
     }
 
     attach(key id)
     changed(integer change)
     {
     {
         if (id)
         if (change & CHANGED_OWNER)
         {
         {
             llOwnerSay("Resetting scripts...");
             llReleaseControls();
             llResetScript();
             llResetScript();
         }
         }
     }
     }
 
    state_entry()
    {
        ownerKey = llGetOwner();
        ownerName = llKey2Name(ownerKey);
        cypherkey = [KEY1,KEY2,KEY3,KEY4];
 
        llSetLinkPrimitiveParamsFast(LINK_THIS, [
            PRIM_NAME, ownerName,
            PRIM_DESC, "Last reset: " + llGetTimestamp()]);
 
        llRequestPermissions(ownerKey, PERMISSION_TAKE_CONTROLS);
        llListen(COMM_CHANNEL, "", NULL_KEY, "");
    }
 
     listen(integer channel, string name, key id, string message)
     listen(integer channel, string name, key id, string message)
     {
     {
         if (channel == communicationsChannel)
         if (channel != COMM_CHANNEL)
            return;
 
        if (id == ownerKey)
        {
            llRegionSay(COMM_CHANNEL, Encrypt(message));
            llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_NAME, ""]);
            llOwnerSay("/me [" + ownerName + "]: '" + message + "'");
            llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_NAME, ownerName]);
        }
        else if (llGetAgentSize(id) == ZERO_VECTOR)
         {
         {
             if (id == llGetOwner())
             message = Decrypt(message);
             {
             llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_NAME, ""]);
                llRegionSay(communicationsChannel, encrypt(Password, message));
            llOwnerSay("/me [" + name + "]: '" + message + "'");
                llOwnerSay("You said: " + message);
             llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_NAME, ownerName]);
            }
            if (llGetAgentSize(id) == ZERO_VECTOR)
            {
                string message = decrypt(Password, message);
                llOwnerSay((string)name + " said: " + (string)message);
             }
         }
         }
    }
    run_time_permissions(integer perm)
    {
        if (perm & PERMISSION_TAKE_CONTROLS)
            llTakeControls(CONTROL_DOWN, TRUE, TRUE);
    }
    control(key id, integer level, integer edge)
    {
        ;
     }
     }
}
}

Revision as of 05:39, 20 December 2011

Check out all my other projects!


SIMchat headset

General information:

This script is being provided "as is". It's been thoroughly tested in May 2010.

If you want to use it, you should drop it into a childprim of a linkset. This setup will give you the possibilty to forward your chat on a certain channel within the whole region your are in and encrypt it. Just make sure anybody you want to talk to has the same variables as you do.


This is what it could look like. There's no particle system in the script, I just added it to see better in the picture.
Yellow marker shows the main prim, red marker shows the invisible childprim containing the script.


Go to top!

Script:

<lsl> key ownerKey; string ownerName;

integer KEY1 = 11111111; integer KEY2 = 22222222; integer KEY3 = 33333333; integer KEY4 = 44444444;

integer COMM_CHANNEL = 9;

integer CYCLES = 6;

list cypherkey = []; integer delta = 0x9E3779B9;

integer ord(string chr) {

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

}

string chr(integer i) {

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

}

string DWord2Hex(integer m) {

   string result;
   integer i = 0;
   integer index = 0;
   string characters = "0123456789ABCDEF";   
   for (i = 0; i < 8; i++)
   {
       index  = (m >> (i * 4)) & 0xF;
       result = llInsertString(result, 0, llGetSubString(characters,index,index));
   }
   return result;

}

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;

}

string Encrypt(string cleartext) {

       integer dword1 = 0;
       integer dword2 = 0;
       integer cyphertext_numeric;
       list cypherblock;
       string cyphertext = "";
       while(llStringLength(cleartext) & 0x7)
           cleartext += " ";
       integer stringlength = llStringLength(cleartext); 
       integer i=0;
       integer character;
       while (i < stringlength)
       {
           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++;
           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++;
           cypherblock = TEAEncrypt(dword1,dword2,cypherkey);
           cyphertext = cyphertext + DWord2Hex(llList2Integer(cypherblock,0)) + DWord2Hex(llList2Integer(cypherblock,1));
           dword1 = 0;
           dword2 = 0;
           cypherblock = [];
        }
       return cyphertext;        

}

string Decrypt(string cyphertext) {

       string hexvalue1 = "";
       string hexvalue2 = "";
       integer dword1 = 0;
       integer dword2 = 0;
       list clearblock = [];
       string cleartext = "";
       integer i;
       while (i < llStringLength(cyphertext))
       {
           hexvalue1 += llGetSubString(cyphertext,i,i + 7);
           i = i + 8;
           hexvalue2 += llGetSubString(cyphertext,i,i + 7);
           i = i + 8;
           dword1 = Hex2DWord(hexvalue1);
           dword2 = Hex2DWord(hexvalue2); 
           clearblock = TEADecrypt(dword1, dword2, cypherkey);
           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);
           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);
           hexvalue1 = "";
           hexvalue2 = "";
           dword1 = 0;
           dword2 = 0;
           clearblock = [];
        }
       return cleartext;        

}

list TEAEncrypt(integer dword1, integer dword2,list cypherkey) {

           list cryptlist = [];
           integer n = CYCLES;
           integer sum = 0;
           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;

}

list TEADecrypt(integer dword1, integer dword2,list cypherkey) {

           list cryptlist = [];
           integer n = CYCLES;
           integer sum = delta * 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;

}

default {

   on_rez(integer start_param)
   {
       if (llGetOwner() != ownerKey)
       {
           llReleaseControls();
           llResetScript();
       }
   }
   changed(integer change)
   {
       if (change & CHANGED_OWNER)
       {
           llReleaseControls();
           llResetScript();
       }
   }
   state_entry()
   {
       ownerKey = llGetOwner();
       ownerName = llKey2Name(ownerKey);
       cypherkey = [KEY1,KEY2,KEY3,KEY4];
       llSetLinkPrimitiveParamsFast(LINK_THIS, [
           PRIM_NAME, ownerName,
           PRIM_DESC, "Last reset: " + llGetTimestamp()]);
       llRequestPermissions(ownerKey, PERMISSION_TAKE_CONTROLS);
       llListen(COMM_CHANNEL, "", NULL_KEY, "");
   }
   listen(integer channel, string name, key id, string message)
   {
       if (channel != COMM_CHANNEL)
           return;
       if (id == ownerKey)
       {
           llRegionSay(COMM_CHANNEL, Encrypt(message));
           llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_NAME, ""]);
           llOwnerSay("/me [" + ownerName + "]: '" + message + "'");
           llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_NAME, ownerName]);
       }
       else if (llGetAgentSize(id) == ZERO_VECTOR)
       {
           message = Decrypt(message);
           llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_NAME, ""]);
           llOwnerSay("/me [" + name + "]: '" + message + "'");
           llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_NAME, ownerName]);
       }
   }
   run_time_permissions(integer perm)
   {
       if (perm & PERMISSION_TAKE_CONTROLS)
           llTakeControls(CONTROL_DOWN, TRUE, TRUE);
   }
   control(key id, integer level, integer edge)
   {
       ;
   }

} </lsl> Go to top!