132
|
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.io.digest.Sha1;
|
|
18
|
|
19 private import tango.io.digest.Sha01;
|
|
20
|
|
21 public import tango.io.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(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 version (UnitTest)
|
|
97 {
|
|
98 unittest
|
|
99 {
|
|
100 static char[][] strings =
|
|
101 [
|
|
102 "abc",
|
|
103 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
|
104 "a",
|
|
105 "0123456701234567012345670123456701234567012345670123456701234567"
|
|
106 ];
|
|
107
|
|
108 static char[][] results =
|
|
109 [
|
|
110 "a9993e364706816aba3e25717850c26c9cd0d89d",
|
|
111 "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
|
|
112 "34aa973cd4c4daa4f61eeb2bdbad27316534016f",
|
|
113 "dea356a2cddd90c7a7ecedc5ebb563934f460452"
|
|
114 ];
|
|
115
|
|
116 static int[] repeat =
|
|
117 [
|
|
118 1,
|
|
119 1,
|
|
120 1000000,
|
|
121 10
|
|
122 ];
|
|
123
|
|
124 Sha1 h = new Sha1();
|
|
125
|
|
126 foreach (int i, 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 }
|