Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

hmac-md5 hash for 64-bit Forth

211 views
Skip to first unread message

Krishna Myneni

unread,
Jan 22, 2022, 4:52:58 PM1/22/22
to
While many of the Forth programs written for 32-bit Forths were easily
ported to 64-bit kForth, in a way that the programs work on both 32-bit
and 64-bit systems, one notable exception was Jabari Zakiya's program
for computing the md5 sum of a buffer or a file, hmac-md5.4th. The
program's arithmetic and logic depended on a 32-bit cell size.

I've been missing this tool in kForth-64 and devoted some time this
weekend to making it run within both 32-bit and 64-bit Forths. After a
lot of pain in trying to understand and simulate the 32-bit arithmetic
within a 64-bit cell size Forth, I found that adding two new macros to
the file, >SL and SL+ , provided the necessary extra arithmetic needed
to do enable it to run under 64-bit cells. The revised program, which
still needs a fix to run on big-endian systems, may be found in the most
recent kForth-32 master and kForth-64 master repos on GitHub. Here is a
link to the revised program:

https://github.com/mynenik/kForth-64/blob/master/forth-src/hmac-md5.4th

It will run the tests, executed by the word HMAC-TESTS properly under
both 32-bit and 64-bit (little-endian) systems. I would have fixed it up
for big-endian systems as well, but I don't have one at hand on which I
can test it.

The program relies on non-standard memory access words SL@ and L!
(sign-extended 32-bit fetch, and 32-bit store) which exist in kForth.
These words also exist in Gforth, I believe.

Cheers,
Krishna Myneni

Krishna Myneni

unread,
Jan 23, 2022, 1:19:01 AM1/23/22
to
On Saturday, January 22, 2022 at 3:52:58 PM UTC-6, Krishna Myneni wrote:
> ... After a
> lot of pain in trying to understand and simulate the 32-bit arithmetic
> within a 64-bit cell size Forth, I found that adding two new macros to
> the file, >SL and SL+ , provided the necessary extra arithmetic needed
> to do enable it to run under 64-bit cells. ...

A clearer name for >SL is SL>S with the stack diagram ( sl -- n ).

--
Krishna

Message has been deleted

Marcel Hendrix

unread,
Jan 24, 2022, 4:20:44 AM1/24/22
to
On Sunday, January 23, 2022 at 7:19:01 AM UTC+1, km361...@gmail.com wrote:
> On Saturday, January 22, 2022 at 3:52:58 PM UTC-6, Krishna Myneni wrote:
> > ... After a
> > lot of pain in trying to understand and simulate the 32-bit arithmetic
> > within a 64-bit cell size Forth, I found that adding two new macros to
> > the file, >SL and SL+ , provided the necessary extra arithmetic needed
> > to do enable it to run under 64-bit cells. ...

When I changed to 64bits a few years (decades?) ago, I faced similar
problems and added the following:

FORTH> words: 32
S32B@ ALIGN32 ALIGNED32
32B, 32B2! 32B2@
S32B@+ 32B@+ 32B@
32B+! 32B!+ 32B!
ASHR32 ROR32 ROL32
RSHIFT32 LSHIFT32
32->64

32->64 is needed for some OS calls that return an unsigned
instead of signed number (S32->S64 would have been clearer).

After the porting period, the usefulness of most of these
words proved very low.

-marcel

Krishna Myneni

unread,
Jan 24, 2022, 6:46:12 AM1/24/22
to
On Monday, January 24, 2022 at 1:20:44 AM UTC-8, Marcel Hendrix wrote:
> On Sunday, January 23, 2022 at 7:19:01 AM UTC+1, km361...@gmail.com wrote:
> > On Saturday, January 22, 2022 at 3:52:58 PM UTC-6, Krishna Myneni wrote:
> > > ... After a
> > > lot of pain in trying to understand and simulate the 32-bit arithmetic
> > > within a 64-bit cell size Forth, I found that adding two new macros to
> > > the file, >SL and SL+ , provided the necessary extra arithmetic needed
> > > to do enable it to run under 64-bit cells. ...
> When I changed to 64bits a few years (decades?) ago, I faced similar
> problems and added the following:
>
> FORTH> words: 32
> S32B@ ALIGN32 ALIGNED32
> 32B, 32B2! 32B2@
> S32B@+ 32B@+ 32B@
> 32B+! 32B!+ 32B!
> ASHR32 ROR32 ROL32
> RSHIFT32 LSHIFT32
> 32->64
>
> 32->64 is needed for some OS calls that return an unsigned
> instead of signed number (S32->S64 would have been clearer).
>

The 'L' in SL>S represents long, C's 32-bit type, but I agree that
the explicit "S32" is clearer.

There is no need to be explicit on the destination type, because
we want it to occupy the full cell width on the system. In fact,
using S32>S64 would not work on a 32 bit system and our code
would no longer be portable between 32-bit and 64-bit systems
if we use S32>S64.

> After the porting period, the usefulness of most of these
> words proved very low.
>
I suppose it depends on the type of programming you are
doing. For example, writing hashing algorithms, cryptography,
or hardware interfacing require this sort of conversion. These
conversion words are just "casts" between different types. In
Forth we have different names for operators on different types,
which is why we need to cast between different data types less
often. But we do have S>D D>S F>D etc.

--
Krishna

Krishna Myneni

unread,
Jan 29, 2022, 5:16:08 PM1/29/22
to
On 1/22/22 15:52, Krishna Myneni wrote:
> While many of the Forth programs written for 32-bit Forths were easily
> ported to 64-bit kForth, in a way that the programs work on both 32-bit
> and 64-bit systems, one notable exception was Jabari Zakiya's program
> for computing the md5 sum of a buffer or a file, hmac-md5.4th. The
> program's arithmetic and logic depended on a 32-bit cell size.
>
> I've been missing this tool in kForth-64 and devoted some time this
> weekend to making it run within both 32-bit and 64-bit Forths. After a
> lot of pain in trying to understand and simulate the 32-bit arithmetic
> within a 64-bit cell size Forth, I found that adding two new macros to
> the file, >SL and SL+ , provided the necessary extra arithmetic needed
> to do enable it to run under 64-bit cells. The revised program, which
> still needs a fix to run on big-endian systems, may be found in the most
> recent kForth-32 master and kForth-64 master repos on GitHub. Here is a
> link to the revised program:
>
> https://github.com/mynenik/kForth-64/blob/master/forth-src/hmac-md5.4th
...

