Skip to content

Instantly share code, notes, and snippets.

@gistya
Created May 26, 2013 19:24
Show Gist options
  • Save gistya/5653753 to your computer and use it in GitHub Desktop.
Save gistya/5653753 to your computer and use it in GitHub Desktop.
Gistya Eusebio's peed-optimized version of Pedro Oval's Base64 HMAC-SHA1 algorithm for Second Life LSL.
list comp;
string K; //GET FROM NOTECARD OR SET HERE
string K64;
string hexc="0123456789ABCDEF";
//THE BELOW HASHING ROUTINES ARE BY PEDRO OVAL WITH OPTIMIZATIONS BY GISTYA EUSEBIO (MAY 2013)
string hx264u(string a) {
integer i = 0; integer len = llStringLength(a += "0000") - 4; string res = "";
while (i < len) {
res += llGetSubString(llIntegerToBase64(4*(integer)("0x" + llGetSubString(a, i, i+5))), 1, 4);
i += 6; }
return llGetSubString(res, 0, len*2/3);
}
string unpad(string b64) {
integer i; do ; while(llGetSubString(b64, i = ~-i, i) == "=");
return llGetSubString(b64, 0, i);
}
list b6hm4comp(string b64, integer H1, integer H2, integer H3, integer H4, integer H5, integer i) {
integer A = H1; integer B = H2; integer C = H3; integer D = H4;
integer E = H5; integer round; integer S = 0; integer T; list x = []; string buf;
do { T = llBase64ToInteger(buf = llGetSubString(b64, T = ((i + round) << 4) / 3, T+6)) << (S = ((i + round) % 3) << 1);
if(S) T = T | (llBase64ToInteger("A" + (llDeleteSubString(buf, 0, 1))) >> (6 - S));
x += T; T += ((A << 5) | ((A >> 27) & 0x1F)) + (D ^ (B & (C ^ D))) + E + 0x5a827999;
E = D; D = C; C = ((B << 30) | ((B >> 2) & 0x3FFFFFFF)); B = A; A = T;
}while(16 > (round = -~round));
do { S = llList2Integer(x, -3) ^ llList2Integer(x, -8) ^ llList2Integer(x, -14) ^ llList2Integer(x, -16);
x = llList2List(x + (T = ((S << 1) | !!(S & v8))), -16, -1);
T += ((A << 5) | ((A >> 27) & 0x1F)) + (D ^ (B & (C ^ D))) + E + 0x5a827999;
E = D; D = C; C = ((B << 30) | ((B >> 2) & 0x3FFFFFFF)); B = A; A = T;
}while(20 > (round = -~round));
do { S = llList2Integer(x, -3) ^ llList2Integer(x, -8) ^ llList2Integer(x, -14) ^ llList2Integer(x, -16);
x = llList2List(x + (T = ((S << 1) | !!(S & v8))), -16, -1);
T += ((A << 5) | ((A >> 27) & 0x1F)) + (B ^ C ^ D) + E + 0x6ed9eba1;
E = D; D = C; C = ((B << 30) | ((B >> 2) & 0x3FFFFFFF)); B = A; A = T;
}while(40 > (round = -~round));
do { S = llList2Integer(x, -3) ^ llList2Integer(x, -8) ^ llList2Integer(x, -14) ^ llList2Integer(x, -16);
x = llList2List(x + (T = ((S << 1) | !!(S & v8))), -16, -1);
T += ((A << 5) | ((A >> 27) & 0x1F)) + ((B & C) | (B & D) | (C & D)) + E + 0x8f1bbcdc;
E = D; D = C; C = ((B << 30) | ((B >> 2) & 0x3FFFFFFF)); B = A; A = T;
}while(60 > (round = -~round));
do { S = llList2Integer(x, -3) ^ llList2Integer(x, -8) ^ llList2Integer(x, -14) ^ llList2Integer(x, -16);
x = llList2List(x + (T = ((S << 1) | !!(S & v8))), -16, -1);
T += ((A << 5) | ((A >> 27) & 0x1F)) + (B ^ C ^ D) + E + 0xca62c1d6;
E = D; D = C; C = ((B << 30) | ((B >> 2) & 0x3FFFFFFF)); B = A; A = T;
}while(80 > (round = -~round)); return [H1+A, H2+B, H3+C, H4+D, H5+E];
}
string b6hm4c(string b64, integer bit_length, integer extra_bit_length, integer H1, integer H2, integer H3, integer H4, integer H5) {
integer b = ((bit_length + 40) >> 5) | 15;
integer T = llBase64ToInteger(unpad(llGetSubString(b64, -4, -1)) + "AAAA");
string buf = "AAA";
integer i = -5;
do buf += buf; while((i = -~i));
if(bit_length) {
i = 0x800000;
if(!(bit_length % 24)) i = 0x80;
else if((bit_length % 24) == 16) i = 0x8000;
}
else T = v8;
bit_length += extra_bit_length;
b64 = llGetSubString( llDeleteSubString(b64, -4, -1) +
llGetSubString(llIntegerToBase64(T | i), 0, 5) +
buf, 0, (b << 4) / 3) + llIntegerToBase64(bit_length << (6 - ((b % 3) << 1)));
list x; i = 0;
do {x = b6hm4comp(b64, H1, H2, H3, H4, H5, i);
H1 = llList2Integer(x, 0);
H2 = llList2Integer(x, 1);
H3 = llList2Integer(x, 2);
H4 = llList2Integer(x, 3);
H5 = llList2Integer(x, 4);
}while(b > (i += 16));
x = [H1, H2, H3, H4, H5];
i = -5;
buf = "";
do {T = llList2Integer(x,i);
bit_length = 32;
do buf += llGetSubString(hexc, b = ((T >> (bit_length -= 4)) & 0xF), b);
while (bit_length);
}while ((i = -~i));
return buf;
}
string hm64c(string B64Data) {
integer bit_length = (6 * !(B64Data=="") * (llStringLength(B64Data)-4+llStringLength(unpad(llGetSubString(B64Data,-4,-1))))) & -8;
B64Data = hx264u(b6hm4c(B64Data, bit_length, 512, llList2Integer(comp, 0), llList2Integer(comp, 1), llList2Integer(comp, 2), llList2Integer(comp, 3), llList2Integer(comp, 4))) + "=";
string K64o = llXorBase64StringsCorrect(K64, "ampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqampqag==");
list comp2 = b6hm4comp(K64o, 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0, 0);
bit_length = 160;
return b6hm4c(B64Data, bit_length, 512, llList2Integer(comp2, 0), llList2Integer(comp2, 1), llList2Integer(comp2, 2), llList2Integer(comp2, 3), llList2Integer(comp2, 4));
}
//GISTYA EUSEBIO MOVED THE CODE IN init_pads() FROM hm64c() FOR GLOBAL INITIALIZATION TO SPEED UP THE HASHING
//AS PER INSTRUCTIONS IN RFC 2104, P. 3, S. 4 (Krawczyk, et. al. 1997, http://tools.ietf.org/html/rfc2104)
init_pads() { //CALL THIS FUNCTION IN STATE_ENTRY OR ANYTIME THE KEY IS MODIFIED
K64 = llStringToBase64(K);
integer bit_length = llSubStringIndex(K64, "=");
if (!~bit_length) {
bit_length = llStringLength(K64);
}
if (bit_length > 86) {
// Use a hash of the key instead as a key
K64 = hx264u(b6hm4c(K64, (bit_length*6)&-8, 0, 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0));
bit_length = 27;
}
K64 = llGetSubString(K64, 0, bit_length-1);
string buf = "AAA";
integer i = -5;
do buf += buf; while((i = -~i));
K64 = llXorBase64StringsCorrect(llGetSubString(K64 + buf, 0, 85) + "==", "NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2Ng==");
comp = b6hm4comp(K64, 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0, 0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment