SHA-1

From Second Life Wiki
Revision as of 18:52, 18 October 2007 by Xaviar Czervik (talk | contribs) (Added to Library and Examples)
Jump to navigation Jump to search

(http://www.gnu.org/copyleft/fdl.html) in the spirit of which this script is GPL'd. Copyright (C) 2007 Xaviar Czervik

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.

Preforms a SHA1 Hash on the text. Similar to and MD5 hash, although (slightly) more secure.

View http://en.wikipedia.org/wiki/SHA1 for more information.

integer ascii(string chr) {
    string ASCIII = "               \n                 !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz";
    if(chr == " ") return 32;
    return llSubStringIndex(ASCIII, chr);
}
integer shiftright(integer number, integer ammount) {
    if (number >= 0) return number >> ammount;
    return (number & 0x7FFFFFFF) >> ammount | 1 << (31 - ammount);
}

integer rol(integer number, integer ammount) {
    return (number << ammount) | shiftright(number,(32 - ammount));
}

list replace(list l, integer p, integer v) {
    return llListReplaceList(l, [v], p, p);
}

string hash(string plain) {
    integer b   = llStringLength(plain) * 16;
    integer tb = ( b + 576 ) & -512;
    integer ml   = tb/32;
    list Message;
    integer i = 0;
    while (i < ml) {
        Message += 0;
        i++;
    }
    integer pos;
    for (pos = 0; pos < ml; pos++ ) {
        if ( pos*32 < b) {
            integer unicode = ascii(llGetSubString(plain, pos*2, pos*2));
            Message = replace(Message, pos, ( unicode << 16));
        }
        else if ( pos*32 == b)
            Message = replace(Message, pos, 0x80000000);
            
        if ((pos*32+16) < b) {
            integer unicode = ascii(llGetSubString(plain, pos*2+1, pos*2+1));
            Message = replace(Message, pos, llList2Integer(Message, pos) | ( unicode & 0xFFFF));
        }
        else if ((pos*32+16) == b) {
            Message = replace(Message, pos, llList2Integer(Message, pos) | 0x00008000);
        }
    }
    Message = replace(Message, ml-1, b);
    
    integer H1 = h1;
    integer H2 = h2;
    integer H3 = h3;
    integer H4 = h4;
    integer H5 = h5;
    integer intcount = llGetListLength(Message);
    list x;
    i = 0;
    while (i < 80) {
        x += 0;
        i++;
    }
    integer j = 0;
    integer block = 0;
    for (block = 0; block < intcount; block += 16) {
        for (j = 0; j < 16; j++)
            x = replace(x, j, llList2Integer(Message, block+j));
        for (j = 16; j < 80; j++)
            x = replace(x, j, rol(llList2Integer(x,j-3)^
                                  llList2Integer(x,j-8)^
                                  llList2Integer(x,j-14)^
                                  llList2Integer(x,j-16), 1));
        integer T;
        integer A = H1;
        integer B = H2;
        integer C = H3;
        integer D = H4;
        integer E = H5;
        for (j = 0; j < 80; j++) {
            T = rol(A,5) + part1(j,B,C,D) + E + llList2Integer(x, j) + part2(j);
            E = D; 
            D = C; 
            C = rol(B, 30); 
            B = A; 
            A = T;
        }
        H1 += A;
        H2 += B;
        H3 += C;
        H4 += D;
        H5 += E;
    }
    string result;
    result += (string)(H1); result += " ";
    result += (string)(H2); result += " ";
    result += (string)(H3); result += " ";
    result += (string)(H4); result += " ";
    result += (string)(H5);;
    return result;
    
}

integer h1 = 0x67452301;
integer h2 = 0xefcdab89;
integer h3 = 0x98badcfe;
integer h4 = 0x10325476;
integer h5 = 0xc3d2e1f0;

integer part1(integer t, integer b, integer c,integer d) {
    return (t<20)*((b & c) | ((~b) & d)) + (t>=20 && t < 40)*(b ^ c ^ d) + 
           (t>=40 && t < 60)*((b & c) | (b & d) | (c & d)) + (t>=60)*(b ^ c ^ d);
}


integer part2(integer t) {
    return (t<20)*0x5a827999 + (t>=20&&t<40)*0x6ed9eba1 + (t>=40&&t<60)*0x8f1bbcdc + (t>=60)*0xca62c1d6;
}


default {
    state_entry() {
        string msg = hash("The quick brown fox jumps over the lazy dog");
        llOwnerSay(msg);
    }
}