Пример #1
0
        void _MulFromLeft(Digits a, Digits b, Digits c)
        {
            Digits product = new Digits(2 * _digitN);

            Digits.Mul(a, _digitN, b, _digitN, product);
            Digits
            .Div(product, 2 * _digitN, _mod, _digitN, _leftRecip, null, c);
        }
Пример #2
0
        internal void _ToModular(Digits a, int aDigitN, Digits b)
        {
            Digits aR;
            int    aRDigitN;

            if (Digits.Compare(a, aDigitN, _mod, _digitN) >= 0)
            {
                aR = new Digits(_digitN);
                Digits.Div(a, aDigitN, _mod, _digitN, _leftRecip, null, aR);
                aRDigitN = _digitN;
            }
            else
            {
                aR       = a;
                aRDigitN = aDigitN;
            }
            aRDigitN = Digits.SigDigitN(aR, aRDigitN);
            Digits.Set(aR, aRDigitN, b, _digitN);
            _Shift(b, _scaleBitN, b);
        }
Пример #3
0
        internal Modulus(Digits mod, int digitN, bool fromRight)
        {
            if (digitN == 0 || mod[digitN - 1] == 0)
            {
                throw new ArgumentException();
            }
            _mod         = mod;
            _digitN      = digitN;
            _fromRight   = fromRight;
            _one         = new Digits(digitN);
            _multiplier1 = new Digits(digitN);
            _multiplier2 = new Digits(digitN);
            // this.mod.Set(this.mod, _digitN);
            _leftRecip = new Reciprocal();
            Digits.DivPrecondition(mod, digitN, _leftRecip);
            Digit mod0inv = 0;

            if ((mod[0] & 1) != 0)
            {
                mod0inv = Digit.TwoAdicInverse(mod[0]);
            }
            _rightRecip = mod0inv;
            int    digitN2 = (digitN + 1) / 2;
            Digits temp    = new Digits(digitN + digitN2);

            if (!fromRight)
            {
                _algorithm = new MulAlgorithm(_MulFromLeft);
                int dividendN = digitN + digitN2;
                _scaleBitN = 0;
                for (int i = 0; i != dividendN; i++)
                {
                    temp[i] = Digit.MaxValue;
                }
                temp[dividendN - 1] = Digit.MaxValue >> _leftRecip._shiftBitN;
                Digits q = new Digits(digitN2 + 1);
                Digits r = new Digits(digitN);
                Digits.Div(temp, dividendN, mod, digitN, _leftRecip, q, r);
                Debug.Assert(q[digitN2] == 1, "internal error");
                Digits.Add(r, 1U, r, digitN);
                Digits.Sub(mod, r, r, digitN);
            }
            else
            {
                _algorithm = new MulAlgorithm(_MulFromRight);
                _scaleBitN = Digit.BitN * digitN;
                if (mod0inv == 0)
                {
                    throw new ArgumentException();
                }
                _multiplier2[0] = mod0inv;
                temp[digitN]    = Digits.Mul(mod, mod0inv, temp, digitN);
                Debug.Assert(temp[0] == 1, "internal error");
                for (int i = 1; i != digitN2; i++)
                {
                    Digit mul = unchecked (0 - mod0inv * temp[i]);
                    _multiplier2[i] = mul;
                    temp[i + digitN]
                        = Digits.Accumulate(mod, mul, temp + i, digitN);
                    Debug.Assert(temp[i] == 0, "internal error");
                }
                _multiplier1._Set(temp + digitN2, digitN);
            }
            _ToModular(new Digits(new Digit[] { 1 }), 1, _one);
        }