public BigInteger(
int bitLength,
int certainty,
Random random)
{
if (bitLength < 2)
throw new ArithmeticException("bitLength < 2");
this.sign = 1;
this.nBitLength = bitLength;
if (bitLength == 2)
{
this.magnitude = random.Next(2) == 0
? Two.magnitude
: Three.magnitude;
return;
}
int nBytes = GetByteLength(bitLength);
byte[] b = new byte[nBytes];
int xBits = BitsPerByte * nBytes - bitLength;
byte mask = rndMask[xBits];
for (;;)
{
random.NextBytes(b);
// strip off any excess bits in the MSB
b[0] &= mask;
// ensure the leading bit is 1 (to meet the strength requirement)
b[0] |= (byte)(1 << (7 - xBits));
// ensure the trailing bit is 1 (i.e. must be odd)
b[nBytes - 1] |= 1;
this.magnitude = MakeMagnitude(b, 0, b.Length);
this.nBits = -1;
this.mQuote = -1L;
if (certainty < 1)
break;
if (CheckProbablePrime(certainty, random))
break;
if (bitLength > 32)
{
for (int rep = 0; rep < 10000; ++rep)
{
int n = 33 + random.Next(bitLength - 2);
this.magnitude[this.magnitude.Length - (n >> 5)] ^= (1 << (n & 31));
this.magnitude[this.magnitude.Length - 1] ^= ((random.Next() + 1) << 1);
this.mQuote = -1L;
if (CheckProbablePrime(certainty, random))
return;
}
}
}
}