PowerBASIC Forums
  Source Code
  RIPEMD-160 Secure Hash for 3.0/7.0

Post New Topic  Post A Reply
profile | register | preferences | faq | search

UBBFriend: Email This Page to Someone! next newest topic | next oldest topic
Author Topic:   RIPEMD-160 Secure Hash for 3.0/7.0
Greg Turgeon
Member
posted July 24, 2002 01:18 AM     Click Here to See the Profile for Greg Turgeon     Edit/Delete Message   Reply w/Quote
#IF 0

=====================================================================
RIPEMD-160 SECURE HASH
=====================================================================

The RMD160 secure hash algorithm creates a 160-bit hash of an input
string of any length. A hash is considered secure when it possesses
the following qualities: 1) Finding two input strings which hash to
the same value is considered not feasible. 2) Determining an input
string from its hash is considered not feasible.

From the RIPEMD-160 home page:
User agrees to give due credit to K.U.Leuven in scientific
publications or communications in relation with the use of the
RIPEMD-160 software as follows: RIPEMD-160 software written by
Antoon Bosselaers, available at
http://www.esat.kuleuven.ac.be/~cosicart/ps/AB-9601/.

The PowerBASIC implementation appearing below is based on that of Brian
Gladman, which is available here:
http://fp.gladman.plus.com/cryptography_technology/

This PB implementation is hereby placed in the public domain. Use it
as you wish. My hope is discourage reliance on home-grown encryption
schemes in favor of well-examined, strong, freely available
algorithms.

In this posting, test-bed code appears below the RMD160.BAS file
contents. All code requires PB compiler releases 3.0/7.0 or later.
All code compiles with either PBCC or PBWin.


Implementation Notes

-- The algorithm operates on plaintext blocks of 64 bytes. Padding
of final blocks < 64 bytes must conform to a specific pattern and is
accomplished automatically by calling MDfinish(). The process of
hashing consists of the following essential steps:

ctx.pBuffer = strptr(target_data)
ctx.BufferLength = len(target_data)
bufflen = ctx.BufferLength
RMD160_Init ctx '<-- Initialize hashing of
do while bufflen > (%BLOCKSIZE-1) ' target_data
Compress ctx '<-- hash target_data
ctx.pBuffer = ctx.pBuffer + %BLOCKSIZE
bufflen = bufflen - %BLOCKSIZE
loop
MDfinish ctx '<-- hash last block of
' target_data
' (if any) + padding

-- Implementation here is handled through an #INCLUDE file. No global
data is employed.

-- Because of the methods of data handling required for most
encryption and hashing, PowerBASIC's LONGs should be used to assure
correct bit-level results (as well as additional speed).

Greg Turgeon 07/2002

#ENDIF

%HASHLENGTH = 20 'bytes
%BLOCKSIZE = 64 'bytes

TYPE HASH_CONTEXT
pBuffer AS LONG PTR
BufferLength AS LONG
MD AS LONG PTR
MD_Buffer AS STRING * %HASHLENGTH '<-- Holds actual hash value
END TYPE

'--------------------
' Utility macros
'--------------------

'--------------------
MACRO zbs(x)=string$(x,0) 'also defined in RMD160.BAS

'--------------------
MACRO FUNCTION rotlc(xx,constant_shiftval)
retval = xx
! rol retval, constant_shiftval
END MACRO = retval


'--------------------
'RMD160 macros
'--------------------

'--------------------
MACRO Fmd(x,y,z)=((x XOR y XOR z))
'--------------------
MACRO Gmd(x,y,z)=((x AND y) OR (NOT(x) AND z))
'--------------------
MACRO Hmd(x,y,z)=((x OR NOT(y)) XOR z)
'--------------------
MACRO Imd(x,y,z)=((x AND z) OR (y AND NOT(z)))
'--------------------
MACRO Jmd(x,y,z)=(x XOR (y OR NOT(z)))

'--------------------
MACRO FFmd(a,b,c,d,e,x,s)
a=a+Fmd(b,c,d)+x
a=(rotlc(a,s))
a=a+e
c=rotlc(c,10)
END MACRO

'--------------------
MACRO GGmd(a,b,c,d,e,x,s)
a=a+Gmd(b,c,d)+(x)+&h5a827999
a=rotlc(a,s)
a=a+e
c=rotlc(c,10)
END MACRO

