         [ d a b c 2  S22 30 ]
         [ c d a b 7  S23 31 ]
         [ b c d a 12 S24 32 ]
-    } [ G ] with-md5-round ;
+    } [ G ] with-md5-round ; inline
 
-: (process-md5-block-H) ( block -- )
+: (process-md5-block-H) ( block v -- )
     {
         [ a b c d 5  S31 33 ]
         [ d a b c 8  S32 34 ]

CONSTANT: S43 15
CONSTANT: S44 21




SYMBOLS: a b c d old-a old-b old-c old-d ;

: initialize-md5 ( -- )
    0 bytes-read set
    HEX: 67452301 dup a set old-a set
    HEX: efcdab89 dup b set old-b set
    HEX: 98badcfe dup c set old-c set
    HEX: 10325476 dup d set old-d set ;

: update-md ( -- )
    old-a a update-old-new
    old-b b update-old-new
    old-c c update-old-new
    old-d d update-old-new ;


:: (ABCD) ( x a b c d k s i func -- )
    #! a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
    a [
        b get c get d get func call w+
        k x nth-unsafe w+
        i T w+
        s bitroll-32
        b get w+
    ] change ; inline

MACRO: with-md5-round ( ops func -- )
    '[ [ _ (ABCD) ] compose ] map '[ _ cleave ] ;

: (process-md5-block-F) ( block -- )
    {
        [ a b c d 0  S11 1  ]
        [ d a b c 1  S12 2  ]

INSTANCE: md5 stream-checksum

M: md5 checksum-stream
    drop <md5-state> [ stream>md5 ] [ get-md5 ] bi ;
