~ubuntu-branches/debian/stretch/electrum/stretch

« back to all changes in this revision

Viewing changes to lib/ripemd.py

  • Committer: Package Import Robot
  • Author(s): Vasudev Kamath
  • Date: 2013-06-19 21:44:47 UTC
  • Revision ID: package-import@ubuntu.com-20130619214447-8n0u7ryn1ftu25w8
Tags: upstream-1.8
ImportĀ upstreamĀ versionĀ 1.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
## ripemd.py - pure Python implementation of the RIPEMD-160 algorithm.
 
2
## Bjorn Edstrom <be@bjrn.se> 16 december 2007.
 
3
##
 
4
## Copyrights
 
5
## ==========
 
6
##
 
7
## This code is a derived from an implementation by Markus Friedl which is
 
8
## subject to the following license. This Python implementation is not
 
9
## subject to any other license.
 
10
##
 
11
##/*
 
12
## * Copyright (c) 2001 Markus Friedl.  All rights reserved.
 
13
## *
 
14
## * Redistribution and use in source and binary forms, with or without
 
15
## * modification, are permitted provided that the following conditions
 
16
## * are met:
 
17
## * 1. Redistributions of source code must retain the above copyright
 
18
## *    notice, this list of conditions and the following disclaimer.
 
19
## * 2. Redistributions in binary form must reproduce the above copyright
 
20
## *    notice, this list of conditions and the following disclaimer in the
 
21
## *    documentation and/or other materials provided with the distribution.
 
22
## *
 
23
## * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
24
## * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
25
## * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
26
## * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
27
## * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
28
## * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
29
## * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
30
## * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
31
## * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
32
## * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
33
## */
 
34
##/*
 
35
## * Preneel, Bosselaers, Dobbertin, "The Cryptographic Hash Function RIPEMD-160",
 
36
## * RSA Laboratories, CryptoBytes, Volume 3, Number 2, Autumn 1997,
 
37
## * ftp://ftp.rsasecurity.com/pub/cryptobytes/crypto3n2.pdf
 
38
## */
 
39
 
 
40
try:
 
41
    import psyco
 
42
    psyco.full()
 
43
except ImportError:
 
44
    pass
 
45
 
 
46
#block_size = 1
 
47
digest_size = 20
 
48
digestsize = 20
 
49
 
 
50
class RIPEMD160:
 
51
    """Return a new RIPEMD160 object. An optional string argument
 
52
    may be provided; if present, this string will be automatically
 
53
    hashed."""
 
54
    
 
55
    def __init__(self, arg=None):
 
56
        self.ctx = RMDContext()
 
57
        if arg:
 
58
            self.update(arg)
 
59
        self.dig = None
 
60
        
 
61
    def update(self, arg):
 
62
        """update(arg)"""        
 
63
        RMD160Update(self.ctx, arg, len(arg))
 
64
        self.dig = None
 
65
        
 
66
    def digest(self):
 
67
        """digest()"""        
 
68
        if self.dig:
 
69
            return self.dig
 
70
        ctx = self.ctx.copy()
 
71
        self.dig = RMD160Final(self.ctx)
 
72
        self.ctx = ctx
 
73
        return self.dig
 
74
    
 
75
    def hexdigest(self):
 
76
        """hexdigest()"""
 
77
        dig = self.digest()
 
78
        hex_digest = ''
 
79
        for d in dig:
 
80
            hex_digest += '%02x' % ord(d)
 
81
        return hex_digest
 
82
    
 
83
    def copy(self):
 
84
        """copy()"""        
 
85
        import copy
 
86
        return copy.deepcopy(self)
 
87
 
 
88
 
 
89
 
 
90
def new(arg=None):
 
91
    """Return a new RIPEMD160 object. An optional string argument
 
92
    may be provided; if present, this string will be automatically
 
93
    hashed."""    
 
94
    return RIPEMD160(arg)
 
95
 
 
96
 
 
97
 
 
98
#
 
99
# Private.
 
100
#
 
101
 
 
102
class RMDContext:
 
103
    def __init__(self):
 
