aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/trilead/ssh2/crypto
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2013-02-03 19:00:31 -0800
committerKenny Root <kenny@the-b.org>2013-02-03 22:59:52 -0800
commitabd16a0d0b44884f1ccb266155d6b4149179ca14 (patch)
treec20d9d6c969ed7ae890fea808b3ab487a02dcca5 /src/com/trilead/ssh2/crypto
parent598fb427f96712191cc264df14688d82db3dd664 (diff)
downloadconnectbot-abd16a0d0b44884f1ccb266155d6b4149179ca14.tar.gz
connectbot-abd16a0d0b44884f1ccb266155d6b4149179ca14.tar.bz2
connectbot-abd16a0d0b44884f1ccb266155d6b4149179ca14.zip
Remove J2ME compatibility layer for keys
Use JCE instead of the DIY crypto library that is in Trilead. This was apparently for J2ME devices. Well, I'm sorry, J2ME devices, you're dead to me.
Diffstat (limited to 'src/com/trilead/ssh2/crypto')
-rw-r--r--src/com/trilead/ssh2/crypto/PEMDecoder.java81
-rw-r--r--src/com/trilead/ssh2/crypto/digest/Digest.java25
-rw-r--r--src/com/trilead/ssh2/crypto/digest/HMAC.java95
-rw-r--r--src/com/trilead/ssh2/crypto/digest/HashForSSH2Types.java31
-rw-r--r--src/com/trilead/ssh2/crypto/digest/MAC.java78
-rw-r--r--src/com/trilead/ssh2/crypto/digest/MD5.java268
-rw-r--r--src/com/trilead/ssh2/crypto/digest/SHA1.java664
7 files changed, 146 insertions, 1096 deletions
diff --git a/src/com/trilead/ssh2/crypto/PEMDecoder.java b/src/com/trilead/ssh2/crypto/PEMDecoder.java
index 7d0a015..cf6be37 100644
--- a/src/com/trilead/ssh2/crypto/PEMDecoder.java
+++ b/src/com/trilead/ssh2/crypto/PEMDecoder.java
@@ -5,15 +5,25 @@ import java.io.BufferedReader;
import java.io.CharArrayReader;
import java.io.IOException;
import java.math.BigInteger;
+import java.security.DigestException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.DSAPrivateKeySpec;
+import java.security.spec.DSAPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
import com.trilead.ssh2.crypto.cipher.AES;
import com.trilead.ssh2.crypto.cipher.BlockCipher;
import com.trilead.ssh2.crypto.cipher.CBCMode;
import com.trilead.ssh2.crypto.cipher.DES;
import com.trilead.ssh2.crypto.cipher.DESede;
-import com.trilead.ssh2.crypto.digest.MD5;
-import com.trilead.ssh2.signature.DSAPrivateKey;
-import com.trilead.ssh2.signature.RSAPrivateKey;
/**
* PEM Support.
@@ -73,7 +83,12 @@ public class PEMDecoder
if (salt.length < 8)
throw new IllegalArgumentException("Salt needs to be at least 8 bytes for key generation.");
- MD5 md5 = new MD5();
+ MessageDigest md5;
+ try {
+ md5 = MessageDigest.getInstance("MD5");
+ } catch (NoSuchAlgorithmException e) {
+ throw new IllegalArgumentException("VM does not support MD5", e);
+ }
byte[] key = new byte[keyLen];
byte[] tmp = new byte[md5.getDigestLength()];
@@ -87,7 +102,13 @@ public class PEMDecoder
int copy = (keyLen < tmp.length) ? keyLen : tmp.length;
- md5.digest(tmp, 0);
+ try {
+ md5.digest(tmp, 0, tmp.length);
+ } catch (DigestException e) {
+ IOException ex = new IOException("could not digest password");
+ ex.initCause(e);
+ throw ex;
+ }
System.arraycopy(tmp, 0, key, key.length - keyLen, copy);
@@ -308,7 +329,7 @@ public class PEMDecoder
return false;
}
- public static Object decode(char[] pem, String password) throws IOException
+ public static KeyPair decode(char[] pem, String password) throws IOException
{
PEMStructure ps = parsePEM(pem);
@@ -345,7 +366,26 @@ public class PEMDecoder
if (dr.available() != 0)
throw new IOException("Padding in DSA PRIVATE KEY DER stream.");
- return new DSAPrivateKey(p, q, g, y, x);
+ DSAPrivateKeySpec privSpec = new DSAPrivateKeySpec(x, p, q, g);
+ DSAPublicKeySpec pubSpec = new DSAPublicKeySpec(y, p, q, g);
+
+ PublicKey pubKey;
+ PrivateKey privKey;
+ try {
+ KeyFactory kf = KeyFactory.getInstance("DSA");
+ pubKey = kf.generatePublic(pubSpec);
+ privKey = kf.generatePrivate(privSpec);
+ } catch (NoSuchAlgorithmException e) {
+ IOException ex = new IOException();
+ ex.initCause(ex);
+ throw ex;
+ } catch (InvalidKeySpecException e) {
+ IOException ex = new IOException();
+ ex.initCause(ex);
+ throw ex;
+ }
+
+ return new KeyPair(pubKey, privKey);
}
if (ps.pemType == PEM_RSA_PRIVATE_KEY)
@@ -367,8 +407,33 @@ public class PEMDecoder
BigInteger n = dr.readInt();
BigInteger e = dr.readInt();
BigInteger d = dr.readInt();
+ // TODO: is this right?
+ BigInteger primeP = dr.readInt();
+ BigInteger primeQ = dr.readInt();
+ BigInteger expP = dr.readInt();
+ BigInteger expQ = dr.readInt();
+ BigInteger coeff = dr.readInt();
+
+ RSAPrivateKeySpec privSpec = new RSAPrivateCrtKeySpec(n, e, d, primeP, primeQ, expP, expQ, coeff);
+ RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(n, e);
+
+ PublicKey pubKey;
+ PrivateKey privKey;
+ try {
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ pubKey = kf.generatePublic(pubSpec);
+ privKey = kf.generatePrivate(privSpec);
+ } catch (NoSuchAlgorithmException ex) {
+ IOException ioex = new IOException();
+ ioex.initCause(ex);
+ throw ioex;
+ } catch (InvalidKeySpecException ex) {
+ IOException ioex = new IOException("invalid keyspec");
+ ioex.initCause(ex);
+ throw ioex;
+ }
- return new RSAPrivateKey(d, e, n);
+ return new KeyPair(pubKey, privKey);
}
throw new IOException("PEM problem: it is of unknown type");
diff --git a/src/com/trilead/ssh2/crypto/digest/Digest.java b/src/com/trilead/ssh2/crypto/digest/Digest.java
deleted file mode 100644
index 6ed969c..0000000
--- a/src/com/trilead/ssh2/crypto/digest/Digest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-
-package com.trilead.ssh2.crypto.digest;
-
-/**
- * Digest.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: Digest.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public interface Digest
-{
- public int getDigestLength();
-
- public void update(byte b);
-
- public void update(byte[] b);
-
- public void update(byte b[], int off, int len);
-
- public void reset();
-
- public void digest(byte[] out);
-
- public void digest(byte[] out, int off);
-}
diff --git a/src/com/trilead/ssh2/crypto/digest/HMAC.java b/src/com/trilead/ssh2/crypto/digest/HMAC.java
deleted file mode 100644
index 8d52758..0000000
--- a/src/com/trilead/ssh2/crypto/digest/HMAC.java
+++ /dev/null
@@ -1,95 +0,0 @@
-
-package com.trilead.ssh2.crypto.digest;
-
-/**
- * HMAC.
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: HMAC.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public final class HMAC implements Digest
-{
- Digest md;
- byte[] k_xor_ipad;
- byte[] k_xor_opad;
-
- byte[] tmp;
-
- int size;
-
- public HMAC(Digest md, byte[] key, int size)
- {
- this.md = md;
- this.size = size;
-
- tmp = new byte[md.getDigestLength()];
-
- final int BLOCKSIZE = 64;
-
- k_xor_ipad = new byte[BLOCKSIZE];
- k_xor_opad = new byte[BLOCKSIZE];
-
- if (key.length > BLOCKSIZE)
- {
- md.reset();
- md.update(key);
- md.digest(tmp);
- key = tmp;
- }
-
- System.arraycopy(key, 0, k_xor_ipad, 0, key.length);
- System.arraycopy(key, 0, k_xor_opad, 0, key.length);
-
- for (int i = 0; i < BLOCKSIZE; i++)
- {
- k_xor_ipad[i] ^= 0x36;
- k_xor_opad[i] ^= 0x5C;
- }
- md.update(k_xor_ipad);
- }
-
- public final int getDigestLength()
- {
- return size;
- }
-
- public final void update(byte b)
- {
- md.update(b);
- }
-
- public final void update(byte[] b)
- {
- md.update(b);
- }
-
- public final void update(byte[] b, int off, int len)
- {
- md.update(b, off, len);
- }
-
- public final void reset()
- {
- md.reset();
- md.update(k_xor_ipad);
- }
-
- public final void digest(byte[] out)
- {
- digest(out, 0);
- }
-
- public final void digest(byte[] out, int off)
- {
- md.digest(tmp);
-
- md.update(k_xor_opad);
- md.update(tmp);
-
- md.digest(tmp);
-
- System.arraycopy(tmp, 0, out, off, size);
-
- md.update(k_xor_ipad);
- }
-}
diff --git a/src/com/trilead/ssh2/crypto/digest/HashForSSH2Types.java b/src/com/trilead/ssh2/crypto/digest/HashForSSH2Types.java
index df84952..30ffe0d 100644
--- a/src/com/trilead/ssh2/crypto/digest/HashForSSH2Types.java
+++ b/src/com/trilead/ssh2/crypto/digest/HashForSSH2Types.java
@@ -2,6 +2,9 @@
package com.trilead.ssh2.crypto.digest;
import java.math.BigInteger;
+import java.security.DigestException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
/**
* HashForSSH2Types.
@@ -11,25 +14,24 @@ import java.math.BigInteger;
*/
public class HashForSSH2Types
{
- Digest md;
+ MessageDigest md;
- public HashForSSH2Types(Digest md)
+ public HashForSSH2Types(MessageDigest md)
{
this.md = md;
}
public HashForSSH2Types(String type)
{
- if (type.equals("SHA1"))
- {
- md = new SHA1();
+ try {
+ if ("SHA1".equals(type) || "MD5".equals(type)) {
+ md = MessageDigest.getInstance(type);
+ } else {
+ throw new IllegalArgumentException("Unknown algorithm " + type);
+ }
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("Unsupported algorithm " + type);
}
- else if (type.equals("MD5"))
- {
- md = new MD5();
- }
- else
- throw new IllegalArgumentException("Unknown algorithm " + type);
}
public void updateByte(byte b)
@@ -88,6 +90,11 @@ public class HashForSSH2Types
public void getDigest(byte[] out, int off)
{
- md.digest(out, off);
+ try {
+ md.digest(out, off, out.length - off);
+ } catch (DigestException e) {
+ // TODO is this right?!
+ throw new RuntimeException("Unable to digest", e);
+ }
}
}
diff --git a/src/com/trilead/ssh2/crypto/digest/MAC.java b/src/com/trilead/ssh2/crypto/digest/MAC.java
index 0433b63..8138e63 100644
--- a/src/com/trilead/ssh2/crypto/digest/MAC.java
+++ b/src/com/trilead/ssh2/crypto/digest/MAC.java
@@ -1,6 +1,13 @@
package com.trilead.ssh2.crypto.digest;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import javax.crypto.Mac;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.SecretKeySpec;
+
/**
* MAC.
*
@@ -9,14 +16,19 @@ package com.trilead.ssh2.crypto.digest;
*/
public final class MAC
{
- Digest mac;
- int size;
+ Mac mac;
+ int outSize;
+ int macSize;
+ byte[] buffer;
+
+ /* Higher Priority First */
+ private static final String[] MAC_LIST = {
+ "hmac-sha1-96", "hmac-sha1", "hmac-md5-96", "hmac-md5"
+ };
public final static String[] getMacList()
{
- /* Higher Priority First */
-
- return new String[] { "hmac-sha1-96", "hmac-sha1", "hmac-md5-96", "hmac-md5" };
+ return MAC_LIST;
}
public final static void checkMacList(String[] macs)
@@ -40,26 +52,35 @@ public final class MAC
public MAC(String type, byte[] key)
{
- if (type.equals("hmac-sha1"))
- {
- mac = new HMAC(new SHA1(), key, 20);
+ try {
+ if ("hmac-sha1".equals(type) || "hmac-sha1-96".equals(type))
+ {
+ mac = Mac.getInstance("HmacSHA1");
+ }
+ else if ("hmac-md5".equals(type) || "hmac-md5-96".equals(type))
+ {
+ mac = Mac.getInstance("HmacMD5");
+ }
+ else
+ throw new IllegalArgumentException("Unkown algorithm " + type);
+ } catch (NoSuchAlgorithmException e) {
+ throw new IllegalArgumentException("Unknown algorithm " + type, e);
}
- else if (type.equals("hmac-sha1-96"))
- {
- mac = new HMAC(new SHA1(), key, 12);
- }
- else if (type.equals("hmac-md5"))
- {
- mac = new HMAC(new MD5(), key, 16);
- }
- else if (type.equals("hmac-md5-96"))
- {
- mac = new HMAC(new MD5(), key, 12);
+
+ macSize = mac.getMacLength();
+ if (type.endsWith("-96")) {
+ outSize = 12;
+ buffer = new byte[macSize];
+ } else {
+ outSize = macSize;
+ buffer = null;
}
- else
- throw new IllegalArgumentException("Unkown algorithm " + type);
- size = mac.getDigestLength();
+ try {
+ mac.init(new SecretKeySpec(key, type));
+ } catch (InvalidKeyException e) {
+ throw new IllegalArgumentException(e);
+ }
}
public final void initMac(int seq)
@@ -78,11 +99,20 @@ public final class MAC
public final void getMac(byte[] out, int off)
{
- mac.digest(out, off);
+ try {
+ if (buffer != null) {
+ mac.doFinal(buffer, 0);
+ System.arraycopy(buffer, 0, out, off, out.length - off);
+ } else {
+ mac.doFinal(out, off);
+ }
+ } catch (ShortBufferException e) {
+ throw new IllegalStateException(e);
+ }
}
public final int size()
{
- return size;
+ return outSize;
}
}
diff --git a/src/com/trilead/ssh2/crypto/digest/MD5.java b/src/com/trilead/ssh2/crypto/digest/MD5.java
deleted file mode 100644
index 567f926..0000000
--- a/src/com/trilead/ssh2/crypto/digest/MD5.java
+++ /dev/null
@@ -1,268 +0,0 @@
-
-package com.trilead.ssh2.crypto.digest;
-
-/**
- * MD5. Based on the example code in RFC 1321. Optimized (...a little).
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: MD5.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-
-/*
- * The following disclaimer has been copied from RFC 1321:
- *
- * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights
- * reserved.
- *
- * License to copy and use this software is granted provided that it is
- * identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in
- * all material mentioning or referencing this software or this function.
- *
- * License is also granted to make and use derivative works provided that such
- * works are identified as "derived from the RSA Data Security, Inc. MD5
- * Message-Digest Algorithm" in all material mentioning or referencing the
- * derived work.
- *
- * RSA Data Security, Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for any
- * particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- *
- * These notices must be retained in any copies of any part of this
- * documentation and/or software.
- *
- */
-
-public final class MD5 implements Digest
-{
- private int state0, state1, state2, state3;
- private long count;
- private final byte[] block = new byte[64];
- private final int x[] = new int[16];
-
- private static final byte[] padding = new byte[] { (byte) 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- public MD5()
- {
- reset();
- }
-
- private static final int FF(int a, int b, int c, int d, int x, int s, int ac)
- {
- a += ((b & c) | ((~b) & d)) + x + ac;
- return ((a << s) | (a >>> (32 - s))) + b;
- }
-
- private static final int GG(int a, int b, int c, int d, int x, int s, int ac)
- {
- a += ((b & d) | (c & (~d))) + x + ac;
- return ((a << s) | (a >>> (32 - s))) + b;
- }
-
- private static final int HH(int a, int b, int c, int d, int x, int s, int ac)
- {
- a += (b ^ c ^ d) + x + ac;
- return ((a << s) | (a >>> (32 - s))) + b;
- }
-
- private static final int II(int a, int b, int c, int d, int x, int s, int ac)
- {
- a += (c ^ (b | (~d))) + x + ac;
- return ((a << s) | (a >>> (32 - s))) + b;
- }
-
- private static final void encode(byte[] dst, int dstoff, int word)
- {
- dst[dstoff] = (byte) (word);
- dst[dstoff + 1] = (byte) (word >> 8);
- dst[dstoff + 2] = (byte) (word >> 16);
- dst[dstoff + 3] = (byte) (word >> 24);
- }
-
- private final void transform(byte[] src, int pos)
- {
- int a = state0;
- int b = state1;
- int c = state2;
- int d = state3;
-
- for (int i = 0; i < 16; i++, pos += 4)
- {
- x[i] = (src[pos] & 0xff) | ((src[pos + 1] & 0xff) << 8) | ((src[pos + 2] & 0xff) << 16)
- | ((src[pos + 3] & 0xff) << 24);
- }
-
- /* Round 1 */
-
- a = FF(a, b, c, d, x[0], 7, 0xd76aa478); /* 1 */
- d = FF(d, a, b, c, x[1], 12, 0xe8c7b756); /* 2 */
- c = FF(c, d, a, b, x[2], 17, 0x242070db); /* 3 */
- b = FF(b, c, d, a, x[3], 22, 0xc1bdceee); /* 4 */
- a = FF(a, b, c, d, x[4], 7, 0xf57c0faf); /* 5 */
- d = FF(d, a, b, c, x[5], 12, 0x4787c62a); /* 6 */
- c = FF(c, d, a, b, x[6], 17, 0xa8304613); /* 7 */
- b = FF(b, c, d, a, x[7], 22, 0xfd469501); /* 8 */
- a = FF(a, b, c, d, x[8], 7, 0x698098d8); /* 9 */
- d = FF(d, a, b, c, x[9], 12, 0x8b44f7af); /* 10 */
- c = FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
- b = FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
- a = FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
- d = FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
- c = FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
- b = FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
-
- /* Round 2 */
- a = GG(a, b, c, d, x[1], 5, 0xf61e2562); /* 17 */
- d = GG(d, a, b, c, x[6], 9, 0xc040b340); /* 18 */
- c = GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
- b = GG(b, c, d, a, x[0], 20, 0xe9b6c7aa); /* 20 */
- a = GG(a, b, c, d, x[5], 5, 0xd62f105d); /* 21 */
- d = GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */
- c = GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
- b = GG(b, c, d, a, x[4], 20, 0xe7d3fbc8); /* 24 */
- a = GG(a, b, c, d, x[9], 5, 0x21e1cde6); /* 25 */
- d = GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
- c = GG(c, d, a, b, x[3], 14, 0xf4d50d87); /* 27 */
- b = GG(b, c, d, a, x[8], 20, 0x455a14ed); /* 28 */
- a = GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
- d = GG(d, a, b, c, x[2], 9, 0xfcefa3f8); /* 30 */
- c = GG(c, d, a, b, x[7], 14, 0x676f02d9); /* 31 */
- b = GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
-
- /* Round 3 */
- a = HH(a, b, c, d, x[5], 4, 0xfffa3942); /* 33 */
- d = HH(d, a, b, c, x[8], 11, 0x8771f681); /* 34 */
- c = HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
- b = HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
- a = HH(a, b, c, d, x[1], 4, 0xa4beea44); /* 37 */
- d = HH(d, a, b, c, x[4], 11, 0x4bdecfa9); /* 38 */
- c = HH(c, d, a, b, x[7], 16, 0xf6bb4b60); /* 39 */
- b = HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
- a = HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
- d = HH(d, a, b, c, x[0], 11, 0xeaa127fa); /* 42 */
- c = HH(c, d, a, b, x[3], 16, 0xd4ef3085); /* 43 */
- b = HH(b, c, d, a, x[6], 23, 0x4881d05); /* 44 */
- a = HH(a, b, c, d, x[9], 4, 0xd9d4d039); /* 45 */
- d = HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
- c = HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
- b = HH(b, c, d, a, x[2], 23, 0xc4ac5665); /* 48 */
-
- /* Round 4 */
- a = II(a, b, c, d, x[0], 6, 0xf4292244); /* 49 */
- d = II(d, a, b, c, x[7], 10, 0x432aff97); /* 50 */
- c = II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
- b = II(b, c, d, a, x[5], 21, 0xfc93a039); /* 52 */
- a = II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
- d = II(d, a, b, c, x[3], 10, 0x8f0ccc92); /* 54 */
- c = II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
- b = II(b, c, d, a, x[1], 21, 0x85845dd1); /* 56 */
- a = II(a, b, c, d, x[8], 6, 0x6fa87e4f); /* 57 */
- d = II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
- c = II(c, d, a, b, x[6], 15, 0xa3014314); /* 59 */
- b = II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
- a = II(a, b, c, d, x[4], 6, 0xf7537e82); /* 61 */
- d = II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
- c = II(c, d, a, b, x[2], 15, 0x2ad7d2bb); /* 63 */
- b = II(b, c, d, a, x[9], 21, 0xeb86d391); /* 64 */
-
- state0 += a;
- state1 += b;
- state2 += c;
- state3 += d;
- }
-
- public final void reset()
- {
- count = 0;
-
- state0 = 0x67452301;
- state1 = 0xefcdab89;
- state2 = 0x98badcfe;
- state3 = 0x10325476;
-
- /* Clear traces in memory... */
-
- for (int i = 0; i < 16; i++)
- x[i] = 0;
- }
-
- public final void update(byte b)
- {
- final int space = 64 - ((int) (count & 0x3f));
-
- count++;
-
- block[64 - space] = b;
-
- if (space == 1)
- transform(block, 0);
- }
-
- public final void update(byte[] buff, int pos, int len)
- {
- int space = 64 - ((int) (count & 0x3f));
-
- count += len;
-
- while (len > 0)
- {
- if (len < space)
- {
- System.arraycopy(buff, pos, block, 64 - space, len);
- break;
- }
-
- if (space == 64)
- {
- transform(buff, pos);
- }
- else
- {
- System.arraycopy(buff, pos, block, 64 - space, space);
- transform(block, 0);
- }
-
- pos += space;
- len -= space;
- space = 64;
- }
- }
-
- public final void update(byte[] b)
- {
- update(b, 0, b.length);
- }
-
- public final void digest(byte[] dst, int pos)
- {
- byte[] bits = new byte[8];
-
- encode(bits, 0, (int) (count << 3));
- encode(bits, 4, (int) (count >> 29));
-
- int idx = (int) count & 0x3f;
- int padLen = (idx < 56) ? (56 - idx) : (120 - idx);
-
- update(padding, 0, padLen);
- update(bits, 0, 8);
-
- encode(dst, pos, state0);
- encode(dst, pos + 4, state1);
- encode(dst, pos + 8, state2);
- encode(dst, pos + 12, state3);
-
- reset();
- }
-
- public final void digest(byte[] dst)
- {
- digest(dst, 0);
- }
-
- public final int getDigestLength()
- {
- return 16;
- }
-}
diff --git a/src/com/trilead/ssh2/crypto/digest/SHA1.java b/src/com/trilead/ssh2/crypto/digest/SHA1.java
deleted file mode 100644
index bba4cc6..0000000
--- a/src/com/trilead/ssh2/crypto/digest/SHA1.java
+++ /dev/null
@@ -1,664 +0,0 @@
-
-package com.trilead.ssh2.crypto.digest;
-
-/**
- * SHA-1 implementation based on FIPS PUB 180-1.
- * Highly optimized.
- * <p>
- * (http://www.itl.nist.gov/fipspubs/fip180-1.htm)
- *
- * @author Christian Plattner, plattner@trilead.com
- * @version $Id: SHA1.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
- */
-public final class SHA1 implements Digest
-{
- private int H0, H1, H2, H3, H4;
-
- private final int[] w = new int[80];
- private int currentPos;
- private long currentLen;
-
- public SHA1()
- {
- reset();
- }
-
- public final int getDigestLength()
- {
- return 20;
- }
-
- public final void reset()
- {
- H0 = 0x67452301;
- H1 = 0xEFCDAB89;
- H2 = 0x98BADCFE;
- H3 = 0x10325476;
- H4 = 0xC3D2E1F0;
-
- currentPos = 0;
- currentLen = 0;
-
- /* In case of complete paranoia, we should also wipe out the
- * information contained in the w[] array */
- }
-
- public final void update(byte b[])
- {
- update(b, 0, b.length);
- }
-
- public final void update(byte b[], int off, int len)
- {
- if (len >= 4)
- {
- int idx = currentPos >> 2;
-
- switch (currentPos & 3)
- {
- case 0:
- w[idx] = (((b[off++] & 0xff) << 24) | ((b[off++] & 0xff) << 16) | ((b[off++] & 0xff) << 8) | (b[off++] & 0xff));
- len -= 4;
- currentPos += 4;
- currentLen += 32;
- if (currentPos == 64)
- {
- perform();
- currentPos = 0;
- }
- break;
- case 1:
- w[idx] = (w[idx] << 24) | (((b[off++] & 0xff) << 16) | ((b[off++] & 0xff) << 8) | (b[off++] & 0xff));
- len -= 3;
- currentPos += 3;
- currentLen += 24;
- if (currentPos == 64)
- {
- perform();
- currentPos = 0;
- }
- break;
- case 2:
- w[idx] = (w[idx] << 16) | (((b[off++] & 0xff) << 8) | (b[off++] & 0xff));
- len -= 2;
- currentPos += 2;
- currentLen += 16;
- if (currentPos == 64)
- {
- perform();
- currentPos = 0;
- }
- break;
- case 3:
- w[idx] = (w[idx] << 8) | (b[off++] & 0xff);
- len--;
- currentPos++;
- currentLen += 8;
- if (currentPos == 64)
- {
- perform();
- currentPos = 0;
- }
- break;
- }
-
- /* Now currentPos is a multiple of 4 - this is the place to be...*/
-
- while (len >= 8)
- {
- w[currentPos >> 2] = ((b[off++] & 0xff) << 24) | ((b[off++] & 0xff) << 16) | ((b[off++] & 0xff) << 8)
- | (b[off++] & 0xff);
- currentPos += 4;
-
- if (currentPos == 64)
- {
- perform();
- currentPos = 0;
- }
-
- w[currentPos >> 2] = ((b[off++] & 0xff) << 24) | ((b[off++] & 0xff) << 16) | ((b[off++] & 0xff) << 8)
- | (b[off++] & 0xff);
-
- currentPos += 4;
-
- if (currentPos == 64)
- {
- perform();
- currentPos = 0;
- }
-
- currentLen += 64;
- len -= 8;
- }
-
- while (len < 0) //(len >= 4)
- {
- w[currentPos >> 2] = ((b[off++] & 0xff) << 24) | ((b[off++] & 0xff) << 16) | ((b[off++] & 0xff) << 8)
- | (b[off++] & 0xff);
- len -= 4;
- currentPos += 4;
- currentLen += 32;
- if (currentPos == 64)
- {
- perform();
- currentPos = 0;
- }
- }
- }
-
- /* Remaining bytes (1-3) */
-
- while (len > 0)
- {
- /* Here is room for further improvements */
- int idx = currentPos >> 2;
- w[idx] = (w[idx] << 8) | (b[off++] & 0xff);
-
- currentLen += 8;
- currentPos++;
-
- if (currentPos == 64)
- {
- perform();
- currentPos = 0;
- }
- len--;
- }
- }
-
- public final void update(byte b)
- {
- int idx = currentPos >> 2;
- w[idx] = (w[idx] << 8) | (b & 0xff);
-
- currentLen += 8;
- currentPos++;
-
- if (currentPos == 64)
- {
- perform();
- currentPos = 0;
- }
- }
-
- private final void putInt(byte[] b, int pos, int val)
- {
- b[pos] = (byte) (val >> 24);
- b[pos + 1] = (byte) (val >> 16);
- b[pos + 2] = (byte) (val >> 8);
- b[pos + 3] = (byte) val;
- }
-
- public final void digest(byte[] out)
- {
- digest(out, 0);
- }
-
- public final void digest(byte[] out, int off)
- {
- /* Pad with a '1' and 7-31 zero bits... */
-
- int idx = currentPos >> 2;
- w[idx] = ((w[idx] << 8) | (0x80)) << ((3 - (currentPos & 3)) << 3);
-
- currentPos = (currentPos & ~3) + 4;
-
- if (currentPos == 64)
- {
- currentPos = 0;
- perform();
- }
- else if (currentPos == 60)
- {
- currentPos = 0;
- w[15] = 0;
- perform();
- }
-
- /* Now currentPos is a multiple of 4 and we can do the remaining
- * padding much more efficiently, furthermore we are sure
- * that currentPos <= 56.
- */
-
- for (int i = currentPos >> 2; i < 14; i++)
- w[i] = 0;
-
- w[14] = (int) (currentLen >> 32);
- w[15] = (int) currentLen;
-
- perform();
-
- putInt(out, off, H0);
- putInt(out, off + 4, H1);
- putInt(out, off + 8, H2);
- putInt(out, off + 12, H3);
- putInt(out, off + 16, H4);
-
- reset();
- }
-
- private final void perform()
- {
- for (int t = 16; t < 80; t++)
- {
- int x = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
- w[t] = ((x << 1) | (x >>> 31));
- }
-
- int A = H0;
- int B = H1;
- int C = H2;
- int D = H3;
- int E = H4;
-
- /* Here we use variable substitution and loop unrolling
- *
- * === Original step:
- *
- * T = s5(A) + f(B,C,D) + E + w[0] + K;
- * E = D; D = C; C = s30(B); B = A; A = T;
- *
- * === Rewritten step:
- *
- * T = s5(A + f(B,C,D) + E + w[0] + K;
- * B = s30(B);
- * E = D; D = C; C = B; B = A; A = T;
- *
- * === Let's rewrite things, introducing new variables:
- *
- * E0 = E; D0 = D; C0 = C; B0 = B; A0 = A;
- *
- * T = s5(A0) + f(B0,C0,D0) + E0 + w[0] + K;
- * B0 = s30(B0);
- * E1 = D0; D1 = C0; C1 = B0; B1 = A0; A1 = T;
- *
- * T = s5(A1) + f(B1,C1,D1) + E1 + w[1] + K;
- * B1 = s30(B1);
- * E2 = D1; D2 = C1; C2 = B1; B2 = A1; A2 = T;
- *
- * E = E2; D = E2; C = C2; B = B2; A = A2;
- *
- * === No need for 'T', we can write into 'Ex' instead since
- * after the calculation of 'T' nobody is interested
- * in 'Ex' anymore.
- *
- * E0 = E; D0 = D; C0 = C; B0 = B; A0 = A;
- *
- * E0 = E0 + s5(A0) + f(B0,C0,D0) + w[0] + K;
- * B0 = s30(B0);
- * E1 = D0; D1 = C0; C1 = B0; B1 = A0; A1 = E0;
- *
- * E1 = E1 + s5(A1) + f(B1,C1,D1) + w[1] + K;
- * B1 = s30(B1);
- * E2 = D1; D2 = C1; C2 = B1; B2 = A1; A2 = E1;
- *
- * E = Ex; D = Ex; C = Cx; B = Bx; A = Ax;
- *
- * === Further optimization: get rid of the swap operations
- * Idea: instead of swapping the variables, swap the names of
- * the used variables in the next step:
- *
- * E0 = E; D0 = d; C0 = C; B0 = B; A0 = A;
- *
- * E0 = E0 + s5(A0) + f(B0,C0,D0) + w[0] + K;
- * B0 = s30(B0);
- * // E1 = D0; D1 = C0; C1 = B0; B1 = A0; A1 = E0;
- *
- * D0 = D0 + s5(E0) + f(A0,B0,C0) + w[1] + K;
- * A0 = s30(A0);
- * E2 = C0; D2 = B0; C2 = A0; B2 = E0; A2 = D0;
- *
- * E = E2; D = D2; C = C2; B = B2; A = A2;
- *
- * === OK, let's do this several times, also, directly
- * use A (instead of A0) and B,C,D,E.
- *
- * E = E + s5(A) + f(B,C,D) + w[0] + K;
- * B = s30(B);
- * // E1 = D; D1 = C; C1 = B; B1 = A; A1 = E;
- *
- * D = D + s5(E) + f(A,B,C) + w[1] + K;
- * A = s30(A);
- * // E2 = C; D2 = B; C2 = A; B2 = E; A2 = D;
- *
- * C = C + s5(D) + f(E,A,B) + w[2] + K;
- * E = s30(E);
- * // E3 = B; D3 = A; C3 = E; B3 = D; A3 = C;
- *
- * B = B + s5(C) + f(D,E,A) + w[3] + K;
- * D = s30(D);
- * // E4 = A; D4 = E; C4 = D; B4 = C; A4 = B;
- *
- * A = A + s5(B) + f(C,D,E) + w[4] + K;
- * C = s30(C);
- * // E5 = E; D5 = D; C5 = C; B5 = B; A5 = A;
- *
- * //E = E5; D = D5; C = C5; B = B5; A = A5;
- *
- * === Very nice, after 5 steps each variable
- * has the same contents as after 5 steps with
- * the original algorithm!
- *
- * We therefore can easily unroll each interval,
- * as the number of steps in each interval is a
- * multiple of 5 (20 steps per interval).
- */
-
- E += ((A << 5) | (A >>> 27)) + ((B & C) | ((~B) & D)) + w[0] + 0x5A827999;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + ((A & B) | ((~A) & C)) + w[1] + 0x5A827999;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + ((E & A) | ((~E) & B)) + w[2] + 0x5A827999;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + ((D & E) | ((~D) & A)) + w[3] + 0x5A827999;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + ((C & D) | ((~C) & E)) + w[4] + 0x5A827999;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + ((B & C) | ((~B) & D)) + w[5] + 0x5A827999;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + ((A & B) | ((~A) & C)) + w[6] + 0x5A827999;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + ((E & A) | ((~E) & B)) + w[7] + 0x5A827999;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + ((D & E) | ((~D) & A)) + w[8] + 0x5A827999;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + ((C & D) | ((~C) & E)) + w[9] + 0x5A827999;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + ((B & C) | ((~B) & D)) + w[10] + 0x5A827999;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + ((A & B) | ((~A) & C)) + w[11] + 0x5A827999;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + ((E & A) | ((~E) & B)) + w[12] + 0x5A827999;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + ((D & E) | ((~D) & A)) + w[13] + 0x5A827999;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + ((C & D) | ((~C) & E)) + w[14] + 0x5A827999;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + ((B & C) | ((~B) & D)) + w[15] + 0x5A827999;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + ((A & B) | ((~A) & C)) + w[16] + 0x5A827999;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + ((E & A) | ((~E) & B)) + w[17] + 0x5A827999;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + ((D & E) | ((~D) & A)) + w[18] + 0x5A827999;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + ((C & D) | ((~C) & E)) + w[19] + 0x5A827999;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[20] + 0x6ED9EBA1;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[21] + 0x6ED9EBA1;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[22] + 0x6ED9EBA1;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[23] + 0x6ED9EBA1;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[24] + 0x6ED9EBA1;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[25] + 0x6ED9EBA1;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[26] + 0x6ED9EBA1;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[27] + 0x6ED9EBA1;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[28] + 0x6ED9EBA1;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[29] + 0x6ED9EBA1;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[30] + 0x6ED9EBA1;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[31] + 0x6ED9EBA1;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[32] + 0x6ED9EBA1;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[33] + 0x6ED9EBA1;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[34] + 0x6ED9EBA1;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[35] + 0x6ED9EBA1;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[36] + 0x6ED9EBA1;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[37] + 0x6ED9EBA1;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[38] + 0x6ED9EBA1;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[39] + 0x6ED9EBA1;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + w[40] + 0x8F1BBCDC;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + w[41] + 0x8F1BBCDC;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + w[42] + 0x8F1BBCDC;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + w[43] + 0x8F1BBCDC;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + w[44] + 0x8F1BBCDC;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + w[45] + 0x8F1BBCDC;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + w[46] + 0x8F1BBCDC;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + w[47] + 0x8F1BBCDC;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + w[48] + 0x8F1BBCDC;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + w[49] + 0x8F1BBCDC;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + w[50] + 0x8F1BBCDC;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + w[51] + 0x8F1BBCDC;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + w[52] + 0x8F1BBCDC;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + w[53] + 0x8F1BBCDC;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + w[54] + 0x8F1BBCDC;
- C = ((C << 30) | (C >>> 2));
-
- E = E + ((A << 5) | (A >>> 27)) + ((B & C) | (B & D) | (C & D)) + w[55] + 0x8F1BBCDC;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + ((A & B) | (A & C) | (B & C)) + w[56] + 0x8F1BBCDC;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + ((E & A) | (E & B) | (A & B)) + w[57] + 0x8F1BBCDC;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + ((D & E) | (D & A) | (E & A)) + w[58] + 0x8F1BBCDC;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + ((C & D) | (C & E) | (D & E)) + w[59] + 0x8F1BBCDC;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[60] + 0xCA62C1D6;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[61] + 0xCA62C1D6;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[62] + 0xCA62C1D6;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[63] + 0xCA62C1D6;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[64] + 0xCA62C1D6;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[65] + 0xCA62C1D6;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[66] + 0xCA62C1D6;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[67] + 0xCA62C1D6;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[68] + 0xCA62C1D6;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[69] + 0xCA62C1D6;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[70] + 0xCA62C1D6;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[71] + 0xCA62C1D6;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[72] + 0xCA62C1D6;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[73] + 0xCA62C1D6;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[74] + 0xCA62C1D6;
- C = ((C << 30) | (C >>> 2));
-
- E += ((A << 5) | (A >>> 27)) + (B ^ C ^ D) + w[75] + 0xCA62C1D6;
- B = ((B << 30) | (B >>> 2));
-
- D += ((E << 5) | (E >>> 27)) + (A ^ B ^ C) + w[76] + 0xCA62C1D6;
- A = ((A << 30) | (A >>> 2));
-
- C += ((D << 5) | (D >>> 27)) + (E ^ A ^ B) + w[77] + 0xCA62C1D6;
- E = ((E << 30) | (E >>> 2));
-
- B += ((C << 5) | (C >>> 27)) + (D ^ E ^ A) + w[78] + 0xCA62C1D6;
- D = ((D << 30) | (D >>> 2));
-
- A += ((B << 5) | (B >>> 27)) + (C ^ D ^ E) + w[79] + 0xCA62C1D6;
- C = ((C << 30) | (C >>> 2));
-
- H0 += A;
- H1 += B;
- H2 += C;
- H3 += D;
- H4 += E;
-
- // debug(80, H0, H1, H2, H3, H4);
- }
-
- private static final String toHexString(byte[] b)
- {
- final String hexChar = "0123456789ABCDEF";
-
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < b.length; i++)
- {
- sb.append(hexChar.charAt((b[i] >> 4) & 0x0f));
- sb.append(hexChar.charAt(b[i] & 0x0f));
- }
- return sb.toString();
- }
-
- public static void main(String[] args)
- {
- SHA1 sha = new SHA1();
-
- byte[] dig1 = new byte[20];
- byte[] dig2 = new byte[20];
- byte[] dig3 = new byte[20];
-
- /*
- * We do not specify a charset name for getBytes(), since we assume that
- * the JVM's default encoder maps the _used_ ASCII characters exactly as
- * getBytes("US-ASCII") would do. (Ah, yes, too lazy to catch the
- * exception that can be thrown by getBytes("US-ASCII")). Note: This has
- * no effect on the SHA-1 implementation, this is just for the following
- * test code.
- */
-
- sha.update("abc".getBytes());
- sha.digest(dig1);
-
- sha.update("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".getBytes());
- sha.digest(dig2);
-
- for (int i = 0; i < 1000000; i++)
- sha.update((byte) 'a');
- sha.digest(dig3);
-
- String dig1_res = toHexString(dig1);
- String dig2_res = toHexString(dig2);
- String dig3_res = toHexString(dig3);
-
- String dig1_ref = "A9993E364706816ABA3E25717850C26C9CD0D89D";
- String dig2_ref = "84983E441C3BD26EBAAE4AA1F95129E5E54670F1";
- String dig3_ref = "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F";
-
- if (dig1_res.equals(dig1_ref))
- System.out.println("SHA-1 Test 1 OK.");
- else
- System.out.println("SHA-1 Test 1 FAILED.");
-
- if (dig2_res.equals(dig2_ref))
- System.out.println("SHA-1 Test 2 OK.");
- else
- System.out.println("SHA-1 Test 2 FAILED.");
-
- if (dig3_res.equals(dig3_ref))
- System.out.println("SHA-1 Test 3 OK.");
- else
- System.out.println("SHA-1 Test 3 FAILED.");
-
- if (dig3_res.equals(dig3_ref))
- System.out.println("SHA-1 Test 3 OK.");
- else
- System.out.println("SHA-1 Test 3 FAILED.");
- }
-}