示例#1
0
        internal static BigInteger evenModPow(BigInteger _base, BigInteger exponent,
                                              BigInteger modulus)
        {
            // PRE: (base > 0), (exponent > 0), (modulus > 0) and (modulus even)
            // STEP 1: Obtain the factorization 'modulus'= q * 2^j.
            int        j = modulus.getLowestSetBit();
            BigInteger q = modulus.shiftRight(j);

            // STEP 2: Compute x1 := base^exponent (mod q).
            BigInteger x1 = oddModPow(_base, exponent, q);

            // STEP 3: Compute x2 := base^exponent (mod 2^j).
            BigInteger x2 = pow2ModPow(_base, exponent, j);

            // STEP 4: Compute q^(-1) (mod 2^j) and y := (x2-x1) * q^(-1) (mod 2^j)
            BigInteger qInv = modPow2Inverse(q, j);
            BigInteger y    = (x2.subtract(x1)).multiply(qInv);

            inplaceModPow2(y, j);
            if (y.sign < 0)
            {
                y = y.add(BigInteger.getPowerOfTwo(j));
            }
            // STEP 5: Compute and return: x1 + q * y
            return(x1.add(q.multiply(y)));
        }
示例#2
0
        private static bool millerRabin(BigInteger n, int t)
        {
            // PRE: n >= 0, t >= 0
            BigInteger x;                                      // x := UNIFORM{2...n-1}
            BigInteger y;                                      // y := x^(q * 2^j) mod n
            BigInteger n_minus_1 = n.subtract(BigInteger.ONE); // n-1
            int        bitLength = n_minus_1.bitLength();      // ~ log2(n-1)
            // (q,k) such that: n-1 = q * 2^k and q is odd
            int        k   = n_minus_1.getLowestSetBit();
            BigInteger q   = n_minus_1.shiftRight(k);
            Random     rnd = new Random();

            for (int i = 0; i < t; i++)
            {
                // To generate a witness 'x', first it use the primes of table
                if (i < primes.Length)
                {
                    x = BIprimes[i];
                }
                else    /*
                         * It generates random witness only if it's necesssary. Note
                         * that all methods would call Miller-Rabin with t <= 50 so
                         * this part is only to do more robust the algorithm
                         */
                {
                    do
                    {
                        x = new BigInteger(bitLength, rnd);
                    } while ((x.compareTo(n) >= BigInteger.EQUALS) || (x.sign == 0) ||
                             x.isOne());
                }
                y = x.modPow(q, n);
                if (y.isOne() || y.Equals(n_minus_1))
                {
                    continue;
                }
                for (int j = 1; j < k; j++)
                {
                    if (y.Equals(n_minus_1))
                    {
                        continue;
                    }
                    y = y.multiply(y).mod(n);
                    if (y.isOne())
                    {
                        return(false);
                    }
                }
                if (!y.Equals(n_minus_1))
                {
                    return(false);
                }
            }
            return(true);
        }
示例#3
0
        private static int howManyIterations(BigInteger bi, int n)
        {
            int i = n - 1;

            if (bi.sign > 0)
            {
                while (!bi.testBit(i))
                {
                    i--;
                }
                return(n - 1 - i);
            }
            else
            {
                while (bi.testBit(i))
                {
                    i--;
                }
                return(n - 1 - Math.Max(i, bi.getLowestSetBit()));
            }
        }
示例#4
0
文件: Division.cs 项目: vic/ioke
 private static int howManyIterations(BigInteger bi, int n)
 {
     int i = n - 1;
     if (bi.sign > 0) {
         while (!bi.testBit(i))
             i--;
         return n - 1 - i;
     } else {
         while (bi.testBit(i))
             i--;
         return n - 1 - Math.Max(i, bi.getLowestSetBit());
     }
 }
