Beispiel #1
0
        private bool LongDivide1(Integer ToDivide,
                                 Integer DivideBy,
                                 Integer Quotient,
                                 Integer Remainder)
        {
            uint    Digit     = 0;
            Integer Test1     = new Integer();
            int     TestIndex = ToDivide.GetIndex() - DivideBy.GetIndex();

            if (TestIndex != 0)
            {
                // Is 1 too high?
                Test1.SetDigitAndClear(TestIndex, 1);
                IntMath.MultiplyTopOne(Test1, DivideBy);
                if (ToDivide.ParamIsGreater(Test1))
                {
                    TestIndex--;
                }
            }

            Quotient.SetDigitAndClear(TestIndex, 1);
            Quotient.SetD(TestIndex, 0);
            uint BitTest = 0x80000000;

            while (true)
            {
                // For-loop to test each bit:
                for (int BitCount = 31; BitCount >= 0; BitCount--)
                {
                    Test1.Copy(Quotient);
                    Digit = (uint)Test1.GetD(TestIndex) | BitTest;
                    Test1.SetD(TestIndex, Digit);
                    IntMath.Multiply(Test1, DivideBy);
                    if (Test1.ParamIsGreaterOrEq(ToDivide))
                    {
                        Digit = (uint)Quotient.GetD(TestIndex) | BitTest;
                        // I want to keep this bit because it
                        // passed the test.
                        Quotient.SetD(TestIndex, Digit);
                    }

                    BitTest >>= 1;
                }

                if (TestIndex == 0)
                {
                    break;
                }

                TestIndex--;
                BitTest = 0x80000000;
            }

            Test1.Copy(Quotient);
            IntMath.Multiply(Test1, DivideBy);
            if (Test1.IsEqual(ToDivide))
            {
                Remainder.SetToZero();
                return(true); // Divides exactly.
            }

            Remainder.Copy(ToDivide);
            IntMath.Subtract(Remainder, Test1);

            // Does not divide it exactly.
            return(false);
        }
Beispiel #2
0
        internal bool DecryptWithQInverse(Integer EncryptedNumber,
                                          Integer DecryptedNumber,
                                          Integer TestDecryptedNumber,
                                          Integer PubKeyN,
                                          Integer PrivKInverseExponentDP,
                                          Integer PrivKInverseExponentDQ,
                                          Integer PrimeP,
                                          Integer PrimeQ,
                                          BackgroundWorker Worker)
        {
            Worker.ReportProgress(0, " ");
            Worker.ReportProgress(0, "Top of DecryptWithQInverse().");
            // QInv and the dP and dQ numbers are normally already set up before
            // you start your listening socket.
            ECTime DecryptTime = new ECTime();

            DecryptTime.SetToNow();
            // See section 5.1.2 of RFC 2437 for these steps:
            // http://tools.ietf.org/html/rfc2437
            //      2.2 Let m_1 = c^dP mod p.
            //      2.3 Let m_2 = c^dQ mod q.
            //      2.4 Let h = qInv ( m_1 - m_2 ) mod p.
            //      2.5 Let m = m_2 + hq.
            Worker.ReportProgress(0, "EncryptedNumber: " + IntMath.ToString10(EncryptedNumber));
            //      2.2 Let m_1 = c^dP mod p.
            TestForDecrypt.Copy(EncryptedNumber);
            IntMathForP.ModReduction.ModularPower(TestForDecrypt, PrivKInverseExponentDP, PrimeP, true);
            if (Worker.CancellationPending)
            {
                return(false);
            }

            M1ForInverse.Copy(TestForDecrypt);
            //      2.3 Let m_2 = c^dQ mod q.
            TestForDecrypt.Copy(EncryptedNumber);
            IntMathForQ.ModReduction.ModularPower(TestForDecrypt, PrivKInverseExponentDQ, PrimeQ, true);
            if (Worker.CancellationPending)
            {
                return(false);
            }

            M2ForInverse.Copy(TestForDecrypt);
            //      2.4 Let h = qInv ( m_1 - m_2 ) mod p.
            // How many is optimal to avoid the division?
            int HowManyIsOptimal = (PrimeP.GetIndex() * 3);

            for (int Count = 0; Count < HowManyIsOptimal; Count++)
            {
                if (M1ForInverse.ParamIsGreater(M2ForInverse))
                {
                    M1ForInverse.Add(PrimeP);
                }
                else
                {
                    break;
                }
            }

            if (M1ForInverse.ParamIsGreater(M2ForInverse))
            {
                M1M2SizeDiff.Copy(M2ForInverse);
                IntMath.Subtract(M1M2SizeDiff, M1ForInverse);
                // Unfortunately this long Divide() has to be done.
                IntMath.Divider.Divide(M1M2SizeDiff, PrimeP, Quotient, Remainder);
                Quotient.AddULong(1);
                Worker.ReportProgress(0, "The Quotient for M1M2SizeDiff is: " + IntMath.ToString10(Quotient));
                IntMath.Multiply(Quotient, PrimeP);
                M1ForInverse.Add(Quotient);
            }

            M1MinusM2.Copy(M1ForInverse);
            IntMath.Subtract(M1MinusM2, M2ForInverse);
            if (M1MinusM2.IsNegative)
            {
                throw(new Exception("M1MinusM2.IsNegative is true."));
            }

            if (QInv.IsNegative)
            {
                throw(new Exception("QInv.IsNegative is true."));
            }

            HForQInv.Copy(M1MinusM2);
            IntMath.Multiply(HForQInv, QInv);
            if (HForQInv.IsNegative)
            {
                throw(new Exception("HForQInv.IsNegative is true."));
            }

            if (PrimeP.ParamIsGreater(HForQInv))
            {
                IntMath.Divider.Divide(HForQInv, PrimeP, Quotient, Remainder);
                HForQInv.Copy(Remainder);
            }

            //      2.5 Let m = m_2 + hq.
            DecryptedNumber.Copy(HForQInv);
            IntMath.Multiply(DecryptedNumber, PrimeQ);
            DecryptedNumber.Add(M2ForInverse);
            if (!TestDecryptedNumber.IsEqual(DecryptedNumber))
            {
                throw(new Exception("!TestDecryptedNumber.IsEqual( DecryptedNumber )."));
            }

            Worker.ReportProgress(0, " ");
            Worker.ReportProgress(0, "DecryptedNumber: " + IntMath.ToString10(DecryptedNumber));
            Worker.ReportProgress(0, " ");
            Worker.ReportProgress(0, "TestDecryptedNumber: " + IntMath.ToString10(TestDecryptedNumber));
            Worker.ReportProgress(0, " ");
            Worker.ReportProgress(0, "Decrypt with QInv time seconds: " + DecryptTime.GetSecondsToNow().ToString("N2"));
            Worker.ReportProgress(0, " ");
            return(true);
        }