104
        self.state = [0x67452301, 0xEFCDAB89, 0x98BADCFE,
 
105
                      0x10325476, 0xC3D2E1F0] # uint32
 
106
        self.count = 0 # uint64
 
107
        self.buffer = [0]*64 # uchar
 
108
    def copy(self):
 
109
        ctx = RMDContext()
 
110
        ctx.state = self.state[:]
 
111
        ctx.count = self.count
 
112
        ctx.buffer = self.buffer[:]
 
113
        return ctx
 
114
 
 
115
K0 = 0x00000000
 
116
K1 = 0x5A827999
 
117
K2 = 0x6ED9EBA1
 
118
K3 = 0x8F1BBCDC
 
119
K4 = 0xA953FD4E
 
120
 
 
121
KK0 = 0x50A28BE6
 
122
KK1 = 0x5C4DD124
 
123
KK2 = 0x6D703EF3
 
124
KK3 = 0x7A6D76E9
 
125
KK4 = 0x00000000
 
126
 
 
127
def ROL(n, x):
 
128
    return ((x << n) & 0xffffffff) | (x >> (32 - n))
 
129
 
 
130
def F0(x, y, z):
 
131
    return x ^ y ^ z
 
132
 
 
133
def F1(x, y, z):
 
134
    return (x & y) | (((~x) % 0x100000000) & z)
 
135
 
 
136
def F2(x, y, z):
 
137
    return (x | ((~y) % 0x100000000)) ^ z
 
138
 
 
139
def F3(x, y, z):
 
140
    return (x & z) | (((~z) % 0x100000000) & y)
 
141
 
 
142
def F4(x, y, z):
 
143
    return x ^ (y | ((~z) % 0x100000000))
 
144
 
 
145
def R(a, b, c, d, e, Fj, Kj, sj, rj, X):
 
146
    a = ROL(sj, (a + Fj(b, c, d) + X[rj] + Kj) % 0x100000000) + e
 
147
    c = ROL(10, c)
 
148
    return a % 0x100000000, c
 
149
 
 
150
PADDING = [0x80] + [0]*63
 
151
 
 
152
import sys
 
153
import struct
 
154
 
 
155
def RMD160Transform(state, block): #uint32 state[5], uchar block[64]
 
156
    x = [0]*16
 
157
    if sys.byteorder == 'little':
 
158
        x = struct.unpack('<16L', ''.join([chr(x) for x in block[0:64]]))
 
159
    else:
 
160
        raise "Error!!"
 
161
    a = state[0]
 
162
    b = state[1]
 
163
    c = state[2]
 
164
    d = state[3]
 
165
    e = state[4]
 
166
 
 
167
    #/* Round 1 */
 
168
    a, c = R(a, b, c, d, e, F0, K0, 11,  0, x);
 
169
    e, b = R(e, a, b, c, d, F0, K0, 14,  1, x);
 
170
    d, a = R(d, e, a, b, c, F0, K0, 15,  2, x);
 
171
    c, e = R(c, d, e, a, b, F0, K0, 12,  3, x);
 
172
    b, d = R(b, c, d, e, a, F0, K0,  5,  4, x);
 
173
    a, c = R(a, b, c, d, e, F0, K0,  8,  5, x);
 
174
    e, b = R(e, a, b, c, d, F0, K0,  7,  6, x);
 
175
    d, a = R(d, e, a, b, c, F0, K0,  9,  7, x);
 
176
    c, e = R(c, d, e, a, b, F0, K0, 11,  8, x);
 
177
    b, d = R(b, c, d, e, a, F0, K0, 13,  9, x);
 
178
    a, c = R(a, b, c, d, e, F0, K0, 14, 10, x);
 
179
    e, b = R(e, a, b, c, d, F0, K0, 15, 11, x);
 
180
    d, a = R(d, e, a, b, c, F0, K0,  6, 12, x);
 
181
    c, e = R(c, d, e, a, b, F0, K0,  7, 13, x);
 
182
    b, d = R(b, c, d, e, a, F0, K0,  9, 14, x);
 
183
    a, c = R(a, b, c, d, e, F0, K0,  8, 15, x); #/* #15 */
 
184
    #/* Round 2 */
 
