1 ## ripemd.py - pure Python implementation of the RIPEMD-160 algorithm.
\r
2 ## Bjorn Edstrom <be@bjrn.se> 16 december 2007.
\r
7 ## This code is a derived from an implementation by Markus Friedl which is
\r
8 ## subject to the following license. This Python implementation is not
\r
9 ## subject to any other license.
\r
12 ## * Copyright (c) 2001 Markus Friedl. All rights reserved.
\r
14 ## * Redistribution and use in source and binary forms, with or without
\r
15 ## * modification, are permitted provided that the following conditions
\r
17 ## * 1. Redistributions of source code must retain the above copyright
\r
18 ## * notice, this list of conditions and the following disclaimer.
\r
19 ## * 2. Redistributions in binary form must reproduce the above copyright
\r
20 ## * notice, this list of conditions and the following disclaimer in the
\r
21 ## * documentation and/or other materials provided with the distribution.
\r
23 ## * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
\r
24 ## * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
\r
25 ## * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
\r
26 ## * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
27 ## * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
\r
28 ## * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
\r
29 ## * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
\r
30 ## * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
31 ## * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
\r
32 ## * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
35 ## * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160",
\r
36 ## * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997,
\r
37 ## * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf
\r
51 """Return a new RIPEMD160 object. An optional string argument
\r
52 may be provided; if present, this string will be automatically
\r
55 def __init__(self, arg=None):
\r
56 self.ctx = RMDContext()
\r
61 def update(self, arg):
\r
63 RMD160Update(self.ctx, arg, len(arg))
\r
70 ctx = self.ctx.copy()
\r
71 self.dig = RMD160Final(self.ctx)
\r
75 def hexdigest(self):
\r
80 hex_digest += '%02x' % ord(d)
\r
86 return copy.deepcopy(self)
\r
91 """Return a new RIPEMD160 object. An optional string argument
\r
92 may be provided; if present, this string will be automatically
\r
94 return RIPEMD160(arg)
\r
103 def __init__(self):
\r
104 self.state = [0x67452301, 0xEFCDAB89, 0x98BADCFE,
\r
105 0x10325476, 0xC3D2E1F0] # uint32
\r
106 self.count = 0 # uint64
\r
107 self.buffer = [0]*64 # uchar
\r
110 ctx.state = self.state[:]
\r
111 ctx.count = self.count
\r
112 ctx.buffer = self.buffer[:]
\r
128 return ((x << n) & 0xffffffff) | (x >> (32 - n))
\r
134 return (x & y) | (((~x) % 0x100000000) & z)
\r
137 return (x | ((~y) % 0x100000000)) ^ z
\r
140 return (x & z) | (((~z) % 0x100000000) & y)
\r
143 return x ^ (y | ((~z) % 0x100000000))
\r
145 def R(a, b, c, d, e, Fj, Kj, sj, rj, X):
\r
146 a = ROL(sj, (a + Fj(b, c, d) + X[rj] + Kj) % 0x100000000) + e
\r
148 return a % 0x100000000, c
\r
150 PADDING = [0x80] + [0]*63
\r
155 def RMD160Transform(state, block): #uint32 state[5], uchar block[64]
\r
157 if sys.byteorder == 'little':
\r
158 x = struct.unpack('<16L', ''.join([chr(x) for x in block[0:64]]))
\r
168 a, c = R(a, b, c, d, e, F0, K0, 11, 0, x);
\r
169 e, b = R(e, a, b, c, d, F0, K0, 14, 1, x);
\r
170 d, a = R(d, e, a, b, c, F0, K0, 15, 2, x);
\r
171 c, e = R(c, d, e, a, b, F0, K0, 12, 3, x);
\r
172 b, d = R(b, c, d, e, a, F0, K0, 5, 4, x);
\r
173 a, c = R(a, b, c, d, e, F0, K0, 8, 5, x);
\r
174 e, b = R(e, a, b, c, d, F0, K0, 7, 6, x);
\r
175 d, a = R(d, e, a, b, c, F0, K0, 9, 7, x);
\r
176 c, e = R(c, d, e, a, b, F0, K0, 11, 8, x);
\r
177 b, d = R(b, c, d, e, a, F0, K0, 13, 9, x);
\r
178 a, c = R(a, b, c, d, e, F0, K0, 14, 10, x);
\r
179 e, b = R(e, a, b, c, d, F0, K0, 15, 11, x);
\r
180 d, a = R(d, e, a, b, c, F0, K0, 6, 12, x);
\r
181 c, e = R(c, d, e, a, b, F0, K0, 7, 13, x);
\r
182 b, d = R(b, c, d, e, a, F0, K0, 9, 14, x);
\r
183 a, c = R(a, b, c, d, e, F0, K0, 8, 15, x); #/* #15 */
\r
185 e, b = R(e, a, b, c, d, F1, K1, 7, 7, x);
\r
186 d, a = R(d, e, a, b, c, F1, K1, 6, 4, x);
\r
187 c, e = R(c, d, e, a, b, F1, K1, 8, 13, x);
\r
188 b, d = R(b, c, d, e, a, F1, K1, 13, 1, x);
\r
189 a, c = R(a, b, c, d, e, F1, K1, 11, 10, x);
\r
190 e, b = R(e, a, b, c, d, F1, K1, 9, 6, x);
\r
191 d, a = R(d, e, a, b, c, F1, K1, 7, 15, x);
\r
192 c, e = R(c, d, e, a, b, F1, K1, 15, 3, x);
\r
193 b, d = R(b, c, d, e, a, F1, K1, 7, 12, x);
\r
194 a, c = R(a, b, c, d, e, F1, K1, 12, 0, x);
\r
195 e, b = R(e, a, b, c, d, F1, K1, 15, 9, x);
\r
196 d, a = R(d, e, a, b, c, F1, K1, 9, 5, x);
\r
197 c, e = R(c, d, e, a, b, F1, K1, 11, 2, x);
\r
198 b, d = R(b, c, d, e, a, F1, K1, 7, 14, x);
\r
199 a, c = R(a, b, c, d, e, F1, K1, 13, 11, x);
\r
200 e, b = R(e, a, b, c, d, F1, K1, 12, 8, x); #/* #31 */
\r
202 d, a = R(d, e, a, b, c, F2, K2, 11, 3, x);
\r
203 c, e = R(c, d, e, a, b, F2, K2, 13, 10, x);
\r
204 b, d = R(b, c, d, e, a, F2, K2, 6, 14, x);
\r
205 a, c = R(a, b, c, d, e, F2, K2, 7, 4, x);
\r
206 e, b = R(e, a, b, c, d, F2, K2, 14, 9, x);
\r
207 d, a = R(d, e, a, b, c, F2, K2, 9, 15, x);
\r
208 c, e = R(c, d, e, a, b, F2, K2, 13, 8, x);
\r
209 b, d = R(b, c, d, e, a, F2, K2, 15, 1, x);
\r
210 a, c = R(a, b, c, d, e, F2, K2, 14, 2, x);
\r
211 e, b = R(e, a, b, c, d, F2, K2, 8, 7, x);
\r
212 d, a = R(d, e, a, b, c, F2, K2, 13, 0, x);
\r
213 c, e = R(c, d, e, a, b, F2, K2, 6, 6, x);
\r
214 b, d = R(b, c, d, e, a, F2, K2, 5, 13, x);
\r
215 a, c = R(a, b, c, d, e, F2, K2, 12, 11, x);
\r
216 e, b = R(e, a, b, c, d, F2, K2, 7, 5, x);
\r
217 d, a = R(d, e, a, b, c, F2, K2, 5, 12, x); #/* #47 */
\r
219 c, e = R(c, d, e, a, b, F3, K3, 11, 1, x);
\r
220 b, d = R(b, c, d, e, a, F3, K3, 12, 9, x);
\r
221 a, c = R(a, b, c, d, e, F3, K3, 14, 11, x);
\r
222 e, b = R(e, a, b, c, d, F3, K3, 15, 10, x);
\r
223 d, a = R(d, e, a, b, c, F3, K3, 14, 0, x);
\r
224 c, e = R(c, d, e, a, b, F3, K3, 15, 8, x);
\r
225 b, d = R(b, c, d, e, a, F3, K3, 9, 12, x);
\r
226 a, c = R(a, b, c, d, e, F3, K3, 8, 4, x);
\r
227 e, b = R(e, a, b, c, d, F3, K3, 9, 13, x);
\r
228 d, a = R(d, e, a, b, c, F3, K3, 14, 3, x);
\r
229 c, e = R(c, d, e, a, b, F3, K3, 5, 7, x);
\r
230 b, d = R(b, c, d, e, a, F3, K3, 6, 15, x);
\r
231 a, c = R(a, b, c, d, e, F3, K3, 8, 14, x);
\r
232 e, b = R(e, a, b, c, d, F3, K3, 6, 5, x);
\r
233 d, a = R(d, e, a, b, c, F3, K3, 5, 6, x);
\r
234 c, e = R(c, d, e, a, b, F3, K3, 12, 2, x); #/* #63 */
\r
236 b, d = R(b, c, d, e, a, F4, K4, 9, 4, x);
\r
237 a, c = R(a, b, c, d, e, F4, K4, 15, 0, x);
\r
238 e, b = R(e, a, b, c, d, F4, K4, 5, 5, x);
\r
239 d, a = R(d, e, a, b, c, F4, K4, 11, 9, x);
\r
240 c, e = R(c, d, e, a, b, F4, K4, 6, 7, x);
\r
241 b, d = R(b, c, d, e, a, F4, K4, 8, 12, x);
\r
242 a, c = R(a, b, c, d, e, F4, K4, 13, 2, x);
\r
243 e, b = R(e, a, b, c, d, F4, K4, 12, 10, x);
\r
244 d, a = R(d, e, a, b, c, F4, K4, 5, 14, x);
\r
245 c, e = R(c, d, e, a, b, F4, K4, 12, 1, x);
\r
246 b, d = R(b, c, d, e, a, F4, K4, 13, 3, x);
\r
247 a, c = R(a, b, c, d, e, F4, K4, 14, 8, x);
\r
248 e, b = R(e, a, b, c, d, F4, K4, 11, 11, x);
\r
249 d, a = R(d, e, a, b, c, F4, K4, 8, 6, x);
\r
250 c, e = R(c, d, e, a, b, F4, K4, 5, 15, x);
\r
251 b, d = R(b, c, d, e, a, F4, K4, 6, 13, x); #/* #79 */
\r
265 #/* Parallel round 1 */
\r
266 a, c = R(a, b, c, d, e, F4, KK0, 8, 5, x)
\r
267 e, b = R(e, a, b, c, d, F4, KK0, 9, 14, x)
\r
268 d, a = R(d, e, a, b, c, F4, KK0, 9, 7, x)
\r
269 c, e = R(c, d, e, a, b, F4, KK0, 11, 0, x)
\r
270 b, d = R(b, c, d, e, a, F4, KK0, 13, 9, x)
\r
271 a, c = R(a, b, c, d, e, F4, KK0, 15, 2, x)
\r
272 e, b = R(e, a, b, c, d, F4, KK0, 15, 11, x)
\r
273 d, a = R(d, e, a, b, c, F4, KK0, 5, 4, x)
\r
274 c, e = R(c, d, e, a, b, F4, KK0, 7, 13, x)
\r
275 b, d = R(b, c, d, e, a, F4, KK0, 7, 6, x)
\r
276 a, c = R(a, b, c, d, e, F4, KK0, 8, 15, x)
\r
277 e, b = R(e, a, b, c, d, F4, KK0, 11, 8, x)
\r
278 d, a = R(d, e, a, b, c, F4, KK0, 14, 1, x)
\r
279 c, e = R(c, d, e, a, b, F4, KK0, 14, 10, x)
\r
280 b, d = R(b, c, d, e, a, F4, KK0, 12, 3, x)
\r
281 a, c = R(a, b, c, d, e, F4, KK0, 6, 12, x) #/* #15 */
\r
282 #/* Parallel round 2 */
\r
283 e, b = R(e, a, b, c, d, F3, KK1, 9, 6, x)
\r
284 d, a = R(d, e, a, b, c, F3, KK1, 13, 11, x)
\r
285 c, e = R(c, d, e, a, b, F3, KK1, 15, 3, x)
\r
286 b, d = R(b, c, d, e, a, F3, KK1, 7, 7, x)
\r
287 a, c = R(a, b, c, d, e, F3, KK1, 12, 0, x)
\r
288 e, b = R(e, a, b, c, d, F3, KK1, 8, 13, x)
\r
289 d, a = R(d, e, a, b, c, F3, KK1, 9, 5, x)
\r
290 c, e = R(c, d, e, a, b, F3, KK1, 11, 10, x)
\r
291 b, d = R(b, c, d, e, a, F3, KK1, 7, 14, x)
\r
292 a, c = R(a, b, c, d, e, F3, KK1, 7, 15, x)
\r
293 e, b = R(e, a, b, c, d, F3, KK1, 12, 8, x)
\r
294 d, a = R(d, e, a, b, c, F3, KK1, 7, 12, x)
\r
295 c, e = R(c, d, e, a, b, F3, KK1, 6, 4, x)
\r
296 b, d = R(b, c, d, e, a, F3, KK1, 15, 9, x)
\r
297 a, c = R(a, b, c, d, e, F3, KK1, 13, 1, x)
\r
298 e, b = R(e, a, b, c, d, F3, KK1, 11, 2, x) #/* #31 */
\r
299 #/* Parallel round 3 */
\r
300 d, a = R(d, e, a, b, c, F2, KK2, 9, 15, x)
\r
301 c, e = R(c, d, e, a, b, F2, KK2, 7, 5, x)
\r
302 b, d = R(b, c, d, e, a, F2, KK2, 15, 1, x)
\r
303 a, c = R(a, b, c, d, e, F2, KK2, 11, 3, x)
\r
304 e, b = R(e, a, b, c, d, F2, KK2, 8, 7, x)
\r
305 d, a = R(d, e, a, b, c, F2, KK2, 6, 14, x)
\r
306 c, e = R(c, d, e, a, b, F2, KK2, 6, 6, x)
\r
307 b, d = R(b, c, d, e, a, F2, KK2, 14, 9, x)
\r
308 a, c = R(a, b, c, d, e, F2, KK2, 12, 11, x)
\r
309 e, b = R(e, a, b, c, d, F2, KK2, 13, 8, x)
\r
310 d, a = R(d, e, a, b, c, F2, KK2, 5, 12, x)
\r
311 c, e = R(c, d, e, a, b, F2, KK2, 14, 2, x)
\r
312 b, d = R(b, c, d, e, a, F2, KK2, 13, 10, x)
\r
313 a, c = R(a, b, c, d, e, F2, KK2, 13, 0, x)
\r
314 e, b = R(e, a, b, c, d, F2, KK2, 7, 4, x)
\r
315 d, a = R(d, e, a, b, c, F2, KK2, 5, 13, x) #/* #47 */
\r
316 #/* Parallel round 4 */
\r
317 c, e = R(c, d, e, a, b, F1, KK3, 15, 8, x)
\r
318 b, d = R(b, c, d, e, a, F1, KK3, 5, 6, x)
\r
319 a, c = R(a, b, c, d, e, F1, KK3, 8, 4, x)
\r
320 e, b = R(e, a, b, c, d, F1, KK3, 11, 1, x)
\r
321 d, a = R(d, e, a, b, c, F1, KK3, 14, 3, x)
\r
322 c, e = R(c, d, e, a, b, F1, KK3, 14, 11, x)
\r
323 b, d = R(b, c, d, e, a, F1, KK3, 6, 15, x)
\r
324 a, c = R(a, b, c, d, e, F1, KK3, 14, 0, x)
\r
325 e, b = R(e, a, b, c, d, F1, KK3, 6, 5, x)
\r
326 d, a = R(d, e, a, b, c, F1, KK3, 9, 12, x)
\r
327 c, e = R(c, d, e, a, b, F1, KK3, 12, 2, x)
\r
328 b, d = R(b, c, d, e, a, F1, KK3, 9, 13, x)
\r
329 a, c = R(a, b, c, d, e, F1, KK3, 12, 9, x)
\r
330 e, b = R(e, a, b, c, d, F1, KK3, 5, 7, x)
\r
331 d, a = R(d, e, a, b, c, F1, KK3, 15, 10, x)
\r
332 c, e = R(c, d, e, a, b, F1, KK3, 8, 14, x) #/* #63 */
\r
333 #/* Parallel round 5 */
\r
334 b, d = R(b, c, d, e, a, F0, KK4, 8, 12, x)
\r
335 a, c = R(a, b, c, d, e, F0, KK4, 5, 15, x)
\r
336 e, b = R(e, a, b, c, d, F0, KK4, 12, 10, x)
\r
337 d, a = R(d, e, a, b, c, F0, KK4, 9, 4, x)
\r
338 c, e = R(c, d, e, a, b, F0, KK4, 12, 1, x)
\r
339 b, d = R(b, c, d, e, a, F0, KK4, 5, 5, x)
\r
340 a, c = R(a, b, c, d, e, F0, KK4, 14, 8, x)
\r
341 e, b = R(e, a, b, c, d, F0, KK4, 6, 7, x)
\r
342 d, a = R(d, e, a, b, c, F0, KK4, 8, 6, x)
\r
343 c, e = R(c, d, e, a, b, F0, KK4, 13, 2, x)
\r
344 b, d = R(b, c, d, e, a, F0, KK4, 6, 13, x)
\r
345 a, c = R(a, b, c, d, e, F0, KK4, 5, 14, x)
\r
346 e, b = R(e, a, b, c, d, F0, KK4, 15, 0, x)
\r
347 d, a = R(d, e, a, b, c, F0, KK4, 13, 3, x)
\r
348 c, e = R(c, d, e, a, b, F0, KK4, 11, 9, x)
\r
349 b, d = R(b, c, d, e, a, F0, KK4, 11, 11, x) #/* #79 */
\r
351 t = (state[1] + cc + d) % 0x100000000;
\r
352 state[1] = (state[2] + dd + e) % 0x100000000;
\r
353 state[2] = (state[3] + ee + a) % 0x100000000;
\r
354 state[3] = (state[4] + aa + b) % 0x100000000;
\r
355 state[4] = (state[0] + bb + c) % 0x100000000;
\r
356 state[0] = t % 0x100000000;
\r
361 def RMD160Update(ctx, inp, inplen):
\r
362 if type(inp) == str:
\r
363 inp = [ord(i)&0xff for i in inp]
\r
365 have = (ctx.count / 8) % 64
\r
367 ctx.count += 8 * inplen
\r
371 for i in xrange(need):
\r
372 ctx.buffer[have+i] = inp[i]
\r
373 RMD160Transform(ctx.state, ctx.buffer)
\r
376 while off + 64 <= inplen:
\r
377 RMD160Transform(ctx.state, inp[off:]) #<---
\r
380 # memcpy(ctx->buffer + have, input+off, len-off);
\r
381 for i in xrange(inplen - off):
\r
382 ctx.buffer[have+i] = inp[off+i]
\r
384 def RMD160Final(ctx):
\r
385 size = struct.pack("<Q", ctx.count)
\r
386 padlen = 64 - ((ctx.count / 8) % 64)
\r
389 RMD160Update(ctx, PADDING, padlen-8)
\r
390 RMD160Update(ctx, size, 8)
\r
391 return struct.pack("<5L", *ctx.state)
\r
394 assert '37f332f68db77bd9d7edd4969571ad671cf9dd3b' == \
\r
395 new('The quick brown fox jumps over the lazy dog').hexdigest()
\r
396 assert '132072df690933835eb8b6ad0b77e7b6f14acad7' == \
\r
397 new('The quick brown fox jumps over the lazy cog').hexdigest()
\r
398 assert '9c1185a5c5e9fc54612808977ee8f548b2258d31' == \
\r
399 new('').hexdigest()
\r