Sorcerer's IsleCode cfPassphrase / diff

287bb43 Add modified versions of algorithms used.

 readme.md                                                        |  18 ++
 src/com/lambdaworks/crypto/SCrypt.java                           |  26 +--
 src/com/lambdaworks/jni/JarLibraryLoader.java (gone)             | 145 ---------------
 src/com/lambdaworks/jni/LibraryLoader.java (gone)                |  21 ---
 src/com/lambdaworks/jni/LibraryLoaders.java (gone)               |  21 ---
 src/com/lambdaworks/jni/Platform.java (gone)                     |  73 --------
 src/com/lambdaworks/jni/SystemLibraryLoader.java (gone)          |  32 ----
 src/com/lambdaworks/jni/UnsupportedPlatformException.java (gone) |  14 --
 src/crackstation/PBKDF2/PasswordHash.java                        | 108 +++++------
 src/mindrot/jbcrypt/BCrypt.java                                  |   8 +-
 src/mindrot/jbcrypt/LICENSE (gone)                               |  18 --
 src/mindrot/jbcrypt/README (gone)                                |  38 ----
 src/mindrot/jbcrypt/TODO (gone)                                  |   4 -
 src/mindrot/jbcrypt/TestBCrypt.java (gone)                       | 194 --------------------
 14 files changed, 81 insertions(+), 639 deletions(-)
diff --git a/readme.md b/readme.md
index 3ef75f2..80769fa 100644
--- a/readme.md
+++ b/readme.md
@@ -33,5 +33,23 @@ LICENSING
 cfPassphrase is a project created and maintained by Peter Boughton,
 licensed under the LGPLv3 (read license.txt for details).
 
