finished last of the compile errors
[org.ibex.crypto.git] / src / org / ibex / crypto / SHA1.java
1 /* Copyright (c) 2000 The Legion Of The Bouncy Castle 
2  * (http://www.bouncycastle.org)
3  * 
4  * Permission is hereby granted, free of charge, to any person obtaining a 
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation 
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense, 
8  * and/or sell copies of the Software, and to permit persons to whom the 
9  * Software is furnished to do so, subject to the following conditions:
10  * 
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  * 
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDER.S BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
20  * DEALINGS IN THE SOFTWARE.
21  */
22
23 package org.ibex.crypto;
24
25 /**
26  * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
27  *
28  * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
29  * is the "endienness" of the word processing!
30  */
31 public class SHA1
32     extends Digest
33 {
34     private static final int    DIGEST_LENGTH = 20;
35
36     private int     H1, H2, H3, H4, H5;
37
38     private int[]   X = new int[80];
39     private int     xOff;
40
41     /**
42      * Standard constructor
43      */
44     public SHA1()
45     {
46         reset();
47     }
48
49     public int getDigestSize()
50     {
51         return DIGEST_LENGTH;
52     }
53
54     protected void processWord(
55         byte[]  in,
56         int     inOff)
57     {
58         X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16)
59                     | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff)); 
60
61         if (xOff == 16)
62         {
63             processBlock();
64         }
65     }
66
67     private void unpackWord(
68         int     word,
69         byte[]  out,
70         int     outOff)
71     {
72         out[outOff]     = (byte)(word >>> 24);
73         out[outOff + 1] = (byte)(word >>> 16);
74         out[outOff + 2] = (byte)(word >>> 8);
75         out[outOff + 3] = (byte)word;
76     }
77
78     protected void processLength(
79         long    bitLength)
80     {
81         if (xOff > 14)
82         {
83             processBlock();
84         }
85
86         X[14] = (int)(bitLength >>> 32);
87         X[15] = (int)(bitLength & 0xffffffff);
88     }
89
90     public void doFinal(
91         byte[]  out,
92         int     outOff)
93     {
94         finish();
95
96         unpackWord(H1, out, outOff);
97         unpackWord(H2, out, outOff + 4);
98         unpackWord(H3, out, outOff + 8);
99         unpackWord(H4, out, outOff + 12);
100         unpackWord(H5, out, outOff + 16);
101
102         reset();
103     }
104
105     /**
106      * reset the chaining variables
107      */
108     public void reset()
109     {
110         super.reset();
111
112         H1 = 0x67452301;
113         H2 = 0xefcdab89;
114         H3 = 0x98badcfe;
115         H4 = 0x10325476;
116         H5 = 0xc3d2e1f0;
117
118         xOff = 0;
119         for (int i = 0; i != X.length; i++)
120         {
121             X[i] = 0;
122         }
123     }
124
125     private int f(
126         int    u,
127         int    v,
128         int    w)
129     {
130         return ((u & v) | ((~u) & w));
131     }
132
133     private int h(
134         int    u,
135         int    v,
136         int    w)
137     {
138         return (u ^ v ^ w);
139     }
140
141     private int g(
142         int    u,
143         int    v,
144         int    w)
145     {
146         return ((u & v) | (u & w) | (v & w));
147     }
148
149     private int rotateLeft(
150         int    x,
151         int    n)
152     {
153         return (x << n) | (x >>> (32 - n));
154     }
155
156     protected void processBlock()
157     {
158         //
159         // expand 16 word block into 80 word block.
160         //
161         for (int i = 16; i <= 79; i++)
162         {
163             X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
164         }
165
166         //
167         // set up working variables.
168         //
169         int     A = H1;
170         int     B = H2;
171         int     C = H3;
172         int     D = H4;
173         int     E = H5;
174
175         //
176         // round 1
177         //
178         for (int j = 0; j <= 19; j++)
179         {
180             int     t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + 0x5a827999;
181
182             E = D;
183             D = C;
184             C = rotateLeft(B, 30);
185             B = A;
186             A = t;
187         }
188
189         //
190         // round 2
191         //
192         for (int j = 20; j <= 39; j++)
193         {
194             int     t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + 0x6ed9eba1;
195
196             E = D;
197             D = C;
198             C = rotateLeft(B, 30);
199             B = A;
200             A = t;
201         }
202
203         //
204         // round 3
205         //
206         for (int j = 40; j <= 59; j++)
207         {
208             int     t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + 0x8f1bbcdc;
209
210             E = D;
211             D = C;
212             C = rotateLeft(B, 30);
213             B = A;
214             A = t;
215         }
216
217         //
218         // round 4
219         //
220         for (int j = 60; j <= 79; j++)
221         {
222             int     t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + 0xca62c1d6;
223
224             E = D;
225             D = C;
226             C = rotateLeft(B, 30);
227             B = A;
228             A = t;
229         }
230
231         H1 += A;
232         H2 += B;
233         H3 += C;
234         H4 += D;
235         H5 += E;
236
237         //
238         // reset the offset and clean out the word buffer.
239         //
240         xOff = 0;
241         for (int i = 0; i != X.length; i++)
242         {
243             X[i] = 0;
244         }
245     }
246 }