public static bool IsProbablePrime(this BigInteger source, int certainty, RandomNumberGenerator random)
        {
            if (source == 2 || source == 3)
                return true;
            if (source < 2 || source % 2 == 0)
                return false;

            BigInteger d = source - 1;
            int s = 0;

            while (d % 2 == 0)
            {
                d /= 2;
                s += 1;
            }

            if (random == null)
            {
                random = Randomizer.GetRandom();
            }

            byte[] bytes = new byte[(source.BitLength() + 7) / 8];
            BigInteger a;

            for (int i = 0; i < certainty; i++)
            {
                do
                {
                    random.GetBytes(bytes);
                    //bytes[bytes.Length - 1] = 0;
                    a = new BigInteger(bytes);
                }
                while (a < 2 || a >= source - 2);

                BigInteger x = BigInteger.ModPow(a, d, source);
                if (x == 1 || x == source - 1)
                    continue;

                for (int r = 1; r < s; r++)
                {
                    x = BigInteger.ModPow(x, 2, source);
                    if (x == 1)
                        return false;
                    if (x == source - 1)
                        break;
                }

                if (x != source - 1)
                    return false;
            }

            return true;
        }
示例#2
0
 public static bool TestBit(this BigInteger i, int n)
 {
     int bitLength = i.BitLength();
     return !(i >> n).IsEven;
 }
示例#3
0
        /// <summary>
        /// Calculates the square root of the current instance.
        /// </summary>
        /// <param name="n">The current instance.</param>
        /// <returns>The square root of the current instance.</returns>
        public static BigInteger Sqrt(this BigInteger n)
        {
            Contract.Requires(n >= 0);
            if (n <= 1) return n;
            BigInteger root = n, lastRoot = BigInteger.Zero;
            int count = 0;
            int bitLength = (n.BitLength() + 1) / 2;
            root = n >> bitLength;

            do
            {
                if (lastRoot > root)
                {
                    if (count++ > 1000)
                    {
                        return root;
                    }
                }

                lastRoot = root;
                root = (BigInteger.Divide(n, root) + root) >> 1;
            }
            while ((root ^ lastRoot) != 0);

            return root;
        }