示例#5
0
文件: Division.cs 项目: vic/ioke
        internal static BigInteger gcdBinary(BigInteger op1, BigInteger op2)
        {
            // PRE: (op1 > 0) and (op2 > 0)

            /*
             * Divide both number the maximal possible times by 2 without rounding
             * gcd(2*a, 2*b) = 2 * gcd(a,b)
             */
            int lsb1 = op1.getLowestSetBit();
            int lsb2 = op2.getLowestSetBit();
            int pow2Count = Math.Min(lsb1, lsb2);

            BitLevel.inplaceShiftRight(op1, lsb1);
            BitLevel.inplaceShiftRight(op2, lsb2);

            BigInteger swap;
            // I want op2 > op1
            if (op1.compareTo(op2) == BigInteger.GREATER) {
                swap = op1;
                op1 = op2;
                op2 = swap;
            }

            do { // INV: op2 >= op1 && both are odd unless op1 = 0

                // Optimization for small operands
                // (op2.bitLength() < 64) implies by INV (op1.bitLength() < 64)
                if (( op2.numberLength == 1 )
                    || ( ( op2.numberLength == 2 ) && ( op2.digits[1] > 0 ) )) {
                    op2 = BigInteger.valueOf(Division.gcdBinary(op1.longValue(),
                                                                op2.longValue()));
                    break;
                }

                // Implements one step of the Euclidean algorithm
                // To reduce one operand if it's much smaller than the other one
                if (op2.numberLength > op1.numberLength * 1.2) {
                    op2 = op2.remainder(op1);
                    if (op2.signum() != 0) {
                        BitLevel.inplaceShiftRight(op2, op2.getLowestSetBit());
                    }
                } else {

                    // Use Knuth's algorithm of successive subtract and shifting
                    do {
                        Elementary.inplaceSubtract(op2, op1); // both are odd
                        BitLevel.inplaceShiftRight(op2, op2.getLowestSetBit()); // op2 is even
                    } while (op2.compareTo(op1) >= BigInteger.EQUALS);
                }
                // now op1 >= op2
                swap = op2;
                op2 = op1;
                op1 = swap;
            } while (op1.sign != 0);
            return op2.shiftLeft(pow2Count);
        }
示例#6
0
文件: Division.cs 项目: vic/ioke
        internal static BigInteger evenModPow(BigInteger _base, BigInteger exponent,
                                     BigInteger modulus)
        {
            // PRE: (base > 0), (exponent > 0), (modulus > 0) and (modulus even)
            // STEP 1: Obtain the factorization 'modulus'= q * 2^j.
            int j = modulus.getLowestSetBit();
            BigInteger q = modulus.shiftRight(j);

            // STEP 2: Compute x1 := base^exponent (mod q).
            BigInteger x1 = oddModPow(_base, exponent, q);

            // STEP 3: Compute x2 := base^exponent (mod 2^j).
            BigInteger x2 = pow2ModPow(_base, exponent, j);

            // STEP 4: Compute q^(-1) (mod 2^j) and y := (x2-x1) * q^(-1) (mod 2^j)
            BigInteger qInv = modPow2Inverse(q, j);
            BigInteger y = (x2.subtract(x1)).multiply(qInv);
            inplaceModPow2(y, j);
            if (y.sign < 0) {
                y = y.add(BigInteger.getPowerOfTwo(j));
            }
            // STEP 5: Compute and return: x1 + q * y
            return x1.add(q.multiply(y));
        }
示例#7
0
        internal static BigInteger gcdBinary(BigInteger op1, BigInteger op2)
        {
            // PRE: (op1 > 0) and (op2 > 0)

            /*
             * Divide both number the maximal possible times by 2 without rounding
             * gcd(2*a, 2*b) = 2 * gcd(a,b)
             */
            int lsb1      = op1.getLowestSetBit();
            int lsb2      = op2.getLowestSetBit();
            int pow2Count = Math.Min(lsb1, lsb2);

            BitLevel.inplaceShiftRight(op1, lsb1);
            BitLevel.inplaceShiftRight(op2, lsb2);

            BigInteger swap;

            // I want op2 > op1
            if (op1.compareTo(op2) == BigInteger.GREATER)
            {
                swap = op1;
                op1  = op2;
                op2  = swap;
            }

            do   // INV: op2 >= op1 && both are odd unless op1 = 0

            // Optimization for small operands
            // (op2.bitLength() < 64) implies by INV (op1.bitLength() < 64)
            {
                if ((op2.numberLength == 1) ||
                    ((op2.numberLength == 2) && (op2.digits[1] > 0)))
                {
                    op2 = BigInteger.valueOf(Division.gcdBinary(op1.longValue(),
                                                                op2.longValue()));
                    break;
                }

                // Implements one step of the Euclidean algorithm
                // To reduce one operand if it's much smaller than the other one
                if (op2.numberLength > op1.numberLength * 1.2)
                {
                    op2 = op2.remainder(op1);
                    if (op2.signum() != 0)
                    {
                        BitLevel.inplaceShiftRight(op2, op2.getLowestSetBit());
                    }
                }
                else
                {
                    // Use Knuth's algorithm of successive subtract and shifting
                    do
                    {
                        Elementary.inplaceSubtract(op2, op1);                   // both are odd
                        BitLevel.inplaceShiftRight(op2, op2.getLowestSetBit()); // op2 is even
                    } while (op2.compareTo(op1) >= BigInteger.EQUALS);
                }
                // now op1 >= op2
                swap = op2;
                op2  = op1;
                op1  = swap;
            } while (op1.sign != 0);
            return(op2.shiftLeft(pow2Count));
        }