The disclaimer is that MD5 hashes should not be used for detecting
intentional corruption of data, since it has been known for some years
that the MD5 hash can be spoofed without a lot of computational
resources. The MD5 hash can still be used profitably for detecting
unintentional corruption. Also, if one is not too concerned about
efficiency for computing a secure hash, one might rig up a more secure
hash using MD5 -- for example, compute a "forward" hash for the data,
then reverse the byte order, and and compute a "reverse" hash and
concatenate the two 128-bit hashes to form a 256-bit hash. DISCLAIMER: I
am not a specialist in cryptography and I have no idea if such a scheme
would actually be strongly resistant to spoofing, although it seems
likely that it might, in practice. There's at least one case where it
wouldn't -- if by some weird coincidence, the byte reversed order of the
message (data) is exactly the same as the original message, e.g.
"abcba", is the same as its byte reversed order when characters are
represented by bytes.

The SHA256 algorithms are far better for detecting intentional
modification of data. Incidentally, I notice there is a Forth example
for Rosetta Stone's SHA-256 example, but it's a bit of a cop-out, as it
doesn't really code the SHA-256 algorithm in Forth but makes a
system-specific library call to the libcrypto C library.

https://rosettacode.org/wiki/SHA-256#GNU_Forth_0.7.9_on_Linux

In fairness, though, most of the other higher level languages do the
same thing, though there are a few exceptions. Nevertheless, for Forth,
the SHA-256 algorithm is available as Forth code:

https://gist.github.com/jzakiya/4544459

I think the Rosetta code Forth example is also an opportunity to show
how assembler and Forth are designed to work together -- after all
ASSEMBLER and CODE are standard words. The hash functions are designed
to work with low-level microprocessor instructions, and a Forth
program/library can make explicit both the high level Forth and low
level assembler code within a single source file.

--
Krishna

Marcel Hendrix

unread,
Jan 29, 2022, 7:26:15 PM1/29/22
to
On Saturday, January 29, 2022 at 11:16:08 PM UTC+1, Krishna Myneni wrote:
> On 1/22/22 15:52, Krishna Myneni wrote:
[..]
> I think the Rosetta code Forth example is also an opportunity to show
> how assembler and Forth are designed to work together -- after all
> ASSEMBLER and CODE are standard words. The hash functions are designed
> to work with low-level microprocessor instructions, and a Forth
> program/library can make explicit both the high level Forth and low
> level assembler code within a single source file.

No assembler needed, but a bit of debugging would be nice...

(*
* LANGUAGE : ANS Forth with extensions
* PROJECT : Forth Environments
* DESCRIPTION : Based on SHA-512 from Aaron D. Gifford - http://www.aarongifford.com/
* CATEGORY : Encrypter tool
* AUTHOR : Marcel Hendrix
* LAST CHANGE : December 1, 2012, Marcel Hendrix
*)



NEEDS -miscutil

REVISION -sha512 "--- SHA-512 64-bit Version 0.00 ---"

PRIVATES

DOC
(*
Examples of SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224 and SHA512/256
are available at http://csrc.nist.gov/groups/ST/toolkit/examples.html
*)
ENDDOC
#128 =: SHA512_BLOCK_LENGTH PRIVATE
#64 =: SHA512_DIGEST_LENGTH PRIVATE
SHA512_DIGEST_LENGTH 2* 1+ =: SHA512_DIGEST_STRING_LENGTH PRIVATE
SHA512_BLOCK_LENGTH #16 - =: SHA512_SHORT_BLOCK_LENGTH PRIVATE

0 VALUE bitcount PRIVATE

CREATE W512[] PRIVATE SHA512_BLOCK_LENGTH CHARS ALLOT
CREATE digest[] PRIVATE SHA512_DIGEST_LENGTH CHARS ALLOT
CREATE digesttext[] PRIVATE SHA512_DIGEST_STRING_LENGTH CHARS ALLOT

-- Hash constant words K for SHA-512
CREATE K512[] PRIVATE
$428A2F98D728AE22 , $7137449123EF65CD , $B5C0FBCFEC4D3B2F , $E9B5DBA58189DBBC ,
$3956C25BF348B538 , $59F111F1B605D019 , $923F82A4AF194F9B , $AB1C5ED5DA6D8118 ,
$D807AA98A3030242 , $12835B0145706FBE , $243185BE4EE4B28C , $550C7DC3D5FFB4E2 ,
$72BE5D74F27B896F , $80DEB1FE3B1696B1 , $9BDC06A725C71235 , $C19BF174CF692694 ,
$E49B69C19EF14AD2 , $EFBE4786384F25E3 , $0FC19DC68B8CD5B5 , $240CA1CC77AC9C65 ,
$2DE92C6F592B0275 , $4A7484AA6EA6E483 , $5CB0A9DCBD41FBD4 , $76F988DA831153B5 ,
$983E5152EE66DFAB , $A831C66D2DB43210 , $B00327C898FB213F , $BF597FC7BEEF0EE4 ,
$C6E00BF33DA88FC2 , $D5A79147930AA725 , $06CA6351E003826F , $142929670A0E6E70 ,
$27B70A8546D22FFC , $2E1B21385C26C926 , $4D2C6DFC5AC42AED , $53380D139D95B3DF ,
$650A73548BAF63DE , $766A0ABB3C77B2A8 , $81C2C92E47EDAEE6 , $92722C851482353B ,
$A2BFE8A14CF10364 , $A81A664BBC423001 , $C24B8B70D0F89791 , $C76C51A30654BE30 ,
$D192E819D6EF5218 , $D69906245565A910 , $F40E35855771202A , $106AA07032BBD1B8 ,
$19A4C116B8D2D0C8 , $1E376C085141AB53 , $2748774CDF8EEB99 , $34B0BCB5E19B48A8 ,
$391C0CB3C5C95A63 , $4ED8AA4AE3418ACB , $5B9CCA4F7763E373 , $682E6FF3D6B2B8A3 ,
$748F82EE5DEFB2FC , $78A5636F43172F60 , $84C87814A1F0AB72 , $8CC702081A6439EC ,
$90BEFFFA23631E28 , $A4506CEBDE82BDE9 , $BEF9A3F7B2C67915 , $C67178F2E372532B ,
$CA273ECEEA26619C , $D186B8C721C0C207 , $EADA7DD6CDE0EB1E , $F57D4F7FEE6ED178 ,
$06F067AA72176FBA , $0A637DC5A2C898A6 , $113F9804BEF90DAE , $1B710B35131C471B ,
$28DB77F523047D84 , $32CAAB7B40C72493 , $3C9EBE0A15C9BEBC , $431D67C49C100D4C ,
$4CC5D4BECB3E42B6 , $597F299CFC657E2A , $5FCB6FAB3AD6FAEC , $6C44198C4A475817 ,
K512[] #80 CELLS CONST-DATA