+The project gratefully makes use of the third-party software detailed below,
+each available individually under their respective licenses.
+
+jBCrypt v0.3 (mindrot.org/projects/jBCrypt)
+* Source: http://mindrot.org/files/jBCrypt/
+* License: ISC/BSD (http://mindrot.org/files/jBCrypt/LICENSE)
+* Files: src/mindrot/jbcrypt/BCrypt.java
+
+Java PBKDF2 (crackstation.net/hashing-security.htm)
+* Source: http://crackstation.net/hashing-security.htm
+* License: Public Domain
+* Files: src/crackstation/PBKDF2/PasswordHash.java
+
+Java scrypt (github.com/wg/scrypt)
+* Source: https://github.com/wg/scrypt
+* License: Apache v2.0 (http://www.apache.org/licenses/LICENSE-2.0) 
+* Files: src/com/lambdaworks/*
+
 
 /eof
\ No newline at end of file
diff --git a/src/com/lambdaworks/crypto/SCrypt.java b/src/com/lambdaworks/crypto/SCrypt.java
index 6274238..abdb2fc 100644
--- a/src/com/lambdaworks/crypto/SCrypt.java
+++ b/src/com/lambdaworks/crypto/SCrypt.java
@@ -2,8 +2,6 @@
 
 package com.lambdaworks.crypto;
 
-import com.lambdaworks.jni.*;
-
 import javax.crypto.Mac;
 import javax.crypto.spec.SecretKeySpec;
 import java.security.GeneralSecurityException;
@@ -21,12 +19,6 @@ import static java.lang.System.arraycopy;
  * @author  Will Glozer
  */
 public class SCrypt {
-    private static final boolean native_library_loaded;
-
-    static {
-        LibraryLoader loader = LibraryLoaders.loader();
-        native_library_loaded = loader.load("scrypt", true);
-    }
 
     /**
      * Implementation of the <a href="http://www.tarsnap.com/scrypt/scrypt.pdf"/>scrypt KDF</a>.
@@ -45,23 +37,9 @@ public class SCrypt {
      * @throws GeneralSecurityException when HMAC_SHA256 is not available.
      */
     public static byte[] scrypt(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen) throws GeneralSecurityException {
-        return native_library_loaded ? scryptN(passwd, salt, N, r, p, dkLen) : scryptJ(passwd, salt, N, r, p, dkLen);
+        return scryptJ(passwd, salt, N, r, p, dkLen);
     }
 
-    /**
-     * Native C implementation of the <a href="http://www.tarsnap.com/scrypt/scrypt.pdf"/>scrypt KDF</a> using
-     * the code from <a href="http://www.tarsnap.com/scrypt.html">http://www.tarsnap.com/scrypt.html<a>.
-     *
-     * @param passwd    Password.
-     * @param salt      Salt.
-     * @param N         CPU cost parameter.
-     * @param r         Memory cost parameter.
-     * @param p         Parallelization parameter.
-     * @param dkLen     Intended length of the derived key.
-     *
-     * @return The derived key.
-     */
-    public static native byte[] scryptN(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen);
 
     /**
      * Pure Java implementation of the <a href="http://www.tarsnap.com/scrypt/scrypt.pdf"/>scrypt KDF</a>.
@@ -211,4 +189,4 @@ public class SCrypt {
 
         return n;
     }
-}
+}
\ No newline at end of file
diff --git a/src/com/lambdaworks/jni/JarLibraryLoader.java b/src/com/lambdaworks/jni/JarLibraryLoader.java
deleted file mode 100644
index fd9d3ab..0000000
--- a/src/com/lambdaworks/jni/JarLibraryLoader.java
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright (C) 2011 - Will Glozer.  All rights reserved.
-
-package com.lambdaworks.jni;
-
-import java.io.*;
-import java.security.CodeSource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-/**
- * A native library loader that will extract and load a shared library contained in a jar.
- * This loader will attempt to detect the {@link Platform platform} (CPU architecture and OS)
- * it is running on and load the appropriate shared library.
- *
- * Given a library path and name this loader looks for a native library with path
- * [libraryPath]/[arch]/[os]/lib[name].[ext]
- *
- * @author Will Glozer
- */
-public class JarLibraryLoader implements LibraryLoader {
-    private final CodeSource codeSource;
-    private final String libraryPath;
-
-    /**
-     * Initialize a new instance that looks for shared libraries located in the same jar
-     * as this class and with a path starting with {@code lib}.
-     */
-    public JarLibraryLoader() {
-        this(JarLibraryLoader.class.getProtectionDomain().getCodeSource(), "lib");
-    }
-
-    /**
-     * Initialize a new instance that looks for shared libraries located in the specified
-     * directory of the supplied code source.
-     *
-     * @param codeSource    Code source containing shared libraries.
-     * @param libraryPath   Path prefix of shared libraries.
-     */
-    public JarLibraryLoader(CodeSource codeSource, String libraryPath) {
-        this.codeSource  = codeSource;
-        this.libraryPath = libraryPath;
-    }
-
-    /**
-     * Load a shared library, and optionally verify the jar signatures.
-     *
-     * @param name      Name of the library to load.
-     * @param verify    Verify the jar file if signed.
-     *
-     * @return true if the library was successfully loaded.
-     */
-    public boolean load(String name, boolean verify) {
-        boolean loaded = false;
-
-        try {
-            Platform platform = Platform.detect();
-            JarFile jar = new JarFile(codeSource.getLocation().getPath(), verify);
-            try {
-                for (String path : libCandidates(platform, name)) {
-                    JarEntry entry = jar.getJarEntry(path);
-                    if (entry == null) continue;
-
-                    File lib = extract(name, jar.getInputStream(entry));
-                    System.load(lib.getAbsolutePath());
-                    lib.delete();
-
-                    loaded = true;
-                    break;
-                }
-            } finally {
-                jar.close();
-            }
-        } catch (Throwable e) {
-            loaded = false;
-        }
-
-        return loaded;
-    }
-
-    /**
-     * Extract a jar entry to a temp file.
-     *
-     * @param name  Name prefix for temp file.
-     * @param is    Jar entry input stream.
-     *
-     * @return A temporary file.
-     *
-     * @throws IOException when an IO error occurs.
-     */
-    private static File extract(String name, InputStream is) throws IOException {
-        byte[] buf = new byte[4096];
-        int len;
-
-        File lib = File.createTempFile(name, "lib");
-        FileOutputStream os = new FileOutputStream(lib);
-
-        try {
-            while ((len = is.read(buf)) > 0) {
-                os.write(buf, 0, len);
-            }
-        } catch (IOException e) {
-            lib.delete();
-            throw e;
-        } finally {
-            os.close();
-            is.close();
-        }
-
-        return lib;
-    }
-
-    /**
-     * Generate a list of candidate libraries for the supplied library name and suitable
-     * for the current platform.
-     *
-     * @param platform  Current platform.
-     * @param name      Library name.
-     *
-     * @return List of potential library names.
-     */
-    private List<String> libCandidates(Platform platform, String name) {
-        List<String> candidates = new ArrayList<String>();
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(libraryPath).append("/");
-        sb.append(platform.arch).append("/");
-        sb.append(platform.os).append("/");
-        sb.append("lib").append(name);
-
-        switch (platform.os) {
-            case darwin:
-                candidates.add(sb + ".dylib");
-                candidates.add(sb + ".jnilib");
-                break;
-            case linux:
-            case freebsd:
-                candidates.add(sb + ".so");
-                break;
-        }
-
-        return candidates;
-    }
-}
diff --git a/src/com/lambdaworks/jni/LibraryLoader.java b/src/com/lambdaworks/jni/LibraryLoader.java
deleted file mode 100644
index e84ee0a..0000000
--- a/src/com/lambdaworks/jni/LibraryLoader.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) 2011 - Will Glozer.  All rights reserved.
-
-package com.lambdaworks.jni;
-
-/**
- * A {@code LibraryLoader} attempts to load the appropriate native library
- * for the current platform.
- *
- * @author Will Glozer
- */
-public interface LibraryLoader {
-    /**
-     * Load a native library, and optionally verify any signatures.
-     *
-     * @param name      Name of the library to load.
-     * @param verify    Verify signatures if signed.
-     *
-     * @return true if the library was successfully loaded.
-     */
-    boolean load(String name, boolean verify);
-}
diff --git a/src/com/lambdaworks/jni/LibraryLoaders.java b/src/com/lambdaworks/jni/LibraryLoaders.java
deleted file mode 100644
index 82eea57..0000000
--- a/src/com/lambdaworks/jni/LibraryLoaders.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) 2011 - Will Glozer.  All rights reserved.
-
-package com.lambdaworks.jni;
-
-/**
- * {@code LibraryLoaders} will create the appropriate {@link LibraryLoader} for
- * the VM it is running on.
- *
- * @author Will Glozer
- */
-public class LibraryLoaders {
-    /**
-     * Create a new {@link LibraryLoader} for the current VM.
-     *
-     * @return the loader.
-     */
-    public static LibraryLoader loader() {
-        String vmSpec = System.getProperty("java.vm.specification.name");
-        return vmSpec.startsWith("Java") ? new JarLibraryLoader() : new SystemLibraryLoader();
-    }
-}
diff --git a/src/com/lambdaworks/jni/Platform.java b/src/com/lambdaworks/jni/Platform.java
deleted file mode 100644
index 953d593..0000000
--- a/src/com/lambdaworks/jni/Platform.java
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright (C) 2011 - Will Glozer.  All rights reserved.
-
-package com.lambdaworks.jni;
-
-import java.util.regex.Pattern;
-
-import static java.lang.System.getProperty;
-import static java.util.regex.Pattern.CASE_INSENSITIVE;
-
-/**
- * A platform is a unique combination of CPU architecture and operating system. This class
- * attempts to determine the platform it is executing on by examining and normalizing the
- * <code>os.arch</code> and <code>os.name</code> system properties.
- *
- * @author Will Glozer
- */
-public class Platform {
-    public enum Arch {
-        x86   ("x86|i386"),
-        x86_64("x86_64|amd64");
-
-        Pattern pattern;
-
-        Arch(String pattern) {
-            this.pattern = Pattern.compile("\\A" + pattern + "\\Z", CASE_INSENSITIVE);
-        }
-    }
-
-    public enum OS {
-        darwin ("darwin|mac os x"),
-        freebsd("freebsd"),
-        linux  ("linux");
-
-        Pattern pattern;
-
-        OS(String pattern) {
-            this.pattern = Pattern.compile("\\A" + pattern + "\\Z", CASE_INSENSITIVE);
-        }
-    }
-
-    public final Arch arch;
-    public final OS os;
-
-    private Platform(Arch arch, OS os) {
-        this.arch = arch;
-        this.os = os;
-    }
-
-    /**
-     * Attempt to detect the current platform.
-     *
-     * @return The current platform.
-     *
-     * @throws UnsupportedPlatformException if the platform cannot be detected.
-     */
-    public static Platform detect() throws UnsupportedPlatformException {
-        String osArch = getProperty("os.arch");
-        String osName = getProperty("os.name");
-
-        for (Arch arch : Arch.values()) {
-            if (arch.pattern.matcher(osArch).matches()) {
-                for (OS os : OS.values()) {
-                    if (os.pattern.matcher(osName).matches()) {
-                        return new Platform(arch, os);
-                    }
-                }
-            }
-        }
-
-        String msg = String.format("Unsupported platform %s %s", osArch, osName);
-        throw new UnsupportedPlatformException(msg);
-    }
-}
diff --git a/src/com/lambdaworks/jni/SystemLibraryLoader.java b/src/com/lambdaworks/jni/SystemLibraryLoader.java
deleted file mode 100644
index 0a5d7e8..0000000
--- a/src/com/lambdaworks/jni/SystemLibraryLoader.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (C) 2011 - Will Glozer.  All rights reserved.
-
-package com.lambdaworks.jni;
-
-/**
- * A native library loader that simply invokes {@link System#loadLibrary}. The shared
- * library path and filename are platform specific.
- *
- * @author Will Glozer
- */
-public class SystemLibraryLoader implements LibraryLoader {
-    /**
-     * Load a shared library.
-     *
-     * @param name      Name of the library to load.
-     * @param verify    Ignored, no verification is done.
-     *
-     * @return true if the library was successfully loaded.
-     */
-    public boolean load(String name, boolean verify) {
-        boolean loaded;
-
-        try {
-            System.loadLibrary(name);
-            loaded = true;
-        } catch (Throwable e) {
-            loaded = false;
-        }
-
-        return loaded;
-    }
-}
diff --git a/src/com/lambdaworks/jni/UnsupportedPlatformException.java b/src/com/lambdaworks/jni/UnsupportedPlatformException.java
deleted file mode 100644
index da0a53a..0000000
--- a/src/com/lambdaworks/jni/UnsupportedPlatformException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (C) 2011 - Will Glozer.  All rights reserved.
-
-package com.lambdaworks.jni;
-
-/**
- * Exception thrown when the current platform cannot be detected.
- *
- * @author Will Glozer
- */
-public class UnsupportedPlatformException extends RuntimeException {
-    public UnsupportedPlatformException(String s) {
-        super(s);
-    }
-}
diff --git a/src/crackstation/PBKDF2/PasswordHash.java b/src/crackstation/PBKDF2/PasswordHash.java
index e4e51ea..c8570ec 100644
--- a/src/crackstation/PBKDF2/PasswordHash.java
+++ b/src/crackstation/PBKDF2/PasswordHash.java
@@ -1,3 +1,5 @@
+package crackstation.PBKDF2;
+
 import java.security.SecureRandom;
 import javax.crypto.spec.PBEKeySpec;
 import javax.crypto.SecretKeyFactory;
@@ -9,6 +11,10 @@ import java.security.spec.InvalidKeySpecException;
  * PBKDF2 salted password hashing.
  * Author: havoc AT defuse.ca
  * www: http://crackstation.net/hashing-security.htm
+ *
+ * Note:
+ * Modified version with additional createHash methods
+ * to receive arguments Iterations,SaltBytes,HashBytes;
  */
 public class PasswordHash
 {
@@ -17,7 +23,7 @@ public class PasswordHash
     // The following constants may be changed without breaking existing hashes.
     public static final int SALT_BYTES = 24;
     public static final int HASH_BYTES = 24;
-    public static final int PBKDF2_ITERATIONS = 1000;
+    public static final int PBKDF2_ITERATIONS = 86000;
 
     public static final int ITERATION_INDEX = 0;
     public static final int SALT_INDEX = 1;
@@ -32,7 +38,27 @@ public class PasswordHash
     public static String createHash(String password)
         throws NoSuchAlgorithmException, InvalidKeySpecException
     {
-        return createHash(password.toCharArray());
+        return createHash(password.toCharArray(),null,null,null);
+    }
+
+    /**
+     * Returns a salted PBKDF2 hash of the password.
+     *
+     * @param   password    the password to hash
+     * @param   Iterations  the number of hash iterations. Default 1000
+     * @param   SaltBytes   the size of the salt. Default 24 bytes.
+     * @param   HashBytes   the size of the hash. Default 24 bytes.
+     * @return              a salted PBKDF2 hash of the password
+     */
+    public static String createHash
+    	( String  password
+    	, Integer Iterations
+    	, Integer SaltBytes
+    	, Integer HashBytes
+    	)
+        throws NoSuchAlgorithmException, InvalidKeySpecException
+    {
+        return createHash(password.toCharArray(),Iterations,SaltBytes,HashBytes);
     }
 
     /**
@@ -44,15 +70,39 @@ public class PasswordHash
     public static String createHash(char[] password)
         throws NoSuchAlgorithmException, InvalidKeySpecException
     {
+        return createHash(password,null,null,null);
+    }
+
+    /**
+     * Returns a salted PBKDF2 hash of the password.
+     *
+     * @param   password    the password to hash
+     * @param   Iterations  the number of hash iterations. Default 1000
+     * @param   SaltBytes   the size of the salt. Default 24 bytes.
+     * @param   HashBytes   the size of the hash. Default 24 bytes.
+     * @return              a salted PBKDF2 hash of the password
+     */
+    public static String createHash
+    	( char[]  password
+    	, Integer Iterations
+    	, Integer SaltBytes
+    	, Integer HashBytes
+    	)
+        throws NoSuchAlgorithmException, InvalidKeySpecException
+    {
+    	if (Iterations == null) Iterations = PBKDF2_ITERATIONS;
+    	if (SaltBytes  == null) SaltBytes  = SALT_BYTES;
+    	if (HashBytes  == null) HashBytes  = HASH_BYTES;
+    	
         // Generate a random salt
         SecureRandom random = new SecureRandom();
-        byte[] salt = new byte[SALT_BYTES];
+        byte[] salt = new byte[SaltBytes];
         random.nextBytes(salt);
 
         // Hash the password
-        byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTES);
+        byte[] hash = pbkdf2(password, salt, Iterations, HashBytes);
         // format iterations:salt:hash
-        return PBKDF2_ITERATIONS + ":" + toHex(salt) + ":" +  toHex(hash);
+        return Iterations + ":" + toHex(salt) + ":" +  toHex(hash);
     }
 
     /**
@@ -158,50 +208,4 @@ public class PasswordHash
             return hex;
     }
 
-    /**
-     * Tests the basic functionality of the PasswordHash class
-     *
-     * @param   args        ignored
-     */
-    public static void main(String[] args)
-    {
-        try
-        {
-            // Print out 10 hashes
-            for(int i = 0; i < 10; i++)
-                System.out.println(PasswordHash.createHash("p\r\nassw0Rd!"));
-
-            // Test password validation
-            boolean failure = false;
-            System.out.println("Running tests...");
-            for(int i = 0; i < 100; i++)
-            {
-                String password = ""+i;
-                String hash = createHash(password);
-                String secondHash = createHash(password);
-                if(hash.equals(secondHash)) {
-                    System.out.println("FAILURE: TWO HASHES ARE EQUAL!");
-                    failure = true;
-                }
-                String wrongPassword = ""+(i+1);
-                if(validatePassword(wrongPassword, hash)) {
-                    System.out.println("FAILURE: WRONG PASSWORD ACCEPTED!");
-                    failure = true;
-                }
-                if(!validatePassword(password, hash)) {
-                    System.out.println("FAILURE: GOOD PASSWORD NOT ACCEPTED!");
-                    failure = true;
-                }
-            }
-            if(failure)
-                System.out.println("TESTS FAILED!");
-            else
-                System.out.println("TESTS PASSED!");
-        }
-        catch(Exception ex)
-        {
-            System.out.println("ERROR: " + ex);
-        }
-    }
-
-}
+}
\ No newline at end of file
diff --git a/src/mindrot/jbcrypt/BCrypt.java b/src/mindrot/jbcrypt/BCrypt.java
index b4d676c..ebfb3be 100644
--- a/src/mindrot/jbcrypt/BCrypt.java
+++ b/src/mindrot/jbcrypt/BCrypt.java
@@ -1,3 +1,5 @@
+package mindrot.jbcrypt;
+
 // Copyright (c) 2006 Damien Miller <djm@mindrot.org>
 //
 // Permission to use, copy, modify, and distribute this software for any
