shiftRight() private static method

private static shiftRight ( uint buffer, int shiftVal ) : int
buffer uint
shiftVal int
return int
Ejemplo n.º 1
0
        /*
         * Performs modular exponentiation using the Montgomery Reduction. It
         * requires that all parameters be positive and the modulus be even. Based
         * <i>The square and multiply algorithm and the Montgomery Reduction C. K.
         * Koc - Montgomery Reduction with Even Modulus</i>. The square and
         * multiply algorithm and the Montgomery Reduction.
         *
         * @ar.org.fitc.ref "C. K. Koc - Montgomery Reduction with Even Modulus"
         * @see BigInteger#modPow(BigInteger, BigInteger)
         */
        internal static BigInteger evenModPow(BigInteger baseJ, 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(baseJ, exponent, q);

            // STEP 3: Compute x2 := base^exponent (mod 2^j).
            BigInteger x2 = pow2ModPow(baseJ, 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)));
        }
Ejemplo n.º 2
0
        public BDD ithVar(BigInteger val)
        {
            if (val.signum() < 0 || val.compareTo(size()) >= 0)
            {
                throw new BDDException(val + " is out of range");
            }

            BDDFactory factory = getFactory();
            BDD        v       = factory.one();

            int[] ivar = this.vars();
            for (int n = 0; n < ivar.Length; n++)
            {
                if (val.testBit(0))
                {
                    v.andWith(factory.ithVar(ivar[n]));
                }
                else
                {
                    v.andWith(factory.nithVar(ivar[n]));
                }
                val = val.shiftRight(1);
            }

            return(v);
        }
Ejemplo n.º 3
0
        /*
         * The Miller-Rabin primality test.
         *
         * @param n the input number to be tested.
         * @param t the number of trials.
         * @return {@code false} if the number is definitely compose, otherwise
         *         {@code true} with probability {@code 1 - 4<sup>(-t)</sup>}.
         * @ar.org.fitc.ref "D. Knuth, The Art of Computer Programming Vo.2, Section
         *                  4.5.4., Algorithm P"
         */
        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);

            java.util.Random rnd = new java.util.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);
        }
Ejemplo n.º 4
0
        /// <summary>Calculate Log2 of a BigInteger object value.</summary>
        /// <remarks>Calculate Log2 of a BigInteger object value.</remarks>
        /// <param name="val">BigInteger object value which will calculate with log2</param>
        /// <returns>Result of calculating of val as double value</returns>
        public static double logBigInteger(BigInteger val)
        {
            double LOG2 = java.lang.Math.log(2.0);
            int    blex = val.bitLength() - 1022;

            if (blex > 0)
            {
                val = val.shiftRight(blex);
            }
            double res = java.lang.Math.log(val.doubleValue());

            return(blex > 0 ? res + blex * LOG2 : res);
        }
Ejemplo n.º 5
0
        /**
         * <p>Returns what corresponds to a disjunction of all possible values of this
         * domain. This is more efficient than doing ithVar(0) OR ithVar(1) ...
         * explicitly for all values in the domain.</p>
         *
         * <p>Compare to fdd_domain.</p>
         */
        public BDD domain()
        {
            BDDFactory factory = getFactory();

            /* Encode V<=X-1. V is the variables in 'var' and X is the domain size */
            BigInteger val = size().subtract(BigInteger.ONE);
            BDD        d   = factory.one();

            int[] ivar = vars();
            for (int n = 0; n < this.varNum(); n++)
            {
                if (val.testBit(0))
                {
                    d.orWith(factory.nithVar(ivar[n]));
                }
                else
                {
                    d.andWith(factory.nithVar(ivar[n]));
                }
                val = val.shiftRight(1);
            }
            return(d);
        }