0 VALUE a PRIVATE 0 VALUE b PRIVATE 0 VALUE c PRIVATE 0 VALUE d PRIVATE
0 VALUE e PRIVATE 0 VALUE f PRIVATE 0 VALUE g PRIVATE 0 VALUE h PRIVATE
0 VALUE jj PRIVATE 0 VALUE data PRIVATE

: Ch ( x y z -- u ) >R OVER AND SWAP INVERT R> AND XOR ; PRIVATE
: Maj ( x y z -- u ) >R DUP >R OVER AND R> R@ AND XOR SWAP R> AND XOR ; PRIVATE
: sigma0_512u ( x -- u ) DUP >R #28 ROR R@ #34 ROR XOR R> #39 ROR XOR ; PRIVATE
: sigma1_512u ( x -- u ) DUP >R #14 ROR R@ #18 ROR XOR R> #41 ROR XOR ; PRIVATE
: sigma0_512l ( x -- u ) DUP >R 1 ROR R@ 8 ROR XOR R> 7 RSHIFT XOR ; PRIVATE
: sigma1_512l ( x -- u ) DUP >R #19 ROR R@ #61 ROR XOR R> 6 RSHIFT XOR ; PRIVATE

-- SHA-512: *********************************************************
: SHA512_Init ( -- )
$6A09E667F3BCC908 TO a $BB67AE8584CAA73B TO b
$3C6EF372FE94F82B TO c $A54FF53A5F1D36F1 TO d
$510E527FADE682D1 TO e $9B05688C2B3E6C1F TO f
$1F83D9ABFB41BD6B TO g $5BE0CD19137E2179 TO h
W512[] SHA512_BLOCK_LENGTH ERASE CLEAR bitcount ; PRIVATE

: ROUND512_0_TO_15_a ( u -- ) >R data @+ SWAP TO data BSWAP W512[] R@ CELL[] ! h e sigma1_512u + e f g Ch + K512[] R@ CELL[] @ + W512[] R> CELL[] @ + DUP +TO d ( T1 ) a sigma0_512u + a b c Maj + TO h ; PRIVATE
: ROUND512_0_TO_15_b ( u -- ) >R data @+ SWAP TO data BSWAP W512[] R@ CELL[] ! a f sigma1_512u + f g h Ch + K512[] R@ CELL[] @ + W512[] R> CELL[] @ + DUP +TO e ( T1 ) b sigma0_512u + b c d Maj + TO a ; PRIVATE
: ROUND512_0_TO_15_c ( u -- ) >R data @+ SWAP TO data BSWAP W512[] R@ CELL[] ! b g sigma1_512u + g h a Ch + K512[] R@ CELL[] @ + W512[] R> CELL[] @ + DUP +TO f ( T1 ) c sigma0_512u + c d e Maj + TO b ; PRIVATE
: ROUND512_0_TO_15_d ( u -- ) >R data @+ SWAP TO data BSWAP W512[] R@ CELL[] ! c h sigma1_512u + h a b Ch + K512[] R@ CELL[] @ + W512[] R> CELL[] @ + DUP +TO g ( T1 ) d sigma0_512u + d e f Maj + TO c ; PRIVATE
: ROUND512_0_TO_15_e ( u -- ) >R data @+ SWAP TO data BSWAP W512[] R@ CELL[] ! d a sigma1_512u + a b c Ch + K512[] R@ CELL[] @ + W512[] R> CELL[] @ + DUP +TO h ( T1 ) e sigma0_512u + e f g Maj + TO d ; PRIVATE
: ROUND512_0_TO_15_f ( u -- ) >R data @+ SWAP TO data BSWAP W512[] R@ CELL[] ! e b sigma1_512u + b c d Ch + K512[] R@ CELL[] @ + W512[] R> CELL[] @ + DUP +TO a ( T1 ) f sigma0_512u + f g h Maj + TO e ; PRIVATE
: ROUND512_0_TO_15_g ( u -- ) >R data @+ SWAP TO data BSWAP W512[] R@ CELL[] ! f c sigma1_512u + c d e Ch + K512[] R@ CELL[] @ + W512[] R> CELL[] @ + DUP +TO b ( T1 ) g sigma0_512u + g h a Maj + TO f ; PRIVATE
: ROUND512_0_TO_15_h ( u -- ) >R data @+ SWAP TO data BSWAP W512[] R@ CELL[] ! g d sigma1_512u + d e f Ch + K512[] R@ CELL[] @ + W512[] R> CELL[] @ + DUP +TO c ( T1 ) h sigma0_512u + h a b Maj + TO g ; PRIVATE

: ROUND512_a ( u -- )
>R
W512[] R@ 1+ $0F AND CELL[] @ sigma0_512l ( s0)
W512[] R@ #14 + $0F AND CELL[] @ sigma0_512l ( s1) +
W512[] R@ 9 + $0F AND CELL[] @ + DUP W512[] R@ $0F AND CELL[] +! ( -- u )
h + e sigma1_512u + e f g Ch + K512[] R> CELL[] @ + DUP +TO d ( T1 )
a sigma0_512u + a b c Maj + TO h ; PRIVATE

: ROUND512_b ( u -- )
>R
W512[] R@ 1+ $0F AND CELL[] @ sigma0_512l ( s0)
W512[] R@ #14 + $0F AND CELL[] @ sigma0_512l ( s1) +
W512[] R@ 9 + $0F AND CELL[] @ + DUP W512[] R@ $0F AND CELL[] +! ( -- u )
a + f sigma1_512u + f g h Ch + K512[] R> CELL[] @ + DUP +TO e ( T1 )
b sigma0_512u + b c d Maj + TO a ; PRIVATE

: ROUND512_c ( u -- )
>R
W512[] R@ 1+ $0F AND CELL[] @ sigma0_512l ( s0)
W512[] R@ #14 + $0F AND CELL[] @ sigma0_512l ( s1) +
W512[] R@ 9 + $0F AND CELL[] @ + DUP W512[] R@ $0F AND CELL[] +! ( -- u )
b + g sigma1_512u + g h a Ch + K512[] R> CELL[] @ + DUP +TO f ( T1 )
c sigma0_512u + c d e Maj + TO b ; PRIVATE

