Author: nextgens
Date: 2006-02-12 18:12:16 +0000 (Sun, 12 Feb 2006)
New Revision: 8029

Added:
   trunk/apps/installer/build/
   trunk/apps/installer/src/gnu/
   trunk/apps/installer/src/gnu/crypto/
   trunk/apps/installer/src/gnu/crypto/Registry.java
   trunk/apps/installer/src/gnu/crypto/hash/
   trunk/apps/installer/src/gnu/crypto/hash/BaseHash.java
   trunk/apps/installer/src/gnu/crypto/hash/IMessageDigest.java
   trunk/apps/installer/src/gnu/crypto/hash/Sha160.java
   trunk/apps/installer/src/gnu/crypto/util/
   trunk/apps/installer/src/gnu/crypto/util/Util.java
Modified:
   trunk/apps/installer/build-installer.xml
   trunk/apps/installer/src/Sha1Test.java
   trunk/apps/installer/src/freenet/support/HexUtil.java
Log:
Antinstaller: Now we use GNU-crypto for sha1sums

Modified: trunk/apps/installer/build-installer.xml
===================================================================
--- trunk/apps/installer/build-installer.xml    2006-02-12 17:41:47 UTC (rev 
8028)
+++ trunk/apps/installer/build-installer.xml    2006-02-12 18:12:16 UTC (rev 
8029)
@@ -14,7 +14,7 @@
                classname="org.tp23.antinstaller.taskdefs.Installer"
                classpathref="taskdef.cp"/>

-       <target name="selfextract" depends="jar_sha1test">
+       <target name="selfextract" depends="compile_sha1test">
                <echo message="Building INSTALLER SELFEXTRACT"/>
                <installer file="./selfextractpack.jar" compress="true"
                                extractType="SelfExtractor"
@@ -37,7 +37,7 @@
            <!-- Create the build directory structure used by compile -->

            <javac srcdir="./src" destdir="./build" optimize="on" source="1.4">
-             <include name="freenet/crypt/SHA1.java"/>
+             <include name="gnu/**/*.java"/>
              <include name="freenet/support/HexUtil"/>
              <include name="Sha1Test.java"/>
            </javac>

Modified: trunk/apps/installer/src/Sha1Test.java
===================================================================
--- trunk/apps/installer/src/Sha1Test.java      2006-02-12 17:41:47 UTC (rev 
8028)
+++ trunk/apps/installer/src/Sha1Test.java      2006-02-12 18:12:16 UTC (rev 
8029)
@@ -1,5 +1,5 @@
-import freenet.crypt.SHA1;
 import freenet.support.HexUtil;
+import gnu.crypto.hash.*;

 import java.io.File;
 import java.io.FileInputStream;
