Exemple #1
0
        internal static BigInteger consBigInteger(int bitLength, int certainty, Random rnd)
        {
            // PRE: bitLength >= 2;
            // For small numbers get a random prime from the prime table
            if (bitLength <= 10) {
                int[] rp = offsetPrimes[bitLength];
                return BIprimes[rp[0] + rnd.Next(rp[1])];
            }
            int shiftCount = (-bitLength) & 31;
            int last = (bitLength + 31) >> 5;
            BigInteger n = new BigInteger(1, last, new int[last]);

            last--;
            do {// To fill the array with random integers
                for (int i = 0; i < n.numberLength; i++) {
                    n.digits[i] = rnd.Next();
                }
                // To fix to the correct bitLength
                n.digits[last] = (int)((uint)n.digits[last] | 0x80000000);
                n.digits[last] = (int)(((uint)n.digits[last]) >> shiftCount);
                // To create an odd number
                n.digits[0] |= 1;
            } while (!isProbablePrime(n, certainty));
            return n;
        }
Exemple #2
0
        internal static BigInteger and(BigInteger val, BigInteger that)
        {
            if (that.sign == 0 || val.sign == 0) {
                return BigInteger.ZERO;
            }
            if (that.Equals(BigInteger.MINUS_ONE)){
                return val;
            }
            if (val.Equals(BigInteger.MINUS_ONE)) {
                return that;
            }

            if (val.sign > 0) {
                if (that.sign > 0) {
                    return andPositive(val, that);
                } else {
                    return andDiffSigns(val, that);
                }
            } else {
                if (that.sign > 0) {
                    return andDiffSigns(that, val);
                } else if (val.numberLength > that.numberLength) {
                    return andNegative(val, that);
                } else {
                    return andNegative(that, val);
                }
            }
        }
Exemple #3
0
        internal static BigInteger andDiffSigns(BigInteger positive, BigInteger negative)
        {
            int iPos = positive.getFirstNonzeroDigit();
            int iNeg = negative.getFirstNonzeroDigit();

            // Look if the trailing zeros of the negative will "blank" all
            // the positive digits
            if (iNeg >= positive.numberLength) {
                return BigInteger.ZERO;
            }
            int resLength = positive.numberLength;
            int[] resDigits = new int[resLength];

            // Must start from max(iPos, iNeg)
            int i = Math.Max(iPos, iNeg);
            if (i == iNeg) {
                resDigits[i] = -negative.digits[i] & positive.digits[i];
                i++;
            }
            int limit = Math.Min(negative.numberLength, positive.numberLength);
            for ( ; i < limit; i++) {
                resDigits[i] = ~negative.digits[i] & positive.digits[i];
            }
            // if the negative was shorter must copy the remaining digits
            // from positive
            if (i >= negative.numberLength) {
                for ( ; i < positive.numberLength; i++) {
                    resDigits[i] = positive.digits[i];
                }
            } // else positive ended and must "copy" virtual 0's, do nothing then

            BigInteger result = new BigInteger(1, resLength, resDigits);
            result.cutOffLeadingZeroes();
            return result;
        }
Exemple #4
0
        internal static bool isProbablePrime(BigInteger n, int certainty)
        {
            // PRE: n >= 0;
            if ((certainty <= 0) || ((n.numberLength == 1) && (n.digits[0] == 2))) {
                return true;
            }
            // To discard all even numbers
            if (!n.testBit(0)) {
                return false;
            }
            // To check if 'n' exists in the table (it fit in 10 bits)
            if ((n.numberLength == 1) && ((n.digits[0] & 0XFFFFFC00) == 0)) {
                return (Array.BinarySearch(primes, n.digits[0]) >= 0);
            }
            // To check if 'n' is divisible by some prime of the table
            for (int i = 1; i < primes.Length; i++) {
                if (Division.remainderArrayByInt(n.digits, n.numberLength,
                                                 primes[i]) == 0) {
                    return false;
                }
            }
            // To set the number of iterations necessary for Miller-Rabin test
            int ix;
            int bitLength = n.bitLength();

            for (ix = 2; bitLength < BITS[ix]; ix++) {
                ;
            }
            certainty = Math.Min(ix, 1 + ((certainty - 1) >> 1));

            return millerRabin(n, certainty);
        }