: ROUND512_d ( u -- )
>R
W512[] R@ 1+ $0F AND CELL[] @ sigma0_512l ( s0)
W512[] R@ #14 + $0F AND CELL[] @ sigma0_512l ( s1) +
W512[] R@ 9 + $0F AND CELL[] @ + DUP W512[] R@ $0F AND CELL[] +! ( -- u )
c + h sigma1_512u + h a b Ch + K512[] R> CELL[] @ + DUP +TO g ( T1 )
d sigma0_512u + d e f Maj + TO c ; PRIVATE

: ROUND512_e ( u -- )
>R
W512[] R@ 1+ $0F AND CELL[] @ sigma0_512l ( s0)
W512[] R@ #14 + $0F AND CELL[] @ sigma0_512l ( s1) +
W512[] R@ 9 + $0F AND CELL[] @ + DUP W512[] R@ $0F AND CELL[] +! ( -- u )
d + a sigma1_512u + a b c Ch + K512[] R> CELL[] @ + DUP +TO h ( T1 )
e sigma0_512u + e f g Maj + TO d ; PRIVATE

: ROUND512_f ( u -- )
>R
W512[] R@ 1+ $0F AND CELL[] @ sigma0_512l ( s0)
W512[] R@ #14 + $0F AND CELL[] @ sigma0_512l ( s1) +
W512[] R@ 9 + $0F AND CELL[] @ + DUP W512[] R@ $0F AND CELL[] +! ( -- u )
e + b sigma1_512u + b c d Ch + K512[] R> CELL[] @ + DUP +TO a ( T1 )
f sigma0_512u + f g h Maj + TO e ; PRIVATE

: ROUND512_g ( u -- )
>R
W512[] R@ 1+ $0F AND CELL[] @ sigma0_512l ( s0)
W512[] R@ #14 + $0F AND CELL[] @ sigma0_512l ( s1) +
W512[] R@ 9 + $0F AND CELL[] @ + DUP W512[] R@ $0F AND CELL[] +! ( -- u )
f + c sigma1_512u + c d e Ch + K512[] R> CELL[] @ + DUP +TO b ( T1 )
g sigma0_512u + g h a Maj + TO f ; PRIVATE

: ROUND512_h ( u -- )
>R
W512[] R@ 1+ $0F AND CELL[] @ sigma0_512l ( s0)
W512[] R@ #14 + $0F AND CELL[] @ sigma0_512l ( s1) +
W512[] R@ 9 + $0F AND CELL[] @ + DUP W512[] R@ $0F AND CELL[] +! ( -- u )
g + d sigma1_512u + d e f Ch + K512[] R> CELL[] @ + DUP +TO c ( T1 )
h sigma0_512u + h a b Maj + TO g ; PRIVATE

0 VALUE r#
: shows CR r# 2 .R SPACE a H. space b H. space c H. space d H.
CR 3 SPACES e H. space f H. space g H. space h H. 1 +TO r#
r# ?EXIT W512[] #16 CELLS DUMP ;

: SHA512_Transform ( addr -- )
TO data
( 16 rounds ) ( a b c d e f g h ) 0 ROUND512_0_TO_15_a ( h a b c d e f g ) 1 ROUND512_0_TO_15_h
( g h a b c d e f ) 2 ROUND512_0_TO_15_g ( f g h a b c d e ) 3 ROUND512_0_TO_15_f
( e f g h a b c d ) 4 ROUND512_0_TO_15_e ( d e f g h a b c ) 5 ROUND512_0_TO_15_d
( c d e f g h a b ) 6 ROUND512_0_TO_15_c ( b c d e f g h a ) 7 ROUND512_0_TO_15_b

( a b c d e f g h ) 8 ROUND512_0_TO_15_a ( h a b c d e f g ) 9 ROUND512_0_TO_15_h
( g h a b c d e f ) #10 ROUND512_0_TO_15_g ( f g h a b c d e ) #11 ROUND512_0_TO_15_f
( e f g h a b c d ) #12 ROUND512_0_TO_15_e ( d e f g h a b c ) #13 ROUND512_0_TO_15_d
( c d e f g h a b ) #14 ROUND512_0_TO_15_c ( b c d e f g h a ) #15 ROUND512_0_TO_15_b


( 64 rounds ) ( a b c d e f g h ) #16 ROUND512_a ( h a b c d e f g ) #17 ROUND512_h
( g h a b c d e f ) #18 ROUND512_g ( f g h a b c d e ) #19 ROUND512_f
( e f g h a b c d ) #20 ROUND512_e ( d e f g h a b c ) #21 ROUND512_d
( c d e f g h a b ) #22 ROUND512_c ( b c d e f g h a ) #23 ROUND512_b

( a b c d e f g h ) #24 ROUND512_a ( h a b c d e f g ) #25 ROUND512_h
( g h a b c d e f ) #26 ROUND512_g ( f g h a b c d e ) #27 ROUND512_f
( e f g h a b c d ) #28 ROUND512_e ( d e f g h a b c ) #29 ROUND512_d
( c d e f g h a b ) #30 ROUND512_c ( b c d e f g h a ) #31 ROUND512_b

( a b c d e f g h ) #32 ROUND512_a ( h a b c d e f g ) #33 ROUND512_h
( g h a b c d e f ) #34 ROUND512_g ( f g h a b c d e ) #35 ROUND512_f
( e f g h a b c d ) #36 ROUND512_e ( d e f g h a b c ) #37 ROUND512_d
( c d e f g h a b ) #38 ROUND512_c ( b c d e f g h a ) #39 ROUND512_b

( a b c d e f g h ) #40 ROUND512_a ( h a b c d e f g ) #41 ROUND512_h
( g h a b c d e f ) #42 ROUND512_g ( f g h a b c d e ) #43 ROUND512_f
( e f g h a b c d ) #44 ROUND512_e ( d e f g h a b c ) #45 ROUND512_d
( c d e f g h a b ) #46 ROUND512_c ( b c d e f g h a ) #47 ROUND512_b

( a b c d e f g h ) #48 ROUND512_a ( h a b c d e f g ) #49 ROUND512_h
( g h a b c d e f ) #50 ROUND512_g ( f g h a b c d e ) #51 ROUND512_f
( e f g h a b c d ) #52 ROUND512_e ( d e f g h a b c ) #53 ROUND512_d
( c d e f g h a b ) #54 ROUND512_c ( b c d e f g h a ) #55 ROUND512_b