Ejemplo n.º 6
0
        /*
         * Performs the multiplication with the Karatsuba's algorithm.
         * <b>Karatsuba's algorithm:</b>
         *<tt>
         *             u = u<sub>1</sub> * B + u<sub>0</sub><br>
         *             v = v<sub>1</sub> * B + v<sub>0</sub><br>
         *
         *
         *  u*v = (u<sub>1</sub> * v<sub>1</sub>) * B<sub>2</sub> + ((u<sub>1</sub> - u<sub>0</sub>) * (v<sub>0</sub> - v<sub>1</sub>) + u<sub>1</sub> * v<sub>1</sub> +
         *  u<sub>0</sub> * v<sub>0</sub> ) * B + u<sub>0</sub> * v<sub>0</sub><br>
         *</tt>
         * @param op1 first factor of the product
         * @param op2 second factor of the product
         * @return {@code op1 * op2}
         * @see #multiply(BigInteger, BigInteger)
         */
        internal static BigInteger karatsuba(BigInteger op1, BigInteger op2)
        {
            BigInteger temp;

            if (op2.numberLength > op1.numberLength)
            {
                temp = op1;
                op1  = op2;
                op2  = temp;
            }
            if (op2.numberLength < whenUseKaratsuba)
            {
                return(multiplyPAP(op1, op2));
            }

            /*  Karatsuba:  u = u1*B + u0
             *              v = v1*B + v0
             *  u*v = (u1*v1)*B^2 + ((u1-u0)*(v0-v1) + u1*v1 + u0*v0)*B + u0*v0
             */
            // ndiv2 = (op1.numberLength / 2) * 32
            int        ndiv2    = (int)((op1.numberLength & 0xFFFFFFFE) << 4);
            BigInteger upperOp1 = op1.shiftRight(ndiv2);
            BigInteger upperOp2 = op2.shiftRight(ndiv2);
            BigInteger lowerOp1 = op1.subtract(upperOp1.shiftLeft(ndiv2));
            BigInteger lowerOp2 = op2.subtract(upperOp2.shiftLeft(ndiv2));

            BigInteger upper  = karatsuba(upperOp1, upperOp2);
            BigInteger lower  = karatsuba(lowerOp1, lowerOp2);
            BigInteger middle = karatsuba(upperOp1.subtract(lowerOp1),
                                          lowerOp2.subtract(upperOp2));

            middle = middle.add(upper).add(lower);
            middle = middle.shiftLeft(ndiv2);
            upper  = upper.shiftLeft(ndiv2 << 1);

            return(upper.add(middle).add(lower));
        }
Ejemplo n.º 7
0
        /**
         * Performs modular exponentiation using the Montgomery Reduction. It
         * requires that all parameters be positive and the modulus be even. Based
         * <i>The square and multiply algorithm and the Montgomery Reduction C. K.
         * Koc - Montgomery Reduction with Even Modulus</i>. The square and
         * multiply algorithm and the Montgomery Reduction.
         *
         * @ar.org.fitc.ref "C. K. Koc - Montgomery Reduction with Even Modulus"
         * @see BigInteger#modPow(BigInteger, BigInteger)
         */
        internal static BigInteger evenModPow(BigInteger baseJ, 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(baseJ, exponent, q);

            // STEP 3: Compute x2 := base^exponent (mod 2^j).
            BigInteger x2 = pow2ModPow(baseJ, 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));
        }
Ejemplo n.º 8
0
        /**
         * Performs the multiplication with the Karatsuba's algorithm.
         * <b>Karatsuba's algorithm:</b>
         *<tt>
         *             u = u<sub>1</sub> * B + u<sub>0</sub><br>
         *             v = v<sub>1</sub> * B + v<sub>0</sub><br>
         *
         *
         *  u*v = (u<sub>1</sub> * v<sub>1</sub>) * B<sub>2</sub> + ((u<sub>1</sub> - u<sub>0</sub>) * (v<sub>0</sub> - v<sub>1</sub>) + u<sub>1</sub> * v<sub>1</sub> +
         *  u<sub>0</sub> * v<sub>0</sub> ) * B + u<sub>0</sub> * v<sub>0</sub><br>
         *</tt>
         * @param op1 first factor of the product
         * @param op2 second factor of the product
         * @return {@code op1 * op2}
         * @see #multiply(BigInteger, BigInteger)
         */
        internal static BigInteger karatsuba(BigInteger op1, BigInteger op2)
        {
            BigInteger temp;
            if (op2.numberLength > op1.numberLength) {
                temp = op1;
                op1 = op2;
                op2 = temp;
            }
            if (op2.numberLength < whenUseKaratsuba) {
                return multiplyPAP(op1, op2);
            }
            /*  Karatsuba:  u = u1*B + u0
             *              v = v1*B + v0
             *  u*v = (u1*v1)*B^2 + ((u1-u0)*(v0-v1) + u1*v1 + u0*v0)*B + u0*v0
             */
            // ndiv2 = (op1.numberLength / 2) * 32
            int ndiv2 = (int)((op1.numberLength & 0xFFFFFFFE) << 4);
            BigInteger upperOp1 = op1.shiftRight(ndiv2);
            BigInteger upperOp2 = op2.shiftRight(ndiv2);
            BigInteger lowerOp1 = op1.subtract(upperOp1.shiftLeft(ndiv2));
            BigInteger lowerOp2 = op2.subtract(upperOp2.shiftLeft(ndiv2));

            BigInteger upper = karatsuba(upperOp1, upperOp2);
            BigInteger lower = karatsuba(lowerOp1, lowerOp2);
            BigInteger middle = karatsuba( upperOp1.subtract(lowerOp1),
                    lowerOp2.subtract(upperOp2));
            middle = middle.add(upper).add(lower);
            middle = middle.shiftLeft(ndiv2);
            upper = upper.shiftLeft(ndiv2 << 1);

            return upper.add(middle).add(lower);
        }