Exemplo n.º 1
0
        static void Random(Digits mod, Digits arr, int n, Random generator)
        {
            Debug.Assert(!arr._Overlaps(mod), "overlapping arguments");
            int sigDigitN = n;

            while (sigDigitN > 0 && mod[sigDigitN - 1] == 0)
            {
                Debug.Assert(false, "untested code");
                arr[sigDigitN - 1] = 0;
                sigDigitN--;
            }
            if (sigDigitN == 0)
            {
                throw new ArgumentException();
            }
            Digit nlead = mod[sigDigitN - 1];
            int   ntry  = 0;

            do
            {
                ntry++;
                Debug.Assert(ntry <= 100, "too many iterations");
                Digits.Random(arr, sigDigitN - 1, generator);
                arr[sigDigitN - 1] = Digit.Random(0, nlead, generator);
            } while (Digits.Compare(arr, mod, sigDigitN) >= 0);
        }
Exemplo n.º 2
0
        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");
            }
        }