'--------------------
MACRO HHmd(a,b,c,d,e,x,s)
a=a+Hmd(b,c,d)+x+&h6ed9eba1
a=rotlc(a,s)
a=a+e
c=rotlc(c,10)
END MACRO

MACRO IImd(a,b,c,d,e,x,s)
a=a+Imd(b,c,d)+x+&h8f1bbcdc
a=rotlc(a,s)
a=a+e
c=rotlc(c,10)
END MACRO

'--------------------
MACRO JJmd(a,b,c,d,e,x,s)
a=a+Jmd(b,c,d)+x+&ha953fd4e
a=rotlc(a,s)
a=a+e
c=rotlc(c,10)
END MACRO

'--------------------
MACRO FFFmd(a,b,c,d,e,x,s)
a=a+Fmd(b,c,d)+x
a=rotlc(a,s)
a=a+e
c=rotlc(c,10)
END MACRO

'--------------------
MACRO GGGmd(a,b,c,d,e,x,s)
a=a+Gmd(b,c,d)+x+&h7a6d76e9
a=rotlc(a,s)
a=a+e
c=rotlc(c,10)
END MACRO

'--------------------
MACRO HHHmd(a,b,c,d,e,x,s)
a=a+Hmd(b,c,d)+(x)+&h6d703ef3
a=rotlc(a,s)
a=a+e
c=rotlc(c,10)
END MACRO

'--------------------
MACRO IIImd(a,b,c,d,e,x,s)
a=a+Imd(b,c,d)+x+&h5c4dd124
a=rotlc(a,s)
a=a+e
c=rotlc(c,10)
END MACRO

'--------------------
MACRO JJJmd(a,b,c,d,e,x,s)
a=a+Jmd(b,c,d)+x+&h50a28be6
a=rotlc(a,s)
a=a+e
c=rotlc(c,10)
END MACRO


DECLARE FUNCTION RMD160_Init(Ctx AS HASH_CONTEXT)
DECLARE FUNCTION Compress(Ctx AS HASH_CONTEXT)
DECLARE FUNCTION MDfinish(Ctx AS HASH_CONTEXT)

'====================
FUNCTION RMD160_Init(Ctx AS HASH_CONTEXT)
Ctx.MD_Buffer = zbs(%HASHLENGTH)
Ctx.MD = varptr(Ctx.MD_Buffer)
Ctx.@MD[0] = &h67452301
Ctx.@MD[1] = &hefcdab89
Ctx.@MD[2] = &h98badcfe
Ctx.@MD[3] = &h10325476
Ctx.@MD[4] = &hc3d2e1f0
END FUNCTION


'====================
FUNCTION Compress(Ctx AS HASH_CONTEXT)
LOCAL aa&, bb&, cc&, dd&, ee&, aaa&, bbb&, ccc&, ddd&, eee&, x AS LONG PTR, retval&

aa = Ctx.@MD[0] : bb = Ctx.@MD[1] : cc = Ctx.@MD[2]
dd = Ctx.@MD[3] : ee = Ctx.@MD[4]
aaa = Ctx.@MD[0] : bbb = Ctx.@MD[1] : ccc = Ctx.@MD[2]
ddd = Ctx.@MD[3] : eee = Ctx.@MD[4]

x = Ctx.pBuffer 'local copy

'-- round 1
FFmd(aa,bb,cc,dd,ee,@x[0],11)
FFmd(ee,aa,bb,cc,dd,@x[1],14)
FFmd(dd,ee,aa,bb,cc,@x[2],15)
FFmd(cc,dd,ee,aa,bb,@x[3],12)
FFmd(bb,cc,dd,ee,aa,@x[4],5)
FFmd(aa,bb,cc,dd,ee,@x[5],8)
FFmd(ee,aa,bb,cc,dd,@x[6],7)
FFmd(dd,ee,aa,bb,cc,@x[7],9)
FFmd(cc,dd,ee,aa,bb,@x[8],11)
FFmd(bb,cc,dd,ee,aa,@x[9],13)
FFmd(aa,bb,cc,dd,ee,@x[10],14)
FFmd(ee,aa,bb,cc,dd,@x[11],15)
FFmd(dd,ee,aa,bb,cc,@x[12],6)
FFmd(cc,dd,ee,aa,bb,@x[13],7)
FFmd(bb,cc,dd,ee,aa,@x[14],9)
FFmd(aa,bb,cc,dd,ee,@x[15],8)

