This is a very good and very fast primality check. - Java java.lang

Java examples for java.lang:int prime

Description

This is a very good and very fast primality check.

Demo Code


//package com.java2s;

import java.math.BigInteger;
import java.security.SecureRandom;

public class Main {
    /** Convienence variable for the BigInteger Zero */
    private static BigInteger ZERO_INT = new BigInteger("0");
    /** Convienence variable for the BigInteger One */
    private static BigInteger ONE_INT = new BigInteger("1");
    /** Convienence variable for the BigInteger Two */
    private static BigInteger TWO_INT = new BigInteger("2");

    /**/*  ww  w . j a  va  2 s .  c  om*/
     * This is a very good and very fast primality check.  It is remarkably accurate
     * when using around 100 witneses.  The accuracy is 2^(-k)
     * 
     * <br>
     * <br>
     * 
     * Read more about it here <br>
     * 
     * <a href="http://en.wikipedia.org/wiki/Solovay-Strassen_primality_test">
     * http://en.wikipedia.org/wiki/Solovay-Strassen_primality_test </a><br>
     * 
     * <dd><b>Inputs </b>: <i>n </i>: a value to test for primality; <i>k </i>:
     * a parameter that determines the accuracy of the test</dd>
     * <dd><b>Output </b>: <u>composite </u> if <i>n </i> is composite,
     * otherwise <u>probably prime </u></dd>
     * 
     * <dd>repeat <i>k </i> times:
     * <dl>
     * <dd><i>x </i>&lsaquo;&mdash; ( <i>a </i>/ <i>n </i>)</dd>
     * <dd>if <i>x </i>= 0 or <i>a </i> <sup>( <i>n</i>-1)/2 </sup> mod
     * <i>n </i> <> <i>x </i> then return <u>composite </u></dd>
     * 
     * </dl>
     * </dd>
     * <dd>return <u>probably prime </u></dd>
     * 
     * @param n The number to check for primality
     * @param w The number of witnesses
     * @return true if the number is most likely prime given the number of
     *         witnesses w.
     */
    public static boolean checkSolovayStrassen(BigInteger n, int w) {
        boolean rval = true;
        BigInteger n_minus_one = n.subtract(ONE_INT);
        BigInteger tmp;
        SecureRandom srnd = new SecureRandom();
        for (int i = 0; i < w && rval; i++) {
            BigInteger a = new BigInteger(n.subtract(TWO_INT).bitCount(),
                    srnd).add(TWO_INT);
            int x = jacobiSymbol(a, n);
            BigInteger X = new BigInteger(x + "");
            tmp = a.modPow(n_minus_one.divide(TWO_INT), n);
            if (x == 0 || (tmp.compareTo(X) != 0)
                    && (tmp.compareTo(n_minus_one) != 0)) {
                rval = false;
            }
        }
        return rval;
    }

    /**
     * Computes the Jacobi Symbol of two integers a and n<br>
     * 
     * <dd><b>Inputs </b>: <i>a </i>: the numerator for the Jacobi Symbol; <i>n </i>:
     * the odd denominator for the Jacobi Symbol</dd>
     * <dd><b>Output </b>: <u>-1</u>, <u>0</u> or <u>1</u></dd>
     * 
     * <dl>
     * <dt>Jacobi(<i>a</i>,<i>n</i>) {</dt>
     * <dd><i>j</i> := 1</dd>
     * <dd>while (<i>a</i> not 0) do {</dd>
     * <dl>
     * <dd>while (<i>a</i> even) do {</dd>
     * <dd>
     * <dl>
     * <dd><i>a</i> := <i>a</i>/2</dd>
     * <dd>if (<i>n</i> = 3 (mod 8) or <i>n</i> = 5 (mod 8)) then <i>j</i> := -<i>j</i></dd>
     * </dl>
     * </dd>
     * <dd>}</dd>
     * <dd>interchange(<i>a</i>,<i>n</i>)</dd>
     * <dd>if (<i>a</i> = 3 (mod 4) and <i>n</i> = 3 (mod 4)) then <i>j</i> := -<i>j</i></dd>
     * <dd><i>a</i> := <i>a</i> mod <i>n</i></dd>
     * </dl>
     * <dd>}</dd>
     * <dd>if (<i>n</i> = 1) then return (<i>j</i>) else return(0)</dd>
     * <dt>}</dt>
     * </dl>
     * 
     * @param a
     *            any number greater than or equal to one and less than n
     * @param n
     *            any odd number
     * @return the value of the jacobi symbol (a/n)
     */
    public static int jacobiSymbol(BigInteger a, BigInteger n) {
        int j = 1;
        BigInteger THREE = new BigInteger("3");
        BigInteger FOUR = new BigInteger("4");
        BigInteger FIVE = new BigInteger("5");
        BigInteger EIGHT = new BigInteger("8");
        BigInteger res;
        BigInteger temp;
        while (a.compareTo(ZERO_INT) != 0) {
            while (a.mod(TWO_INT).compareTo(ZERO_INT) == 0) {
                a = a.divide(TWO_INT);
                res = n.mod(EIGHT);
                if (res.compareTo(THREE) == 0 || res.compareTo(FIVE) == 0) {
                    j = -1 * j;
                }
            }
            temp = a;
            a = n;
            n = temp;

            if (a.mod(FOUR).compareTo(THREE) == 0
                    && n.mod(FOUR).compareTo(THREE) == 0) {
                j = -1 * j;
            }
            a = a.mod(n);
        }

        if (n.compareTo(ONE_INT) != 0)
            j = 0;

        return j;
    }
}

Related Tutorials