162 lines
6 KiB
Text
162 lines
6 KiB
Text
Module Checkit {
|
|
Function Prepare_RiPeMd_160 {
|
|
Dim Base 0, K(5), K1(5)
|
|
K(0)=0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E
|
|
K1(0)=0x50A28BE6,0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000
|
|
Dim Base 0,r(80), r1(80), s(80), s1(80)
|
|
r(0)=0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
|
r(16)=7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
|
|
r(32)= 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
|
|
r(48)=1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
|
|
r(64)=4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
|
|
k=r() : k*=4 ' k is a pointer to array. We have to multiply to make them offsets
|
|
|
|
r1(0)=5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
|
|
r1(16)=6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
|
|
r1(32)=15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
|
|
r1(48)=8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
|
|
r1(64)=12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
|
|
|
|
k=r1() : k*=4
|
|
|
|
s(0)=11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
|
|
s(16)=7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
|
|
s(32)=11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
|
|
s(48)=11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
|
|
s(64)=9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
|
|
|
|
s1(0)=8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
|
|
s1(16)=9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
|
|
s1(32)=9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
|
|
s1(48)=15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
|
|
s1(64)=8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
|
|
|
|
Dim Base 0, T(5), TT(5)
|
|
T(0)=lambda ->binary.xor(binary.xor(number,number),number)
|
|
T(1)=lambda (B,C,D)->binary.or(binary.and(B,C), binary.and(binary.not(B), D))
|
|
T(2)=lambda ->binary.xor(binary.or(number, binary.not(number)), number)
|
|
T(3)=lambda (B,C,D)->binary.or(binary.and(B,D), binary.and(C,binary.not(D)))
|
|
T(4)=lambda ->binary.xor(number, binary.or(number, binary.not(number)))
|
|
|
|
\\ no need for variables we read form stack with number
|
|
TT(0)=lambda ->binary.xor(number, binary.or(number, binary.not(number)))
|
|
TT(1)=lambda (BB,CC,DD)->binary.or(binary.and(BB,DD), binary.and(CC,binary.not(DD)))
|
|
TT(2)=lambda ->binary.xor(binary.or(number, binary.not(number)), number)
|
|
TT(3)=lambda (BB,CC,DD)->binary.or(binary.and(BB,CC), binary.and(binary.not(BB),DD))
|
|
TT(4)=lambda ->binary.xor(binary.xor(number,number),number)
|
|
|
|
\\ return of this function is a lambda function
|
|
\\ all arrays are closures to this lambda
|
|
=lambda K(),K1(),TT(), T(),r(),r1(), s(), s1() (&message$, ansi as boolean=true, ansiid=1033)-> {
|
|
set fast!
|
|
def h0 = 0x67452301, h1 = 0xEFCDAB89, h2 = 0x98BADCFE
|
|
def h3 = 0x10325476, h4 = 0xC3D2E1F0
|
|
def i, j, l, padding, l1, blocks, acc, f64 as boolean=true, oldid
|
|
if ansi then oldid=locale : locale ansiid
|
|
\\ we use a buffer of 64 bytes
|
|
buffer clear message as byte*64
|
|
l=len(message$)*if(ansi->1,2 )
|
|
if binary.and(l,63)>55 then padding=64
|
|
padding+= 64 - (l Mod 64)
|
|
l1=padding+l+1
|
|
|
|
f64=binary.and(l,63)<>0
|
|
|
|
blocks=l1 div 64
|
|
rem
|
|
Print "blocks:";blocks
|
|
\\ now prepare the buffer
|
|
PrepareBuffer()
|
|
def decimal A, B, C, D, E, AA, BB, CC, DD, EE, T, TT
|
|
do
|
|
A = h0 : B = h1 : C = h2 : D = h3 : E = h4
|
|
AA = h0 : BB = h1 : CC = h2 : DD = h3 : EE = h4
|
|
for J=0 to 79 {
|
|
JJ=J DIV 16
|
|
PUSH binary.add(Binary.Rotate(binary.add(A,T(JJ)(B,C,D),eval(message ,r(j) as long),k(jj)), s(j)), e)
|
|
A = E : E = D : D = Binary.Rotate(C, 10) : C = B : READ B
|
|
PUSH binary.add(Binary.Rotate(binary.add(AA,TT(JJ)(BB,CC,DD),eval(message, r1(j) as long),k1(jj)),s1(j)),EE)
|
|
AA = EE : EE = DD : DD = Binary.Rotate(CC, 10) : CC = BB : READ BB
|
|
}
|
|
push binary.add(h1, C, DD)
|
|
h1 = binary.add(h2, D, EE)
|
|
h2 = binary.add(h3, E, AA)
|
|
h3 = binary.add(h4, A, BB)
|
|
h4 = binary.add(h0, B, CC)
|
|
Read h0
|
|
blocks--
|
|
rem
|
|
print over $(0,8), blocks : Refresh
|
|
if blocks=0 then exit
|
|
PrepareBuffer()
|
|
always
|
|
rem
|
|
print
|
|
buffer ans as byte*20
|
|
\\ we put ulong (long is ulong in buffers)
|
|
Return ans, 0:=h0 as long, 4:=h1 as long,8:=h2 as long, 12:=h3 as long, 16:=h4 as long
|
|
=ans
|
|
if ansi then locale oldid
|
|
set fast
|
|
Sub PrepareBuffer()
|
|
|
|
if l-acc>=64 then
|
|
LoadPart(64)
|
|
else.if blocks=1 then
|
|
return message, 0:=string$(chr$(0),32)
|
|
if l-acc=0 and f64 then
|
|
Return message, 56:=l*8 as long, 60 :=binary.shift(l,-29) as long
|
|
else
|
|
Return message, l-acc:=0x80, 56:=l*8 as long, 60 :=binary.shift(l,-29) as long
|
|
if l>acc then LoadPart(l-acc)
|
|
end if
|
|
else
|
|
Return message, l-acc:=0x80
|
|
LoadPart(l-acc)
|
|
end if
|
|
End Sub
|
|
sub LoadPart(many)
|
|
\\ str$() convert to ansi, one byte per character
|
|
\\ using 1033 as Ansi language
|
|
if ansi then
|
|
Return message, 0:=str$(mid$(message$,1+acc, many))
|
|
else
|
|
Return message, 0:=mid$(message$, 1+acc, many)
|
|
end if
|
|
acc+=many
|
|
end sub
|
|
}
|
|
}
|
|
Module TestHash (RIPEMD){
|
|
Flush
|
|
\\ push data to stack of values, as fifo (each entry append to end of stack)
|
|
Data "b3be159860842cebaa7174c8fff0aa9e50a5199f","Rosetta Code"
|
|
Data "9c1185a5c5e9fc54612808977ee8f548b2258d31",""
|
|
Data "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe","a"
|
|
Data "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc","abc"
|
|
Data "5d0689ef49d2fae572b881b123a85ffa21595f36", "message digest"
|
|
Data "f71c27109c692c1b56bbdceb5b9d2865b3708dbc","abcdefghijklmnopqrstuvwxyz"
|
|
Data "b0e20b6e3116640286ed3a87a5713079b21f5189"
|
|
Data "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
|
Data "9b752e45573d4b39f4dbd3323cab82bf63326bfb", String$("1234567890",8)
|
|
rem Data "52783243c1697bdbe16d37f97f68f08325dc1528", String$("a",1000000)
|
|
|
|
While not empty
|
|
Read check$, text$
|
|
Print "RIPEMD160 for ";quote$(Left$(if$(len(text$)>30->left$(text$,27)+"...", text$),30))
|
|
\\ pass text$ by reference
|
|
Display(RIPEMD(&text$))
|
|
End While
|
|
|
|
sub Display(ans)
|
|
local answer$
|
|
for i=0 to len(ans)-1
|
|
answer$+=hex$(eval(ans,i),1)
|
|
next i
|
|
Print lcase$(answer$)
|
|
Print lcase$(answer$)=check$
|
|
end sub
|
|
}
|
|
TestHash Prepare_RiPeMd_160()
|
|
}
|
|
Checkit
|