Exemple #5
0
        public 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);
        }
Exemple #6
0
        internal static BigInteger add(BigInteger op1, BigInteger op2)
        {
            int[] resDigits;
            int resSign;
            int op1Sign = op1.sign;
            int op2Sign = op2.sign;

            if (op1Sign == 0) {
                return op2;
            }
            if (op2Sign == 0) {
                return op1;
            }
            int op1Len = op1.numberLength;
            int op2Len = op2.numberLength;

            if (op1Len + op2Len == 2) {
                long a = (op1.digits[0] & 0xFFFFFFFFL);
                long b = (op2.digits[0] & 0xFFFFFFFFL);
                long ress;
                int valueLo;
                int valueHi;

                if (op1Sign == op2Sign) {
                    ress = a + b;
                    valueLo = (int) ress;
                    valueHi = (int) ((long)(((ulong)ress) >> 32));
                    return ((valueHi == 0) ? new BigInteger(op1Sign, valueLo)
                            : new BigInteger(op1Sign, 2, new int[] { valueLo,
                                                                     valueHi }));
                }
                return BigInteger.valueOf((op1Sign < 0) ? (b - a) : (a - b));
            } else if (op1Sign == op2Sign) {
                resSign = op1Sign;
                // an augend should not be shorter than addend
                resDigits = (op1Len >= op2Len) ? add(op1.digits, op1Len,
                                                     op2.digits, op2Len) : add(op2.digits, op2Len, op1.digits,
                                                                               op1Len);
            } else { // signs are different
                int cmp = ((op1Len != op2Len) ? ((op1Len > op2Len) ? 1 : -1)
                           : compareArrays(op1.digits, op2.digits, op1Len));

                if (cmp == BigInteger.EQUALS) {
                    return BigInteger.ZERO;
                }
                // a minuend should not be shorter than subtrahend
                if (cmp == BigInteger.GREATER) {
                    resSign = op1Sign;
                    resDigits = subtract(op1.digits, op1Len, op2.digits, op2Len);
                } else {
                    resSign = op2Sign;
                    resDigits = subtract(op2.digits, op2Len, op1.digits, op1Len);
                }
            }
            BigInteger res = new BigInteger(resSign, resDigits.Length, resDigits);
            res.cutOffLeadingZeroes();
            return res;
        }
Exemple #7
0
        internal static BigInteger andNegative(BigInteger longer, BigInteger shorter)
        {
            int iLonger = longer.getFirstNonzeroDigit();
            int iShorter = shorter.getFirstNonzeroDigit();

            // Does shorter matter?
            if (iLonger >= shorter.numberLength) {
                return longer;
            }

            int resLength;
            int[] resDigits;
            int i = Math.Max(iShorter, iLonger);
            int digit;
            if (iShorter > iLonger) {
                digit = -shorter.digits[i] & ~longer.digits[i];
            } else if (iShorter < iLonger) {
                digit = ~shorter.digits[i] & -longer.digits[i];
            } else {
                digit = -shorter.digits[i] & -longer.digits[i];
            }
            if (digit == 0) {
                for (i++; i < shorter.numberLength && (digit = ~(longer.digits[i] | shorter.digits[i])) == 0; i++)
                    ;  // digit = ~longer.digits[i] & ~shorter.digits[i]
                if (digit == 0) {
                    // shorter has only the remaining virtual sign bits
                    for ( ; i < longer.numberLength && (digit = ~longer.digits[i]) == 0; i++)
                        ;
                    if (digit == 0) {
                        resLength = longer.numberLength + 1;
                        resDigits = new int[resLength];
                        resDigits[resLength - 1] = 1;

                        return new BigInteger(-1, resLength, resDigits);
                    }
                }
            }
            resLength = longer.numberLength;
            resDigits = new int[resLength];
            resDigits[i] = -digit;
            for (i++; i < shorter.numberLength; i++){
                // resDigits[i] = ~(~longer.digits[i] & ~shorter.digits[i];)
                resDigits[i] = longer.digits[i] | shorter.digits[i];
            }
            // shorter has only the remaining virtual sign bits
            for( ; i < longer.numberLength; i++){
                resDigits[i] = longer.digits[i];
            }

            BigInteger result = new BigInteger(-1, resLength, resDigits);
            return result;
        }