185
    e, b = R(e, a, b, c, d, F1, K1,  7,  7, x);
 
186
    d, a = R(d, e, a, b, c, F1, K1,  6,  4, x);
 
187
    c, e = R(c, d, e, a, b, F1, K1,  8, 13, x);
 
188
    b, d = R(b, c, d, e, a, F1, K1, 13,  1, x);
 
189
    a, c = R(a, b, c, d, e, F1, K1, 11, 10, x);
 
190
    e, b = R(e, a, b, c, d, F1, K1,  9,  6, x);
 
191
    d, a = R(d, e, a, b, c, F1, K1,  7, 15, x);
 
192
    c, e = R(c, d, e, a, b, F1, K1, 15,  3, x);
 
193
    b, d = R(b, c, d, e, a, F1, K1,  7, 12, x);
 
194
    a, c = R(a, b, c, d, e, F1, K1, 12,  0, x);
 
195
    e, b = R(e, a, b, c, d, F1, K1, 15,  9, x);
 
196
    d, a = R(d, e, a, b, c, F1, K1,  9,  5, x);
 
197
    c, e = R(c, d, e, a, b, F1, K1, 11,  2, x);
 
198
    b, d = R(b, c, d, e, a, F1, K1,  7, 14, x);
 
199
    a, c = R(a, b, c, d, e, F1, K1, 13, 11, x);
 
200
    e, b = R(e, a, b, c, d, F1, K1, 12,  8, x); #/* #31 */
 
201
    #/* Round 3 */
 
202
    d, a = R(d, e, a, b, c, F2, K2, 11,  3, x);
 
203
    c, e = R(c, d, e, a, b, F2, K2, 13, 10, x);
 
204
    b, d = R(b, c, d, e, a, F2, K2,  6, 14, x);
 
205
    a, c = R(a, b, c, d, e, F2, K2,  7,  4, x);
 
206
    e, b = R(e, a, b, c, d, F2, K2, 14,  9, x);
 
207
    d, a = R(d, e, a, b, c, F2, K2,  9, 15, x);
 
208
    c, e = R(c, d, e, a, b, F2, K2, 13,  8, x);
 
209
    b, d = R(b, c, d, e, a, F2, K2, 15,  1, x);
 
210
    a, c = R(a, b, c, d, e, F2, K2, 14,  2, x);
 
211
    e, b = R(e, a, b, c, d, F2, K2,  8,  7, x);
 
212
    d, a = R(d, e, a, b, c, F2, K2, 13,  0, x);
 
213
    c, e = R(c, d, e, a, b, F2, K2,  6,  6, x);
 
214
    b, d = R(b, c, d, e, a, F2, K2,  5, 13, x);
 
215
    a, c = R(a, b, c, d, e, F2, K2, 12, 11, x);
 
216
    e, b = R(e, a, b, c, d, F2, K2,  7,  5, x);
 
217
    d, a = R(d, e, a, b, c, F2, K2,  5, 12, x); #/* #47 */
 
218
    #/* Round 4 */
 
219
    c, e = R(c, d, e, a, b, F3, K3, 11,  1, x);
 
220
    b, d = R(b, c, d, e, a, F3, K3, 12,  9, x);
 
221
    a, c = R(a, b, c, d, e, F3, K3, 14, 11, x);
 
222
    e, b = R(e, a, b, c, d, F3, K3, 15, 10, x);
 
223
    d, a = R(d, e, a, b, c, F3, K3, 14,  0, x);
 
224
    c, e = R(c, d, e, a, b, F3, K3, 15,  8, x);
 
225
    b, d = R(b, c, d, e, a, F3, K3,  9, 12, x);
 
226
    a, c = R(a, b, c, d, e, F3, K3,  8,  4, x);
 
227
    e, b = R(e, a, b, c, d, F3, K3,  9, 13, x);
 
228
    d, a = R(d, e, a, b, c, F3, K3, 14,  3, x);
 
229
    c, e = R(c, d, e, a, b, F3, K3,  5,  7, x);
 
230
    b, d = R(b, c, d, e, a, F3, K3,  6, 15, x);
 
