1   package org.bouncycastle.crypto.digests;
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  public class SHA1Digest
33          extends GeneralDigest {
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  
43  
44      public SHA1Digest() {
45          reset();
46      }
47  
48      
49  
50  
51  
52      public SHA1Digest(SHA1Digest t) {
53          super(t);
54  
55          H1 = t.H1;
56          H2 = t.H2;
57          H3 = t.H3;
58          H4 = t.H4;
59          H5 = t.H5;
60  
61          System.arraycopy(t.X, 0, X, 0, t.X.length);
62          xOff = t.xOff;
63      }
64  
65      public String getAlgorithmName() {
66          return "SHA-1";
67      }
68  
69      public int getDigestSize() {
70          return DIGEST_LENGTH;
71      }
72  
73      protected void processWord(
74              byte[] in,
75              int inOff) {
76          X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16)
77                  | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff));
78  
79          if (xOff == 16) {
80              processBlock();
81          }
82      }
83  
84      private void unpackWord(
85              int word,
86              byte[] out,
87              int outOff) {
88          out[outOff] = (byte) (word >>> 24);
89          out[outOff + 1] = (byte) (word >>> 16);
90          out[outOff + 2] = (byte) (word >>> 8);
91          out[outOff + 3] = (byte) word;
92      }
93  
94      protected void processLength(
95              long bitLength) {
96          if (xOff > 14) {
97              processBlock();
98          }
99  
100         X[14] = (int) (bitLength >>> 32);
101         X[15] = (int) (bitLength & 0xffffffff);
102     }
103 
104     public int doFinal(
105             byte[] out,
106             int outOff) {
107         finish();
108 
109         unpackWord(H1, out, outOff);
110         unpackWord(H2, out, outOff + 4);
111         unpackWord(H3, out, outOff + 8);
112         unpackWord(H4, out, outOff + 12);
113         unpackWord(H5, out, outOff + 16);
114 
115         reset();
116 
117         return DIGEST_LENGTH;
118     }
119 
120     
121 
122 
123     public void reset() {
124         super.reset();
125 
126         H1 = 0x67452301;
127         H2 = 0xefcdab89;
128         H3 = 0x98badcfe;
129         H4 = 0x10325476;
130         H5 = 0xc3d2e1f0;
131 
132         xOff = 0;
133         for (int i = 0; i != X.length; i++) {
134             X[i] = 0;
135         }
136     }
137 
138     
139     
140     
141     private static final int Y1 = 0x5a827999;
142     private static final int Y2 = 0x6ed9eba1;
143     private static final int Y3 = 0x8f1bbcdc;
144     private static final int Y4 = 0xca62c1d6;
145 
146     private int f(
147             int u,
148             int v,
149             int w) {
150         return ((u & v) | ((~u) & w));
151     }
152 
153     private int h(
154             int u,
155             int v,
156             int w) {
157         return (u ^ v ^ w);
158     }
159 
160     private int g(
161             int u,
162             int v,
163             int w) {
164         return ((u & v) | (u & w) | (v & w));
165     }
166 
167     private int rotateLeft(
168             int x,
169             int n) {
170         return (x << n) | (x >>> (32 - n));
171     }
172 
173     protected void processBlock() {
174         
175         
176         
177         for (int i = 16; i <= 79; i++) {
178             X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
179         }
180 
181         
182         
183         
184         int A = H1;
185         int B = H2;
186         int C = H3;
187         int D = H4;
188         int E = H5;
189 
190         
191         
192         
193         for (int j = 0; j <= 19; j++) {
194             int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1;
195 
196             E = D;
197             D = C;
198             C = rotateLeft(B, 30);
199             B = A;
200             A = t;
201         }
202 
203         
204         
205         
206         for (int j = 20; j <= 39; j++) {
207             int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2;
208 
209             E = D;
210             D = C;
211             C = rotateLeft(B, 30);
212             B = A;
213             A = t;
214         }
215 
216         
217         
218         
219         for (int j = 40; j <= 59; j++) {
220             int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3;
221 
222             E = D;
223             D = C;
224             C = rotateLeft(B, 30);
225             B = A;
226             A = t;
227         }
228 
229         
230         
231         
232         for (int j = 60; j <= 79; j++) {
233             int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4;
234 
235             E = D;
236             D = C;
237             C = rotateLeft(B, 30);
238             B = A;
239             A = t;
240         }
241 
242         H1 += A;
243         H2 += B;
244         H3 += C;
245         H4 += D;
246         H5 += E;
247 
248         
249         
250         
251         xOff = 0;
252         for (int i = 0; i != X.length; i++) {
253             X[i] = 0;
254         }
255     }
256 }