Exemple #8
0
        /** @see BigInteger#doubleValue() */
        internal static double bigInteger2Double(BigInteger val)
        {
            // val.bitLength() < 64
            if ((val.numberLength < 2)
                || ((val.numberLength == 2) && (val.digits[1] > 0))) {
                return val.longValue();
            }
            // val.bitLength() >= 33 * 32 > 1024
            if (val.numberLength > 32) {
                return ((val.sign > 0) ? double.PositiveInfinity
                        : double.NegativeInfinity);
            }

            return Convert.ToDouble(val.ToString());
        }
Exemple #9
0
        internal static BigInteger flipBit(BigInteger val, int n)
        {
            int resSign = (val.sign == 0) ? 1 : val.sign;
            int intCount = n >> 5;
            int bitN = n & 31;
            int resLength = Math.Max(intCount + 1, val.numberLength) + 1;
            int[] resDigits = new int[resLength];
            int i;

            int bitNumber = 1 << bitN;
            Array.Copy(val.digits, 0, resDigits, 0, val.numberLength);

            if (val.sign < 0) {
                if (intCount >= val.numberLength) {
                    resDigits[intCount] = bitNumber;
                } else {
                    //val.sign<0 y intCount < val.numberLength
                    int firstNonZeroDigit = val.getFirstNonzeroDigit();
                    if (intCount > firstNonZeroDigit) {
                        resDigits[intCount] ^= bitNumber;
                    } else if (intCount < firstNonZeroDigit) {
                        resDigits[intCount] = -bitNumber;
                        for (i=intCount + 1; i < firstNonZeroDigit; i++) {
                            resDigits[i]=-1;
                        }
                        resDigits[i] = resDigits[i]--;
                    } else {
                        i = intCount;
                        resDigits[i] = -((-resDigits[intCount]) ^ bitNumber);
                        if (resDigits[i] == 0) {
                            for (i++; resDigits[i] == -1 ; i++) {
                                resDigits[i] = 0;
                            }
                            resDigits[i]++;
                        }
                    }
                }
            } else {//case where val is positive
                resDigits[intCount] ^= bitNumber;
            }
            BigInteger result = new BigInteger(resSign, resLength, resDigits);
            result.cutOffLeadingZeroes();
            return result;
        }
Exemple #10
0
        internal static int bitLength(BigInteger val)
        {
            if (val.sign == 0) {
                return 0;
            }
            int bLength = (val.numberLength << 5);
            int highDigit = val.digits[val.numberLength - 1];

            if (val.sign < 0) {
                int i = val.getFirstNonzeroDigit();
                // We reduce the problem to the positive case.
                if (i == val.numberLength - 1) {
                    highDigit--;
                }
            }
            // Subtracting all sign bits
            bLength -= BigDecimal.numberOfLeadingZeros(highDigit);
            return bLength;
        }
Exemple #11
0
        internal static int bitCount(BigInteger val)
        {
            int bCount = 0;

            if (val.sign == 0) {
                return 0;
            }

            int i = val.getFirstNonzeroDigit();;
            if (val.sign > 0) {
                for ( ; i < val.numberLength; i++) {
                    bCount += BigDecimal.bitCount(val.digits[i]);
                }
            } else {// (sign < 0)
                // this digit absorbs the carry
                bCount += BigDecimal.bitCount(-val.digits[i]);
                for (i++; i < val.numberLength; i++) {
                    bCount += BigDecimal.bitCount(~val.digits[i]);
                }
                // We take the complement sum:
                bCount = (val.numberLength << 5) - bCount;
            }
            return bCount;
        }