'-- round 2
GGmd(ee,aa,bb,cc,dd,@x[7],7)
GGmd(dd,ee,aa,bb,cc,@x[4],6)
GGmd(cc,dd,ee,aa,bb,@x[13],8)
GGmd(bb,cc,dd,ee,aa,@x[1],13)
GGmd(aa,bb,cc,dd,ee,@x[10],11)
GGmd(ee,aa,bb,cc,dd,@x[6],9)
GGmd(dd,ee,aa,bb,cc,@x[15],7)
GGmd(cc,dd,ee,aa,bb,@x[3],15)
GGmd(bb,cc,dd,ee,aa,@x[12],7)
GGmd(aa,bb,cc,dd,ee,@x[0],12)
GGmd(ee,aa,bb,cc,dd,@x[9],15)
GGmd(dd,ee,aa,bb,cc,@x[5],9)
GGmd(cc,dd,ee,aa,bb,@x[2],11)
GGmd(bb,cc,dd,ee,aa,@x[14],7)
GGmd(aa,bb,cc,dd,ee,@x[11],13)
GGmd(ee,aa,bb,cc,dd,@x[8],12)

'-- round 3
HHmd(dd,ee,aa,bb,cc,@x[3],11)
HHmd(cc,dd,ee,aa,bb,@x[10],13)
HHmd(bb,cc,dd,ee,aa,@x[14],6)
HHmd(aa,bb,cc,dd,ee,@x[4],7)
HHmd(ee,aa,bb,cc,dd,@x[9],14)
HHmd(dd,ee,aa,bb,cc,@x[15],9)
HHmd(cc,dd,ee,aa,bb,@x[8],13)
HHmd(bb,cc,dd,ee,aa,@x[1],15)
HHmd(aa,bb,cc,dd,ee,@x[2],14)
HHmd(ee,aa,bb,cc,dd,@x[7],8)
HHmd(dd,ee,aa,bb,cc,@x[0],13)
HHmd(cc,dd,ee,aa,bb,@x[6],6)
HHmd(bb,cc,dd,ee,aa,@x[13],5)
HHmd(aa,bb,cc,dd,ee,@x[11],12)
HHmd(ee,aa,bb,cc,dd,@x[5],7)
HHmd(dd,ee,aa,bb,cc,@x[12],5)

'-- round 4
IImd(cc,dd,ee,aa,bb,@x[1],11)
IImd(bb,cc,dd,ee,aa,@x[9],12)
IImd(aa,bb,cc,dd,ee,@x[11],14)
IImd(ee,aa,bb,cc,dd,@x[10],15)
IImd(dd,ee,aa,bb,cc,@x[0],14)
IImd(cc,dd,ee,aa,bb,@x[8],15)
IImd(bb,cc,dd,ee,aa,@x[12],9)
IImd(aa,bb,cc,dd,ee,@x[4],8)
IImd(ee,aa,bb,cc,dd,@x[13],9)
IImd(dd,ee,aa,bb,cc,@x[3],14)
IImd(cc,dd,ee,aa,bb,@x[7],5)
IImd(bb,cc,dd,ee,aa,@x[15],6)
IImd(aa,bb,cc,dd,ee,@x[14],8)
IImd(ee,aa,bb,cc,dd,@x[5],6)
IImd(dd,ee,aa,bb,cc,@x[6],5)
IImd(cc,dd,ee,aa,bb,@x[2],12)

'-- round 5
JJmd(bb,cc,dd,ee,aa,@x[4],9)
JJmd(aa,bb,cc,dd,ee,@x[0],15)
JJmd(ee,aa,bb,cc,dd,@x[5],5)
JJmd(dd,ee,aa,bb,cc,@x[9],11)
JJmd(cc,dd,ee,aa,bb,@x[7],6)
JJmd(bb,cc,dd,ee,aa,@x[12],8)
JJmd(aa,bb,cc,dd,ee,@x[2],13)
JJmd(ee,aa,bb,cc,dd,@x[10],12)
JJmd(dd,ee,aa,bb,cc,@x[14],5)
JJmd(cc,dd,ee,aa,bb,@x[1],12)
JJmd(bb,cc,dd,ee,aa,@x[3],13)
JJmd(aa,bb,cc,dd,ee,@x[8],14)
JJmd(ee,aa,bb,cc,dd,@x[11],11)
JJmd(dd,ee,aa,bb,cc,@x[6],8)
JJmd(cc,dd,ee,aa,bb,@x[15],5)
JJmd(bb,cc,dd,ee,aa,@x[13],6)

