]> gitweb.factorcode.org Git - factor.git/blobdiff - basis/checksums/md5/md5.factor
factor: trim using lists
[factor.git] / basis / checksums / md5 / md5.factor
index ee00817ea50cf90f7d0a816ea3ecf39c63dd8b13..bc8481f5ef603899b1bbc0b6da14fd11d7c66404 100644 (file)
@@ -1,47 +1,52 @@
 ! Copyright (C) 2006, 2008 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel io io.binary io.files io.streams.byte-array math
-math.functions math.parser namespaces splitting grouping strings
-sequences byte-arrays locals sequences.private macros fry
-io.encodings.binary math.bitwise checksums accessors
-checksums.common checksums.stream combinators combinators.smart ;
+USING: accessors alien.c-types alien.data byte-arrays checksums
+checksums.common combinators grouping hints kernel
+kernel.private literals math math.bitwise
+math.functions sequences sequences.private specialized-arrays ;
+SPECIALIZED-ARRAY: uint
 IN: checksums.md5
 
 SINGLETON: md5
-INSTANCE: md5 stream-checksum
 
-TUPLE: md5-state < checksum-state state old-state ;
+INSTANCE: md5 block-checksum
 
-: <md5-state> ( -- md5-state )
-    64 md5-state new-checksum-state
-        { HEX: 67452301 HEX: efcdab89 HEX: 98badcfe HEX: 10325476 }
+TUPLE: md5-state < block-checksum-state
+{ state uint-array }
+{ old-state uint-array } ;
+
+: <md5-state> ( -- md5 )
+    md5-state new-checksum-state
+        64 >>block-size
+        uint-array{ 0x67452301 0xefcdab89 0x98badcfe 0x10325476 }
         [ clone >>state ] [ >>old-state ] bi ;
 
-<PRIVATE
+M: md5 initialize-checksum-state drop <md5-state> ;
 
-: v-w+ ( v1 v2 -- v3 ) [ w+ ] 2map ;
+<PRIVATE
 
-: update-md5-state ( md5-state -- )
-    [ state>> ] [ old-state>> v-w+ dup clone ] [ ] tri
-    [ (>>old-state) ] [ (>>state) ] bi ; inline
+: update-md5 ( md5 -- )
+    [ state>> ] [ old-state>> [ w+ ] 2map dup clone ] [ ] tri
+    [ old-state<< ] [ state<< ] bi ; inline
 
-: T ( N -- Y )
-    sin abs 32 2^ * >integer ; inline
+CONSTANT: T $[
+    80 <iota> [ sin abs 32 2^ * >integer ] uint-array{ } map-as
+]
 
 :: F ( X Y Z -- FXYZ )
-    #! F(X,Y,Z) = XY v not(X) Z
+    ! F(X,Y,Z) = XY v not(X) Z
     X Y bitand X bitnot Z bitand bitor ; inline
 
 :: G ( X Y Z -- GXYZ )
-    #! G(X,Y,Z) = XZ v Y not(Z)
+    ! G(X,Y,Z) = XZ v Y not(Z)
     X Z bitand Y Z bitnot bitand bitor ; inline
 
 : H ( X Y Z -- HXYZ )
-    #! H(X,Y,Z) = X xor Y xor Z
+    ! H(X,Y,Z) = X xor Y xor Z
     bitxor bitxor ; inline
 
 :: I ( X Y Z -- IXYZ )
-    #! I(X,Y,Z) = Y xor (X v not(Z))
+    ! I(X,Y,Z) = Y xor (X v not(Z))
     Z bitnot X bitor Y bitxor ; inline
 
 CONSTANT: S11 7
@@ -66,23 +71,23 @@ CONSTANT: b 1
 CONSTANT: c 2
 CONSTANT: d 3
 
-:: (ABCD) ( x V a b c d k s i quot -- )
-    #! a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
-    a V [
-        b V nth-unsafe
-        c V nth-unsafe
-        d V nth-unsafe quot call w+
+:: (ABCD) ( x state a b c d k s i quot -- )
+    ! a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
+    a state [
+        b state nth-unsafe
+        c state nth-unsafe
+        d state nth-unsafe quot call w+
         k x nth-unsafe w+
-        i T w+
+        i T nth-unsafe w+
         s bitroll-32
-        b V nth-unsafe w+
-    ] change-nth ; inline
+        b state nth-unsafe w+
+    ] change-nth-unsafe ; inline
 