231
    a, c = R(a, b, c, d, e, F3, K3,  8, 14, x);
 
232
    e, b = R(e, a, b, c, d, F3, K3,  6,  5, x);
 
233
    d, a = R(d, e, a, b, c, F3, K3,  5,  6, x);
 
234
    c, e = R(c, d, e, a, b, F3, K3, 12,  2, x); #/* #63 */
 
235
    #/* Round 5 */
 
236
    b, d = R(b, c, d, e, a, F4, K4,  9,  4, x);
 
237
    a, c = R(a, b, c, d, e, F4, K4, 15,  0, x);
 
238
    e, b = R(e, a, b, c, d, F4, K4,  5,  5, x);
 
239
    d, a = R(d, e, a, b, c, F4, K4, 11,  9, x);
 
240
    c, e = R(c, d, e, a, b, F4, K4,  6,  7, x);
 
241
    b, d = R(b, c, d, e, a, F4, K4,  8, 12, x);
 
242
    a, c = R(a, b, c, d, e, F4, K4, 13,  2, x);
 
243
    e, b = R(e, a, b, c, d, F4, K4, 12, 10, x);
 
244
    d, a = R(d, e, a, b, c, F4, K4,  5, 14, x);
 
245
    c, e = R(c, d, e, a, b, F4, K4, 12,  1, x);
 
246
    b, d = R(b, c, d, e, a, F4, K4, 13,  3, x);
 
247
    a, c = R(a, b, c, d, e, F4, K4, 14,  8, x);
 
248
    e, b = R(e, a, b, c, d, F4, K4, 11, 11, x);
 
249
    d, a = R(d, e, a, b, c, F4, K4,  8,  6, x);
 
250
    c, e = R(c, d, e, a, b, F4, K4,  5, 15, x);
 
251
    b, d = R(b, c, d, e, a, F4, K4,  6, 13, x); #/* #79 */
 
252
 
 
253
    aa = a;
 
254
    bb = b;
 
255
    cc = c;
 
256
    dd = d;
 
257
    ee = e;
 
258
 
 
259
    a = state[0]
 
260
    b = state[1]
 
261
    c = state[2]
 
262
    d = state[3]
 
263
    e = state[4]    
 
264
 
 
265
    #/* Parallel round 1 */
 
266
    a, c = R(a, b, c, d, e, F4, KK0,  8,  5, x)
 
267
    e, b = R(e, a, b, c, d, F4, KK0,  9, 14, x)
 
268
    d, a = R(d, e, a, b, c, F4, KK0,  9,  7, x)
 
269
    c, e = R(c, d, e, a, b, F4, KK0, 11,  0, x)
 
270
    b, d = R(b, c, d, e, a, F4, KK0, 13,  9, x)
 
271
    a, c = R(a, b, c, d, e, F4, KK0, 15,  2, x)
 
272
    e, b = R(e, a, b, c, d, F4, KK0, 15, 11, x)
 
273
    d, a = R(d, e, a, b, c, F4, KK0,  5,  4, x)
 
274
    c, e = R(c, d, e, a, b, F4, KK0,  7, 13, x)
 
275
    b, d = R(b, c, d, e, a, F4, KK0,  7,  6, x)
 
276
    a, c = R(a, b, c, d, e, F4, KK0,  8, 15, x)
 
277
    e, b = R(e, a, b, c, d, F4, KK0, 11,  8, x)
 
278
    d, a = R(d, e, a, b, c, F4, KK0, 14,  1, x)
 
279
    c, e = R(c, d, e, a, b, F4, KK0, 14, 10, x)
 
280
    b, d = R(b, c, d, e, a, F4, KK0, 12,  3, x)
 
281
    a, c = R(a, b, c, d, e, F4, KK0,  6, 12, x) #/* #15 */
 
282
    #/* Parallel round 2 */
 
283
    e, b = R(e, a, b, c, d, F3, KK1,  9,  6, x)
 
284
    d, a = R(d, e, a, b, c, F3, KK1, 13, 11, x)
 
285
    c, e = R(c, d, e, a, b, F3, KK1, 15,  3, x)
 
286
    b, d = R(b, c, d, e, a, F3, KK1,  7,  7, x)
 