Exemple #12
0
        internal static BigInteger nextProbablePrime(BigInteger n)
        {
            // PRE: n >= 0
            int i, j;
            int certainty;
            int gapSize = 1024; // for searching of the next probable prime number
            int[] modules = new int[primes.Length];
            bool[] isDivisible = new bool[gapSize];
            BigInteger startPoint;
            BigInteger probPrime;
            // If n < "last prime of table" searches next prime in the table
            if ((n.numberLength == 1) && (n.digits[0] >= 0)
                && (n.digits[0] < primes[primes.Length - 1])) {
                for (i = 0; n.digits[0] >= primes[i]; i++) {
                    ;
                }
                return BIprimes[i];
            }
            /*
             * Creates a "N" enough big to hold the next probable prime Note that: N <
             * "next prime" < 2*N
             */
            startPoint = new BigInteger(1, n.numberLength,
                                        new int[n.numberLength + 1]);
            Array.Copy(n.digits, startPoint.digits, n.numberLength);
            // To fix N to the "next odd number"
            if (n.testBit(0)) {
                Elementary.inplaceAdd(startPoint, 2);
            } else {
                startPoint.digits[0] |= 1;
            }
            // To set the improved certainly of Miller-Rabin
            j = startPoint.bitLength();
            for (certainty = 2; j < BITS[certainty]; certainty++) {
                ;
            }
            // To calculate modules: N mod p1, N mod p2, ... for first primes.
            for (i = 0; i < primes.Length; i++) {
                modules[i] = Division.remainder(startPoint, primes[i]) - gapSize;
            }
            while (true) {
                // At this point, all numbers in the gap are initialized as
                // probably primes
                Array.Clear(isDivisible, 0, isDivisible.Length);
                // To discard multiples of first primes
                for (i = 0; i < primes.Length; i++) {
                    modules[i] = (modules[i] + gapSize) % primes[i];
                    j = (modules[i] == 0) ? 0 : (primes[i] - modules[i]);
                    for (; j < gapSize; j += primes[i]) {
                        isDivisible[j] = true;
                    }
                }
                // To execute Miller-Rabin for non-divisible numbers by all first
                // primes
                for (j = 0; j < gapSize; j++) {
                    if (!isDivisible[j]) {
                        probPrime = startPoint.copy();
                        Elementary.inplaceAdd(probPrime, j);

                        if (millerRabin(probPrime, certainty)) {
                            return probPrime;
                        }
                    }
                }
                Elementary.inplaceAdd(startPoint, gapSize);
            }
        }
Exemple #13
0
        private static void setFromString(BigInteger bi, String val, int radix)
        {
            int sign;
            int[] digits;
            int numberLength;
            int stringLength = val.Length;
            int startChar;
            int endChar = stringLength;

            if (val[0] == '-') {
                sign = -1;
                startChar = 1;
                stringLength--;
            } else {
                sign = 1;
                startChar = 0;
            }
            /*
             * We use the following algorithm: split a string into portions of n
             * characters and convert each portion to an integer according to the
             * radix. Then convert an exp(radix, n) based number to binary using the
             * multiplication method. See D. Knuth, The Art of Computer Programming,
             * vol. 2.
             */

            int charsPerInt = Conversion.digitFitInInt[radix];
            int bigRadixDigitsLength = stringLength / charsPerInt;
            int topChars = stringLength % charsPerInt;

            if (topChars != 0) {
                bigRadixDigitsLength++;
            }
            digits = new int[bigRadixDigitsLength];
            // Get the maximal power of radix that fits in int
            int bigRadix = Conversion.bigRadices[radix - 2];
            // Parse an input string and accumulate the BigInteger's magnitude
            int digitIndex = 0; // index of digits array
            int substrEnd = startChar + ((topChars == 0) ? charsPerInt : topChars);
            int newDigit;

            for (int substrStart = startChar; substrStart < endChar; substrStart = substrEnd, substrEnd = substrStart
                     + charsPerInt) {
                int bigRadixDigit = Convert.ToInt32(val.Substring(substrStart,
                                                                  substrEnd - substrStart), radix);
                newDigit = Multiplication.multiplyByInt(digits, digitIndex,
                                                        bigRadix);
                newDigit += Elementary
                    .inplaceAdd(digits, digitIndex, bigRadixDigit);
                digits[digitIndex++] = newDigit;
            }
            numberLength = digitIndex;
            bi.sign = sign;
            bi.numberLength = numberLength;
            bi.digits = digits;
            bi.cutOffLeadingZeroes();
        }