@@ -17,7 +17,7 @@
         * @return 2 if an error occured
         */
        public static void main(String[] args) {
-               SHA1 hash=new SHA1();
+               Sha160 hash=new Sha160();
                if(args.length != 1) System.exit(2);

                try{

Modified: trunk/apps/installer/src/freenet/support/HexUtil.java
===================================================================
--- trunk/apps/installer/src/freenet/support/HexUtil.java       2006-02-12 
17:41:47 UTC (rev 8028)
+++ trunk/apps/installer/src/freenet/support/HexUtil.java       2006-02-12 
18:12:16 UTC (rev 8029)
@@ -15,7 +15,6 @@
  * @author syoung
  */
 public class HexUtil {
-       private static boolean logDEBUG 
=Logger.logger.instanceShouldLog(Logger.DEBUG,HexUtil.class);
        private HexUtil() {             
        }       

@@ -110,7 +109,6 @@
                int bytesAlloc = countBytesForBits(size);
                byte[] b = new byte[bytesAlloc];
                StringBuffer sb =null;
-               if(logDEBUG) sb = new StringBuffer(8*bytesAlloc); //TODO: 
Should it be 2*8*bytesAlloc here?
                for(int i=0;i<b.length;i++) {
                        short s = 0;
                        for(int j=0;j<8;j++) {
@@ -124,8 +122,6 @@
                        if(s > 255) throw new IllegalStateException("WTF? s = 
"+s);
                        b[i] = (byte)s;
                }
-               if(logDEBUG) Logger.debug(HexUtil.class, "bytes: "+bytesAlloc+" 
returned from bitsToBytes("
-                               +ba+","+size+"): "+bytesToHex(b)+" for 
"+sb.toString());
                return b;
        }

@@ -154,7 +150,6 @@
         * @param ba the bitset to write to
         */
        public static void bytesToBits(byte[] b, BitSet ba, int maxSize) {
-               if(logDEBUG) Logger.debug(HexUtil.class, 
"bytesToBits("+bytesToHex(b)+",ba,"+maxSize);
                int x = 0;
                for(int i=0;i<b.length;i++) {
                        for(int j=0;j<8;j++) {
@@ -186,7 +181,6 @@
      */
     public static void writeBigInteger(BigInteger integer, DataOutputStream 
out) throws IOException {
         if(integer.signum() == -1) {
-            //dump("Negative BigInteger", Logger.ERROR, true);
             throw new IllegalStateException("Negative BigInteger!");
         }
         byte[] buf = integer.toByteArray();

Added: trunk/apps/installer/src/gnu/crypto/Registry.java
===================================================================
--- trunk/apps/installer/src/gnu/crypto/Registry.java   2006-02-12 17:41:47 UTC 
(rev 8028)
+++ trunk/apps/installer/src/gnu/crypto/Registry.java   2006-02-12 18:12:16 UTC 
(rev 8029)
@@ -0,0 +1,364 @@
+package gnu.crypto;
+
+// ----------------------------------------------------------------------------
+// $Id: Registry.java.in,v 1.4 2005/10/06 04:24:13 rsdio Exp $
+//
+// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// This file is part of GNU Crypto.
+//
+// GNU Crypto is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GNU Crypto is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING.  If not, write to the
+//
+//    Free Software Foundation Inc.,
+//    51 Franklin Street, Fifth Floor,
+//    Boston, MA 02110-1301
+//    USA
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library.  Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give
+// you permission to link this library with independent modules to
+// produce an executable, regardless of the license terms of these
+// independent modules, and to copy and distribute the resulting
+// executable under terms of your choice, provided that you also meet,
+// for each linked independent module, the terms and conditions of the
+// license of that module.  An independent module is a module which is
+// not derived from or based on this library.  If you modify this
+// library, you may extend this exception to your version of the
+// library, but you are not obligated to do so.  If you do not wish to
+// do so, delete this exception statement from your version.
+// ----------------------------------------------------------------------------
+
+/**
+ * A placeholder for <i>names</i> and <i>literals</i> used throughout this
+ * library.
+ *
+ * @version $Revision: 1.4 $
+ */
+public interface Registry {
+
+   // Constants
+   // -------------------------------------------------------------------------
+
+   /** The name of our Providers. */
+   String GNU_CRYPTO   = "GNU-CRYPTO";
+   String GNU_SASL     = "GNU-SASL";
+   String GNU_SECURITY = "GNU-SECURITY";
+
+   /** Our version number. */
+   String VERSION_STRING = "@VERSION@@PRERELEASE@";
+
+   // Names of properties to use in Maps when initialising primitives .........
+
+   // Symmetric block cipher algorithms and synonyms...........................
+
+   String ANUBIS_CIPHER =    "anubis";
+   String BLOWFISH_CIPHER =  "blowfish";
+   String DES_CIPHER =       "des";
+   String KHAZAD_CIPHER =    "khazad";
+   String RIJNDAEL_CIPHER =  "rijndael";
+   String SERPENT_CIPHER =   "serpent";
+   String SQUARE_CIPHER =    "square";
+   String TRIPLEDES_CIPHER = "tripledes";
+   String TWOFISH_CIPHER =   "twofish";
+   String CAST5_CIPHER =     "cast5";
+   String NULL_CIPHER =      "null";
+
+   /** AES is synonymous to Rijndael for 128-bit block size only. */
+   String AES_CIPHER = "aes";
+
+   /** TripleDES is also known as DESede. */
+   String DESEDE_CIPHER = "desede";
+
+   /** CAST5 is also known as CAST-128. */
+   String CAST128_CIPHER =  "cast128";
+   String CAST_128_CIPHER = "cast-128";
+
+   // Message digest algorithms and synonyms...................................
+
+   String WHIRLPOOL_HASH = "whirlpool";
+   String RIPEMD128_HASH = "ripemd128";
+   String RIPEMD160_HASH = "ripemd160";
+   String SHA160_HASH =    "sha-160";
+   String SHA256_HASH =    "sha-256";
+   String SHA384_HASH =    "sha-384";
+   String SHA512_HASH =    "sha-512";
+   String TIGER_HASH =     "tiger";
+   String HAVAL_HASH =     "haval";
+   String MD5_HASH =       "md5";
+   String MD4_HASH =       "md4";
+   String MD2_HASH =       "md2";
+
+   /** RIPEMD-128 is synonymous to RIPEMD128. */
+   String RIPEMD_128_HASH = "ripemd-128";
+
+   /** RIPEMD-160 is synonymous to RIPEMD160. */
+   String RIPEMD_160_HASH = "ripemd-160";
+
+   /** SHA-1 is synonymous to SHA-160. */
+   String SHA_1_HASH = "sha-1";
+
+   /** SHA1 is synonymous to SHA-160. */
+   String SHA1_HASH = "sha1";
+
+   /** SHA is synonymous to SHA-160. */
+   String SHA_HASH = "sha";
+
+   // Symmetric block cipher modes of operations...............................
+
+   /** Electronic CodeBook mode. */
+   String ECB_MODE = "ecb";
+
+   /** Counter (NIST) mode. */
+   String CTR_MODE = "ctr";
+
+   /** Integer Counter Mode (David McGrew). */
+   String ICM_MODE = "icm";
+
+   /** Output Feedback Mode (NIST). */
+   String OFB_MODE = "ofb";
+
+   /** Cipher block chaining mode (NIST). */
+   String CBC_MODE = "cbc";
+
+   /** Cipher feedback mode (NIST). */
+   String CFB_MODE = "cfb";
+
+   /** Authenticated-Encrypted mode. */
+   String EAX_MODE = "eax";
+
+   // Padding scheme names and synonyms........................................
+
+   /** PKCS#7 padding scheme. */
+   String PKCS7_PAD = "pkcs7";
+
+   /** Trailing Bit Complement padding scheme. */
+   String TBC_PAD = "tbc";
+
+   /** EME-PKCS1-v1_5 padding as described in section 7.2 in RFC-3447. */
+   String EME_PKCS1_V1_5_PAD = "eme-pkcs1-v1.5";
+
+   /** SSLv3 padding scheme. */
+   String SSL3_PAD = "ssl3";
+
+   /** TLSv1 padding scheme. */
+   String TLS1_PAD = "tls1";
+
+   // Pseudo-random number generators..........................................
+
+   /** (Apparently) RC4 keystream PRNG. */
+   String ARCFOUR_PRNG = "arcfour";
+
+   /** We use "rc4" as an alias for "arcfour". */
+   String RC4_PRNG = "rc4";
+
+   /** PRNG based on David McGrew's Integer Counter Mode. */
+   String ICM_PRNG = "icm";
+
+   /** PRNG based on a designated hash function. */
+   String MD_PRNG = "md";
+
+   /** PRNG based on UMAC's Key Derivation Function. */
+   String UMAC_PRNG = "umac-kdf";
+
+   /**
+    * PRNG based on PBKDF2 from PKCS #5 v.2. This is suffixed with the name
+    * of a MAC to be used as a PRF.
+    */
+   String PBKDF2_PRNG_PREFIX = "pbkdf2-";
+
+   /** The continuously-seeded pseudo-random number generator. */
+   String CSPRNG_PRNG = "csprng";
+
+   /** The Fortuna PRNG. */
+   String FORTUNA_PRNG = "fortuna";
+
+   /** The Fortuna generator PRNG. */
+   String FORTUNA_GENERATOR_PRNG = "fortuna-generator";
+
+   // Asymmetric keypair generators............................................
+
+   String DSS_KPG =  "dss";
+   String RSA_KPG =  "rsa";
+   String DH_KPG =   "dh";
+   String SRP_KPG =  "srp";
+
+   /** DSA is synonymous to DSS. */
+   String DSA_KPG = "dsa";
+
+   // Signature-with-appendix schemes..........................................
+
+   String DSS_SIG =            "dss";
+   String RSA_PSS_SIG =        "rsa-pss";
+   String RSA_PKCS1_V1_5_SIG = "rsa-pkcs1-v1.5";
+
+   /** DSA is synonymous to DSS. */
+   String DSA_SIG = "dsa";
+
+   // Key agreement protocols .................................................
+
+   String DH_KA =       "dh";
+   String ELGAMAL_KA =  "elgamal";
+   String SRP6_KA =     "srp6";
+   String SRP_SASL_KA = "srp-sasl";
+   String SRP_TLS_KA =  "srp-tls";
+
+   // Keyed-Hash Message Authentication Code ..................................
+
+   /** Name prefix of every HMAC implementation. */
+   String HMAC_NAME_PREFIX = "hmac-";
+
+   // Other MAC algorithms ....................................................
+
+   /** The One-key CBC MAC. */
+   String OMAC_PREFIX = "omac-";
+
+   /** Message Authentication Code using Universal Hashing (Ted Krovetz). */
+   String UHASH32 = "uhash32";
+   String UMAC32 = "umac32";
+   /** The Truncated Multi-Modular Hash Function -v1 (David McGrew). */
+   String TMMH16 = "tmmh16";
+//   String TMMH32 = "tmmh32";
+
+   // Format IDs used to identify how we externalise asymmetric keys ..........
+   String RAW_ENCODING = "gnu.crypto.raw.format";
+   int RAW_ENCODING_ID = 1;
+
+   // Magic bytes we generate/expect in externalised asymmetric keys ..........
+   // the four bytes represent G (0x47) for GNU, 1 (0x01) for Raw format,
+   // D (0x44) for DSS, R (0x52) for RSA, H (0x48) for Diffie-Hellman, or S
+   // (0x53) for SRP-6, and finally P (0x50) for Public, p (0x70) for private,
+   // or S (0x53) for signature.
+   byte[] MAGIC_RAW_DSS_PUBLIC_KEY =    new byte[] {0x47, RAW_ENCODING_ID, 
0x44, 0x50};
+   byte[] MAGIC_RAW_DSS_PRIVATE_KEY =   new byte[] {0x47, RAW_ENCODING_ID, 
0x44, 0x70};
+   byte[] MAGIC_RAW_DSS_SIGNATURE =     new byte[] {0x47, RAW_ENCODING_ID, 
0x44, 0x53};
+   byte[] MAGIC_RAW_RSA_PUBLIC_KEY =    new byte[] {0x47, RAW_ENCODING_ID, 
0x52, 0x50};
+   byte[] MAGIC_RAW_RSA_PRIVATE_KEY =   new byte[] {0x47, RAW_ENCODING_ID, 
0x52, 0x70};
+   byte[] MAGIC_RAW_RSA_PSS_SIGNATURE = new byte[] {0x47, RAW_ENCODING_ID, 
0x52, 0x53};
+
+   byte[] MAGIC_RAW_DH_PUBLIC_KEY =     new byte[] {0x47, RAW_ENCODING_ID, 
0x48, 0x50};
+   byte[] MAGIC_RAW_DH_PRIVATE_KEY =    new byte[] {0x47, RAW_ENCODING_ID, 
0x48, 0x70};
+
+   byte[] MAGIC_RAW_SRP_PUBLIC_KEY =    new byte[] {0x47, RAW_ENCODING_ID, 
0x53, 0x50};
+   byte[] MAGIC_RAW_SRP_PRIVATE_KEY =   new byte[] {0x47, RAW_ENCODING_ID, 
0x53, 0x70};
+
+   // SASL Property names .....................................................
+
+   String SASL_PREFIX = "gnu.crypto.sasl";
+
+   /** Name of username property. */
+   String SASL_USERNAME = SASL_PREFIX + ".username";
+
+   /** Name of password property. */
+   String SASL_PASSWORD = SASL_PREFIX + ".password";
+
+   /** Name of authentication information provider packages. */
+   String SASL_AUTH_INFO_PROVIDER_PKGS = SASL_PREFIX + 
".auth.info.provider.pkgs";
+
+   /** SASL authorization ID. */
+   String SASL_AUTHORISATION_ID = SASL_PREFIX + ".authorisation.ID";
+
+   /** SASL protocol. */
+   String SASL_PROTOCOL = SASL_PREFIX + ".protocol";
+
+   /** SASL Server name. */
+   String SASL_SERVER_NAME = SASL_PREFIX + ".server.name";
+
+   /** SASL Callback handler. */
+   String SASL_CALLBACK_HANDLER = SASL_PREFIX + ".callback.handler";
+
+   /** SASL channel binding. */
+   String SASL_CHANNEL_BINDING = SASL_PREFIX + ".channel.binding";
+
+   // SASL data element size limits ...........................................
+
+   /** The size limit, in bytes, of a SASL OS (Octet Sequence) element. */
+   int SASL_ONE_BYTE_MAX_LIMIT = 255;
+
+   /**
+    * The size limit, in bytes, of both a SASL MPI (Multi-Precision Integer)
+    * element and a SASL Text element.
+    */
+   int SASL_TWO_BYTE_MAX_LIMIT = 65535;
+
+   /** The size limit, in bytes, of a SASL EOS (Extended Octet Sequence) 
element. */
+   int SASL_FOUR_BYTE_MAX_LIMIT = 2147483383;
+
+   /** The size limit, in bytes, of a SASL Buffer. */
+   int SASL_BUFFER_MAX_LIMIT = 2147483643;
+
+   // Canonical names of SASL mechanisms ......................................
+
+   String SASL_ANONYMOUS_MECHANISM = "ANONYMOUS";
+   String SASL_CRAM_MD5_MECHANISM = "CRAM-MD5";
+   String SASL_PLAIN_MECHANISM = "PLAIN";
+   String SASL_SRP_MECHANISM = "SRP";
+
+   // Canonical names of Integrity Protection algorithms ......................
+
+   String SASL_HMAC_MD5_IALG = "HMACwithMD5";
+   String SASL_HMAC_SHA_IALG = "HMACwithSHA";
+
+   // Quality Of Protection string representations ............................
+
+   /** authentication only. */
+   String QOP_AUTH = "auth";
+   /** authentication plus integrity protection. */
+   String QOP_AUTH_INT = "auth-int";
+   /** authentication plus integrity and confidentiality protection. */
+   String QOP_AUTH_CONF = "auth-conf";
+
+   // SASL mechanism strength string representation ...........................
+
+   String STRENGTH_HIGH = "high";
+   String STRENGTH_MEDIUM = "medium";
+   String STRENGTH_LOW = "low";
+
+   // SASL Server Authentication requirement ..................................
+
+   /** Server must authenticate to the client. */
+   String SERVER_AUTH_TRUE = "true";
+   /** Server does not need to, or cannot, authenticate to the client. */
+   String SERVER_AUTH_FALSE = "false";
+
+   // SASL mechanism reuse capability .........................................
+
+   String REUSE_TRUE = "true";
+   String REUSE_FALSE = "false";
+
+   // Keyrings  ...............................................................
+
+   byte[] GKR_MAGIC = new byte[] { 0x47, 0x4b, 0x52, 0x01 };
+
+   // Ring usage fields.
+   int GKR_PRIVATE_KEYS       = 1 << 0;
+   int GKR_PUBLIC_CREDENTIALS = 1 << 1;
+   int GKR_CERTIFICATES       = 1 << 2;
+
+   // HMac types.
+   int GKR_HMAC_MD5_128 = 0;
+   int GKR_HMAC_SHA_160 = 1;
+   int GKR_HMAC_MD5_96  = 2;
+   int GKR_HMAC_SHA_96  = 3;
+
+   // Cipher types.
+   int GKR_CIPHER_AES_128_OFB = 0;
+   int GKR_CIPHER_AES_128_CBC = 1;
+
+   // Methods
+   // -------------------------------------------------------------------------
+}

Added: trunk/apps/installer/src/gnu/crypto/hash/BaseHash.java
===================================================================
--- trunk/apps/installer/src/gnu/crypto/hash/BaseHash.java      2006-02-12 
17:41:47 UTC (rev 8028)
+++ trunk/apps/installer/src/gnu/crypto/hash/BaseHash.java      2006-02-12 
18:12:16 UTC (rev 8029)
@@ -0,0 +1,198 @@
+package gnu.crypto.hash;
+
+// ----------------------------------------------------------------------------
+// $Id: BaseHash.java,v 1.10 2005/10/06 04:24:14 rsdio Exp $
+//
+// Copyright (C) 2001, 2002, Free Software Foundation, Inc.
+//
+// This file is part of GNU Crypto.
+//
+// GNU Crypto is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GNU Crypto is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING.  If not, write to the
+//
+//    Free Software Foundation Inc.,
+//    51 Franklin Street, Fifth Floor,
+//    Boston, MA 02110-1301
+//    USA
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library.  Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give
+// you permission to link this library with independent modules to
+// produce an executable, regardless of the license terms of these
+// independent modules, and to copy and distribute the resulting
+// executable under terms of your choice, provided that you also meet,
+// for each linked independent module, the terms and conditions of the
+// license of that module.  An independent module is a module which is
+// not derived from or based on this library.  If you modify this
+// library, you may extend this exception to your version of the
+// library, but you are not obligated to do so.  If you do not wish to
+// do so, delete this exception statement from your version.
+// ----------------------------------------------------------------------------
+
+/**
+ * <p>A base abstract class to facilitate hash implementations.</p>
+ *
+ * @version $Revision: 1.10 $
+ */
+public abstract class BaseHash implements IMessageDigest {
+
+   // Constants and variables
+   // -------------------------------------------------------------------------
+
+   /** The canonical name prefix of the hash. */
+   protected String name;
+
+   /** The hash (output) size in bytes. */
+   protected int hashSize;
+
+   /** The hash (inner) block size in bytes. */
+   protected int blockSize;
+
+   /** Number of bytes processed so far. */
+   protected long count;
+
+   /** Temporary input buffer. */
+   protected byte[] buffer;
+
+   // Constructor(s)
+   // -------------------------------------------------------------------------
+
+   /**
+    * <p>Trivial constructor for use by concrete subclasses.</p>
+    *
+    * @param name the canonical name prefix of this instance.
+    * @param hashSize the block size of the output in bytes.
+    * @param blockSize the block size of the internal transform.
+    */
+   protected BaseHash(String name, int hashSize, int blockSize) {
+      super();
+
+      this.name = name;
+      this.hashSize = hashSize;
+      this.blockSize = blockSize;
+      this.buffer = new byte[blockSize];
+
+      resetContext();
+   }
+
+   // Class methods
+   // -------------------------------------------------------------------------
+
+   // Instance methods
+   // -------------------------------------------------------------------------
+
+   // IMessageDigest interface implementation ---------------------------------
+
+   public String name() {
+      return name;
+   }
+
+   public int hashSize() {
+      return hashSize;
+   }
+
+   public int blockSize() {
+      return blockSize;
+   }
+
+   public void update(byte b) {
+      // compute number of bytes still unhashed; ie. present in buffer
+      int i = (int)(count % blockSize);
+      count++;
+      buffer[i] = b;
+      if (i == (blockSize - 1)) {
+         transform(buffer, 0);
+      }
+   }
+
+   public void update(byte[] b) {
+      update(b, 0, b.length);
+   }
+
+   public void update(byte[] b, int offset, int len) {
+      int n = (int)(count % blockSize);
+      count += len;
+      int partLen = blockSize - n;
+      int i = 0;
+
+      if (len >= partLen) {
+         System.arraycopy(b, offset, buffer, n, partLen);
+         transform(buffer, 0);
+         for (i = partLen; i + blockSize - 1 < len; i+= blockSize) {
+            transform(b, offset + i);
+         }
+         n = 0;
+      }
+
+      if (i < len) {
+         System.arraycopy(b, offset + i, buffer, n, len - i);
+      }
+   }
+
+   public byte[] digest() {
+      byte[] tail = padBuffer(); // pad remaining bytes in buffer
+      update(tail, 0, tail.length); // last transform of a message
+      byte[] result = getResult(); // make a result out of context
+
+      reset(); // reset this instance for future re-use
+
+      return result;
+   }
+
+   public void reset() { // reset this instance for future re-use
+      count = 0L;
+      for (int i = 0; i < blockSize; ) {
+         buffer[i++] = 0;
+      }
+
+      resetContext();
+   }
+
+   // methods to be implemented by concrete subclasses ------------------------
+
+   public abstract Object clone();
+
+   public abstract boolean selfTest();
+
+   /**
+    * <p>Returns the byte array to use as padding before completing a hash
+    * operation.</p>
+    *
+    * @return the bytes to pad the remaining bytes in the buffer before
+    * completing a hash operation.
+    */
+   protected abstract byte[] padBuffer();
+
+   /**
+    * <p>Constructs the result from the contents of the current context.</p>
+    *
+    * @return the output of the completed hash operation.
+    */
+   protected abstract byte[] getResult();
+
+   /** Resets the instance for future re-use. */
+   protected abstract void resetContext();
+
+   /**
+    * <p>The block digest transformation per se.</p>
+    *
+    * @param in the <i>blockSize</i> long block, as an array of bytes to 
digest.
+    * @param offset the index where the data to digest is located within the
+    * input buffer.
+    */
+   protected abstract void transform(byte[] in, int offset);
+}

Added: trunk/apps/installer/src/gnu/crypto/hash/IMessageDigest.java
===================================================================
--- trunk/apps/installer/src/gnu/crypto/hash/IMessageDigest.java        
2006-02-12 17:41:47 UTC (rev 8028)
+++ trunk/apps/installer/src/gnu/crypto/hash/IMessageDigest.java        
2006-02-12 18:12:16 UTC (rev 8029)
@@ -0,0 +1,141 @@
+package gnu.crypto.hash;
+
+// ----------------------------------------------------------------------------
+// $Id: IMessageDigest.java,v 1.11 2005/10/06 04:24:14 rsdio Exp $
+//
+// Copyright (C) 2001, 2002, Free Software Foundation, Inc.
+//
+// This file is part of GNU Crypto.
+//
+// GNU Crypto is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GNU Crypto is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING.  If not, write to the
+//
+//    Free Software Foundation Inc.,
+//    51 Franklin Street, Fifth Floor,
+//    Boston, MA 02110-1301
+//    USA
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library.  Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give
+// you permission to link this library with independent modules to
+// produce an executable, regardless of the license terms of these
+// independent modules, and to copy and distribute the resulting
+// executable under terms of your choice, provided that you also meet,
+// for each linked independent module, the terms and conditions of the
+// license of that module.  An independent module is a module which is
+// not derived from or based on this library.  If you modify this
+// library, you may extend this exception to your version of the
+// library, but you are not obligated to do so.  If you do not wish to
+// do so, delete this exception statement from your version.
+// ----------------------------------------------------------------------------
+
+/**
+ * <p>The basic visible methods of any hash algorithm.</p>
+ *
+ * <p>A hash (or message digest) algorithm produces its output by iterating a
+ * basic compression function on blocks of data.</p>
+ *
+ * @version $Revision: 1.11 $
+ */
+public interface IMessageDigest extends Cloneable {
+
+   // Constants
+   // -------------------------------------------------------------------------
+
+   // Methods
+   // -------------------------------------------------------------------------
+
+   /**
+    * <p>Returns the canonical name of this algorithm.</p>
+    *
+    * @return the canonical name of this instance.
+    */
+   String name();
+
+   /**
+    * <p>Returns the output length in bytes of this message digest 
algorithm.</p>
+    *
+    * @return the output length in bytes of this message digest algorithm.
+    */
+   int hashSize();
+
+   /**
+    * <p>Returns the algorithm's (inner) block size in bytes.</p>
+    *
+    * @return the algorithm's inner block size in bytes.
+    */
+   int blockSize();
+
+   /**
+    * <p>Continues a message digest operation using the input byte.</p>
+    *
+    * @param b the input byte to digest.
+    */
+   void update(byte b);
+
+   /**
+    * <p>Continues a message digest operation, by filling the buffer, 
processing
+    * data in the algorithm's HASH_SIZE-bit block(s), updating the context and
+    * count, and buffering the remaining bytes in buffer for the next
+    * operation.</p>
+    *
+    * @param in the input block.
+    */
+   void update(byte[] in);
+
+   /**
+    * <p>Continues a message digest operation, by filling the buffer, 
processing
+    * data in the algorithm's HASH_SIZE-bit block(s), updating the context and
+    * count, and buffering the remaining bytes in buffer for the next
+    * operation.</p>
+    *
+    * @param in the input block.
+    * @param offset start of meaningful bytes in input block.
+    * @param length number of bytes, in input block, to consider.
+    */
+   void update(byte[] in, int offset, int length);
+
+   /**
+    * <p>Completes the message digest by performing final operations such as
+    * padding and resetting the instance.</p>
+    *
+    * @return the array of bytes representing the hash value.
+    */
+   byte[] digest();
+
+   /**
+    * <p>Resets the current context of this instance clearing any eventually 
cached
+    * intermediary values.</p>
+    */
+   void reset();
+
+   /**
+    * <p>A basic test. Ensures that the digest of a pre-determined message is 
equal
+    * to a known pre-computed value.</p>
+    *
+    * @return <tt>true</tt> if the implementation passes a basic self-test.
+    * Returns <tt>false</tt> otherwise.
+    */
+   boolean selfTest();
+
+   /**
+    * <p>Returns a clone copy of this instance.</p>
+    *
+    * @return a clone copy of this instance.
+    */
+   Object clone();
+}

Added: trunk/apps/installer/src/gnu/crypto/hash/Sha160.java
===================================================================
--- trunk/apps/installer/src/gnu/crypto/hash/Sha160.java        2006-02-12 
17:41:47 UTC (rev 8028)
+++ trunk/apps/installer/src/gnu/crypto/hash/Sha160.java        2006-02-12 
18:12:16 UTC (rev 8029)
@@ -0,0 +1,295 @@
+package gnu.crypto.hash;
+
+// ----------------------------------------------------------------------------
+// $Id: Sha160.java,v 1.10 2005/10/06 04:24:14 rsdio Exp $
+//
+// Copyright (C) 2001, 2002, Free Software Foundation, Inc.
+//
+// This file is part of GNU Crypto.
+//
+// GNU Crypto is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GNU Crypto is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING.  If not, write to the
+//
+//    Free Software Foundation Inc.,
+//    51 Franklin Street, Fifth Floor,
+//    Boston, MA 02110-1301
+//    USA
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library.  Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give
+// you permission to link this library with independent modules to
+// produce an executable, regardless of the license terms of these
+// independent modules, and to copy and distribute the resulting
+// executable under terms of your choice, provided that you also meet,
+// for each linked independent module, the terms and conditions of the
+// license of that module.  An independent module is a module which is
+// not derived from or based on this library.  If you modify this
+// library, you may extend this exception to your version of the
+// library, but you are not obligated to do so.  If you do not wish to
+// do so, delete this exception statement from your version.
+// ----------------------------------------------------------------------------
+
+import gnu.crypto.Registry;
+import gnu.crypto.util.Util;
+
+/**
+ * <p>The Secure Hash Algorithm (SHA-1) is required for use with the Digital
+ * Signature Algorithm (DSA) as specified in the Digital Signature Standard
+ * (DSS) and whenever a secure hash algorithm is required for federal
+ * applications. For a message of length less than 2^64 bits, the SHA-1
+ * produces a 160-bit condensed representation of the message called a message
+ * digest. The message digest is used during generation of a signature for the
+ * message. The SHA-1 is also used to compute a message digest for the received
+ * version of the message during the process of verifying the signature. Any
+ * change to the message in transit will, with very high probability, result in
+ * a different message digest, and the signature will fail to verify.</p>
+ *
+ * <p>The SHA-1 is designed to have the following properties: it is
+ * computationally infeasible to find a message which corresponds to a given
+ * message digest, or to find two different messages which produce the same
+ * message digest.</p>
+ *
+ * <p>References:</p>
+ *
+ * <ol>
+ *    <li><a href="http://www.itl.nist.gov/fipspubs/fip180-1.htm";>SECURE HASH
+ *    STANDARD</a><br>
+ *    Federal Information, Processing Standards Publication 180-1, 1995 April 
17.
+ *    </li>
+ * </ol>
+ *
+ * @version $Revision: 1.10 $
+ */
+public class Sha160 extends BaseHash {
+
+   // Constants and variables
+   // -------------------------------------------------------------------------
+
+   private static final int BLOCK_SIZE = 64; // inner block size in bytes
+
+   private static final String DIGEST0 = 
"A9993E364706816ABA3E25717850C26C9CD0D89D";
+
+   private static final int[] w = new int[80];
+
+   /** caches the result of the correctness test, once executed. */
+   private static Boolean valid;
+
+   /** 160-bit interim result. */
+   private int h0, h1, h2, h3, h4;
+
+   // Constructor(s)
+   // -------------------------------------------------------------------------
+
+   /** Trivial 0-arguments constructor. */
+   public Sha160() {
+      super(Registry.SHA160_HASH, 20, BLOCK_SIZE);
+   }
+
+   /**
+    * <p>Private constructor for cloning purposes.</p>
+    *
+    * @param md the instance to clone.
+    */
+   private Sha160(Sha160 md) {
+      this();
+
+      this.h0 = md.h0;
+      this.h1 = md.h1;
+      this.h2 = md.h2;
+      this.h3 = md.h3;
+      this.h4 = md.h4;
+      this.count = md.count;
+      this.buffer = (byte[]) md.buffer.clone();
+   }
+
+   // Class methods
+   // -------------------------------------------------------------------------
+
+   public static final int[]
+   G(int hh0, int hh1, int hh2, int hh3, int hh4, byte[] in, int offset) {
+//      int[] w = new int[80];
+//      int i, T;
+//      for (i = 0; i < 16; i++) {
+//         w[i] = in[offset++]         << 24 |
+//               (in[offset++] & 0xFF) << 16 |
+//               (in[offset++] & 0xFF) <<  8 |
+//               (in[offset++] & 0xFF);
+//      }
+//      for (i = 16; i < 80; i++) {
+//         T = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
+//         w[i] = T << 1 | T >>> 31;
+//      }
+
+//      return sha(hh0, hh1, hh2, hh3, hh4, in, offset, w);
+      return sha(hh0, hh1, hh2, hh3, hh4, in, offset);
+   }
+
+   // Instance methods
+   // -------------------------------------------------------------------------
+
+   // java.lang.Cloneable interface implementation ----------------------------
+
+   public Object clone() {
+      return new Sha160(this);
+   }
+
+   // Implementation of concrete methods in BaseHash --------------------------
+
+   protected void transform(byte[] in, int offset) {
+//      int i, T;
+//      for (i = 0; i < 16; i++) {
+//         W[i] = in[offset++]         << 24 |
+//               (in[offset++] & 0xFF) << 16 |
+//               (in[offset++] & 0xFF) <<  8 |
+//               (in[offset++] & 0xFF);
+//      }
+//      for (i = 16; i < 80; i++) {
+//         T = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
+//         W[i] = T << 1 | T >>> 31;
+//      }
+
+//      int[] result = sha(h0, h1, h2, h3, h4, in, offset, W);
+      int[] result = sha(h0, h1, h2, h3, h4, in, offset);
+
+      h0 = result[0];
+      h1 = result[1];
+      h2 = result[2];
+      h3 = result[3];
+      h4 = result[4];
+   }
+
+   protected byte[] padBuffer() {
+      int n = (int)(count % BLOCK_SIZE);
+      int padding = (n < 56) ? (56 - n) : (120 - n);
+      byte[] result = new byte[padding + 8];
+
+      // padding is always binary 1 followed by binary 0s
+      result[0] = (byte) 0x80;
+
+      // save number of bits, casting the long to an array of 8 bytes
+      long bits = count << 3;
+      result[padding++] = (byte)(bits >>> 56);
+      result[padding++] = (byte)(bits >>> 48);
+      result[padding++] = (byte)(bits >>> 40);
+      result[padding++] = (byte)(bits >>> 32);
+      result[padding++] = (byte)(bits >>> 24);
+      result[padding++] = (byte)(bits >>> 16);
+      result[padding++] = (byte)(bits >>>  8);
+      result[padding  ] = (byte) bits;
+
+      return result;
+   }
+
+   protected byte[] getResult() {
+      byte[] result = new byte[] {
+         (byte)(h0 >>> 24), (byte)(h0 >>> 16), (byte)(h0 >>> 8), (byte) h0,
+         (byte)(h1 >>> 24), (byte)(h1 >>> 16), (byte)(h1 >>> 8), (byte) h1,
+         (byte)(h2 >>> 24), (byte)(h2 >>> 16), (byte)(h2 >>> 8), (byte) h2,
+         (byte)(h3 >>> 24), (byte)(h3 >>> 16), (byte)(h3 >>> 8), (byte) h3,
+         (byte)(h4 >>> 24), (byte)(h4 >>> 16), (byte)(h4 >>> 8), (byte) h4
+      };
+
+      return result;
+   }
+
+   protected void resetContext() {
+      // magic SHA-1/RIPEMD160 initialisation constants
+      h0 = 0x67452301;
+      h1 = 0xEFCDAB89;
+      h2 = 0x98BADCFE;
+      h3 = 0x10325476;
+      h4 = 0xC3D2E1F0;
+   }
+
+   public boolean selfTest() {
+      if (valid == null) {
+         Sha160 md = new Sha160();
+         md.update((byte) 0x61); // a
+         md.update((byte) 0x62); // b
+         md.update((byte) 0x63); // c
+         String result = Util.toString(md.digest());
+         valid = new Boolean(DIGEST0.equals(result));
+      }
+      return valid.booleanValue();
+   }
+
+   // SHA specific methods ----------------------------------------------------
+
+   private static final synchronized int[]
+//   sha(int hh0, int hh1, int hh2, int hh3, int hh4, byte[] in, int offset, 
int[] w) {
+   sha(int hh0, int hh1, int hh2, int hh3, int hh4, byte[] in, int offset) {
+      int A = hh0;
+      int B = hh1;
+      int C = hh2;
+      int D = hh3;
+      int E = hh4;
+      int r, T;
+
+      for (r = 0; r < 16; r++) {
+         w[r] = in[offset++]         << 24 |
+               (in[offset++] & 0xFF) << 16 |
+               (in[offset++] & 0xFF) <<  8 |
+               (in[offset++] & 0xFF);
+      }
+      for (r = 16; r < 80; r++) {
+         T = w[r-3] ^ w[r-8] ^ w[r-14] ^ w[r-16];
+         w[r] = T << 1 | T >>> 31;
+      }
+
+      // rounds 0-19
+      for (r = 0; r < 20; r++) {
+         T = (A << 5 | A >>> 27) + ((B & C) | (~B & D)) + E + w[r] + 
0x5A827999;
+         E = D;
+         D = C;
+         C = B << 30 | B >>> 2;
+         B = A;
+         A = T;
+      }
+
+      // rounds 20-39
+      for (r = 20; r < 40; r++) {
+         T = (A << 5 | A >>> 27) + (B ^ C ^ D) + E + w[r] + 0x6ED9EBA1;
+         E = D;
+         D = C;
+         C = B << 30 | B >>> 2;
+         B = A;
+         A = T;
+      }
+
+      // rounds 40-59
+      for (r = 40; r < 60; r++) {
+         T = (A << 5 | A >>> 27) + (B & C | B & D | C & D) + E + w[r] + 
0x8F1BBCDC;
+         E = D;
+         D = C;
+         C = B << 30 | B >>> 2;
+         B = A;
+         A = T;
+      }
+
+      // rounds 60-79
+      for (r = 60; r < 80; r++) {
+         T = (A << 5 | A >>> 27) + (B ^ C ^ D) + E + w[r] + 0xCA62C1D6;
+         E = D;
+         D = C;
+         C = B << 30 | B >>> 2;
+         B = A;
+         A = T;
+      }
+
+      return new int[] {hh0+A, hh1+B, hh2+C, hh3+D, hh4+E};
+   }
+}

Added: trunk/apps/installer/src/gnu/crypto/util/Util.java
===================================================================
--- trunk/apps/installer/src/gnu/crypto/util/Util.java  2006-02-12 17:41:47 UTC 
(rev 8028)
+++ trunk/apps/installer/src/gnu/crypto/util/Util.java  2006-02-12 18:12:16 UTC 
(rev 8029)
@@ -0,0 +1,612 @@
+package gnu.crypto.util;
+
+// ----------------------------------------------------------------------------
+// $Id: Util.java,v 1.11 2005/10/06 04:24:19 rsdio Exp $
+//
+// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This file is part of GNU Crypto.
+//
+// GNU Crypto is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GNU Crypto is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING.  If not, write to the
+//
+//    Free Software Foundation Inc.,
+//    51 Franklin Street, Fifth Floor,
+//    Boston, MA 02110-1301
+//    USA
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library.  Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give
+// you permission to link this library with independent modules to
+// produce an executable, regardless of the license terms of these
+// independent modules, and to copy and distribute the resulting
+// executable under terms of your choice, provided that you also meet,
+// for each linked independent module, the terms and conditions of the
+// license of that module.  An independent module is a module which is
+// not derived from or based on this library.  If you modify this
+// library, you may extend this exception to your version of the
+// library, but you are not obligated to do so.  If you do not wish to
+// do so, delete this exception statement from your version.
+// ----------------------------------------------------------------------------
+
+import java.math.BigInteger;
+
+/**
+ * <p>A collection of utility methods used throughout this project.</p>
+ *
+ * @version $Revision: 1.11 $
+ */
+public class Util {
+
+   // Constants and variables
+   // -------------------------------------------------------------------------
+
+   // Hex charset
+   private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
+
+   // Base-64 charset
+   private static final String BASE64_CHARS =
+      "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
+   private static final char[] BASE64_CHARSET = BASE64_CHARS.toCharArray();
+
+   // Constructor(s)
+   // -------------------------------------------------------------------------
+
+   /** Trivial constructor to enforce Singleton pattern. */
+   private Util() {
+      super();
+   }
+
+   // Class methods
+   // -------------------------------------------------------------------------
+
+   /**
+    * <p>Returns a string of hexadecimal digits from a byte array. Each byte is
+    * converted to 2 hex symbols; zero(es) included.</p>
+    *
+    * <p>This method calls the method with same name and three arguments 
as:</p>
+    *
+    * <pre>
+    *    toString(ba, 0, ba.length);
+    * </pre>
+    *
+    * @param ba the byte array to convert.
+    * @return a string of hexadecimal characters (two for each byte)
+    * representing the designated input byte array.
+    */
+   public static String toString(byte[] ba) {
+      return toString(ba, 0, ba.length);
+   }
+
+   /**
+    * <p>Returns a string of hexadecimal digits from a byte array, starting at
+    * <code>offset</code> and consisting of <code>length</code> bytes. Each 
byte
+    * is converted to 2 hex symbols; zero(es) included.</p>
+    *
+    * @param ba the byte array to convert.
+    * @param offset the index from which to start considering the bytes to
+    * convert.
+    * @param length the count of bytes, starting from the designated offset to
+    * convert.
+    * @return a string of hexadecimal characters (two for each byte)
+    * representing the designated input byte sub-array.
+    */
+   public static final String toString(byte[] ba, int offset, int length) {
+      char[] buf = new char[length * 2];
+      for (int i = 0, j = 0, k; i < length; ) {
+         k = ba[offset + i++];
+         buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
+         buf[j++] = HEX_DIGITS[ k        & 0x0F];
+      }
+      return new String(buf);
+   }
+
+   /**
+    * <p>Returns a string of hexadecimal digits from a byte array. Each byte is
+    * converted to 2 hex symbols; zero(es) included. The argument is
+    * treated as a large little-endian integer and is returned as a
+    * large big-endian integer.</p>
+    *
+    * <p>This method calls the method with same name and three arguments 
as:</p>
+    *
+    * <pre>
+    *    toReversedString(ba, 0, ba.length);
+    * </pre>
+    *
+    * @param ba the byte array to convert.
+    * @return a string of hexadecimal characters (two for each byte)
+    * representing the designated input byte array.
+    */
+   public static String toReversedString(byte[] ba) {
+      return toReversedString(ba, 0, ba.length);
+   }
+
+   /**
+    * <p>Returns a string of hexadecimal digits from a byte array, starting at
+    * <code>offset</code> and consisting of <code>length</code> bytes. Each 
byte
+    * is converted to 2 hex symbols; zero(es) included.</p>
+    *
+    * <p>The byte array is treated as a large little-endian integer, and
+    * is returned as a large big-endian integer.</p>
+    *
+    * @param ba the byte array to convert.
+    * @param offset the index from which to start considering the bytes to
+    * convert.
+    * @param length the count of bytes, starting from the designated offset to
+    * convert.
+    * @return a string of hexadecimal characters (two for each byte)
+    * representing the designated input byte sub-array.
+    */
+   public static final String
+   toReversedString(byte[] ba, int offset, int length) {
+      char[] buf = new char[length * 2];
+      for (int i = offset+length-1, j = 0, k; i >= offset; ) {
+         k = ba[offset + i--];
+         buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
+         buf[j++] = HEX_DIGITS[ k        & 0x0F];
+      }
+      return new String(buf);
+   }
+
+   /**
+    * <p>Returns a byte array from a string of hexadecimal digits.</p>
+    *
+    * @param s a string of hexadecimal ASCII characters
+    * @return the decoded byte array from the input hexadecimal string.
+    */
+   public static byte[] toBytesFromString(String s) {
+      int limit = s.length();
+      byte[] result = new byte[((limit + 1) / 2)];
+      int i = 0, j = 0;
+      if ((limit % 2) == 1) {
+         result[j++] = (byte) fromDigit(s.charAt(i++));
+      }
+      while (i < limit) {
+         result[j  ]  = (byte) (fromDigit(s.charAt(i++)) << 4);
+         result[j++] |= (byte)  fromDigit(s.charAt(i++));
+      }
+      return result;
+   }
+
+   /**
+    * <p>Returns a byte array from a string of hexadecimal digits, interpreting
+    * them as a large big-endian integer and returning it as a large
+    * little-endian integer.</p>
+    *
+    * @param s a string of hexadecimal ASCII characters
+    * @return the decoded byte array from the input hexadecimal string.
+    */
+   public static byte[] toReversedBytesFromString(String s) {
+      int limit = s.length();
+      byte[] result = new byte[((limit + 1) / 2)];
+      int i = 0;
+      if ((limit % 2) == 1) {
+         result[i++] = (byte) fromDigit(s.charAt(--limit));
+      }
+      while (limit > 0) {
+         result[i  ]  = (byte)  fromDigit(s.charAt(--limit));
+         result[i++] |= (byte) (fromDigit(s.charAt(--limit)) << 4);
+      }
+      return result;
+   }
+
+   /**
+    * <p>Returns a number from <code>0</code> to <code>15</code> corresponding
+    * to the designated hexadecimal digit.</p>
+    *
+    * @param c a hexadecimal ASCII symbol.
+    */
+   public static int fromDigit(char c) {
+      if (c >= '0' && c <= '9') {
+         return c - '0';
+      } else if (c >= 'A' && c <= 'F') {
+         return c - 'A' + 10;
+      } else if (c >= 'a' && c <= 'f') {
+         return c - 'a' + 10;
+      } else
+         throw new IllegalArgumentException("Invalid hexadecimal digit: " + c);
+   }
+
+   /**
+    * <p>Returns a string of 8 hexadecimal digits (most significant digit 
first)
+    * corresponding to the unsigned integer <code>n</code>.</p>
+    *
+    * @param n the unsigned integer to convert.
+    * @return a hexadecimal string 8-character long.
+    */
+   public static String toString(int n) {
+      char[] buf = new char[8];
+      for (int i = 7; i >= 0; i--) {
+         buf[i] = HEX_DIGITS[n & 0x0F];
+         n >>>= 4;
+      }
+      return new String(buf);
+   }
+
+   /**
+    * <p>Returns a string of hexadecimal digits from an integer array. Each int
+    * is converted to 4 hex symbols.</p>
+    */
+   public static String toString(int[] ia) {
+      int length = ia.length;
+      char[] buf = new char[length * 8];
+      for (int i = 0, j = 0, k; i < length; i++) {
+         k = ia[i];
+         buf[j++] = HEX_DIGITS[(k >>> 28) & 0x0F];
+         buf[j++] = HEX_DIGITS[(k >>> 24) & 0x0F];
+         buf[j++] = HEX_DIGITS[(k >>> 20) & 0x0F];
+         buf[j++] = HEX_DIGITS[(k >>> 16) & 0x0F];
+         buf[j++] = HEX_DIGITS[(k >>> 12) & 0x0F];
+         buf[j++] = HEX_DIGITS[(k >>>  8) & 0x0F];
+         buf[j++] = HEX_DIGITS[(k >>>  4) & 0x0F];
+         buf[j++] = HEX_DIGITS[ k         & 0x0F];
+      }
+      return new String(buf);
+   }
+
+   /**
+    * <p>Returns a string of 16 hexadecimal digits (most significant digit 
first)
+    * corresponding to the unsigned long <code>n</code>.</p>
+    *
+    * @param n the unsigned long to convert.
+    * @return a hexadecimal string 16-character long.
+    */
+   public static String toString(long n) {
+      char[] b = new char[16];
+      for (int i = 15; i >= 0; i--) {
+         b[i] = HEX_DIGITS[(int)(n & 0x0FL)];
+         n >>>= 4;
+      }
+      return new String(b);
+   }
+
+   /**
+    * <p>Similar to the <code>toString()</code> method except that the Unicode
+    * escape character is inserted before every pair of bytes. Useful to
+    * externalise byte arrays that will be constructed later from such strings;
+    * eg. s-box values.</p>
+    *
+    * @throws ArrayIndexOutOfBoundsException if the length is odd.
+    */
+   public static String toUnicodeString(byte[] ba) {
+      return toUnicodeString(ba, 0, ba.length);
+   }
+
+   /**
+    * <p>Similar to the <code>toString()</code> method except that the Unicode
+    * escape character is inserted before every pair of bytes. Useful to
+    * externalise byte arrays that will be constructed later from such strings;
+    * eg. s-box values.</p>
+    *
+    * @throws ArrayIndexOutOfBoundsException if the length is odd.
+    */
+   public static final String
+   toUnicodeString(byte[] ba, int offset, int length) {
+      StringBuffer sb = new StringBuffer();
+      int i = 0;
+      int j = 0;
+      int k;
+      sb.append('\n').append("\"");
+      while (i < length) {
+         sb.append("\\u");
+
+         k = ba[offset + i++];
+         sb.append(HEX_DIGITS[(k >>> 4) & 0x0F]);
+         sb.append(HEX_DIGITS[ k        & 0x0F]);
+
+         k = ba[offset + i++];
+         sb.append(HEX_DIGITS[(k >>> 4) & 0x0F]);
+         sb.append(HEX_DIGITS[ k        & 0x0F]);
+
+         if ((++j % 8) == 0) {
+            sb.append("\"+").append('\n').append("\"");
+         }
+      }
+      sb.append("\"").append('\n');
+      return sb.toString();
+   }
+
+   /**
+    * <p>Similar to the <code>toString()</code> method except that the Unicode
+    * escape character is inserted before every pair of bytes. Useful to
+    * externalise integer arrays that will be constructed later from such
+    * strings; eg. s-box values.</p>
+    *
+    * @throws ArrayIndexOutOfBoundsException if the length is not a multiple 
of 4.
+    */
+   public static String toUnicodeString(int[] ia) {
+      StringBuffer sb = new StringBuffer();
+      int i = 0;
+      int j = 0;
+      int k;
+      sb.append('\n').append("\"");
+      while (i < ia.length) {
+         k = ia[i++];
+         sb.append("\\u");
+         sb.append(HEX_DIGITS[(k >>> 28) & 0x0F]);
+         sb.append(HEX_DIGITS[(k >>> 24) & 0x0F]);
+         sb.append(HEX_DIGITS[(k >>> 20) & 0x0F]);
+         sb.append(HEX_DIGITS[(k >>> 16) & 0x0F]);
+         sb.append("\\u");
+         sb.append(HEX_DIGITS[(k >>> 12) & 0x0F]);
+         sb.append(HEX_DIGITS[(k >>>  8) & 0x0F]);
+         sb.append(HEX_DIGITS[(k >>>  4) & 0x0F]);
+         sb.append(HEX_DIGITS[ k         & 0x0F]);
+
+         if ((++j % 4) == 0) {
+            sb.append("\"+").append('\n').append("\"");
+         }
+      }
+      sb.append("\"").append('\n');
+      return sb.toString();
+   }
+
+   public static byte[] toBytesFromUnicode(String s) {
+      int limit = s.length() * 2;
+      byte[] result = new byte[limit];
+      char c;
+      for (int i = 0; i < limit; i++) {
+         c = s.charAt(i >>> 1);
+         result[i] = (byte)(((i & 1) == 0) ? c >>> 8 : c);
+      }
+      return result;
+   }
+
+   /**
+    * <p>Dumps a byte array as a string, in a format that is easy to read for
+    * debugging. The string <code>m</code> is prepended to the start of each
+    * line.</p>
+    *
+    * <p>If <code>offset</code> and <code>length</code> are omitted, the whole
+    * array is used. If <code>m</code> is omitted, nothing is prepended to each
+    * line.</p>
+    *
+    * @param data the byte array to be dumped.
+    * @param offset the offset within <i>data</i> to start from.
+    * @param length the number of bytes to dump.
+    * @param m a string to be prepended to each line.
+    * @return a string containing the result.
+    */
+   public static String dumpString(byte[] data, int offset, int length, String 
m) {
+      if (data == null) {
+         return m + "null\n";
+      }
+      StringBuffer sb = new StringBuffer(length * 3);
+      if (length > 32) {
+         sb.append(m).append("Hexadecimal dump of ").append(length).append(" 
bytes...\n");
+      }
+      // each line will list 32 bytes in 4 groups of 8 each
+      int end = offset + length;
+      String s;
+      int l = Integer.toString(length).length();
+      if (l < 4) {
+         l = 4;
+      }
+      for ( ; offset < end; offset += 32) {
+         if (length > 32) {
+            s = "         " + offset;
+            sb.append(m).append(s.substring(s.length()-l)).append(": ");
+         }
+         int i = 0;
+         for ( ; i < 32 && offset + i + 7 < end; i += 8) {
+            sb.append(toString(data, offset + i, 8)).append(' ');
+         }
+         if (i < 32) {
+            for ( ; i < 32 && offset + i < end; i++) {
+               sb.append(byteToString(data[offset + i]));
+            }
+         }
+         sb.append('\n');
+      }
+      return sb.toString();
+   }
+
+   public static String dumpString(byte[] data) {
+      return (data == null) ? "null\n" : dumpString(data, 0, data.length, "");
+   }
+
+   public static String dumpString(byte[] data, String m) {
+      return (data == null) ? "null\n" : dumpString(data, 0, data.length, m);
+   }
+
+   public static String dumpString(byte[] data, int offset, int length) {
+      return dumpString(data, offset, length, "");
+   }
+
+   /**
+    * <p>Returns a string of 2 hexadecimal digits (most significant digit 
first)
+    * corresponding to the lowest 8 bits of <code>n</code>.</p>
+    *
+    * @param n the byte value to convert.
+    * @return a string of 2 hex characters representing the input.
+    */
+   public static String byteToString(int n) {
+      char[] buf = { HEX_DIGITS[(n >>> 4) & 0x0F], HEX_DIGITS[n & 0x0F] };
+      return new String(buf);
+   }
+
+   /**
+    * <p>Converts a designated byte array to a Base-64 representation, with the
+    * exceptions that (a) leading 0-byte(s) are ignored, and (b) the character
+    * '.' (dot) shall be used instead of "+' (plus).</p>
+    *
+    * <p>Used by SASL password file manipulation primitives.</p>
+    *
+    * @param buffer an arbitrary sequence of bytes to represent in Base-64.
+    * @return unpadded (without the '=' character(s)) Base-64 representation of
+    * the input.
+    */
+   public static final String toBase64(byte[] buffer) {
+      int len = buffer.length, pos = len % 3;
+      byte b0 = 0, b1 = 0, b2 = 0;
+      switch (pos) {
+      case 1:
+         b2 = buffer[0];
+         break;
+      case 2:
+         b1 = buffer[0];
+         b2 = buffer[1];
+         break;
+      }
+      StringBuffer sb = new StringBuffer();
+      int c;
+      boolean notleading = false;
+      do {
+         c = (b0 & 0xFC) >>> 2;
+         if (notleading || c != 0) {
+           sb.append(BASE64_CHARSET[c]);
+           notleading = true;
+         }
+         c = ((b0 & 0x03) << 4) | ((b1 & 0xF0) >>> 4);
+         if (notleading || c != 0) {
+           sb.append(BASE64_CHARSET[c]);
+           notleading = true;
+         }
+         c = ((b1 & 0x0F) << 2) | ((b2 & 0xC0) >>> 6);
+         if (notleading || c != 0) {
+           sb.append(BASE64_CHARSET[c]);
+           notleading = true;
+         }
+         c = b2 & 0x3F;
+         if (notleading || c != 0) {
+           sb.append(BASE64_CHARSET[c]);
+           notleading = true;
+         }
+         if (pos >= len) {
+           break;
+         } else {
+           try {
+             b0 = buffer[pos++];
+             b1 = buffer[pos++];
+             b2 = buffer[pos++];
+           } catch (ArrayIndexOutOfBoundsException x) {
+             break;
+           }
+         }
+      } while (true);
+
+      if (notleading) {
+        return sb.toString();
+      }
+      return "0";
+   }
+
+   /**
+    * <p>The inverse function of the above.</p>
+    *
+    * <p>Converts a string representing the encoding of some bytes in Base-64
+    * to their original form.</p>
+    *
+    * @param str the Base-64 encoded representation of some byte(s).
+    * @return the bytes represented by the <code>str</code>.
+    * @throws NumberFormatException if <code>str</code> is <code>null</code>, 
or
+    * <code>str</code> contains an illegal Base-64 character.
+    * @see #toBase64(byte[])
+    */
+   public static final byte[] fromBase64(String str) {
+      int len = str.length();
+      if (len == 0) {
+         throw new NumberFormatException("Empty string");
+      }
+      byte[] a = new byte[len + 1];
+      int i, j;
+      for (i = 0; i < len; i++) {
+         try {
+            a[i] = (byte) BASE64_CHARS.indexOf(str.charAt(i));
+         } catch (ArrayIndexOutOfBoundsException x) {
+            throw new NumberFormatException("Illegal character at #"+i);
+         }
+      }
+      i = len - 1;
+      j = len;
+      try {
+         while (true) {
+            a[j] = a[i];
+            if (--i < 0) {
+               break;
+            }
+            a[j] |= (a[i] & 0x03) << 6;
+            j--;
+            a[j] = (byte)((a[i] & 0x3C) >>> 2);
+            if (--i < 0) {
+               break;
+            }
+            a[j] |= (a[i] & 0x0F) << 4;
+            j--;
+            a[j] = (byte)((a[i] & 0x30) >>> 4);
+            if (--i < 0) {
+               break;
+            }
+            a[j] |= (a[i] << 2);
+            j--;
+            a[j] = 0;
+            if (--i < 0) {
+               break;
+            }
+         }
+      } catch (Exception ignored) {
+      }
+
+      try { // ignore leading 0-bytes
+         while(a[j] == 0) {
+            j++;
+         }
+      } catch (Exception x) {
+         return new byte[1]; // one 0-byte
+      }
+      byte[] result = new byte[len - j + 1];
+      System.arraycopy(a, j, result, 0, len - j + 1);
+      return result;
+   }
+
+   // BigInteger utilities ----------------------------------------------------
+
+   /**
+    * <p>Treats the input as the MSB representation of a number, and discards
+    * leading zero elements. For efficiency, the input is simply returned if no
+    * leading zeroes are found.</p>
+    *
+    * @param n the {@link BigInteger} to trim.
+    * @return the byte array representation of the designated {@link 
BigInteger}
+    * with no leading 0-bytes.
+    */
+   public static final byte[] trim(BigInteger n) {
+      byte[] in = n.toByteArray();
+      if (in.length == 0 || in[0] != 0) {
+         return in;
+      }
+      int len = in.length;
+      int i = 1;
+      while (in[i] == 0 && i < len) {
+         ++i;
+      }
+      byte[] result = new byte[len - i];
+      System.arraycopy(in, i, result, 0, len - i);
+      return result;
+   }
+
+   /**
+    * <p>Returns a hexadecimal dump of the trimmed bytes of a {@link 
BigInteger}.
+    * </p>
+    *
+    * @param x the {@link BigInteger} to display.
+    * @return the string representation of the designated {@link BigInteger}.
+    */
+   public static final String dump(BigInteger x) {
+      return dumpString(trim(x));
+   }
+}


Reply via email to