Talk:SHA-1

From Second Life Wiki
Revision as of 13:24, 10 December 2010 by Pedro Oval (talk | contribs) (→‎Bug in UTF8_SHA1: Patch for working version)
Jump to navigation Jump to search

Xaviar Czervik's Code?

I - Xaviar Czervik - wrote code for this function and it is no longer here. The function was originally written by me but everything has been replaced. It is even now Copyright Strife Onizuka. I'm not against this - as I'm sure Strife is a better coder than I am - I'd just like to know what happened to my code... Xaviar Czervik 10:18, 22 October 2007 (PDT)

I wracked my brains about your code for a long while before doing it.did it for several reasons:
  • It's slow and uses a lot of memory, converting the entire string into a list isn't a good idea.
  • The original version could only handle ASCII-7 text.
  • A version using UTF8ToUnicodeInteger fail on any Unicode character greater then 0x7FFF (since you didn't do a complete implementation of UTF-16).
  • LSL doesn't use UTF-16, it uses UTF-8; its logical to have a UTF-8 implementation.
  • The license link (FDL) didn't match the license granted (GPL).
  • A GPLed hashing library isn't useful. Anything that depends upon it becomes infected by the GPL. You couldn't use it with products you gave away.
  • The GPL is not compatible with the wiki license and LL has said they will only honor the wiki license.
  • The LGPL is compatible with the wiki CC-BY license.
I wanted to keep your name on the code but that presented a license issue. You wrote it almost verbatim from the pseudo-code from Wikipedia, except for the integer-list code. By the time I had rewritten it, it had none of your hallmarks, and only shared bits in common with the Wikipedia articles pseudo-code. Speaking of which I should put that in the header. -- Strife Onizuka 19:13, 24 October 2007 (PDT)
Okay - that's fine with me, I noticed that yours was very different (not to mention much better). Although, I didn't look at the Wikipedia pseudo-code, I was looking at a Java version of the code and trying to get it to work in LSL ;P. Xaviar Czervik 15:27, 25 October 2007 (PDT)

Bug in UTF8_SHA1

UTF8_SHA1 won't process correctly strings containing non-ASCII characters. The problem is in this code: <lsl>

   integer j = llStringLength(plain) << 3;

</lsl> That sets j to the number of characters in the string, not to the number of UTF-8 bytes, causing the SHA-1 to be computed over a reduced string, not the complete one, when it contains non-ASCII chars. Not that important now that we have llSHA1String, though, but it would be nice to either fix it or remove UTF8_SHA1 completely. -- Pedro Oval 16:01, 7 December 2010 (UTC)

You are correct about there being a problem. Thanks for pointing it out. Upon review, all of my hashing functions are effected by this bug. You should be able to substitute the following code into all of them. I haven't tested it but it looks correct. Please let me know if it works or doesn't work.

<lsl>

   //OR on the extra bit.
   integer T = llBase64ToInteger(llGetSubString((TrimRight(llGetSubString(plain = llStringToBase64(plain), -4, -1),"=")) + "AAAAAAAA", 0, 7));
   string buf = "AAA";
   integer i = -5;
   do buf += buf; while((i = -~i));
   if(T)
   {
       if(T & 0xFF0000)
           i = 8;
       else if(T & 0xFF000000)
           i = 16;
       T = T | (0x80 << i);
   }
   else//nothing to append to
       T = 0x80000000;
   integer j = (llStringLength(plain) << 6) - i;// only accurate to the byte.
   integer b = (~-(((j + 552) & -512) >> 5));//I'm assuming this still works.

// llOwnerSay(llList2CSV([i,j]));

   plain = llGetSubString( llDeleteSubString(plain, -4, -1) + 
                           llGetSubString(llIntegerToBase64(T), 0, 5) + 

</lsl> -- Strife (talk|contribs) 19:33, 7 December 2010 (UTC)

That one didn't work for me. This patch does: <diff>--- 1.txt 2010-12-10 20:57:18.000000000 +0100

+++ 2.txt 2010-12-10 21:08:26.000000000 +0100 @@ -59,9 +59,15 @@

    integer H5 = 0xc3d2e1f0;
    //OR on the extra bit.

- integer j = llStringLength(plain) << 3; + plain = (plain = "") + llStringToBase64(plain); + integer j = llStringLength(plain); + if (j) + { + do ; while (llGetSubString(plain, --j, j) == "="); + j = (integer)((j=-~j) * 0.75) << 3; + }

    integer b = (~-(((j + 552) & -512) >> 5));

- integer T = llBase64ToInteger(llGetSubString((TrimRight(llGetSubString(plain = llStringToBase64(plain), -4, -1),"=")) + "AAAAAAAA", 0, 7)); + integer T = llBase64ToInteger(llGetSubString((TrimRight(llGetSubString(plain, -4, -1),"=")) + "AAAAAAAA", 0, 7));

    string buf = "AAA";
    integer i = -5;
    do buf += buf; while((i = -~i));

</diff> My tests were done with: <lsl> string s = "Étude¿º";

 string s1 = UTF8_SHA1(s);
 string s2 = llToUpper(llSHA1String(s));
 llOwnerSay("\n" + s1 + "\n" + s2 + "\n" + (string)(s1 == s2));</lsl> -- Pedro Oval 20:24, 10 December 2010 (UTC)