( a b c d e f g h ) #56 ROUND512_a ( h a b c d e f g ) #57 ROUND512_h
( g h a b c d e f ) #58 ROUND512_g ( f g h a b c d e ) #59 ROUND512_f
( e f g h a b c d ) #60 ROUND512_e ( d e f g h a b c ) #61 ROUND512_d
( c d e f g h a b ) #62 ROUND512_c ( b c d e f g h a ) #63 ROUND512_b

( a b c d e f g h ) #64 ROUND512_a ( h a b c d e f g ) #65 ROUND512_h
( g h a b c d e f ) #66 ROUND512_g ( f g h a b c d e ) #67 ROUND512_f
( e f g h a b c d ) #68 ROUND512_e ( d e f g h a b c ) #69 ROUND512_d
( c d e f g h a b ) #70 ROUND512_c ( b c d e f g h a ) #71 ROUND512_b

( a b c d e f g h ) #72 ROUND512_a ( h a b c d e f g ) #73 ROUND512_h
( g h a b c d e f ) #74 ROUND512_g ( f g h a b c d e ) #75 ROUND512_f
( e f g h a b c d ) #76 ROUND512_e ( d e f g h a b c ) #77 ROUND512_d
( c d e f g h a b ) #78 ROUND512_c ( b c d e f g h a ) #79 ROUND512_b ; PRIVATE

: SHA512_Update ( c-addr u -- )
0 0 LOCALS| freespace usedspace len addr |
len 0= ?EXIT
bitcount 3 RSHIFT SHA512_BLOCK_LENGTH MOD TO usedspace
usedspace
IF SHA512_BLOCK_LENGTH usedspace - TO freespace
len freespace >=
IF addr W512[] usedspace + freespace MOVE
freespace 3 LSHIFT +TO bitcount
freespace -TO len freespace +TO addr
W512[] SHA512_Transform
ELSE addr W512[] usedspace + len MOVE
len 3 LSHIFT +TO bitcount
CLEAR usedspace CLEAR freespace EXIT
ENDIF
ENDIF
BEGIN len SHA512_BLOCK_LENGTH >=
WHILE addr SHA512_Transform
SHA512_BLOCK_LENGTH 3 LSHIFT +TO bitcount
SHA512_BLOCK_LENGTH -TO len SHA512_BLOCK_LENGTH +TO addr
REPEAT
len IF addr W512[] len MOVE len 3 LSHIFT +TO bitcount ENDIF ; PRIVATE

: SHA512_Last ( -- )
bitcount 3 RSHIFT SHA512_BLOCK_LENGTH MOD LOCAL usedspace
bitcount BSWAP TO bitcount
usedspace
IF $80 W512[] usedspace + C! 1 +TO usedspace
usedspace SHA512_SHORT_BLOCK_LENGTH <=
IF W512[] usedspace + SHA512_SHORT_BLOCK_LENGTH usedspace - ERASE
ELSE usedspace SHA512_BLOCK_LENGTH < IF W512[] usedspace + SHA512_BLOCK_LENGTH usedspace - ERASE ENDIF
W512[] SHA512_Transform W512[] SHA512_BLOCK_LENGTH 2- ERASE
ENDIF
ELSE W512[] SHA512_SHORT_BLOCK_LENGTH ERASE $80 W512[] C!
ENDIF
0 W512[] SHA512_SHORT_BLOCK_LENGTH + !
bitcount W512[] SHA512_SHORT_BLOCK_LENGTH CELL+ + !
W512[] SHA512_Transform ; PRIVATE

: SHA512_Final ( -- )
SHA512_Last
digest[] a BSWAP SWAP !+ b BSWAP SWAP !+
c BSWAP SWAP !+ d BSWAP SWAP !+
e BSWAP SWAP !+ f BSWAP SWAP !+
g BSWAP SWAP !+ h BSWAP SWAP ! ; PRIVATE

: SHA512_End ( -- c-addr u )
SHA512_Final
digesttext[] C0!
digest[] SHA512_DIGEST_LENGTH BOUNDS
DO I @ BSWAP (H.) 1 /STRING digesttext[] PLACE+ 8 +LOOP
digesttext[] COUNT ; PRIVATE

: SHA512_Data ( data len -- c-addr u ) SHA512_Init SHA512_Update SHA512_End ;
: .SHA512 ( c-addr u -- ) 0 LOCAL crs BOUNDS ?DO crs 6 MOD 0= IF CR ENDIF I 8 TYPE SPACE 1 +TO crs 8 +LOOP ;

: SHAspeed ( -- )
#40000000 ALLOCATE ?ALLOCATE LOCAL buf
buf #40000000 'a' FILL
CR ." Processing 40 Mbytes ... " TIMER-RESET
buf #40000000 SHA512_Data 2DROP
.ELAPSED
buf FREE ?ALLOCATE ;

:ABOUT CR .~ Try: S" abc" SHA512_Data TYPE~
CR ." = DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A 2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F"
CR
CR .~ S" abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" SHA512_Data TYPE
CR ." = 8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018 501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909"
CR
CR ." SHAspeed -- test speed with a 40 MB buffer (>181 MB/sec)." ;

.ABOUT -sha512 CR
DEPRIVE

(* End of Source *)

-marcel

Anton Ertl

unread,
Jan 30, 2022, 10:09:03 AM1/30/22
to
Marcel Hendrix <m...@iae.nl> writes:
>On Saturday, January 29, 2022 at 11:16:08 PM UTC+1, Krishna Myneni wrote:
>> On 1/22/22 15:52, Krishna Myneni wrote:
>> The hash functions are designed
>> to work with low-level microprocessor instructions,

As Marcel Hendrix demonstrates, the the necessary operations are
available in Forth or (in case of rotate words) easy to add for a
Forth implementor.

>(*
> * LANGUAGE : ANS Forth with extensions
> * PROJECT : Forth Environments
> * DESCRIPTION : Based on SHA-512 from Aaron D. Gifford - http://www.aarongifford.com/
> * CATEGORY : Encrypter tool
> * AUTHOR : Marcel Hendrix
> * LAST CHANGE : December 1, 2012, Marcel Hendrix
> *)

Thanks. I notice that you have a word ROR, but it does not say
whether it's a 32-bit ROR or a 64-bit ROR. Gforth makes the same
mistake, and documents ROR as "Rotate all bits of u1 right by u
bits.". But algorithms using rotation typically need a specific ROR,
not one that rotates all bits, so I guess we should have ror32 and
ror64 instead of or in addition to ror.

