private static boolean runMillerRabin(BigInteger number, SecureRandom random) {
        if (number.compareTo(BigInteger.valueOf(3)) <= 0) {
            return number.compareTo(BigInteger.ONE) != 0;
        }

        // Ensures that temp > 1 and temp < n.
        BigInteger temp = BigInteger.ZERO;
        do {
            temp = new BigInteger(number.bitLength() - 1, random);
        } while (temp.compareTo(BigInteger.ONE) <= 0);

        // Screen out n if our random number happens to share a factor with n.
        if (!number.gcd(temp).equals(BigInteger.ONE)) {
            return false;
        }
        // For debugging, prints out the integer to test with.
        //System.out.println("Testing with " + temp);

        BigInteger d = number.subtract(BigInteger.ONE);

        // Figure s and d Values
        int s = 0;
        while ((d.mod(TWO)).equals(BigInteger.ZERO)) {
            d = d.divide(TWO);
            s++;
        }

        BigInteger curValue = temp.modPow(d, number);

        // If this works out, it's a prime
        if (curValue.equals(BigInteger.ONE)) {
            return true;
        }

        // Otherwise, we will check to see if this value successively 
        // squared ever yields -1.
        for (int r = 0; r < s; r++) {

            // We need to really check n-1 which is equivalent to -1.
            if (curValue.equals(number.subtract(BigInteger.ONE))) {
                return true;
            } // Square this previous number - here I am just doubling the 
            // exponent. A more efficient implementation would store the
            // value of the exponentiation and square it mod n.
            else {
                curValue = curValue.modPow(TWO, number);
            }
        }

        // If none of our tests pass, we return false. The number is 
        // definitively composite if we ever get here.
        return false;
    }