Exemplo n.º 1
0
        /**
        * Return a random BigInteger not less than 'min' and not greater than 'max'
        *
        * @param min the least value that may be generated
        * @param max the greatest value that may be generated
        * @param random the source of randomness
        * @return a random BigInteger value in the range [min,max]
        */
        public static BigInteger CreateRandomInRange(
            BigInteger		min,
            BigInteger		max,
            // TODO Should have been just Random class
            SecureRandom	random)
        {
            int cmp = min.CompareTo(max);
            if (cmp >= 0)
            {
                if (cmp > 0)
                    throw new ArgumentException("'min' may not be greater than 'max'");

                return min;
            }

            if (min.BitLength > max.BitLength / 2)
            {
                return CreateRandomInRange(BigInteger.Zero, max.Subtract(min), random).Add(min);
            }

            for (int i = 0; i < MaxIterations; ++i)
            {
                BigInteger x = new BigInteger(max.BitLength, random);
                if (x.CompareTo(min) >= 0 && x.CompareTo(max) <= 0)
                {
                    return x;
                }
            }

            // fall back to a faster (restricted) method
            return new BigInteger(max.Subtract(min).BitLength - 1, random).Add(min);
        }
Exemplo n.º 2
0
		internal bool RabinMillerTest(
			int		certainty,
			Random	random)
		{
			Debug.Assert(certainty > 0);
			Debug.Assert(BitLength > 2);
			Debug.Assert(TestBit(0));

			// let n = 1 + d . 2^s
			BigInteger n = this;
			BigInteger nMinusOne = n.Subtract(One);
			int s = nMinusOne.GetLowestSetBit();
			BigInteger r = nMinusOne.ShiftRight(s);

			Debug.Assert(s >= 1);

			do
			{
				// TODO Make a method for random BigIntegers in range 0 < x < n)
				// - Method can be optimized by only replacing examined bits at each trial
				BigInteger a;
				do
				{
					a = new BigInteger(n.BitLength, random);
				}
				while (a.CompareTo(One) <= 0 || a.CompareTo(nMinusOne) >= 0);

				BigInteger y = a.ModPow(r, n);

				if (!y.Equals(One))
				{
					int j = 0;
					while (!y.Equals(nMinusOne))
					{
						if (++j == s)
							return false;

						y = y.ModPow(Two, n);

						if (y.Equals(One))
							return false;
					}
				}

				certainty -= 2; // composites pass for only 1/4 possible 'a'
			}
			while (certainty > 0);

			return true;
		}