1 package org.bouncycastle.crypto.digests;
3 import org.bouncycastle.crypto.Digest;
6 * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
8 * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
9 * is the "endienness" of the word processing!
11 public class SHA1Digest
14 private static final int DIGEST_LENGTH = 20;
16 private int H1, H2, H3, H4, H5;
18 private int[] X = new int[80];
22 * Standard constructor
30 * Copy constructor. This will copy the state of the provided
33 public SHA1Digest(SHA1Digest t)
43 System.arraycopy(t.X, 0, X, 0, t.X.length);
47 public String getAlgorithmName()
52 public int getDigestSize()
57 protected void processWord(
61 X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16)
62 | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff));
70 private void unpackWord(
75 out[outOff] = (byte)(word >>> 24);
76 out[outOff + 1] = (byte)(word >>> 16);
77 out[outOff + 2] = (byte)(word >>> 8);
78 out[outOff + 3] = (byte)word;
81 protected void processLength(
89 X[14] = (int)(bitLength >>> 32);
90 X[15] = (int)(bitLength & 0xffffffff);
99 unpackWord(H1, out, outOff);
100 unpackWord(H2, out, outOff + 4);
101 unpackWord(H3, out, outOff + 8);
102 unpackWord(H4, out, outOff + 12);
103 unpackWord(H5, out, outOff + 16);
107 return DIGEST_LENGTH;
111 * reset the chaining variables
124 for (int i = 0; i != X.length; i++)
131 // Additive constants
133 private static final int Y1 = 0x5a827999;
134 private static final int Y2 = 0x6ed9eba1;
135 private static final int Y3 = 0x8f1bbcdc;
136 private static final int Y4 = 0xca62c1d6;
143 return ((u & v) | ((~u) & w));
159 return ((u & v) | (u & w) | (v & w));
162 private int rotateLeft(
166 return (x << n) | (x >>> (32 - n));
169 protected void processBlock()
172 // expand 16 word block into 80 word block.
174 for (int i = 16; i <= 79; i++)
176 X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
180 // set up working variables.
191 for (int j = 0; j <= 19; j++)
193 int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1;
197 C = rotateLeft(B, 30);
205 for (int j = 20; j <= 39; j++)
207 int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2;
211 C = rotateLeft(B, 30);
219 for (int j = 40; j <= 59; j++)
221 int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3;
225 C = rotateLeft(B, 30);
233 for (int j = 60; j <= 79; j++)
235 int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4;
239 C = rotateLeft(B, 30);
251 // reset the offset and clean out the word buffer.
254 for (int i = 0; i != X.length; i++)