'-- parallel round 1
JJJmd(aaa,bbb,ccc,ddd,eee,@x[5],8)
JJJmd(eee,aaa,bbb,ccc,ddd,@x[14],9)
JJJmd(ddd,eee,aaa,bbb,ccc,@x[7],9)
JJJmd(ccc,ddd,eee,aaa,bbb,@x[0],11)
JJJmd(bbb,ccc,ddd,eee,aaa,@x[9],13)
JJJmd(aaa,bbb,ccc,ddd,eee,@x[2],15)
JJJmd(eee,aaa,bbb,ccc,ddd,@x[11],15)
JJJmd(ddd,eee,aaa,bbb,ccc,@x[4],5)
JJJmd(ccc,ddd,eee,aaa,bbb,@x[13],7)
JJJmd(bbb,ccc,ddd,eee,aaa,@x[6],7)
JJJmd(aaa,bbb,ccc,ddd,eee,@x[15],8)
JJJmd(eee,aaa,bbb,ccc,ddd,@x[8],11)
JJJmd(ddd,eee,aaa,bbb,ccc,@x[1],14)
JJJmd(ccc,ddd,eee,aaa,bbb,@x[10],14)
JJJmd(bbb,ccc,ddd,eee,aaa,@x[3],12)
JJJmd(aaa,bbb,ccc,ddd,eee,@x[12],6)

'-- parallel round 2
IIImd(eee,aaa,bbb,ccc,ddd,@x[6],9)
IIImd(ddd,eee,aaa,bbb,ccc,@x[11],13)
IIImd(ccc,ddd,eee,aaa,bbb,@x[3],15)
IIImd(bbb,ccc,ddd,eee,aaa,@x[7],7)
IIImd(aaa,bbb,ccc,ddd,eee,@x[0],12)
IIImd(eee,aaa,bbb,ccc,ddd,@x[13],8)
IIImd(ddd,eee,aaa,bbb,ccc,@x[5],9)
IIImd(ccc,ddd,eee,aaa,bbb,@x[10],11)
IIImd(bbb,ccc,ddd,eee,aaa,@x[14],7)
IIImd(aaa,bbb,ccc,ddd,eee,@x[15],7)
IIImd(eee,aaa,bbb,ccc,ddd,@x[8],12)
IIImd(ddd,eee,aaa,bbb,ccc,@x[12],7)
IIImd(ccc,ddd,eee,aaa,bbb,@x[4],6)
IIImd(bbb,ccc,ddd,eee,aaa,@x[9],15)
IIImd(aaa,bbb,ccc,ddd,eee,@x[1],13)
IIImd(eee,aaa,bbb,ccc,ddd,@x[2],11)

'-- parallel round 3
HHHmd(ddd,eee,aaa,bbb,ccc,@x[15],9)
HHHmd(ccc,ddd,eee,aaa,bbb,@x[5],7)
HHHmd(bbb,ccc,ddd,eee,aaa,@x[1],15)
HHHmd(aaa,bbb,ccc,ddd,eee,@x[3],11)
HHHmd(eee,aaa,bbb,ccc,ddd,@x[7],8)
HHHmd(ddd,eee,aaa,bbb,ccc,@x[14],6)
HHHmd(ccc,ddd,eee,aaa,bbb,@x[6],6)
HHHmd(bbb,ccc,ddd,eee,aaa,@x[9],14)
HHHmd(aaa,bbb,ccc,ddd,eee,@x[11],12)
HHHmd(eee,aaa,bbb,ccc,ddd,@x[8],13)
HHHmd(ddd,eee,aaa,bbb,ccc,@x[12],5)
HHHmd(ccc,ddd,eee,aaa,bbb,@x[2],14)
HHHmd(bbb,ccc,ddd,eee,aaa,@x[10],13)
HHHmd(aaa,bbb,ccc,ddd,eee,@x[0],13)
HHHmd(eee,aaa,bbb,ccc,ddd,@x[4],7)
HHHmd(ddd,eee,aaa,bbb,ccc,@x[13],5)