-MACRO: with-md5-round ( ops quot -- )
+MACRO: with-md5-round ( ops quot -- quot )
     '[ [ _ (ABCD) ] compose ] map '[ _ 2cleave ] ;
 
-: (process-md5-block-F) ( block v -- )
-    {
+: (process-md5-block-F) ( block state -- )
+    { uint-array uint-array } declare {
         [ a b c d 0  S11 1  ]
         [ d a b c 1  S12 2  ]
         [ c d a b 2  S13 3  ]
@@ -99,10 +104,10 @@ MACRO: with-md5-round ( ops quot -- )
         [ d a b c 13 S12 14 ]
         [ c d a b 14 S13 15 ]
         [ b c d a 15 S14 16 ]
-    } [ F ] with-md5-round ; inline
+    } [ F ] with-md5-round ;
 
-: (process-md5-block-G) ( block v -- )
-    {
+: (process-md5-block-G) ( block state -- )
+    { uint-array uint-array } declare {
         [ a b c d 1  S21 17 ]
         [ d a b c 6  S22 18 ]
         [ c d a b 11 S23 19 ]
@@ -119,10 +124,10 @@ MACRO: with-md5-round ( ops quot -- )
         [ 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 ; inline
+    } [ G ] with-md5-round ;
 
-: (process-md5-block-H) ( block v -- )
-    {
+: (process-md5-block-H) ( block state -- )
+    { uint-array uint-array } declare {
         [ a b c d 5  S31 33 ]
         [ d a b c 8  S32 34 ]
         [ c d a b 11 S33 35 ]
@@ -139,10 +144,10 @@ MACRO: with-md5-round ( ops quot -- )
         [ d a b c 12 S32 46 ]
         [ c d a b 15 S33 47 ]
         [ b c d a 2  S34 48 ]
-    } [ H ] with-md5-round ; inline
+    } [ H ] with-md5-round ;
 
-: (process-md5-block-I) ( block v -- )
-    {
+: (process-md5-block-I) ( block state -- )
+    { uint-array uint-array } declare {
         [ a b c d 0  S41 49 ]
         [ d a b c 7  S42 50 ]
         [ c d a b 14 S43 51 ]
@@ -159,25 +164,41 @@ MACRO: with-md5-round ( ops quot -- )
         [ d a b c 11 S42 62 ]
         [ c d a b 2  S43 63 ]
         [ b c d a 9  S44 64 ]
-    } [ I ] with-md5-round ; inline
+    } [ I ] with-md5-round ;
 
-M: md5-state checksum-block ( block state -- )
+: byte-array>le ( byte-array -- byte-array )
+    little-endian? [
+        dup 4 <groups> [
+            [ [ 1 2 ] dip exchange-unsafe ]
+            [ [ 0 3 ] dip exchange-unsafe ] bi
+        ] each
+    ] unless ;
+
+HINTS: byte-array>le byte-array ;
+
+M: md5-state checksum-block
     [
-        [ 4 <groups> [ le> ] map ] [ state>> ] bi* {
+        [ byte-array>le uint cast-array ] [ state>> ] bi* {
             [ (process-md5-block-F) ]
             [ (process-md5-block-G) ]
             [ (process-md5-block-H) ]
             [ (process-md5-block-I) ]
         } 2cleave
     ] [
-        nip update-md5-state
-    ] 2bi ;
+        update-md5
+    ] bi ;
+
+: md5>checksum ( md5 -- bytes )
+    state>> underlying>> byte-array>le ;
 
-: md5-state>checksum ( md5-state -- bytes )
-    state>> [ 4 >le ] map B{ } concat-as ;
+M: md5-state clone
+    call-next-method
+    [ clone ] change-state
+    [ clone ] change-old-state ;
 
-M: md5-state get-checksum ( md5-state -- bytes )
-    clone [ bytes>> f ] [ bytes-read>> pad-last-block ] [ ] tri
-    [ [ checksum-block ] curry each ] [ md5-state>checksum ] bi ;
+M: md5-state get-checksum
+    clone
+    [ bytes>> f ] [ bytes-read>> pad-last-block ] [ ] tri
+    [ [ checksum-block ] curry each ] [ md5>checksum ] bi ;
 
 PRIVATE>