]> gitweb.factorcode.org Git - factor.git/blob - basis/checksums/md5/md5.factor
Merge branch 'master' into checksums
[factor.git] / basis / checksums / md5 / md5.factor
1 ! Copyright (C) 2006, 2008 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel io io.binary io.files io.streams.byte-array math
4 math.functions math.parser namespaces splitting grouping strings
5 sequences byte-arrays locals sequences.private macros fry
6 io.encodings.binary math.bitwise checksums accessors
7 checksums.common checksums.stream combinators combinators.smart ;
8 IN: checksums.md5
9
10 SINGLETON: md5
11 INSTANCE: md5 stream-checksum
12
13 TUPLE: md5-state < checksum-state state old-state ;
14
15 : <md5-state> ( -- md5-state )
16     64 md5-state new-checksum-state
17         { HEX: 67452301 HEX: efcdab89 HEX: 98badcfe HEX: 10325476 }
18         [ clone >>state ] [ >>old-state ] bi ;
19
20 <PRIVATE
21
22 : v-w+ ( v1 v2 -- v3 ) [ w+ ] 2map ;
23
24 : update-md5-state ( md5-state -- )
25     [ state>> ] [ old-state>> v-w+ dup clone ] [ ] tri
26     [ (>>old-state) ] [ (>>state) ] bi ; inline
27
28 : T ( N -- Y )
29     sin abs 32 2^ * >integer ; inline
30
31 :: F ( X Y Z -- FXYZ )
32     #! F(X,Y,Z) = XY v not(X) Z
33     X Y bitand X bitnot Z bitand bitor ; inline
34
35 :: G ( X Y Z -- GXYZ )
36     #! G(X,Y,Z) = XZ v Y not(Z)
37     X Z bitand Y Z bitnot bitand bitor ; inline
38
39 : H ( X Y Z -- HXYZ )
40     #! H(X,Y,Z) = X xor Y xor Z
41     bitxor bitxor ; inline
42
43 :: I ( X Y Z -- IXYZ )
44     #! I(X,Y,Z) = Y xor (X v not(Z))
45     Z bitnot X bitor Y bitxor ; inline
46
47 CONSTANT: S11 7
48 CONSTANT: S12 12
49 CONSTANT: S13 17
50 CONSTANT: S14 22
51 CONSTANT: S21 5
52 CONSTANT: S22 9
53 CONSTANT: S23 14
54 CONSTANT: S24 20
55 CONSTANT: S31 4
56 CONSTANT: S32 11
57 CONSTANT: S33 16
58 CONSTANT: S34 23
59 CONSTANT: S41 6
60 CONSTANT: S42 10
61 CONSTANT: S43 15
62 CONSTANT: S44 21
63
64 CONSTANT: a 0
65 CONSTANT: b 1
66 CONSTANT: c 2
67 CONSTANT: d 3
68
69 :: (ABCD) ( x V a b c d k s i quot -- )
70     #! a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
71     a V [
72         b V nth-unsafe
73         c V nth-unsafe
74         d V nth-unsafe quot call w+
75         k x nth-unsafe w+
76         i T w+
77         s bitroll-32
78         b V nth-unsafe w+
79     ] change-nth ; inline
80
81 MACRO: with-md5-round ( ops quot -- )
82     '[ [ _ (ABCD) ] compose ] map '[ _ 2cleave ] ;
83
84 : (process-md5-block-F) ( block v -- )
85     {
86         [ a b c d 0  S11 1  ]
87         [ d a b c 1  S12 2  ]
88         [ c d a b 2  S13 3  ]
89         [ b c d a 3  S14 4  ]
90         [ a b c d 4  S11 5  ]
91         [ d a b c 5  S12 6  ]
92         [ c d a b 6  S13 7  ]
93         [ b c d a 7  S14 8  ]
94         [ a b c d 8  S11 9  ]
95         [ d a b c 9  S12 10 ]
96         [ c d a b 10 S13 11 ]
97         [ b c d a 11 S14 12 ]
98         [ a b c d 12 S11 13 ]
99         [ d a b c 13 S12 14 ]
100         [ c d a b 14 S13 15 ]
101         [ b c d a 15 S14 16 ]
102     } [ F ] with-md5-round ; inline
103
104 : (process-md5-block-G) ( block v -- )
105     {
106         [ a b c d 1  S21 17 ]
107         [ d a b c 6  S22 18 ]
108         [ c d a b 11 S23 19 ]
109         [ b c d a 0  S24 20 ]
110         [ a b c d 5  S21 21 ]
111         [ d a b c 10 S22 22 ]
112         [ c d a b 15 S23 23 ]
113         [ b c d a 4  S24 24 ]
114         [ a b c d 9  S21 25 ]
115         [ d a b c 14 S22 26 ]
116         [ c d a b 3  S23 27 ]
117         [ b c d a 8  S24 28 ]
118         [ a b c d 13 S21 29 ]
119         [ d a b c 2  S22 30 ]
120         [ c d a b 7  S23 31 ]
121         [ b c d a 12 S24 32 ]
122     } [ G ] with-md5-round ; inline
123
124 : (process-md5-block-H) ( block v -- )
125     {
126         [ a b c d 5  S31 33 ]
127         [ d a b c 8  S32 34 ]
128         [ c d a b 11 S33 35 ]
129         [ b c d a 14 S34 36 ]
130         [ a b c d 1  S31 37 ]
131         [ d a b c 4  S32 38 ]
132         [ c d a b 7  S33 39 ]
133         [ b c d a 10 S34 40 ]
134         [ a b c d 13 S31 41 ]
135         [ d a b c 0  S32 42 ]
136         [ c d a b 3  S33 43 ]
137         [ b c d a 6  S34 44 ]
138         [ a b c d 9  S31 45 ]
139         [ d a b c 12 S32 46 ]
140         [ c d a b 15 S33 47 ]
141         [ b c d a 2  S34 48 ]
142     } [ H ] with-md5-round ; inline
143
144 : (process-md5-block-I) ( block v -- )
145     {
146         [ a b c d 0  S41 49 ]
147         [ d a b c 7  S42 50 ]
148         [ c d a b 14 S43 51 ]
149         [ b c d a 5  S44 52 ]
150         [ a b c d 12 S41 53 ]
151         [ d a b c 3  S42 54 ]
152         [ c d a b 10 S43 55 ]
153         [ b c d a 1  S44 56 ]
154         [ a b c d 8  S41 57 ]
155         [ d a b c 15 S42 58 ]
156         [ c d a b 6  S43 59 ]
157         [ b c d a 13 S44 60 ]
158         [ a b c d 4  S41 61 ]
159         [ d a b c 11 S42 62 ]
160         [ c d a b 2  S43 63 ]
161         [ b c d a 9  S44 64 ]
162     } [ I ] with-md5-round ; inline
163
164 M: md5-state checksum-block ( block state -- )
165     [
166         [ 4 <groups> [ le> ] map ] [ state>> ] bi* {
167             [ (process-md5-block-F) ]
168             [ (process-md5-block-G) ]
169             [ (process-md5-block-H) ]
170             [ (process-md5-block-I) ]
171         } 2cleave
172     ] [
173         nip update-md5-state
174     ] 2bi ;
175
176 : md5-state>checksum ( md5-state -- bytes )
177     state>> [ 4 >le ] map B{ } concat-as ;
178
179 M: md5-state get-checksum ( md5-state -- bytes )
180     clone [ bytes>> f ] [ bytes-read>> pad-last-block ] [ ] tri
181     [ [ checksum-block ] curry each ] [ md5-state>checksum ] bi ;
182
183 PRIVATE>