'-- parallel round 4
GGGmd(ccc,ddd,eee,aaa,bbb,@x[8],15)
GGGmd(bbb,ccc,ddd,eee,aaa,@x[6],5)
GGGmd(aaa,bbb,ccc,ddd,eee,@x[4],8)
GGGmd(eee,aaa,bbb,ccc,ddd,@x[1],11)
GGGmd(ddd,eee,aaa,bbb,ccc,@x[3],14)
GGGmd(ccc,ddd,eee,aaa,bbb,@x[11],14)
GGGmd(bbb,ccc,ddd,eee,aaa,@x[15],6)
GGGmd(aaa,bbb,ccc,ddd,eee,@x[0],14)
GGGmd(eee,aaa,bbb,ccc,ddd,@x[5],6)
GGGmd(ddd,eee,aaa,bbb,ccc,@x[12],9)
GGGmd(ccc,ddd,eee,aaa,bbb,@x[2],12)
GGGmd(bbb,ccc,ddd,eee,aaa,@x[13],9)
GGGmd(aaa,bbb,ccc,ddd,eee,@x[9],12)
GGGmd(eee,aaa,bbb,ccc,ddd,@x[7],5)
GGGmd(ddd,eee,aaa,bbb,ccc,@x[10],15)
GGGmd(ccc,ddd,eee,aaa,bbb,@x[14],8)

'-- parallel round 5
FFFmd(bbb,ccc,ddd,eee,aaa,@x[12],8)
FFFmd(aaa,bbb,ccc,ddd,eee,@x[15],5)
FFFmd(eee,aaa,bbb,ccc,ddd,@x[10],12)
FFFmd(ddd,eee,aaa,bbb,ccc,@x[4],9)
FFFmd(ccc,ddd,eee,aaa,bbb,@x[1],12)
FFFmd(bbb,ccc,ddd,eee,aaa,@x[5],5)
FFFmd(aaa,bbb,ccc,ddd,eee,@x[8],14)
FFFmd(eee,aaa,bbb,ccc,ddd,@x[7],6)
FFFmd(ddd,eee,aaa,bbb,ccc,@x[6],8)
FFFmd(ccc,ddd,eee,aaa,bbb,@x[2],13)
FFFmd(bbb,ccc,ddd,eee,aaa,@x[13],6)
FFFmd(aaa,bbb,ccc,ddd,eee,@x[14],5)
FFFmd(eee,aaa,bbb,ccc,ddd,@x[0],15)
FFFmd(ddd,eee,aaa,bbb,ccc,@x[3],13)
FFFmd(ccc,ddd,eee,aaa,bbb,@x[9],11)
FFFmd(bbb,ccc,ddd,eee,aaa,@x[11],11)

'-- combine results
ddd = ddd + cc + Ctx.@MD[1]
Ctx.@MD[1] = Ctx.@MD[2] + dd + eee
Ctx.@MD[2] = Ctx.@MD[3] + ee + aaa
Ctx.@MD[3] = Ctx.@MD[4] + aa + bbb
Ctx.@MD[4] = Ctx.@MD[0] + bb + ccc
Ctx.@MD[0] = ddd
END FUNCTION


'=========================
FUNCTION MakePadding$(BYVAL TotalBytes&)
LOCAL padding$, buffbits&&, padbytes&

buffbits = TotalBytes * 8
padding = zbs(8)
poke$ strptr(padding), peek$(varptr(buffbits),8)

padbytes = %BLOCKSIZE - ((TotalBytes+9) AND (%BLOCKSIZE-1))
function = chr$(&h80) + zbs(padbytes) + padding
END FUNCTION


'====================
FUNCTION MDfinish(Ctx AS HASH_CONTEXT)
LOCAL x_buffer$, x AS BYTE PTR, retval&, padding$, bytesleft&

x_buffer$ = zbs(%BLOCKSIZE) : x = strptr(x_buffer$)

padding = MakePadding$(Ctx.BufferLength)
bytesleft = Ctx.BufferLength AND 63
poke$ x, peek$(Ctx.pBuffer, bytesleft)
poke$ x+bytesleft, padding

Ctx.pBuffer = x
Compress Ctx
END FUNCTION

'-- end RMD160.BAS


'=====================================================================
' RIPEMD-160 Test Bed code
' Compiles with either PBWIN 7.0+ or PBCC 3.0+
'=====================================================================
#COMPILE EXE
#REGISTER NONE
#DIM ALL
'============
DEFLNG A-Z

'--------------------
'-- Utility macros
'--------------------

#IF %def(%pb_win32)
MACRO eol=$CR
MACRO mbox(t)=msgbox t
#ELSEIF %def(%pb_cc32)
MACRO eol=$CRLF
MACRO mbox(t)=stdout t
#ENDIF

'--------------------
MACRO EnterCC
#IF %def(%pb_cc32)
LOCAL launched&
if (cursory = 1) and (cursorx = 1) then launched = -1
#ENDIF
END MACRO