One other thing I notice is that you put the values a..h into values.
I wonder if it's possible to write the code such that the Forth system
has a better chance of keeping them in registers; maybe keep the
values on the stack. And if I understand correctly how the values are
handled, this means that the ROUND512 words become one, with a 7 -roll
between the rounds.

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2021: https://euro.theforth.net/2021

Marcel Hendrix

unread,
Jan 30, 2022, 2:10:28 PM1/30/22
to
On Sunday, January 30, 2022 at 4:09:03 PM UTC+1, Anton Ertl wrote:
> Marcel Hendrix <m...@iae.nl> writes:
> >On Saturday, January 29, 2022 at 11:16:08 PM UTC+1, Krishna Myneni wrote:
> >> On 1/22/22 15:52, Krishna Myneni wrote:
> >> The hash functions are designed
> >> to work with low-level microprocessor instructions,
> As Marcel Hendrix demonstrates, the the necessary operations are
> available in Forth or (in case of rotate words) easy to add for a
> Forth implementor.
> >(*
> > * LANGUAGE : ANS Forth with extensions
> > * PROJECT : Forth Environments
> > * DESCRIPTION : Based on SHA-512 from Aaron D. Gifford - http://www.aarongifford.com/
> > * CATEGORY : Encrypter tool
> > * AUTHOR : Marcel Hendrix
> > * LAST CHANGE : December 1, 2012, Marcel Hendrix
> > *)
> Thanks. I notice that you have a word ROR, but it does not say
> whether it's a 32-bit ROR or a 64-bit ROR. Gforth makes the same
> mistake, and documents ROR as "Rotate all bits of u1 right by u
> bits.". But algorithms using rotation typically need a specific ROR,
> not one that rotates all bits, so I guess we should have ror32 and
> ror64 instead of or in addition to ror.

At thread start I mentioned ASHR32 ROR32 ROL32 RSHIFT32
LSHIFT32 but apparently there was no need for them here.

> One other thing I notice is that you put the values a..h into values.
> I wonder if it's possible to write the code such that the Forth system
> has a better chance of keeping them in registers; maybe keep the
> values on the stack.

I would have gone picking and rolling mad without locals here.

It runs at 400MB/s with current hardware so for now it should
be ok for encoding an occasional e-mail.

> And if I understand correctly how the values are
> handled, this means that the ROUND512 words become one, with a 7 -roll
> between the rounds.

I am sorry, but -- "becomes one?"

-marcel

minf...@arcor.de

unread,
Jan 30, 2022, 2:56:53 PM1/30/22
to
Anton Ertl schrieb am Sonntag, 30. Januar 2022 um 16:09:03 UTC+1:
> One other thing I notice is that you put the values a..h into values.
> I wonder if it's possible to write the code such that the Forth system
> has a better chance of keeping them in registers; maybe keep the
> values on the stack.

Just musing:

Put the values into locals of a wrapper function, declare SHA512 et al
as (pseudo)closures with access to outer wrapper's locals (classic
closures store a copy of outer locals in the heap, this wouldn't help here).

Alas standard Forth quotations are rather limited, so one would have to
extend their concept.

Paul Rubin

unread,
Jan 30, 2022, 3:55:12 PM1/30/22
to
Marcel Hendrix <m...@iae.nl> writes:
>> And if I understand correctly how the values are handled, this means
>> that the ROUND512 words become one, with a 7 -roll between the
>> rounds.
>
> I am sorry, but -- "becomes one?"

I think that means: the words ROUND512_0_TO_15_a , ROUND512_0_TO_15_b
etc. are all the same code except the args are permuted. By taking
the args on the stack instead, and doing 7 -ROLL between rounds, you
can combine those ROUND512_0_TO_15_x words into a single word.
Although, -ROLL is non-standard iirc.

Anton Ertl

unread,
Jan 30, 2022, 5:46:28 PM1/30/22
to
Exactly. I have now changed to program to replace all the
ROUND512_0_TO_15 and all ROUND512 words with:

: ROUND512_0_TO_15 ( a b c d e f g h u -- h a b c d e f g ) locals| u h g f e d c b a |
data @+ SWAP TO data BSWAP W512[] u CELL[] !
h e sigma1_512u + e f g Ch + K512[] u CELL[] @ + W512[] u CELL[] @ + DUP +TO d ( T1 )
a sigma0_512u + a b c Maj + ( h )
a b c d e f g ; PRIVATE

: ROUND512 ( a b c d e f g h u -- h a b c d e f g ) locals| u h g f e d c b a |
W512[] u 1+ $0F AND CELL[] @ sigma0_512l ( s0)
W512[] u #14 + $0F AND CELL[] @ sigma0_512l ( s1) +
W512[] u 9 + $0F AND CELL[] @ + DUP W512[] u $0F AND CELL[] +! ( -- u )
h + e sigma1_512u + e f g Ch + K512[] u CELL[] @ + DUP +TO d ( T1 )
a sigma0_512u + a b c Maj + ( h )
a b c d e f g ; PRIVATE

and SHA512_Transform with

: SHA512_Transform ( addr -- )
TO data
a b c d e f g h
( 16 rounds ) 0 ROUND512_0_TO_15 1 ROUND512_0_TO_15
2 ROUND512_0_TO_15 3 ROUND512_0_TO_15
4 ROUND512_0_TO_15 5 ROUND512_0_TO_15
6 ROUND512_0_TO_15 7 ROUND512_0_TO_15

8 ROUND512_0_TO_15 9 ROUND512_0_TO_15
#10 ROUND512_0_TO_15 #11 ROUND512_0_TO_15
#12 ROUND512_0_TO_15 #13 ROUND512_0_TO_15
#14 ROUND512_0_TO_15 #15 ROUND512_0_TO_15


( 64 rounds ) #16 ROUND512 #17 ROUND512
#18 ROUND512 #19 ROUND512
#20 ROUND512 #21 ROUND512
#22 ROUND512 #23 ROUND512

#24 ROUND512 #25 ROUND512
#26 ROUND512 #27 ROUND512
#28 ROUND512 #29 ROUND512
#30 ROUND512 #31 ROUND512

#32 ROUND512 #33 ROUND512
#34 ROUND512 #35 ROUND512
#36 ROUND512 #37 ROUND512
#38 ROUND512 #39 ROUND512

#40 ROUND512 #41 ROUND512
#42 ROUND512 #43 ROUND512
#44 ROUND512 #45 ROUND512
#46 ROUND512 #47 ROUND512