Beispiel #3
0
        internal bool MultiplicativeInverse(Integer X, Integer Modulus, Integer MultInverse)
        {
            // This is the extended Euclidean Algorithm.
            // A*X + B*Y = Gcd
            // A*X + B*Y = 1 If there's a multiplicative inverse.
            // A*X = 1 - B*Y so A is the multiplicative inverse of X mod Y.
            if (X.IsZero())
            {
                throw(new Exception("Doing Multiplicative Inverse with a parameter that is zero."));
            }

            if (Modulus.IsZero())
            {
                throw(new Exception("Doing Multiplicative Inverse with a parameter that is zero."));
            }

            // This happens sometimes:
            // if( Modulus.ParamIsGreaterOrEq( X ))
            // throw( new Exception( "Modulus.ParamIsGreaterOrEq( X ) for Euclid." ));

            // Worker.ReportProgress( 0, " " );
            // Worker.ReportProgress( 0, " " );
            // Worker.ReportProgress( 0, "Top of mod inverse." );
            // U is the old part to keep.
            U0.SetToZero();
            U1.SetToOne();
            U2.Copy(Modulus); // Don't change the original numbers that came in as parameters.
            // V is the new part.
            V0.SetToOne();
            V1.SetToZero();
            V2.Copy(X);
            T0.SetToZero();
            T1.SetToZero();
            T2.SetToZero();
            Quotient.SetToZero();
            // while( not forever if there's a problem )
            for (int Count = 0; Count < 10000; Count++)
            {
                if (U2.IsNegative)
                {
                    throw(new Exception("U2 was negative."));
                }

                if (V2.IsNegative)
                {
                    throw(new Exception("V2 was negative."));
                }

                IntMath.Divider.Divide(U2, V2, Quotient, Remainder);
                if (Remainder.IsZero())
                {
                    // Worker.ReportProgress( 0, "Remainder is zero. No multiplicative-inverse." );
                    return(false);
                }

                TempEuclid1.Copy(U0);
                TempEuclid2.Copy(V0);
                IntMath.Multiplier.Multiply(TempEuclid2, Quotient);
                IntMath.Subtract(TempEuclid1, TempEuclid2);
                T0.Copy(TempEuclid1);
                TempEuclid1.Copy(U1);
                TempEuclid2.Copy(V1);
                IntMath.Multiplier.Multiply(TempEuclid2, Quotient);
                IntMath.Subtract(TempEuclid1, TempEuclid2);
                T1.Copy(TempEuclid1);
                TempEuclid1.Copy(U2);
                TempEuclid2.Copy(V2);
                IntMath.Multiplier.Multiply(TempEuclid2, Quotient);
                IntMath.Subtract(TempEuclid1, TempEuclid2);
                T2.Copy(TempEuclid1);
                U0.Copy(V0);
                U1.Copy(V1);
                U2.Copy(V2);
                V0.Copy(T0);
                V1.Copy(T1);
                V2.Copy(T2);
                if (Remainder.IsOne())
                {
                    // Worker.ReportProgress( 0, " " );
                    // Worker.ReportProgress( 0, "Remainder is 1. There is a multiplicative-inverse." );
                    break;
                }
            }

            MultInverse.Copy(T0);
            if (MultInverse.IsNegative)
            {
                IntMath.Add(MultInverse, Modulus);
            }

            // Worker.ReportProgress( 0, "MultInverse: " + ToString10( MultInverse ));
            TestForModInverse1.Copy(MultInverse);
            TestForModInverse2.Copy(X);
            IntMath.Multiplier.Multiply(TestForModInverse1, TestForModInverse2);
            IntMath.Divider.Divide(TestForModInverse1, Modulus, Quotient, Remainder);
            if (!Remainder.IsOne()) // By the definition of Multiplicative inverse:
            {
                throw(new Exception("MultInverse is wrong: " + IntMath.ToString10(Remainder)));
            }

            // Worker.ReportProgress( 0, "MultInverse is the right number: " + ToString10( MultInverse ));
            return(true);
        }