287
    a, c = R(a, b, c, d, e, F3, KK1, 12,  0, x)
 
288
    e, b = R(e, a, b, c, d, F3, KK1,  8, 13, x)
 
289
    d, a = R(d, e, a, b, c, F3, KK1,  9,  5, x)
 
290
    c, e = R(c, d, e, a, b, F3, KK1, 11, 10, x)
 
291
    b, d = R(b, c, d, e, a, F3, KK1,  7, 14, x)
 
292
    a, c = R(a, b, c, d, e, F3, KK1,  7, 15, x)
 
293
    e, b = R(e, a, b, c, d, F3, KK1, 12,  8, x)
 
294
    d, a = R(d, e, a, b, c, F3, KK1,  7, 12, x)
 
295
    c, e = R(c, d, e, a, b, F3, KK1,  6,  4, x)
 
296
    b, d = R(b, c, d, e, a, F3, KK1, 15,  9, x)
 
297
    a, c = R(a, b, c, d, e, F3, KK1, 13,  1, x)
 
298
    e, b = R(e, a, b, c, d, F3, KK1, 11,  2, x) #/* #31 */
 
299
    #/* Parallel round 3 */
 
300
    d, a = R(d, e, a, b, c, F2, KK2,  9, 15, x)
 
301
    c, e = R(c, d, e, a, b, F2, KK2,  7,  5, x)
 
302
    b, d = R(b, c, d, e, a, F2, KK2, 15,  1, x)
 
303
    a, c = R(a, b, c, d, e, F2, KK2, 11,  3, x)
 
304
    e, b = R(e, a, b, c, d, F2, KK2,  8,  7, x)
 
305
    d, a = R(d, e, a, b, c, F2, KK2,  6, 14, x)
 
306
    c, e = R(c, d, e, a, b, F2, KK2,  6,  6, x)
 
307
    b, d = R(b, c, d, e, a, F2, KK2, 14,  9, x)
 
308
    a, c = R(a, b, c, d, e, F2, KK2, 12, 11, x)
 
309
    e, b = R(e, a, b, c, d, F2, KK2, 13,  8, x)
 
310
    d, a = R(d, e, a, b, c, F2, KK2,  5, 12, x)
 
311
    c, e = R(c, d, e, a, b, F2, KK2, 14,  2, x)
 
312
    b, d = R(b, c, d, e, a, F2, KK2, 13, 10, x)
 
313
    a, c = R(a, b, c, d, e, F2, KK2, 13,  0, x)
 
314
    e, b = R(e, a, b, c, d, F2, KK2,  7,  4, x)
 
315
    d, a = R(d, e, a, b, c, F2, KK2,  5, 13, x) #/* #47 */
 
316
    #/* Parallel round 4 */
 
317
    c, e = R(c, d, e, a, b, F1, KK3, 15,  8, x)
 
318
    b, d = R(b, c, d, e, a, F1, KK3,  5,  6, x)
 
319
    a, c = R(a, b, c, d, e, F1, KK3,  8,  4, x)
 
320
    e, b = R(e, a, b, c, d, F1, KK3, 11,  1, x)
 
321
    d, a = R(d, e, a, b, c, F1, KK3, 14,  3, x)
 
322
    c, e = R(c, d, e, a, b, F1, KK3, 14, 11, x)
 
323
    b, d = R(b, c, d, e, a, F1, KK3,  6, 15, x)
 
324
    a, c = R(a, b, c, d, e, F1, KK3, 14,  0, x)
 
325
    e, b = R(e, a, b, c, d, F1, KK3,  6,  5, x)
 
326
    d, a = R(d, e, a, b, c, F1, KK3,  9, 12, x)
 
327
    c, e = R(c, d, e, a, b, F1, KK3, 12,  2, x)
 
328
    b, d = R(b, c, d, e, a, F1, KK3,  9, 13, x)
 
329
    a, c = R(a, b, c, d, e, F1, KK3, 12,  9, x)
 
330
    e, b = R(e, a, b, c, d, F1, KK3,  5,  7, x)
 
331
    d, a = R(d, e, a, b, c, F1, KK3, 15, 10, x)
 