#48 ROUND512 #49 ROUND512
#50 ROUND512 #51 ROUND512
#52 ROUND512 #53 ROUND512
#54 ROUND512 #55 ROUND512

#56 ROUND512 #57 ROUND512
#58 ROUND512 #59 ROUND512
#60 ROUND512 #61 ROUND512
#62 ROUND512 #63 ROUND512

#64 ROUND512 #65 ROUND512
#66 ROUND512 #67 ROUND512
#68 ROUND512 #69 ROUND512
#70 ROUND512 #71 ROUND512

#72 ROUND512 #73 ROUND512
#74 ROUND512 #75 ROUND512
#76 ROUND512 #77 ROUND512
#78 ROUND512 #79 ROUND512
TO h TO g TO f TO e TO d TO c TO b TO a
; PRIVATE

It seems to work and takes almost twice as much time on
iForth-5.1-mini as the original version. However, I expect that on a
Forth system with a better locals implementation and enough registers,
the performance would be better than the original version.

>Although, -ROLL is non-standard iirc.

I eliminated -ROLL by letting the word put the updated values on the
stack already in rotated form.

Another approach would be to have the values on the stack in reverse
order, then one could use 7 ROLL (instead of using 7 -ROLL for the
order currently used).

Anton Ertl

unread,
Jan 31, 2022, 2:00:44 AM1/31/22
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>Paul Rubin <no.e...@nospam.invalid> writes:
>>Marcel Hendrix <m...@iae.nl> writes:
>>>> And if I understand correctly how the values are handled, this means
>>>> that the ROUND512 words become one, with a 7 -roll between the
>>>> rounds.
>>>
>>> I am sorry, but -- "becomes one?"
>>
>>I think that means: the words ROUND512_0_TO_15_a , ROUND512_0_TO_15_b
>>etc. are all the same code except the args are permuted. By taking
>>the args on the stack instead, and doing 7 -ROLL between rounds, you
>>can combine those ROUND512_0_TO_15_x words into a single word.
>
>Exactly. I have now changed to program to replace all the
>ROUND512_0_TO_15 and all ROUND512 words with:
...
You can find the changed program in

https://www.complang.tuwien.ac.at/forth/programs/sha512.4th

Paul Rubin

unread,
Jan 31, 2022, 2:50:43 AM1/31/22
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> Exactly. I have now changed to program to replace all the
> ROUND512_0_TO_15 and all ROUND512 words with:

I wonder how difficult it would have been to make a macro generate the
code for a given permutation, so you could have unrolled code by

ROUNDX a b c d e f g h
ROUNDX b c d e f g h a
etc.

or something like that.

Anton Ertl

unread,
Jan 31, 2022, 5:12:37 AM1/31/22
to
Try it out. It's possible, but not pretty. There is a reason why
Marcel Hendrix did not go there. I like my current solution much
better, and with inlining, allocating stack items and locals to
registers, and a decent native code generator, it will be as fast as
assembly language; and it's easier to comprehend and change.

Marcel Hendrix

unread,
Jan 31, 2022, 10:55:22 AM1/31/22
to
On Sunday, January 30, 2022 at 11:46:28 PM UTC+1, Anton Ertl wrote:
> Paul Rubin <no.e...@nospam.invalid> writes:
> >Marcel Hendrix <m...@iae.nl> writes:
> >>> And if I understand correctly how the values are handled, this means
> >>> that the ROUND512 words become one, with a 7 -roll between the
> >>> rounds.
> >>
> >> I am sorry, but -- "becomes one?"
[..]
> ( 64 rounds ) #16 ROUND512 #17 ROUND512
> #18 ROUND512 #19 ROUND512
> #20 ROUND512 #21 ROUND512
> #22 ROUND512 #23 ROUND512
[..]
> #72 ROUND512 #73 ROUND512
> #74 ROUND512 #75 ROUND512
> #76 ROUND512 #77 ROUND512
> #78 ROUND512 #79 ROUND512
> TO h TO g TO f TO e TO d TO c TO b TO a
> ; PRIVATE

Isn't that just a DO LOOP now?
[..]
> - anton

Anton Ertl

unread,
Jan 31, 2022, 1:04:05 PM1/31/22
to
Marcel Hendrix <m...@iae.nl> writes:
>> ( 64 rounds ) #16 ROUND512 #17 ROUND512
>> #18 ROUND512 #19 ROUND512
>> #20 ROUND512 #21 ROUND512
>> #22 ROUND512 #23 ROUND512
>[..]
>> #72 ROUND512 #73 ROUND512
>> #74 ROUND512 #75 ROUND512
>> #76 ROUND512 #77 ROUND512
>> #78 ROUND512 #79 ROUND512
>> TO h TO g TO f TO e TO d TO c TO b TO a
>> ; PRIVATE
>
>Isn't that just a DO LOOP now?

Yes, one could put it in a DO LOOP:

: SHA512_Transform ( addr -- )
TO data
a b c d e f g h
#16 #00 do i ROUND512_0_TO_15 loop
#80 #16 do i ROUND512 loop
TO h TO g TO f TO e TO d TO c TO b TO a
; PRIVATE

Causes a slowdown by a factor 1.14, which I find quite surprising
given the large amount of stuff going on in ROUND512 and
ROUND512_0_TO_15.

Unrolling by a factor of 8 could help a compiler of the kind I have in
mind to avoid a bunch of register-register moves at the end of each
round, but I doubt that it helps iForth as much; checking, it provides
a speedup factor 1.06-1.07 over no unrolling.

What's more disturbing is that I have now first read the greeting
properly, tried 'S" abc" SHA512_Data TYPE' and got a result different
from what the greeting suggests:

According to the greeting:

Try: S" abc" SHA512_Data TYPE
= DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A
2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F

Actual output (iforth 5.1 mini):
FORTH> S" abc" SHA512_Data cr TYPE
66F8388B39DA945C7815A02216740C7F48EAF39A508EE81D353D0C20199047119416DAA70D9C76FA
81EA7D11420050678981B29D107A5D90E86D04F8E90144A8 ok

Paul Rubin

unread,
Jan 31, 2022, 4:27:05 PM1/31/22
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>>I wonder how difficult it would have been to make a macro
> Try it out. It's possible, but not pretty.

I didn't see any non-horrendous ways to do it but figured I'm not adept
enough to see the right way. Maybe all are horrendous?

> with inlining, allocating stack items and locals to registers, and a
> decent native code generator

Are there Forth compilers in common use that do that?

Krishna Myneni

