-- -- builtins\ripemd160.e -- ==================== -- function rol(atom v, integer n) -- Programming note: this use of #ilASM{} is more for expediency than efficiency #ilASM{ mov eax,[v] call :%pLoadMint mov ecx,[n] rol eax,cl lea edi,[v] call :%pStoreMint } return v end function constant K = {#00000000,#5A827999,#6ED9EBA1,#8F1BBCDC,#A953FD4E}, KK = {#50A28BE6,#5C4DD124,#6D703EF3,#7A6D76E9,#00000000}, r = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 }, rr = { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 }, s = {11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 }, ss = { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 } global function ripemd160(string message, bool asString=true, atom pMem=NULL) -- -- Calculate the ripe-md-160 checksum. -- -- if asString is true (the default), returns a string representation of the -- checksum (and pMem is ignored) -- if asString is false, returns pMem (for want of anything better), which -- must be a non-NULL pointer to at least 20 bytes of memory. -- atom h0 = #67452301, h1 = #EFCDAB89, h2 = #98BADCFE, h3 = #10325476, h4 = #C3D2E1F0, mraw, t, tt integer l = length(message), padding = 64 - mod(l+1,64) if padding<8 then padding += 64 end if message &= #80 & repeat('\0',padding-8) & int_to_bytes(l*8,8) #ilASM{ mov eax,[message] lea edi,[mraw] shl eax,2 -- ref -> raw address call :%pStoreMint } for i=0 to length(message)-64 by 64 do atom {a, b, c, d, e} = {h0, h1, h2, h3, h4} atom {aa, bb, cc, dd, ee} = {h0, h1, h2, h3, h4} for j = 1 to 80 do integer k = floor((j-1)/16) switch k case 0: t = xor_bits(xor_bits(b, c), d) tt = xor_bits(bb,or_bits(cc,not_bits(dd))) case 1: t = or_bits(and_bits(b,c),and_bits(not_bits(b),d)) tt = or_bits(and_bits(bb,dd),and_bits(cc,not_bits(dd))) case 2: t = xor_bits(or_bits(b,not_bits(c)),d) tt = xor_bits(or_bits(bb,not_bits(cc)),dd) case 3: t = or_bits(and_bits(b,d),and_bits(c,not_bits(d))) tt = or_bits(and_bits(bb,cc),and_bits(not_bits(bb),dd)) case 4: t = xor_bits(b,or_bits(c,not_bits(d))) tt = xor_bits(xor_bits(bb, cc), dd) end switch t = rol( a + t + peek4u(mraw+i+ r[j]*4) + K[k+1], s[j]) + e tt = rol(aa + tt + peek4u(mraw+i+rr[j]*4) + KK[k+1], ss[j]) + ee {a, e, d, c, b } = {e, d, rol(c, 10), b, t } {aa,ee,dd,cc,bb} = {ee,dd,rol(cc, 10),bb,tt} end for {h0, h1, h2, h3, h4} = {h1+c+dd, h2+d+ee, h3+e+aa, h4+a+bb, h0+b+cc} end for if not asString then if pMem=NULL then ?9/0 end if poke4(pMem,{h0,h1,h2,h3,h4}) return pMem end if atom mem = allocate(20,true) poke4(mem,{h0,h1,h2,h3,h4}) string res = "" for i=1 to 20 do res &= sprintf("%02X",peek(mem+i-1)) end for return res end function