Esempio n. 1
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;
		}