unread,
Jan 31, 2022, 4:51:31 PM1/31/22
to
The intermediate NIST test case, after each round, is shown here

https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA512.pdf

Interestingly, the original program from Aaron D. Gifford,

https://aarongifford.com/computers/sha2-1.0.1.zip

also does not appear to produce the NIST-documented output for this test
case. The input file, testfile.txt, contains the string "abc".

$ ./sha2prog testfile.txt
SHA-256 (testfile.txt) =
edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb
...
SHA-512 (testfile.txt) =
4f285d0c0cc77286d8731798b7aae2639e28270d4166f40d769cbbdca5230714d848483d364e2f39fe6cb9083c15229b39a33615ebc6d57605f7c43f6906739d

The SHA-256 hash output by Gifford's program matches the hash from
sha256sum utility on Linux,

$ sha256sum testfile.txt
edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb
testfile.txt

--
Krishna

Anton Ertl

unread,
Feb 1, 2022, 3:52:25 AM2/1/22
to
lxf allocates data and return stack items and locals to registers, has
a decent native code generator, but not inlining. I could work around
the non-inlining; however, we also need a Forth system that can use
~11 registers for these purposes, and that's not the case for 32-bit
lxf (and the 64-bit variant has not yet been published).

iForth and VFX have inlining and a decent native-code generator, but
don't allocate locals to registers.

So, for now, we don't have a system that does it all.

Anton Ertl

unread,
Feb 1, 2022, 4:05:05 AM2/1/22
to
However, the sha512sum tool does:

[~:127967] echo -n abc|sha512sum
ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f -

Paul Rubin

unread,
Feb 1, 2022, 6:32:58 AM2/1/22
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>>https://aarongifford.com/computers/sha2-1.0.1.zip
>>also does not appear to produce the NIST-documented output for this test
>>case. The input file, testfile.txt, contains the string "abc".

I don't see a testfile.txt file in this zip. I was able to compile
the C program though it gave a compiler warning about undeclared strcmp.

>>SHA-512 (testfile.txt) =
>>4f285d0c0cc77286d8731798b7aae2639e282....

That is the sha512 hash of "abc\n" (4 chars, abc followed by newline).

> [~:127967] echo -n abc|sha512sum
> ddaf35a193617a...

I get the same with Aaron Gifford's program.

Krishna Myneni

unread,
Feb 1, 2022, 8:27:09 AM2/1/22
to
The file, testfile.txt, is one which I created for use with programs.

Please show your input command and output from Aaron Gifford's program.
I compiled it with gcc without any special switches. How did you build
the program?

--
Krishna

Krishna Myneni

unread,
Feb 1, 2022, 8:32:58 AM2/1/22
to
Never mind. I see that the trailing newline is the problem. Aaron
Gifford's program works.

--
Krishna

Krishna Myneni

unread,
Feb 1, 2022, 12:13:45 PM2/1/22
to
On 1/31/22 11:36, Anton Ertl wrote:
...
> What's more disturbing is that I have now first read the greeting
> properly, tried 'S" abc" SHA512_Data TYPE' and got a result different
> from what the greeting suggests:
>
> According to the greeting:
>
> Try: S" abc" SHA512_Data TYPE
> = DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A
> 2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F
>
> Actual output (iforth 5.1 mini):
> FORTH> S" abc" SHA512_Data cr TYPE
> 66F8388B39DA945C7815A02216740C7F48EAF39A508EE81D353D0C20199047119416DAA70D9C76FA
> 81EA7D11420050678981B29D107A5D90E86D04F8E90144A8 ok
>

I can confirm the above result with the kforth64 port of Marcel's posted
code. The kforth64 port of sha512.4th may be found at

https://github.com/mynenik/kForth-64/blob/master/forth-src/sha512.4th

The code should run on standard Forth (include files specific to kForth
may be omitted, except for modules.4th which is in standard Forth).

To load the code under kforth64 and place the SHA512 module words in the
search order,

include ans-words
include modules
include strings
include utils
include dump
include sha512
also sha512

--
Krishna

------
s" abc" SHA512_Data
ok
type
66F8388B39DA945C7815A02216740C7F48EAF39A508EE81D353D0C20199047119416DAA70D9C76FA81EA7D11420050678981B29D107A5D90E86D04F8E90144A8
ok
ok
SHAspeed

Processing 40 Mbytes ... 11906 ms elapsed
ok
------






Krishna Myneni

unread,
Feb 4, 2022, 10:41:40 AM2/4/22
to
On 1/22/22 15:52, Krishna Myneni wrote:
> While many of the Forth programs written for 32-bit Forths were easily
> ported to 64-bit kForth, in a way that the programs work on both 32-bit
> and 64-bit systems, one notable exception was Jabari Zakiya's program
> for computing the md5 sum of a buffer or a file, hmac-md5.4th. The
> program's arithmetic and logic depended on a 32-bit cell size.
>
...
> ... The revised program, which
> still needs a fix to run on big-endian systems, may be found in the most
> recent kForth-32 master and kForth-64 master repos on GitHub. Here is a
> link to the revised program:
>
> https://github.com/mynenik/kForth-64/blob/master/forth-src/hmac-md5.4th
>
> It will run the tests, executed by the word HMAC-TESTS properly under
> both 32-bit and 64-bit (little-endian) systems.
...
A subtle problem in the definition of the word STORELEN limited the
maximum file size for which an accurate MD5 hash could be generated on a
64-bit Forth system, to about 256 MB. The tests provided in the program
for small data buffers did not pick this up, but I recently performed
tests of the word MD5FILE on kforth64 and found that it gave the wrong
hash for files above this size. The problem does not occur on 32-bit
Forth systems, for which the hmac-md5.4th program was originally written
-- on 32-bit systems, the file size is limited anyway to about 2 GB.

The problem has been fixed, and the revised hmac-md5.4th now appears to
work properly for file sizes exceeding 256 MB. The revised file may be
found at

https://github.com/mynenik/kForth-64/blob/master/forth-src/hmac-md5.4th

The largest file I tested with the program under kforth64 was about 2.2 GB:

---
md5file StarTrails.mp4

Bytesize: 2245592130
MD5 Hash: 12f30e7bdf4c6a4f9974f1473e79ad56
---
$ md5sum StarTrails.mp4
12f30e7bdf4c6a4f9974f1473e79ad56 StarTrails.mp4
---

The hmac-md5.4th program, under kforth64, is really too slow to be
useful for such large files. Critical parts of the program need to be in
the form of CODE words.

--
Krishna



0 new messages