• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.bouncycastle.crypto.digests;
2 
3 import org.bouncycastle.crypto.util.Pack;
4 
5 /**
6  * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
7  *
8  * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
9  * is the "endienness" of the word processing!
10  */
11 public class SHA1Digest
12     extends GeneralDigest
13 {
14     private static final int    DIGEST_LENGTH = 20;
15 
16     private int     H1, H2, H3, H4, H5;
17 
18     private int[]   X = new int[80];
19     private int     xOff;
20 
21     /**
22      * Standard constructor
23      */
SHA1Digest()24     public SHA1Digest()
25     {
26         reset();
27     }
28 
29     /**
30      * Copy constructor.  This will copy the state of the provided
31      * message digest.
32      */
SHA1Digest(SHA1Digest t)33     public SHA1Digest(SHA1Digest t)
34     {
35         super(t);
36 
37         H1 = t.H1;
38         H2 = t.H2;
39         H3 = t.H3;
40         H4 = t.H4;
41         H5 = t.H5;
42 
43         System.arraycopy(t.X, 0, X, 0, t.X.length);
44         xOff = t.xOff;
45     }
46 
getAlgorithmName()47     public String getAlgorithmName()
48     {
49         return "SHA-1";
50     }
51 
getDigestSize()52     public int getDigestSize()
53     {
54         return DIGEST_LENGTH;
55     }
56 
processWord( byte[] in, int inOff)57     protected void processWord(
58         byte[]  in,
59         int     inOff)
60     {
61         // Note: Inlined for performance
62 //        X[xOff] = Pack.bigEndianToInt(in, inOff);
63         int n = in[  inOff] << 24;
64         n |= (in[++inOff] & 0xff) << 16;
65         n |= (in[++inOff] & 0xff) << 8;
66         n |= (in[++inOff] & 0xff);
67         X[xOff] = n;
68 
69         if (++xOff == 16)
70         {
71             processBlock();
72         }
73     }
74 
processLength( long bitLength)75     protected void processLength(
76         long    bitLength)
77     {
78         if (xOff > 14)
79         {
80             processBlock();
81         }
82 
83         X[14] = (int)(bitLength >>> 32);
84         X[15] = (int)(bitLength & 0xffffffff);
85     }
86 
doFinal( byte[] out, int outOff)87     public int doFinal(
88         byte[]  out,
89         int     outOff)
90     {
91         finish();
92 
93         Pack.intToBigEndian(H1, out, outOff);
94         Pack.intToBigEndian(H2, out, outOff + 4);
95         Pack.intToBigEndian(H3, out, outOff + 8);
96         Pack.intToBigEndian(H4, out, outOff + 12);
97         Pack.intToBigEndian(H5, out, outOff + 16);
98 
99         reset();
100 
101         return DIGEST_LENGTH;
102     }
103 
104     /**
105      * reset the chaining variables
106      */
reset()107     public void reset()
108     {
109         super.reset();
110 
111         H1 = 0x67452301;
112         H2 = 0xefcdab89;
113         H3 = 0x98badcfe;
114         H4 = 0x10325476;
115         H5 = 0xc3d2e1f0;
116 
117         xOff = 0;
118         for (int i = 0; i != X.length; i++)
119         {
120             X[i] = 0;
121         }
122     }
123 
124     //
125     // Additive constants
126     //
127     private static final int    Y1 = 0x5a827999;
128     private static final int    Y2 = 0x6ed9eba1;
129     private static final int    Y3 = 0x8f1bbcdc;
130     private static final int    Y4 = 0xca62c1d6;
131 
f( int u, int v, int w)132     private int f(
133         int    u,
134         int    v,
135         int    w)
136     {
137         return ((u & v) | ((~u) & w));
138     }
139 
h( int u, int v, int w)140     private int h(
141         int    u,
142         int    v,
143         int    w)
144     {
145         return (u ^ v ^ w);
146     }
147 
g( int u, int v, int w)148     private int g(
149         int    u,
150         int    v,
151         int    w)
152     {
153         return ((u & v) | (u & w) | (v & w));
154     }
155 
processBlock()156     protected void processBlock()
157     {
158         //
159         // expand 16 word block into 80 word block.
160         //
161         for (int i = 16; i < 80; i++)
162         {
163             int t = X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16];
164             X[i] = t << 1 | t >>> 31;
165         }
166 
167         //
168         // set up working variables.
169         //
170         int     A = H1;
171         int     B = H2;
172         int     C = H3;
173         int     D = H4;
174         int     E = H5;
175 
176         //
177         // round 1
178         //
179         int idx = 0;
180 
181         for (int j = 0; j < 4; j++)
182         {
183             // E = rotateLeft(A, 5) + f(B, C, D) + E + X[idx++] + Y1
184             // B = rotateLeft(B, 30)
185             E += (A << 5 | A >>> 27) + f(B, C, D) + X[idx++] + Y1;
186             B = B << 30 | B >>> 2;
187 
188             D += (E << 5 | E >>> 27) + f(A, B, C) + X[idx++] + Y1;
189             A = A << 30 | A >>> 2;
190 
191             C += (D << 5 | D >>> 27) + f(E, A, B) + X[idx++] + Y1;
192             E = E << 30 | E >>> 2;
193 
194             B += (C << 5 | C >>> 27) + f(D, E, A) + X[idx++] + Y1;
195             D = D << 30 | D >>> 2;
196 
197             A += (B << 5 | B >>> 27) + f(C, D, E) + X[idx++] + Y1;
198             C = C << 30 | C >>> 2;
199         }
200 
201         //
202         // round 2
203         //
204         for (int j = 0; j < 4; j++)
205         {
206             // E = rotateLeft(A, 5) + h(B, C, D) + E + X[idx++] + Y2
207             // B = rotateLeft(B, 30)
208             E += (A << 5 | A >>> 27) + h(B, C, D) + X[idx++] + Y2;
209             B = B << 30 | B >>> 2;
210 
211             D += (E << 5 | E >>> 27) + h(A, B, C) + X[idx++] + Y2;
212             A = A << 30 | A >>> 2;
213 
214             C += (D << 5 | D >>> 27) + h(E, A, B) + X[idx++] + Y2;
215             E = E << 30 | E >>> 2;
216 
217             B += (C << 5 | C >>> 27) + h(D, E, A) + X[idx++] + Y2;
218             D = D << 30 | D >>> 2;
219 
220             A += (B << 5 | B >>> 27) + h(C, D, E) + X[idx++] + Y2;
221             C = C << 30 | C >>> 2;
222         }
223 
224         //
225         // round 3
226         //
227         for (int j = 0; j < 4; j++)
228         {
229             // E = rotateLeft(A, 5) + g(B, C, D) + E + X[idx++] + Y3
230             // B = rotateLeft(B, 30)
231             E += (A << 5 | A >>> 27) + g(B, C, D) + X[idx++] + Y3;
232             B = B << 30 | B >>> 2;
233 
234             D += (E << 5 | E >>> 27) + g(A, B, C) + X[idx++] + Y3;
235             A = A << 30 | A >>> 2;
236 
237             C += (D << 5 | D >>> 27) + g(E, A, B) + X[idx++] + Y3;
238             E = E << 30 | E >>> 2;
239 
240             B += (C << 5 | C >>> 27) + g(D, E, A) + X[idx++] + Y3;
241             D = D << 30 | D >>> 2;
242 
243             A += (B << 5 | B >>> 27) + g(C, D, E) + X[idx++] + Y3;
244             C = C << 30 | C >>> 2;
245         }
246 
247         //
248         // round 4
249         //
250         for (int j = 0; j <= 3; j++)
251         {
252             // E = rotateLeft(A, 5) + h(B, C, D) + E + X[idx++] + Y4
253             // B = rotateLeft(B, 30)
254             E += (A << 5 | A >>> 27) + h(B, C, D) + X[idx++] + Y4;
255             B = B << 30 | B >>> 2;
256 
257             D += (E << 5 | E >>> 27) + h(A, B, C) + X[idx++] + Y4;
258             A = A << 30 | A >>> 2;
259 
260             C += (D << 5 | D >>> 27) + h(E, A, B) + X[idx++] + Y4;
261             E = E << 30 | E >>> 2;
262 
263             B += (C << 5 | C >>> 27) + h(D, E, A) + X[idx++] + Y4;
264             D = D << 30 | D >>> 2;
265 
266             A += (B << 5 | B >>> 27) + h(C, D, E) + X[idx++] + Y4;
267             C = C << 30 | C >>> 2;
268         }
269 
270 
271         H1 += A;
272         H2 += B;
273         H3 += C;
274         H4 += D;
275         H5 += E;
276 
277         //
278         // reset start of the buffer.
279         //
280         xOff = 0;
281         for (int i = 0; i < 16; i++)
282         {
283             X[i] = 0;
284         }
285     }
286 }
287 
288 
289 
290 
291