2 # -*- coding: iso-8859-1 -*-
4 # Note that PyPy contains also a built-in module 'md5' which will hide
5 # this one if compiled in.
7 """A sample implementation of MD5 in pure Python.
9 This is an implementation of the MD5 hash function, as specified by
10 RFC 1321, in pure Python. It was implemented using Bruce Schneier's
11 excellent book "Applied Cryptography", 2nd ed., 1996.
13 Surely this is not meant to compete with the existing implementation
14 of the Python standard library (written in C). Rather, it should be
15 seen as a Python complement that is more readable than C and can be
16 used more conveniently for learning and experimenting purposes in
17 the field of cryptography.
19 This module tries very hard to follow the API of the existing Python
20 standard library's "md5" module, but although it seems to work fine,
21 it has not been extensively tested! (But note that there is a test
22 module, test_md5py.py, that compares this Python implementation with
23 the C one of the Python standard library.
25 BEWARE: this comes with no guarantee whatsoever about fitness and/or
26 other properties! Specifically, do not use this in any production
27 code! License is Python License!
29 Special thanks to Aurelian Coman who fixed some nasty bugs!
35 __date__
= '2004-11-17'
36 __version__
= 0.91 # Modernised by J. Hallén and L. Creighton for Pypy
38 __metaclass__
= type # or genrpy won't work
43 # ======================================================================
44 # Bit-Manipulation helpers
45 # ======================================================================
47 def _bytelist2long(list):
48 "Transform a list of characters into a list of longs."
56 b0
= long(ord(list[j
]))
57 b1
= (long(ord(list[j
+1]))) << 8
58 b2
= (long(ord(list[j
+2]))) << 16
59 b3
= (long(ord(list[j
+3]))) << 24
60 hl
[i
] = b0 | b1 |b2 | b3
67 def _rotateLeft(x
, n
):
68 "Rotate x (32 bit) left n bits circularly."
70 return (x
<< n
) |
(x
>> (32-n
))
73 # ======================================================================
74 # The real MD5 meat...
76 # Implemented after "Applied Cryptography", 2nd ed., 1996,
77 # pp. 436-441 by Bruce Schneier.
78 # ======================================================================
80 # F, G, H and I are basic MD5 functions.
83 return (x
& y
) |
((~x
) & z
)
86 return (x
& z
) |
(y
& (~z
))
95 def XX(func
, a
, b
, c
, d
, x
, s
, ac
):
96 """Wrapper for call distribution to functions F, G, H and I.
98 This replaces functions FF, GG, HH and II from "Appl. Crypto."
99 Rotation is separate from addition to prevent recomputation
100 (now summed-up in one function).
104 res
= res
+ a
+ func(b
, c
, d
)
107 res
= res
& 0xffffffffL
108 res
= _rotateLeft(res
, s
)
109 res
= res
& 0xffffffffL
112 return res
& 0xffffffffL
116 "An implementation of the MD5 hash function in pure Python."
121 # Initial message length in bits(!).
125 # Initial empty message as a sequence of bytes (8 bit characters).
128 # Call a separate init function, that can be used repeatedly
129 # to start from scratch on the same object.
134 "Initialize the message-digest and set all fields to zero."
140 # Load magic initialization constants.
147 def _transform(self
, inp
):
148 """Basic MD5 step transforming the digest based on the input.
150 Note that if the Mysterious Constants are arranged backwards
151 in little-endian order and decrypted with the DES they produce
155 a
, b
, c
, d
= A
, B
, C
, D
= self
.A
, self
.B
, self
.C
, self
.D
159 S11
, S12
, S13
, S14
= 7, 12, 17, 22
161 a
= XX(F
, a
, b
, c
, d
, inp
[ 0], S11
, 0xD76AA478L
) # 1
162 d
= XX(F
, d
, a
, b
, c
, inp
[ 1], S12
, 0xE8C7B756L
) # 2
163 c
= XX(F
, c
, d
, a
, b
, inp
[ 2], S13
, 0x242070DBL
) # 3
164 b
= XX(F
, b
, c
, d
, a
, inp
[ 3], S14
, 0xC1BDCEEEL
) # 4
165 a
= XX(F
, a
, b
, c
, d
, inp
[ 4], S11
, 0xF57C0FAFL
) # 5
166 d
= XX(F
, d
, a
, b
, c
, inp
[ 5], S12
, 0x4787C62AL
) # 6
167 c
= XX(F
, c
, d
, a
, b
, inp
[ 6], S13
, 0xA8304613L
) # 7
168 b
= XX(F
, b
, c
, d
, a
, inp
[ 7], S14
, 0xFD469501L
) # 8
169 a
= XX(F
, a
, b
, c
, d
, inp
[ 8], S11
, 0x698098D8L
) # 9
170 d
= XX(F
, d
, a
, b
, c
, inp
[ 9], S12
, 0x8B44F7AFL
) # 10
171 c
= XX(F
, c
, d
, a
, b
, inp
[10], S13
, 0xFFFF5BB1L
) # 11
172 b
= XX(F
, b
, c
, d
, a
, inp
[11], S14
, 0x895CD7BEL
) # 12
173 a
= XX(F
, a
, b
, c
, d
, inp
[12], S11
, 0x6B901122L
) # 13
174 d
= XX(F
, d
, a
, b
, c
, inp
[13], S12
, 0xFD987193L
) # 14
175 c
= XX(F
, c
, d
, a
, b
, inp
[14], S13
, 0xA679438EL
) # 15
176 b
= XX(F
, b
, c
, d
, a
, inp
[15], S14
, 0x49B40821L
) # 16
180 S21
, S22
, S23
, S24
= 5, 9, 14, 20
182 a
= XX(G
, a
, b
, c
, d
, inp
[ 1], S21
, 0xF61E2562L
) # 17
183 d
= XX(G
, d
, a
, b
, c
, inp
[ 6], S22
, 0xC040B340L
) # 18
184 c
= XX(G
, c
, d
, a
, b
, inp
[11], S23
, 0x265E5A51L
) # 19
185 b
= XX(G
, b
, c
, d
, a
, inp
[ 0], S24
, 0xE9B6C7AAL
) # 20
186 a
= XX(G
, a
, b
, c
, d
, inp
[ 5], S21
, 0xD62F105DL
) # 21
187 d
= XX(G
, d
, a
, b
, c
, inp
[10], S22
, 0x02441453L
) # 22
188 c
= XX(G
, c
, d
, a
, b
, inp
[15], S23
, 0xD8A1E681L
) # 23
189 b
= XX(G
, b
, c
, d
, a
, inp
[ 4], S24
, 0xE7D3FBC8L
) # 24
190 a
= XX(G
, a
, b
, c
, d
, inp
[ 9], S21
, 0x21E1CDE6L
) # 25
191 d
= XX(G
, d
, a
, b
, c
, inp
[14], S22
, 0xC33707D6L
) # 26
192 c
= XX(G
, c
, d
, a
, b
, inp
[ 3], S23
, 0xF4D50D87L
) # 27
193 b
= XX(G
, b
, c
, d
, a
, inp
[ 8], S24
, 0x455A14EDL
) # 28
194 a
= XX(G
, a
, b
, c
, d
, inp
[13], S21
, 0xA9E3E905L
) # 29
195 d
= XX(G
, d
, a
, b
, c
, inp
[ 2], S22
, 0xFCEFA3F8L
) # 30
196 c
= XX(G
, c
, d
, a
, b
, inp
[ 7], S23
, 0x676F02D9L
) # 31
197 b
= XX(G
, b
, c
, d
, a
, inp
[12], S24
, 0x8D2A4C8AL
) # 32
201 S31
, S32
, S33
, S34
= 4, 11, 16, 23
203 a
= XX(H
, a
, b
, c
, d
, inp
[ 5], S31
, 0xFFFA3942L
) # 33
204 d
= XX(H
, d
, a
, b
, c
, inp
[ 8], S32
, 0x8771F681L
) # 34
205 c
= XX(H
, c
, d
, a
, b
, inp
[11], S33
, 0x6D9D6122L
) # 35
206 b
= XX(H
, b
, c
, d
, a
, inp
[14], S34
, 0xFDE5380CL
) # 36
207 a
= XX(H
, a
, b
, c
, d
, inp
[ 1], S31
, 0xA4BEEA44L
) # 37
208 d
= XX(H
, d
, a
, b
, c
, inp
[ 4], S32
, 0x4BDECFA9L
) # 38
209 c
= XX(H
, c
, d
, a
, b
, inp
[ 7], S33
, 0xF6BB4B60L
) # 39
210 b
= XX(H
, b
, c
, d
, a
, inp
[10], S34
, 0xBEBFBC70L
) # 40
211 a
= XX(H
, a
, b
, c
, d
, inp
[13], S31
, 0x289B7EC6L
) # 41
212 d
= XX(H
, d
, a
, b
, c
, inp
[ 0], S32
, 0xEAA127FAL
) # 42
213 c
= XX(H
, c
, d
, a
, b
, inp
[ 3], S33
, 0xD4EF3085L
) # 43
214 b
= XX(H
, b
, c
, d
, a
, inp
[ 6], S34
, 0x04881D05L
) # 44
215 a
= XX(H
, a
, b
, c
, d
, inp
[ 9], S31
, 0xD9D4D039L
) # 45
216 d
= XX(H
, d
, a
, b
, c
, inp
[12], S32
, 0xE6DB99E5L
) # 46
217 c
= XX(H
, c
, d
, a
, b
, inp
[15], S33
, 0x1FA27CF8L
) # 47
218 b
= XX(H
, b
, c
, d
, a
, inp
[ 2], S34
, 0xC4AC5665L
) # 48
222 S41
, S42
, S43
, S44
= 6, 10, 15, 21
224 a
= XX(I
, a
, b
, c
, d
, inp
[ 0], S41
, 0xF4292244L
) # 49
225 d
= XX(I
, d
, a
, b
, c
, inp
[ 7], S42
, 0x432AFF97L
) # 50
226 c
= XX(I
, c
, d
, a
, b
, inp
[14], S43
, 0xAB9423A7L
) # 51
227 b
= XX(I
, b
, c
, d
, a
, inp
[ 5], S44
, 0xFC93A039L
) # 52
228 a
= XX(I
, a
, b
, c
, d
, inp
[12], S41
, 0x655B59C3L
) # 53
229 d
= XX(I
, d
, a
, b
, c
, inp
[ 3], S42
, 0x8F0CCC92L
) # 54
230 c
= XX(I
, c
, d
, a
, b
, inp
[10], S43
, 0xFFEFF47DL
) # 55
231 b
= XX(I
, b
, c
, d
, a
, inp
[ 1], S44
, 0x85845DD1L
) # 56
232 a
= XX(I
, a
, b
, c
, d
, inp
[ 8], S41
, 0x6FA87E4FL
) # 57
233 d
= XX(I
, d
, a
, b
, c
, inp
[15], S42
, 0xFE2CE6E0L
) # 58
234 c
= XX(I
, c
, d
, a
, b
, inp
[ 6], S43
, 0xA3014314L
) # 59
235 b
= XX(I
, b
, c
, d
, a
, inp
[13], S44
, 0x4E0811A1L
) # 60
236 a
= XX(I
, a
, b
, c
, d
, inp
[ 4], S41
, 0xF7537E82L
) # 61
237 d
= XX(I
, d
, a
, b
, c
, inp
[11], S42
, 0xBD3AF235L
) # 62
238 c
= XX(I
, c
, d
, a
, b
, inp
[ 2], S43
, 0x2AD7D2BBL
) # 63
239 b
= XX(I
, b
, c
, d
, a
, inp
[ 9], S44
, 0xEB86D391L
) # 64
241 A
= (A
+ a
) & 0xffffffffL
242 B
= (B
+ b
) & 0xffffffffL
243 C
= (C
+ c
) & 0xffffffffL
244 D
= (D
+ d
) & 0xffffffffL
246 self
.A
, self
.B
, self
.C
, self
.D
= A
, B
, C
, D
249 # Down from here all methods follow the Python Standard Library
250 # API of the md5 module.
252 def update(self
, inBuf
):
253 """Add to the current message.
255 Update the md5 object with the string arg. Repeated calls
256 are equivalent to a single call with the concatenation of all
257 the arguments, i.e. m.update(a); m.update(b) is equivalent
260 The hash is immediately calculated for all full blocks. The final
261 calculation is made in digest(). This allows us to keep an
262 intermediate value for the hash, so that we only need to make
263 minimal recalculation if we call update() to add moredata to
267 leninBuf
= long(len(inBuf
))
269 # Compute number of bytes mod 64.
270 index
= (self
.count
[0] >> 3) & 0x3FL
272 # Update number of bits.
273 self
.count
[0] = self
.count
[0] + (leninBuf
<< 3)
274 if self
.count
[0] < (leninBuf
<< 3):
275 self
.count
[1] = self
.count
[1] + 1
276 self
.count
[1] = self
.count
[1] + (leninBuf
>> 29)
280 if leninBuf
>= partLen
:
281 self
.input[index
:] = list(inBuf
[:partLen
])
282 self
._transform
(_bytelist2long(self
.input))
284 while i
+ 63 < leninBuf
:
285 self
._transform
(_bytelist2long(list(inBuf
[i
:i
+64])))
288 self
.input = list(inBuf
[i
:leninBuf
])
291 self
.input = self
.input + list(inBuf
)
295 """Terminate the message-digest computation and return digest.
297 Return the digest of the strings passed to the update()
298 method so far. This is a 16-byte string which may contain
299 non-ASCII characters, including null bytes.
306 input = [] + self
.input
307 count
= [] + self
.count
309 index
= (self
.count
[0] >> 3) & 0x3fL
316 padding
= ['\200'] + ['\000'] * 63
317 self
.update(padding
[:padLen
])
319 # Append length (before padding).
320 bits
= _bytelist2long(self
.input[:56]) + count
322 self
._transform
(bits
)
324 # Store state in digest.
325 digest
= struct
.pack("<IIII", self
.A
, self
.B
, self
.C
, self
.D
)
338 """Terminate and return digest in HEX form.
340 Like digest() except the digest is returned as a string of
341 length 32, containing only hexadecimal digits. This may be
342 used to exchange the value safely in email or other non-
346 return ''.join(['%02x' % ord(c
) for c
in self
.digest()])
349 """Return a clone object.
351 Return a copy ('clone') of the md5 object. This can be used
352 to efficiently compute the digests of strings that share
353 a common initial substring.
355 if 0: # set this to 1 to make the flow space crash
356 return copy
.deepcopy(self
)
357 clone
= self
.__class
__()
358 clone
.length
= self
.length
359 clone
.count
= [] + self
.count
[:]
360 clone
.input = [] + self
.input
368 # ======================================================================
369 # Mimic Python top-level functions from standard library API
370 # for consistency with the md5 module of the standard library.
371 # ======================================================================
376 """Return a new md5 crypto object.
378 If arg is present, the method call update(arg) is made.
391 For backward compatibility reasons, this is an alternative
392 name for the new() function.