The OpenD Programming Language

1 /**
2  * Computes RIPEMD-160 hashes of arbitrary data. RIPEMD-160 hashes are 20 byte quantities
3  * that are like a checksum or CRC, but are more robust.
4  *
5 $(SCRIPT inhibitQuickIndex = 1;)
6 
7 $(DIVC quickindex,
8 $(BOOKTABLE ,
9 $(TR $(TH Category) $(TH Functions)
10 )
11 $(TR $(TDNW Template API) $(TD $(MYREF RIPEMD160)
12 )
13 )
14 $(TR $(TDNW OOP API) $(TD $(MYREF RIPEMD160Digest))
15 )
16 $(TR $(TDNW Helpers) $(TD $(MYREF ripemd160Of))
17 )
18 )
19 )
20 
21  * This module conforms to the APIs defined in $(MREF std, digest). To understand the
22  * differences between the template and the OOP API, see $(MREF std, digest).
23  *
24  * This module publicly imports `std.digest` and can be used as a stand-alone
25  * module.
26  *
27  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
28  *
29  * CTFE:
30  * Digests do not work in CTFE
31  *
32  * Authors:
33  * Kai Nacke $(BR)
34  * The algorithm was designed by Hans Dobbertin, Antoon Bosselaers, and Bart Preneel. $(BR)
35  * The D implementation is a direct translation of the ANSI C implementation by Antoon Bosselaers.
36  *
37  * References:
38  * $(UL
39  * $(LI $(LINK2 http://homes.esat.kuleuven.be/~bosselae/ripemd160.html, The hash function RIPEMD-160))
40  * $(LI $(LINK2 http://en.wikipedia.org/wiki/RIPEMD-160, Wikipedia on RIPEMD-160))
41  * )
42  *
43  * Source: $(PHOBOSSRC std/digest/ripemd.d)
44  *
45  */
46 
47 module std.digest.ripemd;
48 
49 public import std.digest;
50 
51 ///
52 @safe unittest
53 {
54     //Template API
55     import std.digest.md;
56 
57     ubyte[20] hash = ripemd160Of("abc");
58     assert(toHexString(hash) == "8EB208F7E05D987A9B044A8E98C6B087F15A0BFC");
59 
60     //Feeding data
61     ubyte[1024] data;
62     RIPEMD160 md;
63     md.start();
64     md.put(data[]);
65     md.start(); //Start again
66     md.put(data[]);
67     hash = md.finish();
68 }
69 
70 ///
71 @safe unittest
72 {
73     //OOP API
74     import std.digest.md;
75 
76     auto md = new RIPEMD160Digest();
77     ubyte[] hash = md.digest("abc");
78     assert(toHexString(hash) == "8EB208F7E05D987A9B044A8E98C6B087F15A0BFC");
79 
80     //Feeding data
81     ubyte[1024] data;
82     md.put(data[]);
83     md.reset(); //Start again
84     md.put(data[]);
85     hash = md.finish();
86 }
87 
88 /**
89  * Template API RIPEMD160 implementation.
90  * See `std.digest` for differences between template and OOP API.
91  */
92 struct RIPEMD160
93 {
94     import core.bitop : rol;
95     private:
96         // magic initialization constants
97         uint[5] _state = [0x67452301,0xefcdab89,0x98badcfe,0x10325476,0xc3d2e1f0]; // state (ABCDE)
98         ulong _count; //number of bits, modulo 2^64
99         ubyte[64] _buffer; // input buffer
100 
101         static immutable ubyte[64] _padding =
102         [
103           0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105           0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
106         ];
107 
108         // F, G, H, I and J are basic RIPEMD160 functions
109         static @safe pure nothrow @nogc
110         {
111             uint F(uint x, uint y, uint z) { return x ^ y ^ z; }
112             uint G(uint x, uint y, uint z) { return (x & y) | (~x & z); }
113             uint H(uint x, uint y, uint z) { return (x | ~y) ^ z; }
114             uint I(uint x, uint y, uint z) { return (x & z) | (y & ~z); }
115             uint J(uint x, uint y, uint z) { return x ^ (y | ~z); }
116         }
117 
118         /*
119          * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
120          * Rotation is separate from addition to prevent recomputation.
121          */
122 
123         /* the ten basic operations FF() through III() */
124         static void FF(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)
125             @safe pure nothrow @nogc
126         {
127             a += F(b, c, d) + x;
128             a = rol(a, s) + e;
129             c = rol(c, 10);
130         }
131 
132         static void GG(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)
133             @safe pure nothrow @nogc
134         {
135             a += G(b, c, d) + x + 0x5a827999UL;
136             a = rol(a, s) + e;
137             c = rol(c, 10);
138         }
139 
140         static void HH(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)
141             @safe pure nothrow @nogc
142         {
143             a += H(b, c, d) + x + 0x6ed9eba1UL;
144             a = rol(a, s) + e;
145             c = rol(c, 10);
146         }
147 
148         static void II(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)
149             @safe pure nothrow @nogc
150         {
151             a += I(b, c, d) + x + 0x8f1bbcdcUL;
152             a = rol(a, s) + e;
153             c = rol(c, 10);
154         }
155 
156         static void JJ(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)
157             @safe pure nothrow @nogc
158         {
159             a += J(b, c, d) + x + 0xa953fd4eUL;
160             a = rol(a, s) + e;
161             c = rol(c, 10);
162         }
163 
164         /*
165          * FFF, GGG, HHH, and III transformations for parallel rounds 1, 2, 3, and 4.
166          * Rotation is separate from addition to prevent recomputation.
167          */
168 
169         static void FFF(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)
170             @safe pure nothrow @nogc
171         {
172             a += F(b, c, d) + x;
173             a = rol(a, s) + e;
174             c = rol(c, 10);
175         }
176 
177         static void GGG(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)
178             @safe pure nothrow @nogc
179         {
180             a += G(b, c, d) + x + 0x7a6d76e9UL;
181             a = rol(a, s) + e;
182             c = rol(c, 10);
183         }
184 
185         static void HHH(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)
186             @safe pure nothrow @nogc
187         {
188             a += H(b, c, d) + x + 0x6d703ef3UL;
189             a = rol(a, s) + e;
190             c = rol(c, 10);
191         }
192 
193         static void III(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)
194             @safe pure nothrow @nogc
195         {
196             a += I(b, c, d) + x + 0x5c4dd124UL;
197             a = rol(a, s) + e;
198             c = rol(c, 10);
199         }
200 
201         static void JJJ(ref uint a, uint b, ref uint c, uint d, uint e, uint x, uint s)
202             @safe pure nothrow @nogc
203         {
204             a += J(b, c, d) + x + 0x50a28be6UL;
205             a = rol(a, s) + e;
206             c = rol(c, 10);
207         }
208 
209         /*
210          * RIPEMD160 basic transformation. Transforms state based on block.
211          */
212 
213         void transform(const(ubyte[64])* block)
214             pure nothrow @nogc
215         {
216             uint aa = _state[0],
217                  bb = _state[1],
218                  cc = _state[2],
219                  dd = _state[3],
220                  ee = _state[4];
221             uint aaa = _state[0],
222                  bbb = _state[1],
223                  ccc = _state[2],
224                  ddd = _state[3],
225                  eee = _state[4];
226 
227             uint[16] x = void;
228 
229             version (BigEndian)
230             {
231                 import std.bitmanip : littleEndianToNative;
232 
233                 for (size_t i = 0; i < 16; i++)
234                 {
235                     x[i] = littleEndianToNative!uint(*cast(ubyte[4]*)&(*block)[i*4]);
236                 }
237             }
238             else
239             {
240                 (cast(ubyte*) x.ptr)[0 .. 64] = (cast(ubyte*) block)[0 .. 64];
241             }
242 
243             /* round 1 */
244             FF(aa, bb, cc, dd, ee, x[ 0], 11);
245             FF(ee, aa, bb, cc, dd, x[ 1], 14);
246             FF(dd, ee, aa, bb, cc, x[ 2], 15);
247             FF(cc, dd, ee, aa, bb, x[ 3], 12);
248             FF(bb, cc, dd, ee, aa, x[ 4],  5);
249             FF(aa, bb, cc, dd, ee, x[ 5],  8);
250             FF(ee, aa, bb, cc, dd, x[ 6],  7);
251             FF(dd, ee, aa, bb, cc, x[ 7],  9);
252             FF(cc, dd, ee, aa, bb, x[ 8], 11);
253             FF(bb, cc, dd, ee, aa, x[ 9], 13);
254             FF(aa, bb, cc, dd, ee, x[10], 14);
255             FF(ee, aa, bb, cc, dd, x[11], 15);
256             FF(dd, ee, aa, bb, cc, x[12],  6);
257             FF(cc, dd, ee, aa, bb, x[13],  7);
258             FF(bb, cc, dd, ee, aa, x[14],  9);
259             FF(aa, bb, cc, dd, ee, x[15],  8);
260 
261             /* round 2 */
262             GG(ee, aa, bb, cc, dd, x[ 7],  7);
263             GG(dd, ee, aa, bb, cc, x[ 4],  6);
264             GG(cc, dd, ee, aa, bb, x[13],  8);
265             GG(bb, cc, dd, ee, aa, x[ 1], 13);
266             GG(aa, bb, cc, dd, ee, x[10], 11);
267             GG(ee, aa, bb, cc, dd, x[ 6],  9);
268             GG(dd, ee, aa, bb, cc, x[15],  7);
269             GG(cc, dd, ee, aa, bb, x[ 3], 15);
270             GG(bb, cc, dd, ee, aa, x[12],  7);
271             GG(aa, bb, cc, dd, ee, x[ 0], 12);
272             GG(ee, aa, bb, cc, dd, x[ 9], 15);
273             GG(dd, ee, aa, bb, cc, x[ 5],  9);
274             GG(cc, dd, ee, aa, bb, x[ 2], 11);
275             GG(bb, cc, dd, ee, aa, x[14],  7);
276             GG(aa, bb, cc, dd, ee, x[11], 13);
277             GG(ee, aa, bb, cc, dd, x[ 8], 12);
278 
279             /* round 3 */
280             HH(dd, ee, aa, bb, cc, x[ 3], 11);
281             HH(cc, dd, ee, aa, bb, x[10], 13);
282             HH(bb, cc, dd, ee, aa, x[14],  6);
283             HH(aa, bb, cc, dd, ee, x[ 4],  7);
284             HH(ee, aa, bb, cc, dd, x[ 9], 14);
285             HH(dd, ee, aa, bb, cc, x[15],  9);
286             HH(cc, dd, ee, aa, bb, x[ 8], 13);
287             HH(bb, cc, dd, ee, aa, x[ 1], 15);
288             HH(aa, bb, cc, dd, ee, x[ 2], 14);
289             HH(ee, aa, bb, cc, dd, x[ 7],  8);
290             HH(dd, ee, aa, bb, cc, x[ 0], 13);
291             HH(cc, dd, ee, aa, bb, x[ 6],  6);
292             HH(bb, cc, dd, ee, aa, x[13],  5);
293             HH(aa, bb, cc, dd, ee, x[11], 12);
294             HH(ee, aa, bb, cc, dd, x[ 5],  7);
295             HH(dd, ee, aa, bb, cc, x[12],  5);
296 
297             /* round 4 */
298             II(cc, dd, ee, aa, bb, x[ 1], 11);
299             II(bb, cc, dd, ee, aa, x[ 9], 12);
300             II(aa, bb, cc, dd, ee, x[11], 14);
301             II(ee, aa, bb, cc, dd, x[10], 15);
302             II(dd, ee, aa, bb, cc, x[ 0], 14);
303             II(cc, dd, ee, aa, bb, x[ 8], 15);
304             II(bb, cc, dd, ee, aa, x[12],  9);
305             II(aa, bb, cc, dd, ee, x[ 4],  8);
306             II(ee, aa, bb, cc, dd, x[13],  9);
307             II(dd, ee, aa, bb, cc, x[ 3], 14);
308             II(cc, dd, ee, aa, bb, x[ 7],  5);
309             II(bb, cc, dd, ee, aa, x[15],  6);
310             II(aa, bb, cc, dd, ee, x[14],  8);
311             II(ee, aa, bb, cc, dd, x[ 5],  6);
312             II(dd, ee, aa, bb, cc, x[ 6],  5);
313             II(cc, dd, ee, aa, bb, x[ 2], 12);
314 
315             /* round 5 */
316             JJ(bb, cc, dd, ee, aa, x[ 4],  9);
317             JJ(aa, bb, cc, dd, ee, x[ 0], 15);
318             JJ(ee, aa, bb, cc, dd, x[ 5],  5);
319             JJ(dd, ee, aa, bb, cc, x[ 9], 11);
320             JJ(cc, dd, ee, aa, bb, x[ 7],  6);
321             JJ(bb, cc, dd, ee, aa, x[12],  8);
322             JJ(aa, bb, cc, dd, ee, x[ 2], 13);
323             JJ(ee, aa, bb, cc, dd, x[10], 12);
324             JJ(dd, ee, aa, bb, cc, x[14],  5);
325             JJ(cc, dd, ee, aa, bb, x[ 1], 12);
326             JJ(bb, cc, dd, ee, aa, x[ 3], 13);
327             JJ(aa, bb, cc, dd, ee, x[ 8], 14);
328             JJ(ee, aa, bb, cc, dd, x[11], 11);
329             JJ(dd, ee, aa, bb, cc, x[ 6],  8);
330             JJ(cc, dd, ee, aa, bb, x[15],  5);
331             JJ(bb, cc, dd, ee, aa, x[13],  6);
332 
333             /* parallel round 1 */
334             JJJ(aaa, bbb, ccc, ddd, eee, x[ 5],  8);
335             JJJ(eee, aaa, bbb, ccc, ddd, x[14],  9);
336             JJJ(ddd, eee, aaa, bbb, ccc, x[ 7],  9);
337             JJJ(ccc, ddd, eee, aaa, bbb, x[ 0], 11);
338             JJJ(bbb, ccc, ddd, eee, aaa, x[ 9], 13);
339             JJJ(aaa, bbb, ccc, ddd, eee, x[ 2], 15);
340             JJJ(eee, aaa, bbb, ccc, ddd, x[11], 15);
341             JJJ(ddd, eee, aaa, bbb, ccc, x[ 4],  5);
342             JJJ(ccc, ddd, eee, aaa, bbb, x[13],  7);
343             JJJ(bbb, ccc, ddd, eee, aaa, x[ 6],  7);
344             JJJ(aaa, bbb, ccc, ddd, eee, x[15],  8);
345             JJJ(eee, aaa, bbb, ccc, ddd, x[ 8], 11);
346             JJJ(ddd, eee, aaa, bbb, ccc, x[ 1], 14);
347             JJJ(ccc, ddd, eee, aaa, bbb, x[10], 14);
348             JJJ(bbb, ccc, ddd, eee, aaa, x[ 3], 12);
349             JJJ(aaa, bbb, ccc, ddd, eee, x[12],  6);
350 
351             /* parallel round 2 */
352             III(eee, aaa, bbb, ccc, ddd, x[ 6],  9);
353             III(ddd, eee, aaa, bbb, ccc, x[11], 13);
354             III(ccc, ddd, eee, aaa, bbb, x[ 3], 15);
355             III(bbb, ccc, ddd, eee, aaa, x[ 7],  7);
356             III(aaa, bbb, ccc, ddd, eee, x[ 0], 12);
357             III(eee, aaa, bbb, ccc, ddd, x[13],  8);
358             III(ddd, eee, aaa, bbb, ccc, x[ 5],  9);
359             III(ccc, ddd, eee, aaa, bbb, x[10], 11);
360             III(bbb, ccc, ddd, eee, aaa, x[14],  7);
361             III(aaa, bbb, ccc, ddd, eee, x[15],  7);
362             III(eee, aaa, bbb, ccc, ddd, x[ 8], 12);
363             III(ddd, eee, aaa, bbb, ccc, x[12],  7);
364             III(ccc, ddd, eee, aaa, bbb, x[ 4],  6);
365             III(bbb, ccc, ddd, eee, aaa, x[ 9], 15);
366             III(aaa, bbb, ccc, ddd, eee, x[ 1], 13);
367             III(eee, aaa, bbb, ccc, ddd, x[ 2], 11);
368 
369             /* parallel round 3 */
370             HHH(ddd, eee, aaa, bbb, ccc, x[15],  9);
371             HHH(ccc, ddd, eee, aaa, bbb, x[ 5],  7);
372             HHH(bbb, ccc, ddd, eee, aaa, x[ 1], 15);
373             HHH(aaa, bbb, ccc, ddd, eee, x[ 3], 11);
374             HHH(eee, aaa, bbb, ccc, ddd, x[ 7],  8);
375             HHH(ddd, eee, aaa, bbb, ccc, x[14],  6);
376             HHH(ccc, ddd, eee, aaa, bbb, x[ 6],  6);
377             HHH(bbb, ccc, ddd, eee, aaa, x[ 9], 14);
378             HHH(aaa, bbb, ccc, ddd, eee, x[11], 12);
379             HHH(eee, aaa, bbb, ccc, ddd, x[ 8], 13);
380             HHH(ddd, eee, aaa, bbb, ccc, x[12],  5);
381             HHH(ccc, ddd, eee, aaa, bbb, x[ 2], 14);
382             HHH(bbb, ccc, ddd, eee, aaa, x[10], 13);
383             HHH(aaa, bbb, ccc, ddd, eee, x[ 0], 13);
384             HHH(eee, aaa, bbb, ccc, ddd, x[ 4],  7);
385             HHH(ddd, eee, aaa, bbb, ccc, x[13],  5);
386 
387             /* parallel round 4 */
388             GGG(ccc, ddd, eee, aaa, bbb, x[ 8], 15);
389             GGG(bbb, ccc, ddd, eee, aaa, x[ 6],  5);
390             GGG(aaa, bbb, ccc, ddd, eee, x[ 4],  8);
391             GGG(eee, aaa, bbb, ccc, ddd, x[ 1], 11);
392             GGG(ddd, eee, aaa, bbb, ccc, x[ 3], 14);
393             GGG(ccc, ddd, eee, aaa, bbb, x[11], 14);
394             GGG(bbb, ccc, ddd, eee, aaa, x[15],  6);
395             GGG(aaa, bbb, ccc, ddd, eee, x[ 0], 14);
396             GGG(eee, aaa, bbb, ccc, ddd, x[ 5],  6);
397             GGG(ddd, eee, aaa, bbb, ccc, x[12],  9);
398             GGG(ccc, ddd, eee, aaa, bbb, x[ 2], 12);
399             GGG(bbb, ccc, ddd, eee, aaa, x[13],  9);
400             GGG(aaa, bbb, ccc, ddd, eee, x[ 9], 12);
401             GGG(eee, aaa, bbb, ccc, ddd, x[ 7],  5);
402             GGG(ddd, eee, aaa, bbb, ccc, x[10], 15);
403             GGG(ccc, ddd, eee, aaa, bbb, x[14],  8);
404 
405             /* parallel round 5 */
406             FFF(bbb, ccc, ddd, eee, aaa, x[12] ,  8);
407             FFF(aaa, bbb, ccc, ddd, eee, x[15] ,  5);
408             FFF(eee, aaa, bbb, ccc, ddd, x[10] , 12);
409             FFF(ddd, eee, aaa, bbb, ccc, x[ 4] ,  9);
410             FFF(ccc, ddd, eee, aaa, bbb, x[ 1] , 12);
411             FFF(bbb, ccc, ddd, eee, aaa, x[ 5] ,  5);
412             FFF(aaa, bbb, ccc, ddd, eee, x[ 8] , 14);
413             FFF(eee, aaa, bbb, ccc, ddd, x[ 7] ,  6);
414             FFF(ddd, eee, aaa, bbb, ccc, x[ 6] ,  8);
415             FFF(ccc, ddd, eee, aaa, bbb, x[ 2] , 13);
416             FFF(bbb, ccc, ddd, eee, aaa, x[13] ,  6);
417             FFF(aaa, bbb, ccc, ddd, eee, x[14] ,  5);
418             FFF(eee, aaa, bbb, ccc, ddd, x[ 0] , 15);
419             FFF(ddd, eee, aaa, bbb, ccc, x[ 3] , 13);
420             FFF(ccc, ddd, eee, aaa, bbb, x[ 9] , 11);
421             FFF(bbb, ccc, ddd, eee, aaa, x[11] , 11);
422 
423             /* combine results */
424             ddd += cc + _state[1];               /* final result for _state[0] */
425             _state[1] = _state[2] + dd + eee;
426             _state[2] = _state[3] + ee + aaa;
427             _state[3] = _state[4] + aa + bbb;
428             _state[4] = _state[0] + bb + ccc;
429             _state[0] = ddd;
430 
431             //Zeroize sensitive information.
432             x[] = 0;
433         }
434 
435     public:
436         enum blockSize = 512;
437 
438         /**
439          * Use this to feed the digest with data.
440          * Also implements the $(REF isOutputRange, std,range,primitives)
441          * interface for `ubyte` and `const(ubyte)[]`.
442          *
443          * Example:
444          * ----
445          * RIPEMD160 dig;
446          * dig.put(cast(ubyte) 0); //single ubyte
447          * dig.put(cast(ubyte) 0, cast(ubyte) 0); //variadic
448          * ubyte[10] buf;
449          * dig.put(buf); //buffer
450          * ----
451          */
452         void put(scope const(ubyte)[] data...) @trusted pure nothrow @nogc
453         {
454             uint i, index, partLen;
455             auto inputLen = data.length;
456 
457             //Compute number of bytes mod 64
458             index = (cast(uint)_count >> 3) & (64 - 1);
459 
460             //Update number of bits
461             _count += inputLen * 8;
462 
463             partLen = 64 - index;
464 
465             //Transform as many times as possible
466             if (inputLen >= partLen)
467             {
468                 (&_buffer[index])[0 .. partLen] = data.ptr[0 .. partLen];
469                 transform(&_buffer);
470 
471                 for (i = partLen; i + 63 < inputLen; i += 64)
472                 {
473                     transform(cast(const(ubyte[64])*)(data[i .. i + 64].ptr));
474                 }
475 
476                 index = 0;
477             }
478             else
479             {
480                 i = 0;
481             }
482 
483             /* Buffer remaining input */
484             if (inputLen - i)
485                 (&_buffer[index])[0 .. inputLen-i] = (&data[i])[0 .. inputLen-i];
486         }
487 
488         /**
489          * Used to (re)initialize the RIPEMD160 digest.
490          *
491          * Note:
492          * For this RIPEMD160 Digest implementation calling start after default construction
493          * is not necessary. Calling start is only necessary to reset the Digest.
494          *
495          * Generic code which deals with different Digest types should always call start though.
496          *
497          * Example:
498          * --------
499          * RIPEMD160 digest;
500          * //digest.start(); //Not necessary
501          * digest.put(0);
502          * --------
503          */
504         void start() @safe pure nothrow @nogc
505         {
506             this = RIPEMD160.init;
507         }
508 
509         /**
510          * Returns the finished RIPEMD160 hash. This also calls $(LREF start) to
511          * reset the internal state.
512          *
513          * Example:
514          * --------
515          * //Simple example
516          * RIPEMD160 hash;
517          * hash.start();
518          * hash.put(cast(ubyte) 0);
519          * ubyte[20] result = hash.finish();
520          * assert(toHexString(result) == "C81B94933420221A7AC004A90242D8B1D3E5070D");
521          * --------
522          */
523         ubyte[20] finish() @trusted pure nothrow @nogc
524         {
525             import std.bitmanip : nativeToLittleEndian;
526 
527             ubyte[20] data = void;
528             ubyte[8] bits = void;
529             uint index, padLen;
530 
531             //Save number of bits
532             bits[0 .. 8] = nativeToLittleEndian(_count)[];
533 
534             //Pad out to 56 mod 64
535             index = (cast(uint)_count >> 3) & (64 - 1);
536             padLen = (index < 56) ? (56 - index) : (120 - index);
537             put(_padding[0 .. padLen]);
538 
539             //Append length (before padding)
540             put(bits);
541 
542             //Store state in digest
543             data[0 .. 4]   = nativeToLittleEndian(_state[0])[];
544             data[4 .. 8]   = nativeToLittleEndian(_state[1])[];
545             data[8 .. 12]  = nativeToLittleEndian(_state[2])[];
546             data[12 .. 16] = nativeToLittleEndian(_state[3])[];
547             data[16 .. 20] = nativeToLittleEndian(_state[4])[];
548 
549             /* Zeroize sensitive information. */
550             start();
551             return data;
552         }
553 }
554 
555 ///
556 @safe unittest
557 {
558     //Simple example, hashing a string using ripemd160Of helper function
559     ubyte[20] hash = ripemd160Of("abc");
560     //Let's get a hash string
561     assert(toHexString(hash) == "8EB208F7E05D987A9B044A8E98C6B087F15A0BFC");
562 }
563 
564 ///
565 @safe unittest
566 {
567     //Using the basic API
568     RIPEMD160 hash;
569     hash.start();
570     ubyte[1024] data;
571     //Initialize data here...
572     hash.put(data);
573     ubyte[20] result = hash.finish();
574 }
575 
576 ///
577 @safe unittest
578 {
579     //Let's use the template features:
580     void doSomething(T)(ref T hash)
581     if (isDigest!T)
582     {
583         hash.put(cast(ubyte) 0);
584     }
585     RIPEMD160 md;
586     md.start();
587     doSomething(md);
588     assert(toHexString(md.finish()) == "C81B94933420221A7AC004A90242D8B1D3E5070D");
589 }
590 
591 ///
592 @safe unittest
593 {
594     //Simple example
595     RIPEMD160 hash;
596     hash.start();
597     hash.put(cast(ubyte) 0);
598     ubyte[20] result = hash.finish();
599     assert(toHexString(result) == "C81B94933420221A7AC004A90242D8B1D3E5070D");
600 }
601 
602 @safe unittest
603 {
604     assert(isDigest!RIPEMD160);
605 }
606 
607 @system unittest
608 {
609     import std.conv : hexString;
610     import std.range;
611 
612     ubyte[20] digest;
613 
614     RIPEMD160 md;
615     md.put(cast(ubyte[])"abcdef");
616     md.start();
617     md.put(cast(ubyte[])"");
618     assert(md.finish() == cast(ubyte[]) hexString!"9c1185a5c5e9fc54612808977ee8f548b2258d31");
619 
620     digest = ripemd160Of("");
621     assert(digest == cast(ubyte[]) hexString!"9c1185a5c5e9fc54612808977ee8f548b2258d31");
622 
623     digest = ripemd160Of("a");
624     assert(digest == cast(ubyte[]) hexString!"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe");
625 
626     digest = ripemd160Of("abc");
627     assert(digest == cast(ubyte[]) hexString!"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
628 
629     digest = ripemd160Of("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq");
630     assert(digest == cast(ubyte[]) hexString!"12a053384a9c0c88e405a06c27dcf49ada62eb2b");
631 
632     digest = ripemd160Of("message digest");
633     assert(digest == cast(ubyte[]) hexString!"5d0689ef49d2fae572b881b123a85ffa21595f36");
634 
635     digest = ripemd160Of("abcdefghijklmnopqrstuvwxyz");
636     assert(digest == cast(ubyte[]) hexString!"f71c27109c692c1b56bbdceb5b9d2865b3708dbc");
637 
638     digest = ripemd160Of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
639     assert(digest == cast(ubyte[]) hexString!"b0e20b6e3116640286ed3a87a5713079b21f5189");
640 
641     digest = ripemd160Of("1234567890123456789012345678901234567890"~
642                     "1234567890123456789012345678901234567890");
643     assert(digest == cast(ubyte[]) hexString!"9b752e45573d4b39f4dbd3323cab82bf63326bfb");
644 
645     enum ubyte[20] input = cast(ubyte[20]) hexString!"f71c27109c692c1b56bbdceb5b9d2865b3708dbc";
646     assert(toHexString(input)
647         == "F71C27109C692C1B56BBDCEB5B9D2865B3708DBC");
648 
649     ubyte[] onemilliona = new ubyte[1000000];
650     onemilliona[] = 'a';
651     digest = ripemd160Of(onemilliona);
652     assert(digest == cast(ubyte[]) hexString!"52783243c1697bdbe16d37f97f68f08325dc1528");
653 
654     auto oneMillionRange = repeat!ubyte(cast(ubyte)'a', 1000000);
655     digest = ripemd160Of(oneMillionRange);
656     assert(digest == cast(ubyte[]) hexString!"52783243c1697bdbe16d37f97f68f08325dc1528");
657 }
658 
659 /**
660  * This is a convenience alias for $(REF digest, std,digest) using the
661  * RIPEMD160 implementation.
662  */
663 //simple alias doesn't work here, hope this gets inlined...
664 auto ripemd160Of(T...)(T data)
665 {
666     return digest!(RIPEMD160, T)(data);
667 }
668 
669 ///
670 @safe unittest
671 {
672     ubyte[20] hash = ripemd160Of("abc");
673     assert(hash == digest!RIPEMD160("abc"));
674 }
675 
676 /**
677  * OOP API RIPEMD160 implementation.
678  * See `std.digest` for differences between template and OOP API.
679  *
680  * This is an alias for $(D $(REF WrapperDigest, std,digest)!RIPEMD160),
681  * see there for more information.
682  */
683 alias RIPEMD160Digest = WrapperDigest!RIPEMD160;
684 
685 ///
686 @safe unittest
687 {
688     //Simple example, hashing a string using Digest.digest helper function
689     auto md = new RIPEMD160Digest();
690     ubyte[] hash = md.digest("abc");
691     //Let's get a hash string
692     assert(toHexString(hash) == "8EB208F7E05D987A9B044A8E98C6B087F15A0BFC");
693 }
694 
695 ///
696 @system unittest
697 {
698     //Let's use the OOP features:
699     void test(Digest dig)
700     {
701       dig.put(cast(ubyte) 0);
702     }
703     auto md = new RIPEMD160Digest();
704     test(md);
705 
706     //Let's use a custom buffer:
707     ubyte[20] buf;
708     ubyte[] result = md.finish(buf[]);
709     assert(toHexString(result) == "C81B94933420221A7AC004A90242D8B1D3E5070D");
710 }
711 
712 @system unittest
713 {
714     import std.conv : hexString;
715     auto md = new RIPEMD160Digest();
716 
717     md.put(cast(ubyte[])"abcdef");
718     md.reset();
719     md.put(cast(ubyte[])"");
720     assert(md.finish() == cast(ubyte[]) hexString!"9c1185a5c5e9fc54612808977ee8f548b2258d31");
721 
722     md.put(cast(ubyte[])"abcdefghijklmnopqrstuvwxyz");
723     ubyte[20] result;
724     auto result2 = md.finish(result[]);
725     assert(result[0 .. 20] == result2 && result2 == cast(ubyte[]) hexString!"f71c27109c692c1b56bbdceb5b9d2865b3708dbc");
726 
727     debug
728     {
729         import std.exception;
730         assertThrown!Error(md.finish(result[0 .. 19]));
731     }
732 
733     assert(md.length == 20);
734 
735     assert(md.digest("") == cast(ubyte[]) hexString!"9c1185a5c5e9fc54612808977ee8f548b2258d31");
736 
737     assert(md.digest("a") == cast(ubyte[]) hexString!"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe");
738 
739     assert(md.digest("abc") == cast(ubyte[]) hexString!"8eb208f7e05d987a9b044a8e98c6b087f15a0bfc");
740 
741     assert(md.digest("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq")
742            == cast(ubyte[]) hexString!"12a053384a9c0c88e405a06c27dcf49ada62eb2b");
743 
744     assert(md.digest("message digest") == cast(ubyte[]) hexString!"5d0689ef49d2fae572b881b123a85ffa21595f36");
745 
746     assert(md.digest("abcdefghijklmnopqrstuvwxyz")
747            == cast(ubyte[]) hexString!"f71c27109c692c1b56bbdceb5b9d2865b3708dbc");
748 
749     assert(md.digest("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
750            == cast(ubyte[]) hexString!"b0e20b6e3116640286ed3a87a5713079b21f5189");
751 
752     assert(md.digest("1234567890123456789012345678901234567890",
753                                    "1234567890123456789012345678901234567890")
754            == cast(ubyte[]) hexString!"9b752e45573d4b39f4dbd3323cab82bf63326bfb");
755 
756     assert(md.digest(new ubyte[160/8]) // 160 zero bits
757            == cast(ubyte[]) hexString!"5c00bd4aca04a9057c09b20b05f723f2e23deb65");
758 }