1 /*******************************************************************************
2 
3         This module implements the SHA-1 Algorithm described by Secure Hash
4         Standard, FIPS PUB 180-1, and RFC 3174 US Secure Hash Algorithm 1
5         (SHA1). D. Eastlake 3rd, P. Jones. September 2001.
6 
7         Copyright:
8             Copyright (c) 2006 Tango contributors.
9             Some parts copyright (c) 2009-2016 dunnhumby Germany GmbH.
10             All rights reserved.
11 
12         License:
13             Tango Dual License: 3-Clause BSD License / Academic Free License v3.0.
14             See LICENSE_TANGO.txt for details.
15 
16         Version: Initial release: Feb 2006
17 
18         Authors: Regan Heath, Oskar Linde
19 
20 *******************************************************************************/
21 
22 module ocean.util.digest.Sha1;
23 
24 import ocean.meta.types.Qualifiers;
25 
26 import ocean.util.digest.Sha01;
27 
28 public  import ocean.util.digest.Digest;
29 
30 version (unittest) import ocean.core.Test;
31 
32 /*******************************************************************************
33 
34 *******************************************************************************/
35 
36 final class Sha1 : Sha01
37 {
38         /***********************************************************************
39 
40                 Construct a Sha1 hash algorithm context
41 
42         ***********************************************************************/
43 
44         this() { }
45 
46         /***********************************************************************
47 
48                 Performs the cipher on a block of data
49 
50                 Params:
51                 input = the block of data to cipher
52 
53                 Remarks:
54                 The actual cipher algorithm is carried out by this method on
55                 the passed block of data. This method is called for every
56                 blockSize() bytes of input data and once more with the remaining
57                 data padded to blockSize().
58 
59         ***********************************************************************/
60 
61         final protected override void transform(ubyte[] input)
62         {
63                 uint A,B,C,D,E,TEMP;
64                 uint[16] W;
65                 uint s;
66 
67                 bigEndian32(input,W);
68                 A = context[0];
69                 B = context[1];
70                 C = context[2];
71                 D = context[3];
72                 E = context[4];
73 
74                 for(uint t = 0; t < 80; t++) {
75                         s = t & mask;
76                         if (t >= 16)
77                                 expand(W,s);
78                         TEMP = rotateLeft(A,5) + f(t,B,C,D) + E + W[s] + K[t/20];
79                         E = D; D = C; C = rotateLeft(B,30); B = A; A = TEMP;
80                 }
81 
82                 context[0] += A;
83                 context[1] += B;
84                 context[2] += C;
85                 context[3] += D;
86                 context[4] += E;
87         }
88 
89         /***********************************************************************
90 
91         ***********************************************************************/
92 
93         final static void expand (uint[] W, uint s)
94         {
95                 W[s] = rotateLeft(W[(s+13)&mask] ^ W[(s+8)&mask] ^ W[(s+2)&mask] ^ W[s],1);
96         }
97 
98 }
99 
100 
101 /*******************************************************************************
102 
103 *******************************************************************************/
104 
105 unittest
106 {
107     static istring[] strings = [
108             "abc",
109             "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
110             "a",
111             "0123456701234567012345670123456701234567012345670123456701234567"
112     ];
113 
114     static istring[] results = [
115             "a9993e364706816aba3e25717850c26c9cd0d89d",
116             "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
117             "34aa973cd4c4daa4f61eeb2bdbad27316534016f",
118             "dea356a2cddd90c7a7ecedc5ebb563934f460452"
119     ];
120 
121     static int[] repeat = [
122             1,
123             1,
124             1000000,
125             10
126     ];
127 
128     Sha1 h = new Sha1();
129 
130     foreach (i, s; strings)
131     {
132         for(int r = 0; r < repeat[i]; r++)
133             h.update(s);
134 
135         char[] d = h.hexDigest();
136         test(d == results[i],":("~s~")("~d~")!=("~results[i]~")");
137     }
138 }