Esempio n. 1
0
        Sub(Digits a, Digits b, Digits c, Digits mod, int n)
        {
            Debug.Assert(n > 0, "internal error");
            Digit alead = a[n - 1], blead = b[n - 1], mlead = mod[n - 1];
            int   itest;

            if (alead == blead)
            {
                itest = Digits.Compare(a, b, n - 1);
            }
            else
            {
                itest = alead < blead ? -1 : +1;
            }
            if (itest < 0)
            {
                if (blead >= mlead)
                {
                    ValidateData(b, mod, n);
                }
                int carry = Digits.AddSub(a, mod, b, c, n);
                Debug.Assert(carry == 0, "internal error");
            }
            else
            {
                if (alead >= mlead)
                {
                    Debug.Assert(false, "untested code");
                    ValidateData(a, mod, n);
                }
                uint borrow = Digits.Sub(a, b, c, n);
                Debug.Assert(borrow == 0, "internal error");
            }
        }
Esempio n. 2
0
        internal static void Neg(Digits a, Digits b, Digits mod, int n)
        {
            Digit allZero = 0;

            for (int i = 0; i != n; i++)
            {
                allZero |= a[i]; b[i] = a[i];
            }
            if (allZero != 0)
            {
                if (Digits.Sub(mod, b, b, n) != 0)
                {
                    throw new ArgumentException();
                }
            }
        }
Esempio n. 3
0
 void _Shift(Digits a, int n, Digits b)
 {
     if (a != b)
     {
         b._Set(a, _digitN);
     }
     Modular.ValidateData(a, _mod, _digitN);
     if (n < 0 && (_mod[0] & 1) == 0)
     {
         throw new ArgumentException();
     }
     while (n > 0)
     {
         int   shiftNow = n > Digit.BitN ? Digit.BitN : n;
         Digit carryOut = Digits.ShiftLost(b, shiftNow, b, _digitN)
         , qest         = _leftRecip
                          .EstQuotient(carryOut
                                       , b[_digitN - 1]
                                       , _digitN >= 2 ? b[_digitN - 2] : 0);
         carryOut -= Digits.Decumulate(_mod, qest, b, _digitN);
         if (carryOut != 0 || Digits.Compare(b, _mod, _digitN) >= 0)
         {
             carryOut -= Digits.Sub(b, _mod, b, _digitN);
         }
         Debug.Assert(carryOut == 0, "internal error");
         n -= shiftNow;
     }
     while (n < 0)
     {
         int   shiftNow = -n > Digit.BitN ? Digit.BitN : -n;
         Digit mul      = unchecked (0 - _rightRecip * b[0])
                          & Digit.MaxValue >> Digit.BitN - shiftNow
         , carry       = Digits.Accumulate(_mod, mul, b, _digitN)
         , lowBitNLost = Digits.ShiftLost(b, -shiftNow, b, _digitN);
         b[_digitN - 1] |= carry << Digit.BitN - shiftNow;
         Debug.Assert(lowBitNLost == 0, "internal error");
         n += shiftNow;
     }
 }
Esempio n. 4
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);
        }
