1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43:
44:
69: public class Sha160
70: extends BaseHash
71: {
72: private static final int BLOCK_SIZE = 64;
73:
74: private static final String DIGEST0 = "A9993E364706816ABA3E25717850C26C9CD0D89D";
75:
76: private static final int[] w = new int[80];
77:
78:
79: private static Boolean valid;
80:
81:
82: private int h0, h1, h2, h3, h4;
83:
84:
85: public Sha160()
86: {
87: super(Registry.SHA160_HASH, 20, BLOCK_SIZE);
88: }
89:
90:
95: private Sha160(Sha160 md)
96: {
97: this();
98:
99: this.h0 = md.h0;
100: this.h1 = md.h1;
101: this.h2 = md.h2;
102: this.h3 = md.h3;
103: this.h4 = md.h4;
104: this.count = md.count;
105: this.buffer = (byte[]) md.buffer.clone();
106: }
107:
108: public static final int[] G(int hh0, int hh1, int hh2, int hh3, int hh4,
109: byte[] in, int offset)
110: {
111: return sha(hh0, hh1, hh2, hh3, hh4, in, offset);
112: }
113:
114: public Object clone()
115: {
116: return new Sha160(this);
117: }
118:
119: protected void transform(byte[] in, int offset)
120: {
121: int[] result = sha(h0, h1, h2, h3, h4, in, offset);
122: h0 = result[0];
123: h1 = result[1];
124: h2 = result[2];
125: h3 = result[3];
126: h4 = result[4];
127: }
128:
129: protected byte[] padBuffer()
130: {
131: int n = (int)(count % BLOCK_SIZE);
132: int padding = (n < 56) ? (56 - n) : (120 - n);
133: byte[] result = new byte[padding + 8];
134:
135: result[0] = (byte) 0x80;
136:
137: long bits = count << 3;
138: result[padding++] = (byte)(bits >>> 56);
139: result[padding++] = (byte)(bits >>> 48);
140: result[padding++] = (byte)(bits >>> 40);
141: result[padding++] = (byte)(bits >>> 32);
142: result[padding++] = (byte)(bits >>> 24);
143: result[padding++] = (byte)(bits >>> 16);
144: result[padding++] = (byte)(bits >>> 8);
145: result[padding ] = (byte) bits;
146: return result;
147: }
148:
149: protected byte[] getResult()
150: {
151: return new byte[] {
152: (byte)(h0 >>> 24), (byte)(h0 >>> 16), (byte)(h0 >>> 8), (byte) h0,
153: (byte)(h1 >>> 24), (byte)(h1 >>> 16), (byte)(h1 >>> 8), (byte) h1,
154: (byte)(h2 >>> 24), (byte)(h2 >>> 16), (byte)(h2 >>> 8), (byte) h2,
155: (byte)(h3 >>> 24), (byte)(h3 >>> 16), (byte)(h3 >>> 8), (byte) h3,
156: (byte)(h4 >>> 24), (byte)(h4 >>> 16), (byte)(h4 >>> 8), (byte) h4 };
157: }
158:
159: protected void resetContext()
160: {
161:
162: h0 = 0x67452301;
163: h1 = 0xEFCDAB89;
164: h2 = 0x98BADCFE;
165: h3 = 0x10325476;
166: h4 = 0xC3D2E1F0;
167: }
168:
169: public boolean selfTest()
170: {
171: if (valid == null)
172: {
173: Sha160 md = new Sha160();
174: md.update((byte) 0x61);
175: md.update((byte) 0x62);
176: md.update((byte) 0x63);
177: String result = Util.toString(md.digest());
178: valid = Boolean.valueOf(DIGEST0.equals(result));
179: }
180: return valid.booleanValue();
181: }
182:
183: private static synchronized final int[] sha(int hh0, int hh1, int hh2,
184: int hh3, int hh4, byte[] in,
185: int offset)
186: {
187: int A = hh0;
188: int B = hh1;
189: int C = hh2;
190: int D = hh3;
191: int E = hh4;
192: int r, T;
193: for (r = 0; r < 16; r++)
194: w[r] = in[offset++] << 24
195: | (in[offset++] & 0xFF) << 16
196: | (in[offset++] & 0xFF) << 8
197: | (in[offset++] & 0xFF);
198: for (r = 16; r < 80; r++)
199: {
200: T = w[r - 3] ^ w[r - 8] ^ w[r - 14] ^ w[r - 16];
201: w[r] = T << 1 | T >>> 31;
202: }
203: for (r = 0; r < 20; r++)
204: {
205: T = (A << 5 | A >>> 27) + ((B & C) | (~B & D)) + E + w[r] + 0x5A827999;
206: E = D;
207: D = C;
208: C = B << 30 | B >>> 2;
209: B = A;
210: A = T;
211: }
212: for (r = 20; r < 40; r++)
213: {
214: T = (A << 5 | A >>> 27) + (B ^ C ^ D) + E + w[r] + 0x6ED9EBA1;
215: E = D;
216: D = C;
217: C = B << 30 | B >>> 2;
218: B = A;
219: A = T;
220: }
221: for (r = 40; r < 60; r++)
222: {
223: T = (A << 5 | A >>> 27) + (B & C | B & D | C & D) + E + w[r] + 0x8F1BBCDC;
224: E = D;
225: D = C;
226: C = B << 30 | B >>> 2;
227: B = A;
228: A = T;
229: }
230: for (r = 60; r < 80; r++)
231: {
232: T = (A << 5 | A >>> 27) + (B ^ C ^ D) + E + w[r] + 0xCA62C1D6;
233: E = D;
234: D = C;
235: C = B << 30 | B >>> 2;
236: B = A;
237: A = T;
238: }
239: return new int[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E };
240: }
241: }