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