⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 biginteger.java

📁 整体思路 用createkey.java 文件来产生秘钥
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    }    // Create an integer with the digits between the two indexes    // Assumes start < end. The result may be negative, but it    // is to be treated as an unsigned value.    private int parseInt(char[] source, int start, int end) {        int result = Character.digit(source[start++], 10);        if (result == -1)            throw new NumberFormatException(new String(source));        for (int index = start; index<end; index++) {            int nextVal = Character.digit(source[index], 10);            if (nextVal == -1)                throw new NumberFormatException(new String(source));            result = 10*result + nextVal;        }        return result;    }    // bitsPerDigit in the given radix times 1024    // Rounded up to avoid underallocation.    private static long bitsPerDigit[] = { 0, 0,        1024, 1624, 2048, 2378, 2648, 2875, 3072, 3247, 3402, 3543, 3672,        3790, 3899, 4001, 4096, 4186, 4271, 4350, 4426, 4498, 4567, 4633,        4696, 4756, 4814, 4870, 4923, 4975, 5025, 5074, 5120, 5166, 5210,                                           5253, 5295};    // Multiply x array times word y in place, and add word z    private static void destructiveMulAdd(int[] x, int y, int z) {        // Perform the multiplication word by word        long ylong = y & LONG_MASK;        long zlong = z & LONG_MASK;        int len = x.length;        long product = 0;        long carry = 0;        for (int i = len-1; i >= 0; i--) {            product = ylong * (x[i] & LONG_MASK) + carry;            x[i] = (int)product;            carry = product >>> 32;        }        // Perform the addition        long sum = (x[len-1] & LONG_MASK) + zlong;        x[len-1] = (int)sum;        carry = sum >>> 32;        for (int i = len-2; i >= 0; i--) {            sum = (x[i] & LONG_MASK) + carry;            x[i] = (int)sum;            carry = sum >>> 32;        }    }    /**     * Translates the decimal String representation of a BigInteger into a     * BigInteger.  The String representation consists of an optional minus     * sign followed by a sequence of one or more decimal digits.  The     * character-to-digit mapping is provided by <tt>Character.digit</tt>.     * The String may not contain any extraneous characters (whitespace, for     * example).     *     * @param val decimal String representation of BigInteger.     * @throws NumberFormatException <tt>val</tt> is not a valid representation     *	       of a BigInteger.     * @see    Character#digit     */    public BigInteger(String val) {	this(val, 10);    }    /**     * Constructs a randomly generated BigInteger, uniformly distributed over     * the range <tt>0</tt> to <tt>(2<sup>numBits</sup> - 1)</tt>, inclusive.     * The uniformity of the distribution assumes that a fair source of random     * bits is provided in <tt>rnd</tt>.  Note that this constructor always     * constructs a non-negative BigInteger.     *     * @param  numBits maximum bitLength of the new BigInteger.     * @param  rnd source of randomness to be used in computing the new     *	       BigInteger.     * @throws IllegalArgumentException <tt>numBits</tt> is negative.     * @see #bitLength     */    public BigInteger(int numBits, Random rnd) {	this(1, randomBits(numBits, rnd));    }    private static byte[] randomBits(int numBits, Random rnd) {	if (numBits < 0)	    throw new IllegalArgumentException("numBits must be non-negative");	int numBytes = (numBits+7)/8;	byte[] randomBits = new byte[numBytes];	// Generate random bytes and mask out any excess bits	if (numBytes > 0) {	    rnd.nextBytes(randomBits);	    int excessBits = 8*numBytes - numBits;	    randomBits[0] &= (1 << (8-excessBits)) - 1;	}	return randomBits;    }    /**     * Constructs a randomly generated positive BigInteger that is probably     * prime, with the specified bitLength.<p>     *     * It is recommended that the {@link #probablePrime probablePrime}     * method be used in preference to this constructor unless there     * is a compelling need to specify a certainty.     *     * @param  bitLength bitLength of the returned BigInteger.     * @param  certainty a measure of the uncertainty that the caller is     *         willing to tolerate.  The probability that the new BigInteger     *	       represents a prime number will exceed     *	       <tt>(1 - 1/2<sup>certainty</sup></tt>).  The execution time of     *	       this constructor is proportional to the value of this parameter.     * @param  rnd source of random bits used to select candidates to be     *	       tested for primality.     * @throws ArithmeticException <tt>bitLength &lt; 2</tt>.     * @see    #bitLength     */    public BigInteger(int bitLength, int certainty, Random rnd) {        BigInteger prime;	if (bitLength < 2)	    throw new ArithmeticException("bitLength < 2");        // The cutoff of 95 was chosen empirically for best performance        prime = (bitLength < 95 ? smallPrime(bitLength, certainty, rnd)                                : largePrime(bitLength, certainty, rnd));	signum = 1;	mag = prime.mag;    }    // Minimum size in bits that the requested prime number has    // before we use the large prime number generating algorithms    private static final int SMALL_PRIME_THRESHOLD = 95;    // Certainty required to meet the spec of probablePrime    private static final int DEFAULT_PRIME_CERTAINTY = 100;    /**     * Returns a positive BigInteger that is probably prime, with the     * specified bitLength. The probability that a BigInteger returned     * by this method is composite does not exceed 2<sup>-100</sup>.     *     * @param  bitLength bitLength of the returned BigInteger.     * @param  rnd source of random bits used to select candidates to be     *	       tested for primality.     * @return a BigInteger of <tt>bitLength</tt> bits that is probably prime     * @throws ArithmeticException <tt>bitLength &lt; 2</tt>.     * @see    #bitLength     */    public static BigInteger probablePrime(int bitLength, Random rnd) {	if (bitLength < 2)	    throw new ArithmeticException("bitLength < 2");        // The cutoff of 95 was chosen empirically for best performance        return (bitLength < SMALL_PRIME_THRESHOLD ?                smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :                largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));    }    /**     * Find a random number of the specified bitLength that is probably prime.     * This method is used for smaller primes, its performance degrades on     * larger bitlengths.     *     * This method assumes bitLength > 1.     */    private static BigInteger smallPrime(int bitLength, int certainty, Random rnd) {        int magLen = (bitLength + 31) >>> 5;        int temp[] = new int[magLen];        int highBit = 1 << ((bitLength+31) & 0x1f);  // High bit of high int        int highMask = (highBit << 1) - 1;  // Bits to keep in high int        while(true) {            // Construct a candidate            for (int i=0; i<magLen; i++)                temp[i] = rnd.nextInt();            temp[0] = (temp[0] & highMask) | highBit;  // Ensure exact length            if (bitLength > 2)                temp[magLen-1] |= 1;  // Make odd if bitlen > 2            BigInteger p = new BigInteger(temp, 1);            // Do cheap "pre-test" if applicable            if (bitLength > 6) {                long r = p.remainder(SMALL_PRIME_PRODUCT).longValue();                if ((r%3==0)  || (r%5==0)  || (r%7==0)  || (r%11==0) ||                     (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) ||                     (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0))                    continue; // Candidate is composite; try another            }                        // All candidates of bitLength 2 and 3 are prime by this point            if (bitLength < 4)                return p;            // Do expensive test if we survive pre-test (or it's inapplicable)            if (p.primeToCertainty(certainty))                return p;        }    }    private static final BigInteger SMALL_PRIME_PRODUCT                       = valueOf(3L*5*7*11*13*17*19*23*29*31*37*41);    /**     * Find a random number of the specified bitLength that is probably prime.     * This method is more appropriate for larger bitlengths since it uses     * a sieve to eliminate most composites before using a more expensive     * test.     */    private static BigInteger largePrime(int bitLength, int certainty, Random rnd) {        BigInteger p;        p = new BigInteger(bitLength, rnd).setBit(bitLength-1);        p.mag[p.mag.length-1] &= 0xfffffffe;        // Use a sieve length likely to contain the next prime number        int searchLen = (bitLength / 20) * 64;        BitSieve searchSieve = new BitSieve(p, searchLen);        BigInteger candidate = searchSieve.retrieve(p, certainty);        while ((candidate == null) || (candidate.bitLength() != bitLength)) {            p = p.add(BigInteger.valueOf(2*searchLen));            if (p.bitLength() != bitLength)                p = new BigInteger(bitLength, rnd).setBit(bitLength-1);            p.mag[p.mag.length-1] &= 0xfffffffe;            searchSieve = new BitSieve(p, searchLen);            candidate = searchSieve.retrieve(p, certainty);        }        return candidate;    }   /**    * Returns the first integer greater than this <code>BigInteger</code> that    * is probably prime.  The probability that the number returned by this    * method is composite does not exceed 2<sup>-100</sup>. This method will    * never skip over a prime when searching: if it returns <tt>p</tt>, there    * is no prime <tt>q</tt> such that <tt>this &lt; q &lt; p</tt>.    *    * @return the first integer greater than this <code>BigInteger</code> that    *         is probably prime.    * @throws ArithmeticException <tt>this &lt; 0</tt>.    * @since 1.5    */    public BigInteger nextProbablePrime() {        if (this.signum < 0)            throw new ArithmeticException("start < 0: " + this);                // Handle trivial cases        if ((this.signum == 0) || this.equals(ONE))            return TWO;        BigInteger result = this.add(ONE);        // Fastpath for small numbers        if (result.bitLength() < SMALL_PRIME_THRESHOLD) {             // Ensure an odd number            if (!result.testBit(0))                result = result.add(ONE);            while(true) {                // Do cheap "pre-test" if applicable                if (result.bitLength() > 6) {                    long r = result.remainder(SMALL_PRIME_PRODUCT).longValue();                    if ((r%3==0)  || (r%5==0)  || (r%7==0)  || (r%11==0) ||                         (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) ||                         (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0)) {                        result = result.add(TWO);                        continue; // Candidate is composite; try another                    }                }                            // All candidates of bitLength 2 and 3 are prime by this point                if (result.bitLength() < 4)                    return result;                // The expensive test                if (result.primeToCertainty(DEFAULT_PRIME_CERTAINTY))                    return result;                result = result.add(TWO);            }        }        // Start at previous even number        if (result.testBit(0))            result = result.subtract(ONE);        // Looking for the next large prime        int searchLen = (result.bitLength() / 20) * 64;        while(true) {           BitSieve searchSieve = new BitSieve(result, searchLen);           BigInteger candidate = searchSieve.retrieve(result,                                                     DEFAULT_PRIME_CERTAINTY);           if (candidate != null)               return candidate;           result = result.add(BigInteger.valueOf(2 * searchLen));        }    }    /**     * Returns <tt>true</tt> if this BigInteger is probably prime,     * <tt>false</tt> if it's definitely composite.     *     * This method assumes bitLength > 2.     *     * @param  certainty a measure of the uncertainty that the caller is     *	       willing to tolerate: if the call returns <tt>true</tt>     *	       the probability that this BigInteger is prime exceeds     *	       <tt>(1 - 1/2<sup>certainty</sup>)</tt>.  The execution time of     * 	       this method is proportional to the value of this parameter.     * @return <tt>true</tt> if this BigInteger is probably prime,     * 	       <tt>false</tt> if it's definitely composite.     */    boolean primeToCertainty(int certainty) {        int rounds = 0;        int n = (Math.min(certainty, Integer.MAX_VALUE-1)+1)/2;        // The relationship between the certainty and the number of rounds        // we perform is given in the draft standard ANSI X9.80, "PRIME        // NUMBER GENERATION, PRIMALITY TESTING, AND PRIMALITY CERTIFICATES".        int sizeInBits = this.bitLength();        if (sizeInBits < 100) {            rounds = 50;            rounds = n < rounds ? n : rounds;            return passesMillerRabin(rounds);        }        if (sizeInBits < 256) {            rounds = 27;        } else if (sizeInBits < 512) {            rounds = 15;        } else if (sizeInBits < 768) {            rounds = 8;        } else if (sizeInBits < 1024) {            rounds = 4;        } else {            rounds = 2;        }        rounds = n < rounds ? n : rounds;        return passesMillerRabin(rounds) && passesLucasLehmer();    }    /**     * Returns true iff this BigInteger is a Lucas-Lehmer probable prime.     *     * The following assumptions are made:     * This BigInteger is a positive, odd number.     */    private boolean passesLucasLehmer() {        BigInteger thisPlusOne = this.add(ONE);        // Step 1        int d = 5;        while (jacobiSymbol(d, this) != -1) {            // 5, -7, 9, -11, ...            d = (d<0) ? Math.abs(d)+2 : -(d+2);        }                // Step 2        BigInteger u = lucasLehmerSequence(d, thisPlusOne, this);        // Step 3        return u.mod(this).equals(ZERO);    }    /**     * Computes Jacobi(p,n).     * Assumes n positive, odd, n>=3.     */    private static int jacobiSymbol(int p, BigInteger n) {        if (p == 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -