78 lines
2.3 KiB
Plaintext
78 lines
2.3 KiB
Plaintext
--
|
|
-- demo\rosetta\md4.exw
|
|
-- ====================
|
|
--
|
|
function r32(atom a)
|
|
if a<0 then a+=#100000000 end if
|
|
return remainder(a,#100000000)
|
|
end function
|
|
|
|
function rol(atom word, integer bits)
|
|
-- left rotate the bits of a 32-bit number by the specified number of bits
|
|
word = r32(word) -- trim to a 32-bit uint again
|
|
return r32(word*power(2,bits))+floor(word/power(2,32-bits))
|
|
end function
|
|
|
|
function f(atom x,y,z)
|
|
return or_bits(and_bits(x,y),and_bits(not_bits(x),z))
|
|
end function
|
|
|
|
function g(atom x,y,z)
|
|
return or_all({r32(and_bits(x,y)),and_bits(x,z),and_bits(y,z)})
|
|
end function
|
|
|
|
function h(atom x,y,z)
|
|
return xor_bits(r32(xor_bits(x,y)),z)
|
|
end function
|
|
|
|
function md4(sequence data)
|
|
integer bytes_to_add = 64-remainder(length(data)+9,64)
|
|
if bytes_to_add=64 then bytes_to_add = 0 end if
|
|
data = dataP&repeat(0,bytes_to_add)&
|
|
int_to_bytes(length(data)*8,8)
|
|
|
|
atom a = 0x67452301, b = 0xefcdab89, c = 0x98badcfe, d = 0x10325476
|
|
|
|
atom m64 = allocate(64,true)
|
|
integer i
|
|
for x=1 to length(data)-1 by 64 do
|
|
poke(m64,data[x..x+63])
|
|
sequence z = peek4u({m64,16})
|
|
atom a2 = a, b2 = b, c2 = c, d2 = d
|
|
for i=0 to 12 by 4 do
|
|
a = rol(a + f(b, c, d) + z[i+1], 3)
|
|
d = rol(d + f(a, b, c) + z[i+2], 7)
|
|
c = rol(c + f(d, a, b) + z[i+3], 11)
|
|
b = rol(b + f(c, d, a) + z[i+4], 19)
|
|
end for
|
|
for i=1 to 4 do
|
|
a = rol(a + g(b, c, d) + z[i+0] + 0x5a827999, 3)
|
|
d = rol(d + g(a, b, c) + z[i+4] + 0x5a827999, 5)
|
|
c = rol(c + g(d, a, b) + z[i+8] + 0x5a827999, 9)
|
|
b = rol(b + g(c, d, a) + z[i+12] + 0x5a827999, 13)
|
|
end for
|
|
for j=1 to 4 do
|
|
i = {1, 3, 2, 4}[j]
|
|
a = rol(a + h(b, c, d) + z[i+0] + 0x6ed9eba1, 3)
|
|
d = rol(d + h(a, b, c) + z[i+8] + 0x6ed9eba1, 9)
|
|
c = rol(c + h(d, a, b) + z[i+4] + 0x6ed9eba1, 11)
|
|
b = rol(b + h(c, d, a) + z[i+12] + 0x6ed9eba1, 15)
|
|
end for
|
|
a = r32(a+a2)
|
|
b = r32(b+b2)
|
|
c = r32(c+c2)
|
|
d = r32(d+d2)
|
|
end for
|
|
poke4(m64,{a,b,c,d})
|
|
return peek({m64,16})
|
|
end function
|
|
|
|
function hexify(sequence s)
|
|
for i=1 to length(s) do
|
|
s[i] = sprintf("%02X",s[i])
|
|
end for
|
|
return join(s,"")
|
|
end function
|
|
|
|
?hexify(md4("Rosetta Code"))
|