Esempio n. 5
0
            public Key(int bitN, Random generator)
            {
                _modBitN = bitN;
                // The public exponent is 2^16 + 1
                _eBitN  = 17;
                _eBytes = new byte[] { 1, 0, 1 };
                int p1BitN = (bitN + 1) / 2
                , p1ByteN = (p1BitN + 7) / 8
                , p1DigitN = (p1BitN + (Digit.BitN - 1)) / Digit.BitN
                , p2BitN = bitN / 2
                , p2ByteN = (p2BitN + 7) / 8
                , p2DigitN = (p2BitN + (Digit.BitN - 1)) / Digit.BitN
                , longerDigitN = p1DigitN > p2DigitN ? p1DigitN : p2DigitN;
                Digits d1 = new Digits(p1DigitN), d2 = new Digits(p2DigitN);

                _modDigits = new Digits(_modDigitN);
                _eDigits   = new Digits(1);
                Digits gcd = new Digits(longerDigitN)
                , temp     = new Digits(longerDigitN);

                Digits.BytesToDigits(_eBytes, 0, _eDigits, _eBitN);
                int[]  pBitN = new int[] { p1BitN, p2BitN };
                int    nPrimeFound = 0;
                Digits p1 = null, p2 = null;

                while (nPrimeFound != 2)
                {
                    int pNowBitN = pBitN[nPrimeFound]
                    , pNowDigitN
                        = (pNowBitN + (Digit.BitN - 1)) / Digit.BitN;
                    Digits pNow = Prime.NewPrime(pNowBitN, generator);
                    if (nPrimeFound == 0)
                    {
                        p1 = pNow;
                    }
                    else
                    {
                        p2 = pNow;
                    }
                    Digits.Sub(pNow, 1, temp, pNowDigitN);
                    int lgcd;
                    Digits.ExtendedGcd(_eDigits
                                       , _eDigitN
                                       , temp
                                       , pNowDigitN
                                       , nPrimeFound == 0 ? d1 : d2
                                       , null
                                       , gcd
                                       , out lgcd);
                    if (Digits.Compare(gcd, 1, lgcd) != 0)
                    {
                        Debug.Assert(false, "untested code");
                        continue;
                    }
                    if (
                        nPrimeFound == 1 &&
                        Digits.Compare(p1, p1DigitN, p2, p2DigitN) == 0
                        )
                    {
                        Debug.Assert(false, "untested code");
                        continue;
                    }
                    nPrimeFound++;
                }
                Digits.Mul(p1, p1DigitN, p2, p2DigitN, _modDigits);
                int modBitN = Digits.SigBitN(_modDigits, _modDigitN);

                Debug.Assert(modBitN == p1BitN + p2BitN && modBitN == _modBitN
                             , "internal error");
                _primeBitN = new int[2] {
                    p1BitN, p2BitN
                };
                _modBytes = new byte[_modByteN];
                _primeBytes
                    = new byte[2][] { new byte[p1ByteN], new byte[p2ByteN] };
                _dBytes
                    = new byte[2][] { new byte[p1ByteN], new byte[p2ByteN] };
                Digits.DigitsToBytes(_modDigits, _modBytes, 0, _modBitN);
                for (int ip = 0; ip != 2; ip++)
                {
                    Digits.DigitsToBytes(
                        ip == 0 ? p1 : p2, _primeBytes[ip], 0, pBitN[ip]);
                    Digits.DigitsToBytes(
                        ip == 0 ? d1 : d2, _dBytes[ip], 0, pBitN[ip]);
                }
                int moduliCreated = 0;

                Digits.BytesToDigits(_eBytes, 0, _eDigits, _eBitN);
                _modulus        = new Modulus(_modDigits, _modDigitN, true);
                _privateModulus = new Modulus[2];
                _dDigits        = new Digits[2];
                _chineseDigits  = new Digits[2];
                for (int ip = 0; ip != 2; ip++)
                {
                    Digits temp2 = new Digits(_modDigitN);
                    _dDigits[ip]       = new Digits(p1DigitN);
                    _chineseDigits[ip] = new Digits(p1DigitN);
                    Digits.BytesToDigits(
                        _primeBytes[ip], 0, temp2, _primeBitN[ip]);
                    _privateModulus[ip]
                        = new
                          Modulus(temp2
                                  , (_primeBitN[ip] + (Digit.BitN - 1)) / Digit.BitN
                                  , true);
                    moduliCreated++;
                    Digits.BytesToDigits(
                        _dBytes[ip], 0, _dDigits[ip], _primeBitN[ip]);
                }
                int    lgcd2 = 0;
                Digits gcd2  = new Digits(_modDigitN);

                Digits.ExtendedGcd(_privateModulus[0]._mod
                                   , p1DigitN
                                   , _privateModulus[1]._mod
                                   , p2DigitN
                                   , _chineseDigits[1]
                                   , _chineseDigits[0]
                                   , gcd2
                                   , out lgcd2);
                if (Digits.Compare(gcd2, 1, lgcd2) != 0)
                {
                    throw new ArgumentException();
                }
            }