OSDN Git Service

Add license clarification.
[pf3gnuchains/gcc-fork.git] / libjava / gnu / java / security / provider / SHA.java
1 /* SHA.java -- Class implementing the SHA-1 algorithm as specified in [1].
2    Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10  
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38   
39 package gnu.java.security.provider;
40
41 import java.security.MessageDigest;
42
43 /**
44    This class implements the SHA-1 algorithm as described in [1].
45
46    [1] Federal Information Processing Standards Publication 180-1.
47    Specifications for the Secure Hash Standard.  April 17, 1995.
48
49    @see java.security.MessageDigest
50 */
51 public class SHA extends MessageDigest implements Cloneable
52 {
53   public SHA ()
54   {
55     super("SHA");
56     engineReset ();
57   }
58
59   public int engineGetDigestLength()
60   {
61     return 16;
62   }
63
64   public void engineUpdate (byte b)
65   {
66     int i = (int)bytecount % 64;
67     int shift = (3 - i % 4) * 8;
68     int idx = i / 4;
69
70     // if you could index ints, this would be: W[idx][shift/8] = b
71     W[idx] = (W[idx] & ~(0xff << shift)) | ((b & 0xff) << shift);
72
73     // if we've filled up a block, then process it
74     if ((++ bytecount) % 64 == 0)
75       munch ();
76   }
77
78   // This could be optimized.
79   public void engineUpdate (byte bytes[], int off, int len)
80   {
81     if (len < 0)
82       throw new ArrayIndexOutOfBoundsException ();
83
84     int end = off + len;
85     while (off < end)
86       engineUpdate (bytes[off++]);
87   }
88
89   public void engineReset ()
90   {
91     bytecount = 0;
92     // magic numbers from [1] p. 10.
93     H0 = 0x67452301;
94     H1 = 0xefcdab89;
95     H2 = 0x98badcfe;
96     H3 = 0x10325476;
97     H4 = 0xc3d2e1f0;
98   }
99
100   public byte[] engineDigest ()
101   {
102     long bitcount = bytecount * 8;
103     engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding
104
105     // add the rest of the padding to fill this block out, but leave 8
106     // bytes to put in the original bytecount
107     while ((int)bytecount % 64 != 56)
108       engineUpdate ((byte)0);
109
110     // add the length of the original, unpadded block to the end of
111     // the padding
112     W[14] = (int)(bitcount >>> 32);
113     W[15] = (int)bitcount;
114     bytecount += 8;
115
116     // digest the fully padded block
117     munch ();
118
119     byte[] result
120       = new byte[] {(byte)(H0 >>> 24), (byte)(H0 >>> 16),
121                     (byte)(H0 >>> 8), (byte)H0,
122                     (byte)(H1 >>> 24), (byte)(H1 >>> 16),
123                     (byte)(H1 >>> 8), (byte)H1,
124                     (byte)(H2 >>> 24), (byte)(H2 >>> 16),
125                     (byte)(H2 >>> 8), (byte)H2,
126                     (byte)(H3 >>> 24), (byte)(H3 >>> 16),
127                     (byte)(H3 >>> 8), (byte)H3,
128                     (byte)(H4 >>> 24), (byte)(H4 >>> 16),
129                     (byte)(H4 >>> 8), (byte)H4};
130     
131     engineReset ();
132     return result;
133   }
134
135   // Process a single block.  This is pretty much copied verbatim from
136   // [1] pp. 9, 10.
137   private void munch ()
138   {
139     for (int t = 16; t < 80; ++ t)
140       {
141         int Wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16];
142         W[t] = Wt << 1 | Wt >>> 31;
143       }
144
145     int A = H0;
146     int B = H1;
147     int C = H2;
148     int D = H3;
149     int E = H4;
150
151     for (int t = 0; t < 20; ++ t)
152       {
153         int TEMP = (A << 5 | A >>> 27) // S^5(A)
154           + ((B & C) | (~B & D))       // f_t(B,C,D)
155           + E + W[t]
156           + 0x5a827999;                // K_t
157
158         E = D;
159         D = C;
160         C = B << 30 | B >>> 2;         // S^30(B)
161         B = A;
162         A = TEMP;
163       }
164
165     for (int t = 20; t < 40; ++ t)
166       {
167         int TEMP = (A << 5 | A >>> 27) // S^5(A)
168           + (B ^ C ^ D)                // f_t(B,C,D)
169           + E + W[t]                   
170           + 0x6ed9eba1;                // K_t
171
172         E = D;
173         D = C;
174         C = B << 30 | B >>> 2;         // S^30(B)
175         B = A;
176         A = TEMP;
177       }
178
179     for (int t = 40; t < 60; ++ t)
180       {
181         int TEMP = (A << 5 | A >>> 27) // S^5(A)
182           + (B & C | B & D | C & D)    // f_t(B,C,D)
183           + E + W[t]
184           + 0x8f1bbcdc;                // K_t
185
186         E = D;
187         D = C;
188         C = B << 30 | B >>> 2;         // S^30(B)
189         B = A;
190         A = TEMP;
191       }
192
193     for (int t = 60; t < 80; ++ t)
194       {
195         int TEMP = (A << 5 | A >>> 27) // S^5(A)
196           + (B ^ C ^ D)                // f_t(B,C,D)
197           + E + W[t]
198           + 0xca62c1d6;                // K_t
199
200         E = D;
201         D = C;
202         C = B << 30 | B >>> 2;         // S^30(B)
203         B = A;
204         A = TEMP;
205       }
206
207     H0 += A;
208     H1 += B;
209     H2 += C;
210     H3 += D;
211     H4 += E;
212
213     // Reset W by clearing it.
214     for (int t = 0; t < 80; ++ t)
215       W[t] = 0;
216   }
217   
218   public Object clone ()
219   {
220     return new SHA (this);
221   }
222
223   private SHA (SHA copy)
224   {
225     this ();
226     bytecount = copy.bytecount;
227     H0 = copy.H0;
228     H1 = copy.H1;
229     H2 = copy.H2;
230     H3 = copy.H3;
231     H4 = copy.H4;
232     System.arraycopy (copy.W, 0, W, 0, 80);
233   }
234   
235   private final int W[] = new int[80];
236   private long bytecount;
237   private int H0;
238   private int H1;
239   private int H2;
240   private int H3;
241   private int H4;
242 }