332
    c, e = R(c, d, e, a, b, F1, KK3,  8, 14, x) #/* #63 */
 
333
    #/* Parallel round 5 */
 
334
    b, d = R(b, c, d, e, a, F0, KK4,  8, 12, x)
 
335
    a, c = R(a, b, c, d, e, F0, KK4,  5, 15, x)
 
336
    e, b = R(e, a, b, c, d, F0, KK4, 12, 10, x)
 
337
    d, a = R(d, e, a, b, c, F0, KK4,  9,  4, x)
 
338
    c, e = R(c, d, e, a, b, F0, KK4, 12,  1, x)
 
339
    b, d = R(b, c, d, e, a, F0, KK4,  5,  5, x)
 
340
    a, c = R(a, b, c, d, e, F0, KK4, 14,  8, x)
 
341
    e, b = R(e, a, b, c, d, F0, KK4,  6,  7, x)
 
342
    d, a = R(d, e, a, b, c, F0, KK4,  8,  6, x)
 
343
    c, e = R(c, d, e, a, b, F0, KK4, 13,  2, x)
 
344
    b, d = R(b, c, d, e, a, F0, KK4,  6, 13, x)
 
345
    a, c = R(a, b, c, d, e, F0, KK4,  5, 14, x)
 
346
    e, b = R(e, a, b, c, d, F0, KK4, 15,  0, x)
 
347
    d, a = R(d, e, a, b, c, F0, KK4, 13,  3, x)
 
348
    c, e = R(c, d, e, a, b, F0, KK4, 11,  9, x)
 
349
    b, d = R(b, c, d, e, a, F0, KK4, 11, 11, x) #/* #79 */
 
350
 
 
351
    t = (state[1] + cc + d) % 0x100000000;
 
352
    state[1] = (state[2] + dd + e) % 0x100000000;
 
353
    state[2] = (state[3] + ee + a) % 0x100000000;
 
354
    state[3] = (state[4] + aa + b) % 0x100000000;
 
355
    state[4] = (state[0] + bb + c) % 0x100000000;
 
356
    state[0] = t % 0x100000000;
 
357
 
 
358
    pass
 
359
 
 
360
 
 
361
def RMD160Update(ctx, inp, inplen):
 
362
    if type(inp) == str:
 
363
        inp = [ord(i)&0xff for i in inp]
 
364
    
 
365
    have = (ctx.count / 8) % 64
 
366
    need = 64 - have
 
367
    ctx.count += 8 * inplen
 
368
    off = 0
 
369
    if inplen >= need:
 
370
        if have:
 
371
            for i in xrange(need):
 
372
                ctx.buffer[have+i] = inp[i]
 
373
            RMD160Transform(ctx.state, ctx.buffer)
 
374
            off = need
 
375
            have = 0
 
376
        while off + 64 <= inplen:
 
377
            RMD160Transform(ctx.state, inp[off:]) #<---
 
378
            off += 64
 
379
    if off < inplen:
 
380
        # memcpy(ctx->buffer + have, input+off, len-off);
 
381
        for i in xrange(inplen - off):
 
382
            ctx.buffer[have+i] = inp[off+i]
 
383
 
 
384
def RMD160Final(ctx):
 
385
    size = struct.pack("<Q", ctx.count)
 
386
    padlen = 64 - ((ctx.count / 8) % 64)
 
387
    if padlen < 1+8:
 
388
        padlen += 64
 
389
    RMD160Update(ctx, PADDING, padlen-8)
 
390
    RMD160Update(ctx, size, 8)
 
391
    return struct.pack("<5L", *ctx.state)
 
392
 
 
393
 
 
394
assert '37f332f68db77bd9d7edd4969571ad671cf9dd3b' == \
 
395
       new('The quick brown fox jumps over the lazy dog').hexdigest()
 
396
assert '132072df690933835eb8b6ad0b77e7b6f14acad7' == \
 
397
       new('The quick brown fox jumps over the lazy cog').hexdigest()
 
398
assert '9c1185a5c5e9fc54612808977ee8f548b2258d31' == \
 
399
       new('').hexdigest()