1 """Pure-Python MD4 digest algorithm implementation."""
2
3
4
5 """
6 From: "Dmitry Rozmanov" <dima@xenon.spb.ru>
7 To: "Tommi Virtanen" <tv@debian.org>
8 Subject: Re: About your md4.py
9
10 Hi.
11
12 Year, I am thinking of this, but could not find time for this. Thanks for
13 the link.
14
15 But why?
16
17 Consider it as a GPL for now if it is important.
18
19 Regards.
20
21 ---Dmitry.
22
23 ----- Original Message -----
24 From: "Tommi Virtanen" <tv@debian.org>
25 To: "Dmitry Rozmanov" <dima@xenon.spb.ru>
26 Sent: Tuesday, August 27, 2002 9:17 PM
27 Subject: About your md4.py
28
29
30 > Hi. Could you consider adding a license
31 > in your U32.py and md4.py files? Here's
32 > a quick reference:
33 >
34 > http://zooko.com/license_quick_ref.html
35 >
36 > --
37 > :(){ :|:&};:
38 """
39
40 """
41 From: "Dmitry Rozmanov" <dima@xenon.spb.ru>
42 To: "Tommi Virtanen" <tv@debian.org>
43 Subject: Re: About your md4.py
44
45 Ok. Let it be LGPL. Use libs, soon I will modify them and post to the site.
46
47 Regards.
48
49 ---Dmitry.
50
51 ----- Original Message -----
52 From: "Tommi Virtanen" <tv@debian.org>
53 To: "Dmitry Rozmanov" <dima@xenon.spb.ru>
54 Sent: Wednesday, August 28, 2002 9:21 AM
55 Subject: Re: About your md4.py
56
57
58 > On Wed, Aug 28, 2002 at 02:56:25AM +0400, Dmitry Rozmanov wrote:
59 > > Year, I am thinking of this, but could not find time for
60 > > this. Thanks for the link.
61 > >
62 > > But why?
63 > >
64 > > Consider it as a GPL for now if it is important.
65 >
66 > Please include that information in the files themselves;
67 > it would really help. Otherwise, all I have is this
68 > email to point to.
69 >
70 > Oh, and please reconsider the actual license. For example,
71 > I have an LGPL'ed library I need md4 in. If you choose GPL,
72 > my library couldn't use your md4.py.
73 >
74 > --
75 > :(){ :|:&};:
76 """
77
78
79
80 md4_test= [
81 ('', 0x31d6cfe0d16ae931b73c59d7e0c089c0L),
82 ("a", 0xbde52cb31de33e46245e05fbdbd6fb24L),
83 ("abc", 0xa448017aaf21d8525fc10ae87aa6729dL),
84 ("message digest", 0xd9130a8164549fe818874806e1c7014bL),
85 ("abcdefghijklmnopqrstuvwxyz", 0xd79e1c308aa5bbcdeea8ed63df412da9L),
86 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
87 0x043f8582f241db351ce627e153e7f0e4L),
88 ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
89 0xe33b4ddc9c38f2199c3e7b164fcc0536L),
90 ]
91
92 from U32 import U32
93
95 A = None
96 B = None
97 C = None
98 D = None
99 count, len1, len2 = None, None, None
100 buf = []
101
112
114
115 dest = new()
116
117 dest.len1 = self.len1
118 dest.len2 = self.len2
119 dest.A = self.A
120 dest.B = self.B
121 dest.C = self.C
122 dest.D = self.D
123 dest.count = self.count
124 for i in range(self.count):
125 dest.buf[i] = self.buf[i]
126
127 return dest
128
130
131 buf = []
132 for i in str: buf.append(ord(i))
133 ilen = U32(len(buf))
134
135
136 if (long(self.len1 + (ilen << 3)) < long(self.len1)):
137 self.len2 = self.len2 + U32(1)
138
139 self.len1 = self.len1 + (ilen << 3)
140 self.len2 = self.len2 + (ilen >> 29)
141
142
143
144 L = U32(0)
145 bufpos = 0
146 while (long(ilen) > 0):
147 if (64 - long(self.count)) < long(ilen): L = U32(64 - long(self.count))
148 else: L = ilen
149 for i in range(int(L)): self.buf[i + int(self.count)] = buf[i + bufpos]
150 self.count = self.count + L
151 ilen = ilen - L
152 bufpos = bufpos + int(L)
153
154
155 if (long(self.count) == 64L):
156 self.count = U32(0L)
157 X = []
158 i = 0
159 for j in range(16):
160 X.append(U32(self.buf[i]) + (U32(self.buf[i+1]) << 8) + \
161 (U32(self.buf[i+2]) << 16) + (U32(self.buf[i+3]) << 24))
162 i = i + 4
163
164 A = self.A
165 B = self.B
166 C = self.C
167 D = self.D
168
169 A = f1(A,B,C,D, 0, 3, X)
170 D = f1(D,A,B,C, 1, 7, X)
171 C = f1(C,D,A,B, 2,11, X)
172 B = f1(B,C,D,A, 3,19, X)
173 A = f1(A,B,C,D, 4, 3, X)
174 D = f1(D,A,B,C, 5, 7, X)
175 C = f1(C,D,A,B, 6,11, X)
176 B = f1(B,C,D,A, 7,19, X)
177 A = f1(A,B,C,D, 8, 3, X)
178 D = f1(D,A,B,C, 9, 7, X)
179 C = f1(C,D,A,B,10,11, X)
180 B = f1(B,C,D,A,11,19, X)
181 A = f1(A,B,C,D,12, 3, X)
182 D = f1(D,A,B,C,13, 7, X)
183 C = f1(C,D,A,B,14,11, X)
184 B = f1(B,C,D,A,15,19, X)
185
186 A = f2(A,B,C,D, 0, 3, X)
187 D = f2(D,A,B,C, 4, 5, X)
188 C = f2(C,D,A,B, 8, 9, X)
189 B = f2(B,C,D,A,12,13, X)
190 A = f2(A,B,C,D, 1, 3, X)
191 D = f2(D,A,B,C, 5, 5, X)
192 C = f2(C,D,A,B, 9, 9, X)
193 B = f2(B,C,D,A,13,13, X)
194 A = f2(A,B,C,D, 2, 3, X)
195 D = f2(D,A,B,C, 6, 5, X)
196 C = f2(C,D,A,B,10, 9, X)
197 B = f2(B,C,D,A,14,13, X)
198 A = f2(A,B,C,D, 3, 3, X)
199 D = f2(D,A,B,C, 7, 5, X)
200 C = f2(C,D,A,B,11, 9, X)
201 B = f2(B,C,D,A,15,13, X)
202
203 A = f3(A,B,C,D, 0, 3, X)
204 D = f3(D,A,B,C, 8, 9, X)
205 C = f3(C,D,A,B, 4,11, X)
206 B = f3(B,C,D,A,12,15, X)
207 A = f3(A,B,C,D, 2, 3, X)
208 D = f3(D,A,B,C,10, 9, X)
209 C = f3(C,D,A,B, 6,11, X)
210 B = f3(B,C,D,A,14,15, X)
211 A = f3(A,B,C,D, 1, 3, X)
212 D = f3(D,A,B,C, 9, 9, X)
213 C = f3(C,D,A,B, 5,11, X)
214 B = f3(B,C,D,A,13,15, X)
215 A = f3(A,B,C,D, 3, 3, X)
216 D = f3(D,A,B,C,11, 9, X)
217 C = f3(C,D,A,B, 7,11, X)
218 B = f3(B,C,D,A,15,15, X)
219
220 self.A = self.A + A
221 self.B = self.B + B
222 self.C = self.C + C
223 self.D = self.D + D
224
225
227
228 res = [0x00] * 16
229 s = [0x00] * 8
230 padding = [0x00] * 64
231 padding[0] = 0x80
232 padlen, oldlen1, oldlen2 = U32(0), U32(0), U32(0)
233
234 temp = self.copy()
235
236 oldlen1 = temp.len1
237 oldlen2 = temp.len2
238 if (56 <= long(self.count)): padlen = U32(56 - long(self.count) + 64)
239 else: padlen = U32(56 - long(self.count))
240
241 temp.update(int_array2str(padding[:int(padlen)]))
242
243
244 s[0]= (oldlen1) & U32(0xFF)
245 s[1]=((oldlen1) >> 8) & U32(0xFF)
246 s[2]=((oldlen1) >> 16) & U32(0xFF)
247 s[3]=((oldlen1) >> 24) & U32(0xFF)
248 s[4]= (oldlen2) & U32(0xFF)
249 s[5]=((oldlen2) >> 8) & U32(0xFF)
250 s[6]=((oldlen2) >> 16) & U32(0xFF)
251 s[7]=((oldlen2) >> 24) & U32(0xFF)
252 temp.update(int_array2str(s))
253
254
255
256 res[ 0]= temp.A & U32(0xFF)
257 res[ 1]=(temp.A >> 8) & U32(0xFF)
258 res[ 2]=(temp.A >> 16) & U32(0xFF)
259 res[ 3]=(temp.A >> 24) & U32(0xFF)
260 res[ 4]= temp.B & U32(0xFF)
261 res[ 5]=(temp.B >> 8) & U32(0xFF)
262 res[ 6]=(temp.B >> 16) & U32(0xFF)
263 res[ 7]=(temp.B >> 24) & U32(0xFF)
264 res[ 8]= temp.C & U32(0xFF)
265 res[ 9]=(temp.C >> 8) & U32(0xFF)
266 res[10]=(temp.C >> 16) & U32(0xFF)
267 res[11]=(temp.C >> 24) & U32(0xFF)
268 res[12]= temp.D & U32(0xFF)
269 res[13]=(temp.D >> 8) & U32(0xFF)
270 res[14]=(temp.D >> 16) & U32(0xFF)
271 res[15]=(temp.D >> 24) & U32(0xFF)
272
273 return int_array2str(res)
274
276 d=self.digest()
277 return ''.join(map(lambda c: '%02x'%ord(c), d))
278
279 -def F(x, y, z): return (((x) & (y)) | ((~x) & (z)))
280 -def G(x, y, z): return (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
281 -def H(x, y, z): return ((x) ^ (y) ^ (z))
282
283 -def ROL(x, n): return (((x) << n) | ((x) >> (32-n)))
284
285 -def f1(a, b, c, d, k, s, X): return ROL(a + F(b, c, d) + X[k], s)
286 -def f2(a, b, c, d, k, s, X): return ROL(a + G(b, c, d) + X[k] + U32(0x5a827999L), s)
287 -def f3(a, b, c, d, k, s, X): return ROL(a + H(b, c, d) + X[k] + U32(0x6ed9eba1L), s)
288
290 str = ''
291 for i in array:
292 str = str + chr(i)
293 return str
294
299