コード例 #1
0
ファイル: Prime.cs プロジェクト: vmkc/research-environment
        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");
            }
        }