1:
37:
38:
39: package ;
40:
41: import ;
42:
43:
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 20;
62: }
63:
64: public void engineUpdate (byte b)
65: {
66: int i = ((int)bytecount) & 0x3f;
67: int shift = (3 - i % 4) << 3;
68: int idx = i / 4;
69:
70: i = (int)b;
71: W[idx] = (W[idx] & ~(0xff << shift)) | ((i & 0xff) << shift);
72:
73:
74: if (((++bytecount) & 0x3f) == 0)
75: munch ();
76: }
77:
78:
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:
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 << 3;
103: engineUpdate ((byte)0x80);
104:
105:
106:
107: while ((bytecount & 0x3f) != 56)
108: engineUpdate ((byte)0);
109:
110:
111:
112: W[14] = (int)(bitcount >>> 32);
113: W[15] = (int)bitcount;
114: bytecount += 8;
115:
116:
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:
136:
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)
154: + ((B & C) | (~B & D))
155: + E + W[t]
156: + 0x5a827999;
157:
158: E = D;
159: D = C;
160: C = B << 30 | B >>> 2;
161: B = A;
162: A = TEMP;
163: }
164:
165: for (int t = 20; t < 40; ++ t)
166: {
167: int TEMP = (A << 5 | A >>> 27)
168: + (B ^ C ^ D)
169: + E + W[t]
170: + 0x6ed9eba1;
171:
172: E = D;
173: D = C;
174: C = B << 30 | B >>> 2;
175: B = A;
176: A = TEMP;
177: }
178:
179: for (int t = 40; t < 60; ++ t)
180: {
181: int TEMP = (A << 5 | A >>> 27)
182: + (B & C | B & D | C & D)
183: + E + W[t]
184: + 0x8f1bbcdc;
185:
186: E = D;
187: D = C;
188: C = B << 30 | B >>> 2;
189: B = A;
190: A = TEMP;
191: }
192:
193: for (int t = 60; t < 80; ++ t)
194: {
195: int TEMP = (A << 5 | A >>> 27)
196: + (B ^ C ^ D)
197: + E + W[t]
198: + 0xca62c1d6;
199:
200: E = D;
201: D = C;
202: C = B << 30 | B >>> 2;
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:
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: }