'--------------------
MACRO ExitCC
#IF %def(%pb_cc32)
if launched then
input flush
stdout "Press any key to end"
waitkey$
end if
#ENDIF
END MACRO

''--------------------
'MACRO zbs(x)=string$(x,0) 'also defined in RMD160.BAS

'%HASHLENGTH = 20 'bytes
'%BLOCKSIZE = 64 'bytes

'TYPE HASH_CONTEXT
' pBuffer AS LONG PTR
' BufferLength AS LONG
' MD AS LONG PTR
' MD_Buffer AS STRING * %HASHLENGTH
'END TYPE


#INCLUDE "RMD160.BAS"

DECLARE FUNCTION Hex2Show$(Buffer$)

'====================
FUNCTION PBMain&()
LOCAL i&, plain$, hash$, shouldbe$, t$
LOCAL ctx AS HASH_CONTEXT ' defined in RMD160.BAS
EnterCC

'-- Standard RIPEMD-160 test vectors:
plain = "" 'empty string
hash = zbs(%HASHLENGTH)
shouldbe = chr$(&h9c,&h11,&h85,&ha5,&hc5,&he9,&hfc,&h54,&h61,&h28,&h08,&h97,&h7e,&he8,&hf5,&h48,&hb2,&h25,&h8d,&h31)
t = "plain: " + plain + eol
gosub DoRMD160
t = t + "hash: " + Hex2Show$(hash) + eol
t = t + "shouldbe: " + Hex2Show$(shouldbe) + eol + eol

plain = "a"
hash = zbs(%HASHLENGTH)
shouldbe = chr$(&h0b,&hdc,&h9d,&h2d,&h25,&h6b,&h3e,&he9,&hda,&hae,&h34,&h7b,&he6,&hf4,&hdc,&h83,&h5a,&h46,&h7f,&hfe)
t = T + "plain: " + plain + eol
gosub DoRMD160
t = t + "hash: " + Hex2Show$(hash) + eol
t = t + "shouldbe: " + Hex2Show$(shouldbe) + eol + eol

plain = "message digest"
hash = zbs(%HASHLENGTH)
shouldbe = chr$(&h5d,&h06,&h89,&hef,&h49,&hd2,&hfa,&he5,&h72,&hb8,&h81,&hb1,&h23,&ha8,&h5f,&hfa,&h21,&h59,&h5f,&h36)
t = t + "plain: " + plain + eol
gosub DoRMD160
t = t + "hash: " + Hex2Show$(hash) + eol
t = t + "shouldbe: " + Hex2Show$(shouldbe) + eol + eol


plain = repeat$(1000000,"a")
hash = zbs(%HASHLENGTH)
shouldbe = chr$(&h52,&h78,&h32,&h43,&hc1,&h69,&h7b,&hdb,&he1,&h6d,&h37,&hf9,&h7f,&h68,&hf0,&h83,&h25,&hdc,&h15,&h28)
t = t + "Million chars test" + eol
gosub DoRMD160
t = t + "hash: " + Hex2Show$(hash) + eol
t = t + "shouldbe: " + Hex2Show$(shouldbe) + eol + eol

mbox(t)

'============
ExitPBMain:
ExitCC
exit function

'============
DoRMD160:
REGISTER bufflen&
ctx.pBuffer = strptr(plain)
ctx.BufferLength = len(plain)
RMD160_Init ctx

bufflen = ctx.BufferLength
do while bufflen > (%BLOCKSIZE-1)
Compress ctx
ctx.pBuffer = ctx.pBuffer + %BLOCKSIZE
bufflen = bufflen - %BLOCKSIZE
loop
MDfinish ctx

hash = peek$(Ctx.MD, %HASHLENGTH)
RETURN
END FUNCTION

'====================
FUNCTION Hex2Show$(Buffer$)
REGISTER i&
LOCAL t$, b AS BYTE PTR
b = strptr(Buffer$)
for i = 0 to len(Buffer$)-1
t = t + hex$(@b[i],2) + " "
next i
function = t
END FUNCTION

'-- end TESTBED.BAS

[This message has been edited by Greg Turgeon (edited July 24, 2002).]

IP: Logged

All times are EasternTime (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply
Hop to:

Contact Us | PowerBASIC BASIC Compilers

Copyright © 1999-2005 PowerBASIC, Inc. All Rights Reserved.


Ultimate Bulletin Board 5.45c