Exemple #14
0
 public BigInteger xor(BigInteger val)
 {
     return Logical.xor(this, val);
 }
Exemple #15
0
 public BigInteger subtract(BigInteger val)
 {
     return Elementary.subtract(this, val);
 }
Exemple #16
0
 public BigInteger remainder(BigInteger divisor)
 {
     if (divisor.sign == 0) {
         throw new ArithmeticException("BigInteger divide by zero");
     }
     int thisLen = numberLength;
     int divisorLen = divisor.numberLength;
     if (((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
          : Elementary.compareArrays(digits, divisor.digits, thisLen)) == LESS) {
         return this;
     }
     int resLength = divisorLen;
     int[] resDigits = new int[resLength];
     if (resLength == 1) {
         resDigits[0] = Division.remainderArrayByInt(digits, thisLen,
                                                     divisor.digits[0]);
     } else {
         int qLen = thisLen - divisorLen + 1;
         resDigits = Division.divide(null, qLen, digits, thisLen,
                                     divisor.digits, divisorLen);
     }
     BigInteger result = new BigInteger(sign, resLength, resDigits);
     result.cutOffLeadingZeroes();
     return result;
 }
Exemple #17
0
 public BigInteger multiply(BigInteger val)
 {
     // This let us to throw NullReferenceException when val == null
     if (val.sign == 0) {
         return ZERO;
     }
     if (sign == 0) {
         return ZERO;
     }
     return Multiplication.multiply(this, val);
 }
Exemple #18
0
 public int compareTo(BigInteger val)
 {
     if (sign > val.sign) {
         return GREATER;
     }
     if (sign < val.sign) {
         return LESS;
     }
     if (numberLength > val.numberLength) {
         return sign;
     }
     if (numberLength < val.numberLength) {
         return -val.sign;
     }
     // Equal sign and equal numberLength
     return (sign * Elementary.compareArrays(digits, val.digits,
                                             numberLength));
 }
Exemple #19
0
        public BigInteger modInverse(BigInteger m)
        {
            if (m.sign <= 0) {
                throw new ArithmeticException("BigInteger: modulus not positive");
            }
            // If both are even, no inverse exists
            if (!(testBit(0) || m.testBit(0))) {
                throw new ArithmeticException("BigInteger not invertible.");
            }
            if (m.isOne()) {
                return ZERO;
            }

            // From now on: (m > 1)
            BigInteger res = Division.modInverseMontgomery(abs().mod(m), m);
            if (res.sign == 0) {
                throw new ArithmeticException("BigInteger not invertible.");
            }

            res = ((sign < 0) ? m.subtract(res) : res);
            return res;
        }
Exemple #20
0
        public BigInteger gcd(BigInteger val)
        {
            BigInteger val1 = this.abs();
            BigInteger val2 = val.abs();
            // To avoid a possible division by zero
            if (val1.signum() == 0) {
                return val2;
            } else if (val2.signum() == 0) {
                return val1;
            }

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

            return Division.gcdBinary(val1.copy(), val2.copy());
        }
Exemple #21
0
        public BigInteger[] divideAndRemainder(BigInteger divisor)
        {
            int divisorSign = divisor.sign;
            if (divisorSign == 0) {
                throw new ArithmeticException("BigInteger divide by zero");
            }
            int divisorLen = divisor.numberLength;
            int[] divisorDigits = divisor.digits;
            if (divisorLen == 1) {
                return Division.divideAndRemainderByInteger(this, divisorDigits[0],
                                                            divisorSign);
            }

            // res[0] is a quotient and res[1] is a remainder:
            int[] thisDigits = digits;
            int thisLen = numberLength;
            int cmp = (thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
                : Elementary.compareArrays(thisDigits, divisorDigits, thisLen);
            if (cmp < 0) {
                return new BigInteger[] { ZERO, this };
            }
            int thisSign = sign;
            int quotientLength = thisLen - divisorLen + 1;
            int remainderLength = divisorLen;
            int quotientSign = ((thisSign == divisorSign) ? 1 : -1);
            int[] quotientDigits = new int[quotientLength];
            int[] remainderDigits = Division.divide(quotientDigits, quotientLength,
                                                    thisDigits, thisLen, divisorDigits, divisorLen);
            BigInteger result0 = new BigInteger(quotientSign, quotientLength,
                                                quotientDigits);
            BigInteger result1 = new BigInteger(thisSign, remainderLength,
                                                remainderDigits);
            result0.cutOffLeadingZeroes();
            result1.cutOffLeadingZeroes();
            return new BigInteger[] { result0, result1 };
        }
Exemple #22
0
 public BigInteger divide(BigInteger divisor)
 {
     if (divisor.sign == 0) {
         throw new ArithmeticException("BigInteger divide by zero");
     }
     int divisorSign = divisor.sign;
     if (divisor.isOne()) {
         return ((divisor.sign > 0) ? this : this.negate());
     }
     int thisSign = sign;
     int thisLen = numberLength;
     int divisorLen = divisor.numberLength;
     if (thisLen + divisorLen == 2) {
         long val = (digits[0] & 0xFFFFFFFFL)
             / (divisor.digits[0] & 0xFFFFFFFFL);
         if (thisSign != divisorSign) {
             val = -val;
         }
         return valueOf(val);
     }
     int cmp = ((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1)
                : Elementary.compareArrays(digits, divisor.digits, thisLen));
     if (cmp == EQUALS) {
         return ((thisSign == divisorSign) ? ONE : MINUS_ONE);
     }
     if (cmp == LESS) {
         return ZERO;
     }
     int resLength = thisLen - divisorLen + 1;
     int[] resDigits = new int[resLength];
     int resSign = ((thisSign == divisorSign) ? 1 : -1);
     if (divisorLen == 1) {
         Division.divideArrayByInt(resDigits, digits, thisLen,
                                   divisor.digits[0]);
     } else {
         Division.divide(resDigits, resLength, digits, thisLen,
                         divisor.digits, divisorLen);
     }
     BigInteger result = new BigInteger(resSign, resLength, resDigits);
     result.cutOffLeadingZeroes();
     return result;
 }
Exemple #23
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;
        }
Exemple #24
0
        public BigInteger modPow(BigInteger exponent, BigInteger m)
        {
            if (m.sign <= 0) {
                throw new ArithmeticException("BigInteger: modulus not positive");
            }
            BigInteger _base = this;

            if (m.isOne() | (exponent.sign > 0 & _base.sign == 0)) {
                return BigInteger.ZERO;
            }
            if (_base.sign == 0 && exponent.sign == 0) {
                return BigInteger.ONE;
            }
            if (exponent.sign < 0) {
                _base = modInverse(m);
                exponent = exponent.negate();
            }
            // From now on: (m > 0) and (exponent >= 0)
            BigInteger res = (m.testBit(0)) ? Division.oddModPow(_base.abs(),
                                                                 exponent, m) : Division.evenModPow(_base.abs(), exponent, m);
            if ((_base.sign < 0) && exponent.testBit(0)) {
                // -b^e mod m == ((-1 mod m) * (b^e mod m)) mod m
                res = m.subtract(BigInteger.ONE).multiply(res).mod(m);
            }
            // else exponent is even, so base^exp is positive
            return res;
        }
Exemple #25
0
 public BigInteger max(BigInteger val)
 {
     return ((this.compareTo(val) == GREATER) ? this : val);
 }
Exemple #26
0
 public BigInteger andNot(BigInteger val)
 {
     return Logical.andNot(this, val);
 }
Exemple #27
0
        internal static String toDecimalScaledString(BigInteger val, int scale)
        {
            int sign = val.sign;
            int numberLength = val.numberLength;
            int[] digits = val.digits;
            int resLengthInChars;
            int currentChar;
            char[] result;

            if (sign == 0) {
                switch (scale) {
                case 0:
                    return "0"; //$NON-NLS-1$
                case 1:
                    return "0.0"; //$NON-NLS-1$
                case 2:
                    return "0.00"; //$NON-NLS-1$
                case 3:
                    return "0.000"; //$NON-NLS-1$
                case 4:
                    return "0.0000"; //$NON-NLS-1$
                case 5:
                    return "0.00000"; //$NON-NLS-1$
                case 6:
                    return "0.000000"; //$NON-NLS-1$
                default:
                    StringBuilder result1x = new StringBuilder();
                    if (scale < 0) {
                        result1x.Append("0E+"); //$NON-NLS-1$
                    } else {
                        result1x.Append("0E"); //$NON-NLS-1$
                    }
                    result1x.Append(-scale);
                    return result1x.ToString();
                }
            }
            // one 32-bit unsigned value may contains 10 decimal digits
            resLengthInChars = numberLength * 10 + 1 + 7;
            // Explanation why +1+7:
            // +1 - one char for sign if needed.
            // +7 - For "special case 2" (see below) we have 7 free chars for
            // inserting necessary scaled digits.
            result = new char[resLengthInChars + 1];
            // allocated [resLengthInChars+1] characters.
            // a free latest character may be used for "special case 1" (see
            // below)
            currentChar = resLengthInChars;
            if (numberLength == 1) {
                int highDigit = digits[0];
                if (highDigit < 0) {
                    long v = highDigit & 0xFFFFFFFFL;
                    do {
                        long prev = v;
                        v /= 10;
                        result[--currentChar] = (char) (0x0030 + ((int) (prev - v * 10)));
                    } while (v != 0);
                } else {
                    int v = highDigit;
                    do {
                        int prev = v;
                        v /= 10;
                        result[--currentChar] = (char) (0x0030 + (prev - v * 10));
                    } while (v != 0);
                }
            } else {
                int[] temp = new int[numberLength];
                int tempLen = numberLength;
                Array.Copy(digits, temp, tempLen);
                while (true) {
                    // divide the array of digits by bigRadix and convert
                    // remainders
                    // to characters collecting them in the char array
                    long result11 = 0;
                    for (int i1 = tempLen - 1; i1 >= 0; i1--) {
                        long temp1 = (result11 << 32)
                            + (temp[i1] & 0xFFFFFFFFL);
                        long res = divideLongByBillion(temp1);
                        temp[i1] = (int) res;
                        result11 = (int) (res >> 32);
                    }
                    int resDigit = (int) result11;
                    int previous = currentChar;
                    do {
                        result[--currentChar] = (char) (0x0030 + (resDigit % 10));
                    } while (((resDigit /= 10) != 0) && (currentChar != 0));
                    int delta = 9 - previous + currentChar;
                    for (int i = 0; (i < delta) && (currentChar > 0); i++) {
                        result[--currentChar] = '0';
                    }
                    int j = tempLen - 1;
                    bool bigloop = false;
                    for (; temp[j] == 0; j--) {
                        if (j == 0) { // means temp[0] == 0
                            bigloop = true;
                            break;
                        }
                    }
                    if(bigloop) break;
                    tempLen = j + 1;
                }
                while (result[currentChar] == '0') {
                    currentChar++;
                }
            }
            bool negNumber = (sign < 0);
            int exponent = resLengthInChars - currentChar - scale - 1;
            if (scale == 0) {
                if (negNumber) {
                    result[--currentChar] = '-';
                }
                return new String(result, currentChar, resLengthInChars
                                  - currentChar);
            }
            if ((scale > 0) && (exponent >= -6)) {
                if (exponent >= 0) {
                    // special case 1
                    int insertPoint = currentChar + exponent;
                    for (int j = resLengthInChars - 1; j >= insertPoint; j--) {
                        result[j + 1] = result[j];
                    }
                    result[++insertPoint] = '.';
                    if (negNumber) {
                        result[--currentChar] = '-';
                    }
                    return new String(result, currentChar, resLengthInChars
                                      - currentChar + 1);
                }
                // special case 2
                for (int j = 2; j < -exponent + 1; j++) {
                    result[--currentChar] = '0';
                }
                result[--currentChar] = '.';
                result[--currentChar] = '0';
                if (negNumber) {
                    result[--currentChar] = '-';
                }
                return new String(result, currentChar, resLengthInChars
                                  - currentChar);
            }
            int startPoint = currentChar + 1;
            int endPoint = resLengthInChars;
            StringBuilder result1 = new StringBuilder(16 + endPoint - startPoint);
            if (negNumber) {
                result1.Append('-');
            }
            if (endPoint - startPoint >= 1) {
                result1.Append(result[currentChar]);
                result1.Append('.');
                result1.Append(result, currentChar + 1, resLengthInChars
                               - currentChar - 1);
            } else {
                result1.Append(result, currentChar, resLengthInChars
                               - currentChar);
            }
            result1.Append('E');
            if (exponent > 0) {
                result1.Append('+');
            }
            result1.Append(exponent.ToString());
            return result1.ToString();
        }
Exemple #28
0
 public BigInteger min(BigInteger val)
 {
     return ((this.compareTo(val) == LESS) ? this : val);
 }
Exemple #29
0
        internal static String bigInteger2String(BigInteger val, int radix)
        {
            int sign = val.sign;
            int numberLength = val.numberLength;
            int[] digits = val.digits;

            if (sign == 0) {
                return "0"; //$NON-NLS-1$
            }
            if (numberLength == 1) {
                int highDigit = digits[numberLength - 1];
                long v = highDigit & 0xFFFFFFFFL;
                if (sign < 0) {
                    v = -v;
                }
                return Convert.ToString(v, radix);
            }
            if ((radix == 10) || (radix < 0)
                || (radix > 26)) {
                return val.ToString();
            }
            double bitsForRadixDigit;
            bitsForRadixDigit = Math.Log(radix) / Math.Log(2);
            int resLengthInChars = (int) (val.abs().bitLength() / bitsForRadixDigit + ((sign < 0) ? 1
                                                                                       : 0)) + 1;

            char[] result = new char[resLengthInChars];
            int currentChar = resLengthInChars;
            int resDigit;
            if (radix != 16) {
                int[] temp = new int[numberLength];
                Array.Copy(digits, 0, temp, 0, numberLength);
                int tempLen = numberLength;
                int charsPerInt = digitFitInInt[radix];
                int i;
                // get the maximal power of radix that fits in int
                int bigRadix = bigRadices[radix - 2];
                while (true) {
                    // divide the array of digits by bigRadix and convert remainders
                    // to characters collecting them in the char array
                    resDigit = Division.divideArrayByInt(temp, temp, tempLen,
                                                         bigRadix);
                    int previous = currentChar;
                    do {
                        result[--currentChar] = Convert.ToString(resDigit % radix, radix)[0];
                    } while (((resDigit /= radix) != 0) && (currentChar != 0));
                    int delta = charsPerInt - previous + currentChar;
                    for (i = 0; i < delta && currentChar > 0; i++) {
                        result[--currentChar] = '0';
                    }
                    for (i = tempLen - 1; (i > 0) && (temp[i] == 0); i--) {
                        ;
                    }
                    tempLen = i + 1;
                    if ((tempLen == 1) && (temp[0] == 0)) { // the quotient is 0
                        break;
                    }
                }
            } else {
                // radix == 16
                for (int i = 0; i < numberLength; i++) {
                    for (int j = 0; (j < 8) && (currentChar > 0); j++) {
                        resDigit = digits[i] >> (j << 2) & 0xf;
                        result[--currentChar] = Convert.ToString(resDigit % radix, 16)[0];
                    }
                }
            }
            while (result[currentChar] == '0') {
                currentChar++;
            }
            if (sign == -1) {
                result[--currentChar] = '-';
            }
            return new String(result, currentChar, resLengthInChars - currentChar);
        }
Exemple #30
0
 public BigInteger mod(BigInteger m)
 {
     if (m.sign <= 0) {
         throw new ArithmeticException("BigInteger: modulus not positive");
     }
     BigInteger rem = remainder(m);
     return ((rem.sign < 0) ? rem.add(m) : rem);
 }