@@ -52,7 +54,7 @@ import java.security.SecureRandom;
  * String stronger_salt = BCrypt.gensalt(12)<br />
  * </code>
  * <p>
- * The amount of work increases exponentially (2**log_rounds), so 
+ * The amount of work increases exponentially (2**log_rounds), so
  * each increment is twice as much work. The default log_rounds is
  * 10, and the valid range is 4 to 31.
  *
@@ -61,7 +63,7 @@ import java.security.SecureRandom;
  */
 public class BCrypt {
 	// BCrypt parameters
-	private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 10;
+	private static final int GENSALT_DEFAULT_LOG2_ROUNDS = 16;
 	private static final int BCRYPT_SALT_LEN = 16;
 
 	// Blowfish parameters
@@ -747,4 +749,4 @@ public class BCrypt {
 	public static boolean checkpw(String plaintext, String hashed) {
 		return (hashed.compareTo(hashpw(plaintext, hashed)) == 0);
 	}
-}
+}
\ No newline at end of file
diff --git a/src/mindrot/jbcrypt/LICENSE b/src/mindrot/jbcrypt/LICENSE
deleted file mode 100644
index bf0d67b..0000000
--- a/src/mindrot/jbcrypt/LICENSE
+++ /dev/null
@@ -1,18 +0,0 @@
-jBCrypt is subject to the following license:
-
-/*
- * Copyright (c) 2006 Damien Miller <djm@mindrot.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
diff --git a/src/mindrot/jbcrypt/README b/src/mindrot/jbcrypt/README
deleted file mode 100644
index 2ceb74d..0000000
--- a/src/mindrot/jbcrypt/README
+++ /dev/null
@@ -1,38 +0,0 @@
-jBCrypt is an implementation the OpenBSD Blowfish password hashing
-algorithm, as described in "A Future-Adaptable Password Scheme" by Niels
-Provos and David Mazieres: http://www.openbsd.org/papers/bcrypt-paper.ps
-
-This system hashes passwords using a version of Bruce Schneier's
-Blowfish block cipher with modifications designed to raise the cost of
-off-line password cracking. The computation cost of the algorithm is
-parameterised, so it can be increased as computers get faster.
-
-JUnit regression tests are available in in TestBCrypt.java
-
-jBCrypt is licensed under a ISC/BSD licence. See the LICENSE file for details.
-
-Please report bugs to Damien Miller <djm@mindrot.org>. Please check the
-TODO file first, in case your problem is something I already know about
-(please send patches!)
-
-A simple example that demonstrates most of the features:
-
-	// Hash a password for the first time
-	String hashed = BCrypt.hashpw(password, BCrypt.gensalt());
-
-	// gensalt's log_rounds parameter determines the complexity
-	// the work factor is 2**log_rounds, and the default is 10
-	String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12));
-
-	// Check that an unencrypted password matches one that has
-	// previously been hashed
-	if (BCrypt.checkpw(candidate, hashed))
-		System.out.println("It matches");
-	else
-		System.out.println("It does not match");
-
-There is also a C#/.NET port by Derek Slager:
-
-http://derekslager.com/blog/posts/2007/10/bcrypt-dotnet-strong-password-hashing-for-dotnet-and-mono.ashx
-
-$Id: README,v 1.3 2008/04/10 11:02:25 djm Exp $
diff --git a/src/mindrot/jbcrypt/TODO b/src/mindrot/jbcrypt/TODO
deleted file mode 100644
index 230b322..0000000
--- a/src/mindrot/jbcrypt/TODO
+++ /dev/null
@@ -1,4 +0,0 @@
-nothing yet
-
-$Id: TODO,v 1.1.1.1 2006/05/24 05:23:22 djm Exp $
-
diff --git a/src/mindrot/jbcrypt/TestBCrypt.java b/src/mindrot/jbcrypt/TestBCrypt.java
deleted file mode 100644
index c481ff3..0000000
--- a/src/mindrot/jbcrypt/TestBCrypt.java
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright (c) 2006 Damien Miller <djm@mindrot.org>
-//
-// Permission to use, copy, modify, and distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import junit.framework.TestCase;
-
-/**
- * JUnit unit tests for BCrypt routines
- * @author Damien Miller
- * @version 0.2
- */
-public class TestBCrypt extends TestCase {
-	String test_vectors[][] = {
-			{ "", 
-			"$2a$06$DCq7YPn5Rq63x1Lad4cll.",
-			"$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s." },
-			{ "",
-			"$2a$08$HqWuK6/Ng6sg9gQzbLrgb.",
-			"$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye" },
-			{ "",
-			"$2a$10$k1wbIrmNyFAPwPVPSVa/ze",
-			"$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW" },
-			{ "",
-			"$2a$12$k42ZFHFWqBp3vWli.nIn8u",
-			"$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO" },
-			{ "a",
-			"$2a$06$m0CrhHm10qJ3lXRY.5zDGO",
-			"$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe" },
-			{ "a", 
-			"$2a$08$cfcvVd2aQ8CMvoMpP2EBfe",
-			"$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V." },
-			{ "a",
-			"$2a$10$k87L/MF28Q673VKh8/cPi.",
-			"$2a$10$k87L/MF28Q673VKh8/cPi.SUl7MU/rWuSiIDDFayrKk/1tBsSQu4u" },
-			{ "a",
-			"$2a$12$8NJH3LsPrANStV6XtBakCe",
-			"$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS" },
-			{ "abc",
-			"$2a$06$If6bvum7DFjUnE9p2uDeDu",
-			"$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i" },
-			{ "abc",
-			"$2a$08$Ro0CUfOqk6cXEKf3dyaM7O",
-			"$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm" },
-			{ "abc",
-			"$2a$10$WvvTPHKwdBJ3uk0Z37EMR.",
-			"$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi" },
-			{ "abc",
-			"$2a$12$EXRkfkdmXn2gzds2SSitu.",
-			"$2a$12$EXRkfkdmXn2gzds2SSitu.MW9.gAVqa9eLS1//RYtYCmB1eLHg.9q" },
-			{ "abcdefghijklmnopqrstuvwxyz",
-			"$2a$06$.rCVZVOThsIa97pEDOxvGu",
-			"$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC" },
-			{ "abcdefghijklmnopqrstuvwxyz",
-			"$2a$08$aTsUwsyowQuzRrDqFflhge",
-			"$2a$08$aTsUwsyowQuzRrDqFflhgekJ8d9/7Z3GV3UcgvzQW3J5zMyrTvlz." },
-			{ "abcdefghijklmnopqrstuvwxyz",
-			"$2a$10$fVH8e28OQRj9tqiDXs1e1u",
-			"$2a$10$fVH8e28OQRj9tqiDXs1e1uxpsjN0c7II7YPKXua2NAKYvM6iQk7dq" },
-			{ "abcdefghijklmnopqrstuvwxyz",
-			"$2a$12$D4G5f18o7aMMfwasBL7Gpu",
-			"$2a$12$D4G5f18o7aMMfwasBL7GpuQWuP3pkrZrOAnqP.bmezbMng.QwJ/pG" },
-			{ "~!@#$%^&*()      ~!@#$%^&*()PNBFRD",
-			"$2a$06$fPIsBO8qRqkjj273rfaOI.",
-			"$2a$06$fPIsBO8qRqkjj273rfaOI.HtSV9jLDpTbZn782DC6/t7qT67P6FfO" },
-			{ "~!@#$%^&*()      ~!@#$%^&*()PNBFRD",
-			"$2a$08$Eq2r4G/76Wv39MzSX262hu",
-			"$2a$08$Eq2r4G/76Wv39MzSX262huzPz612MZiYHVUJe/OcOql2jo4.9UxTW" },
-			{ "~!@#$%^&*()      ~!@#$%^&*()PNBFRD",
-			"$2a$10$LgfYWkbzEvQ4JakH7rOvHe",
-			"$2a$10$LgfYWkbzEvQ4JakH7rOvHe0y8pHKF9OaFgwUZ2q7W2FFZmZzJYlfS" },
-			{ "~!@#$%^&*()      ~!@#$%^&*()PNBFRD",
-			"$2a$12$WApznUOJfkEGSmYRfnkrPO",
-			"$2a$12$WApznUOJfkEGSmYRfnkrPOr466oFDCaj4b6HY3EXGvfxm43seyhgC" },
-		};
-
-	/**
-	 * Entry point for unit tests
-	 * @param args unused
-	 */
-	public static void main(String[] args) {
-		junit.textui.TestRunner.run(TestBCrypt.class);
-	}
-
-	/**
-	 * Test method for 'BCrypt.hashpw(String, String)'
-	 */
-	public void testHashpw() {
-		System.out.print("BCrypt.hashpw(): ");
-		for (int i = 0; i < test_vectors.length; i++) {
-			String plain = test_vectors[i][0];
-			String salt = test_vectors[i][1];
-			String expected = test_vectors[i][2];
-			String hashed = BCrypt.hashpw(plain, salt);
-			assertEquals(hashed, expected);
-			System.out.print(".");
-		}
-		System.out.println("");
-	}
-
-	/**
-	 * Test method for 'BCrypt.gensalt(int)'
-	 */
-	public void testGensaltInt() {
-		System.out.print("BCrypt.gensalt(log_rounds):");
-		for (int i = 4; i <= 12; i++) {
-			System.out.print(" " + Integer.toString(i) + ":");
-			for (int j = 0; j < test_vectors.length; j += 4) {
-				String plain = test_vectors[j][0];
-				String salt = BCrypt.gensalt(i);
-				String hashed1 = BCrypt.hashpw(plain, salt);
-				String hashed2 = BCrypt.hashpw(plain, hashed1);
-				assertEquals(hashed1, hashed2);
-				System.out.print(".");
-			}
-		}
-		System.out.println("");
-	}
-
-	/**
-	 * Test method for 'BCrypt.gensalt()'
-	 */
-	public void testGensalt() {
-		System.out.print("BCrypt.gensalt(): ");
-		for (int i = 0; i < test_vectors.length; i += 4) {
-			String plain = test_vectors[i][0];
-			String salt = BCrypt.gensalt();
-			String hashed1 = BCrypt.hashpw(plain, salt);
-			String hashed2 = BCrypt.hashpw(plain, hashed1);
-			assertEquals(hashed1, hashed2);
-			System.out.print(".");
-		}
-		System.out.println("");
-	}
-
-	/**
-	 * Test method for 'BCrypt.checkpw(String, String)'
-	 * expecting success
-	 */
-	public void testCheckpw_success() {
-		System.out.print("BCrypt.checkpw w/ good passwords: ");
-		for (int i = 0; i < test_vectors.length; i++) {
-			String plain = test_vectors[i][0];
-			String expected = test_vectors[i][2];
-			assertTrue(BCrypt.checkpw(plain, expected));
-			System.out.print(".");
-		}
-		System.out.println("");
-	}
-
-	/**
-	 * Test method for 'BCrypt.checkpw(String, String)'
-	 * expecting failure
-	 */
-	public void testCheckpw_failure() {
-		System.out.print("BCrypt.checkpw w/ bad passwords: ");
-		for (int i = 0; i < test_vectors.length; i++) {
-			int broken_index = (i + 4) % test_vectors.length;
-			String plain = test_vectors[i][0];
-			String expected = test_vectors[broken_index][2];
-			assertFalse(BCrypt.checkpw(plain, expected));
-			System.out.print(".");
-		}
-		System.out.println("");
-	}
-
-	/**
-	 * Test for correct hashing of non-US-ASCII passwords
-	 */
-	public void testInternationalChars() {
-		System.out.print("BCrypt.hashpw w/ international chars: ");
-		String pw1 = "ππππππππ";
-		String pw2 = "????????";
-
-		String h1 = BCrypt.hashpw(pw1, BCrypt.gensalt());
-		assertFalse(BCrypt.checkpw(pw2, h1));
-		System.out.print(".");
-
-		String h2 = BCrypt.hashpw(pw2, BCrypt.gensalt());
-		assertFalse(BCrypt.checkpw(pw1, h2));
-		System.out.print(".");
-		System.out.println("");
-	}
-
-}