internal static Digits NewPrime(int pBitN, Random generator) { if (pBitN < Digit.BitN) { throw new ArgumentException(); } int pDigitN = (pBitN + (Digit.BitN - 1)) / Digit.BitN; Digits p = new Digits(pDigitN); while (true) { for ( int iteration = 0; iteration < _IterationsAllowed; iteration++ ) { Digits.Random(p, pDigitN, generator); p[pDigitN - 1] >>= Digit.BitN * pDigitN - pBitN; p[0] |= 1; Digits.SetBit(p, pBitN - 1, 1); Digits.SetBit(p, pBitN - 2, 1); if (DivisibleBySomeLowPrime(p, pDigitN)) { continue; } Modulus modulus = new Modulus(p, pDigitN, true); Digits minus1 = new Digits(pDigitN); Modular .Neg(modulus._one, minus1, modulus._mod, modulus._digitN); Digits exp = new Digits(pDigitN); Digits.Shift(p, -1, exp, pDigitN); Digits @base = new Digits(pDigitN); for (int i = 1; i <= _RabinTestN; i++) { if (i == 1) { Modular.Add(modulus._one , modulus._one , @base , modulus._mod , modulus._digitN); } else { Modular.NonZeroRandom( p, @base, pDigitN, generator); } Digits result = new Digits(pDigitN); modulus._Exp(@base, exp, pDigitN, result); if (Digits.Compare(result, minus1, pDigitN) == 0) { return(p); } if ( Digits.Compare(result, modulus._one, pDigitN) != 0 ) { break; } } } Debug.Assert(false, "too many iterations"); } }