SHA1Digest.java
资源名称:security.rar [点击查看]
上传用户:lior1029
上传日期:2013-05-07
资源大小:209k
文件大小:5k
源码类别:
CA认证
开发平台:
Java
- package org.bouncycastle.crypto.digests;
- import org.bouncycastle.crypto.Digest;
- /**
- * implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
- *
- * It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
- * is the "endienness" of the word processing!
- */
- public class SHA1Digest
- extends GeneralDigest
- {
- private static final int DIGEST_LENGTH = 20;
- private int H1, H2, H3, H4, H5;
- private int[] X = new int[80];
- private int xOff;
- /**
- * Standard constructor
- */
- public SHA1Digest()
- {
- reset();
- }
- /**
- * Copy constructor. This will copy the state of the provided
- * message digest.
- */
- public SHA1Digest(SHA1Digest t)
- {
- super(t);
- H1 = t.H1;
- H2 = t.H2;
- H3 = t.H3;
- H4 = t.H4;
- H5 = t.H5;
- System.arraycopy(t.X, 0, X, 0, t.X.length);
- xOff = t.xOff;
- }
- public String getAlgorithmName()
- {
- return "SHA-1";
- }
- public int getDigestSize()
- {
- return DIGEST_LENGTH;
- }
- protected void processWord(
- byte[] in,
- int inOff)
- {
- X[xOff++] = ((in[inOff] & 0xff) << 24) | ((in[inOff + 1] & 0xff) << 16)
- | ((in[inOff + 2] & 0xff) << 8) | ((in[inOff + 3] & 0xff));
- if (xOff == 16)
- {
- processBlock();
- }
- }
- private void unpackWord(
- int word,
- byte[] out,
- int outOff)
- {
- out[outOff] = (byte)(word >>> 24);
- out[outOff + 1] = (byte)(word >>> 16);
- out[outOff + 2] = (byte)(word >>> 8);
- out[outOff + 3] = (byte)word;
- }
- protected void processLength(
- long bitLength)
- {
- if (xOff > 14)
- {
- processBlock();
- }
- X[14] = (int)(bitLength >>> 32);
- X[15] = (int)(bitLength & 0xffffffff);
- }
- public int doFinal(
- byte[] out,
- int outOff)
- {
- finish();
- unpackWord(H1, out, outOff);
- unpackWord(H2, out, outOff + 4);
- unpackWord(H3, out, outOff + 8);
- unpackWord(H4, out, outOff + 12);
- unpackWord(H5, out, outOff + 16);
- reset();
- return DIGEST_LENGTH;
- }
- /**
- * reset the chaining variables
- */
- public void reset()
- {
- super.reset();
- H1 = 0x67452301;
- H2 = 0xefcdab89;
- H3 = 0x98badcfe;
- H4 = 0x10325476;
- H5 = 0xc3d2e1f0;
- xOff = 0;
- for (int i = 0; i != X.length; i++)
- {
- X[i] = 0;
- }
- }
- //
- // Additive constants
- //
- private static final int Y1 = 0x5a827999;
- private static final int Y2 = 0x6ed9eba1;
- private static final int Y3 = 0x8f1bbcdc;
- private static final int Y4 = 0xca62c1d6;
- private int f(
- int u,
- int v,
- int w)
- {
- return ((u & v) | ((~u) & w));
- }
- private int h(
- int u,
- int v,
- int w)
- {
- return (u ^ v ^ w);
- }
- private int g(
- int u,
- int v,
- int w)
- {
- return ((u & v) | (u & w) | (v & w));
- }
- private int rotateLeft(
- int x,
- int n)
- {
- return (x << n) | (x >>> (32 - n));
- }
- protected void processBlock()
- {
- //
- // expand 16 word block into 80 word block.
- //
- for (int i = 16; i <= 79; i++)
- {
- X[i] = rotateLeft((X[i - 3] ^ X[i - 8] ^ X[i - 14] ^ X[i - 16]), 1);
- }
- //
- // set up working variables.
- //
- int A = H1;
- int B = H2;
- int C = H3;
- int D = H4;
- int E = H5;
- //
- // round 1
- //
- for (int j = 0; j <= 19; j++)
- {
- int t = rotateLeft(A, 5) + f(B, C, D) + E + X[j] + Y1;
- E = D;
- D = C;
- C = rotateLeft(B, 30);
- B = A;
- A = t;
- }
- //
- // round 2
- //
- for (int j = 20; j <= 39; j++)
- {
- int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y2;
- E = D;
- D = C;
- C = rotateLeft(B, 30);
- B = A;
- A = t;
- }
- //
- // round 3
- //
- for (int j = 40; j <= 59; j++)
- {
- int t = rotateLeft(A, 5) + g(B, C, D) + E + X[j] + Y3;
- E = D;
- D = C;
- C = rotateLeft(B, 30);
- B = A;
- A = t;
- }
- //
- // round 4
- //
- for (int j = 60; j <= 79; j++)
- {
- int t = rotateLeft(A, 5) + h(B, C, D) + E + X[j] + Y4;
- E = D;
- D = C;
- C = rotateLeft(B, 30);
- B = A;
- A = t;
- }
- H1 += A;
- H2 += B;
- H3 += C;
- H4 += D;
- H5 += E;
- //
- // reset the offset and clean out the word buffer.
- //
- xOff = 0;
- for (int i = 0; i != X.length; i++)
- {
- X[i] = 0;
- }
- }
- }